Browse Source

Merge branch 'class-validator' into dev

Conflicts:
	dist/index.js
sanex3339 8 years ago
parent
commit
835051ac72

+ 295 - 209
dist/index.js

@@ -79,7 +79,7 @@ module.exports =
 /******/ 	__webpack_require__.p = "";
 /******/
 /******/ 	// Load entry module and return exports
-/******/ 	return __webpack_require__(__webpack_require__.s = 60);
+/******/ 	return __webpack_require__(__webpack_require__.s = 61);
 /******/ })
 /************************************************************************/
 /******/ ([
@@ -93,7 +93,7 @@ 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 chance_1 = __webpack_require__(55);
+var chance_1 = __webpack_require__(56);
 var JSFuck_1 = __webpack_require__(9);
 
 var Utils = function () {
@@ -629,7 +629,7 @@ 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 JavaScriptObfuscatorCLI_1 = __webpack_require__(25);
+var JavaScriptObfuscatorCLI_1 = __webpack_require__(23);
 var JavaScriptObfuscatorInternal_1 = __webpack_require__(14);
 
 var JavaScriptObfuscator = function () {
@@ -811,8 +811,8 @@ var esprima = __webpack_require__(17);
 var escodegen = __webpack_require__(10);
 var ObfuscationResult_1 = __webpack_require__(15);
 var Obfuscator_1 = __webpack_require__(20);
-var Options_1 = __webpack_require__(21);
-var SourceMapCorrector_1 = __webpack_require__(23);
+var Options_1 = __webpack_require__(45);
+var SourceMapCorrector_1 = __webpack_require__(21);
 
 var JavaScriptObfuscatorInternal = function () {
     function JavaScriptObfuscatorInternal(sourceCode, obfuscatorOptions) {
@@ -970,19 +970,19 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
 var estraverse = __webpack_require__(4);
 var AppendState_1 = __webpack_require__(2);
 var NodeType_1 = __webpack_require__(6);
-var CatchClauseObfuscator_1 = __webpack_require__(39);
-var ConsoleOutputNodesGroup_1 = __webpack_require__(35);
-var DebugProtectionNodesGroup_1 = __webpack_require__(36);
-var FunctionDeclarationObfuscator_1 = __webpack_require__(40);
-var FunctionObfuscator_1 = __webpack_require__(41);
-var LiteralObfuscator_1 = __webpack_require__(42);
-var MemberExpressionObfuscator_1 = __webpack_require__(43);
-var MethodDefinitionObfuscator_1 = __webpack_require__(44);
+var CatchClauseObfuscator_1 = __webpack_require__(37);
+var ConsoleOutputNodesGroup_1 = __webpack_require__(33);
+var DebugProtectionNodesGroup_1 = __webpack_require__(34);
+var FunctionDeclarationObfuscator_1 = __webpack_require__(38);
+var FunctionObfuscator_1 = __webpack_require__(39);
+var LiteralObfuscator_1 = __webpack_require__(40);
+var MemberExpressionObfuscator_1 = __webpack_require__(41);
+var MethodDefinitionObfuscator_1 = __webpack_require__(42);
 var NodeUtils_1 = __webpack_require__(1);
-var ObjectExpressionObfuscator_1 = __webpack_require__(45);
-var SelfDefendingNodesGroup_1 = __webpack_require__(37);
-var UnicodeArrayNodesGroup_1 = __webpack_require__(38);
-var VariableDeclarationObfuscator_1 = __webpack_require__(46);
+var ObjectExpressionObfuscator_1 = __webpack_require__(43);
+var SelfDefendingNodesGroup_1 = __webpack_require__(35);
+var UnicodeArrayNodesGroup_1 = __webpack_require__(36);
+var VariableDeclarationObfuscator_1 = __webpack_require__(44);
 
 var Obfuscator = function () {
     function Obfuscator(options) {
@@ -1058,137 +1058,6 @@ exports.Obfuscator = Obfuscator;
 "use strict";
 "use strict";
 
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var Joi = __webpack_require__(58);
-var DefaultPreset_1 = __webpack_require__(16);
-var OptionsNormalizer_1 = __webpack_require__(22);
-
-var Options = function Options(obfuscatorOptions) {
-    _classCallCheck(this, Options);
-
-    this.schema = Joi.object({
-        compact: Joi.boolean(),
-        debugProtection: Joi.boolean(),
-        debugProtectionInterval: Joi.boolean(),
-        disableConsoleOutput: Joi.boolean(),
-        encodeUnicodeLiterals: Joi.boolean(),
-        reservedNames: Joi.array().items(Joi.string()),
-        rotateUnicodeArray: Joi.boolean(),
-        selfDefending: Joi.boolean(),
-        sourceMap: Joi.boolean(),
-        sourceMapMode: Joi.string().valid(['inline', 'separate']),
-        unicodeArray: Joi.boolean(),
-        unicodeArrayThreshold: Joi.number().min(0).max(1),
-        wrapUnicodeArrayCalls: Joi.boolean()
-    });
-    Joi.validate(obfuscatorOptions, this.schema, function (error) {
-        if (error) {
-            throw error;
-        }
-    });
-    Object.assign(this, OptionsNormalizer_1.OptionsNormalizer.normalizeOptions(Object.assign({}, DefaultPreset_1.DEFAULT_PRESET, obfuscatorOptions)));
-};
-
-exports.Options = Options;
-
-/***/ },
-/* 22 */
-/***/ function(module, exports) {
-
-"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; }; }();
-
-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);
-    }
-
-    _createClass(OptionsNormalizer, null, [{
-        key: "normalizeOptions",
-        value: function normalizeOptions(options) {
-            var normalizedOptions = Object.assign({}, options);
-            var _iteratorNormalCompletion = true;
-            var _didIteratorError = false;
-            var _iteratorError = undefined;
-
-            try {
-                for (var _iterator = OptionsNormalizer.normalizerRules[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
-                    var normalizerRule = _step.value;
-
-                    normalizedOptions = normalizerRule(normalizedOptions);
-                }
-            } catch (err) {
-                _didIteratorError = true;
-                _iteratorError = err;
-            } finally {
-                try {
-                    if (!_iteratorNormalCompletion && _iterator.return) {
-                        _iterator.return();
-                    }
-                } finally {
-                    if (_didIteratorError) {
-                        throw _iteratorError;
-                    }
-                }
-            }
-
-            return normalizedOptions;
-        }
-    }, {
-        key: "selfDefendingRule",
-        value: function selfDefendingRule(options) {
-            if (options.selfDefending) {
-                Object.assign(options, OptionsNormalizer.SELF_DEFENDING_OPTIONS);
-            }
-            return options;
-        }
-    }, {
-        key: "unicodeArrayRule",
-        value: function unicodeArrayRule(options) {
-            if (!options.unicodeArray) {
-                Object.assign(options, OptionsNormalizer.DISABLED_UNICODE_ARRAY_OPTIONS);
-            }
-            return options;
-        }
-    }, {
-        key: "unicodeArrayThresholdRule",
-        value: function unicodeArrayThresholdRule(options) {
-            if (options.unicodeArrayThreshold === 0) {
-                Object.assign(options, OptionsNormalizer.DISABLED_UNICODE_ARRAY_OPTIONS);
-            }
-            return options;
-        }
-    }]);
-
-    return OptionsNormalizer;
-}();
-
-OptionsNormalizer.DISABLED_UNICODE_ARRAY_OPTIONS = {
-    encodeUnicodeLiterals: false,
-    rotateUnicodeArray: false,
-    unicodeArray: false,
-    unicodeArrayThreshold: 0,
-    wrapUnicodeArrayCalls: false
-};
-OptionsNormalizer.SELF_DEFENDING_OPTIONS = {
-    compact: true,
-    selfDefending: true
-};
-OptionsNormalizer.normalizerRules = [OptionsNormalizer.unicodeArrayRule, OptionsNormalizer.unicodeArrayThresholdRule, OptionsNormalizer.selfDefendingRule];
-exports.OptionsNormalizer = OptionsNormalizer;
-
-/***/ },
-/* 23 */
-/***/ 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; }; }();
 
 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
@@ -1249,7 +1118,7 @@ var SourceMapCorrector = function () {
 exports.SourceMapCorrector = SourceMapCorrector;
 
 /***/ },
-/* 24 */
+/* 22 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -1259,8 +1128,8 @@ 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 fs = __webpack_require__(57);
-var mkdirp = __webpack_require__(59);
+var fs = __webpack_require__(59);
+var mkdirp = __webpack_require__(60);
 var path = __webpack_require__(18);
 var Utils_1 = __webpack_require__(0);
 
@@ -1336,7 +1205,7 @@ CLIUtils.encoding = 'utf8';
 exports.CLIUtils = CLIUtils;
 
 /***/ },
-/* 25 */
+/* 23 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -1346,11 +1215,11 @@ 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 commander = __webpack_require__(56);
 var path = __webpack_require__(18);
+var commander_1 = __webpack_require__(58);
 var SourceMapMode_1 = __webpack_require__(11);
 var DefaultPreset_1 = __webpack_require__(16);
-var CLIUtils_1 = __webpack_require__(24);
+var CLIUtils_1 = __webpack_require__(22);
 var JavaScriptObfuscator_1 = __webpack_require__(8);
 var JavaScriptObfuscatorInternal_1 = __webpack_require__(14);
 var Utils_1 = __webpack_require__(0);
@@ -1395,7 +1264,7 @@ var JavaScriptObfuscatorCLI = function () {
     }, {
         key: 'configureCommands',
         value: function configureCommands() {
-            this.commands = new commander.Command().version(JavaScriptObfuscatorCLI.getBuildVersion(), '-v, --version').usage('<inputPath> [options]').option('-o, --output <path>', 'Output path for obfuscated code').option('--compact <boolean>', 'Disable one line output code compacting', JavaScriptObfuscatorCLI.parseBoolean).option('--debugProtection <boolean>', 'Disable browser Debug panel (can cause DevTools enabled browser freeze)', JavaScriptObfuscatorCLI.parseBoolean).option('--debugProtectionInterval <boolean>', 'Disable browser Debug panel even after page was loaded (can cause DevTools enabled browser freeze)', JavaScriptObfuscatorCLI.parseBoolean).option('--disableConsoleOutput <boolean>', 'Allow console.log, console.info, console.error and console.warn messages output into browser console', JavaScriptObfuscatorCLI.parseBoolean).option('--encodeUnicodeLiterals <boolean>', 'All literals in Unicode array become encoded in Base64 (this option can slightly slow down your code speed)', JavaScriptObfuscatorCLI.parseBoolean).option('--reservedNames <list>', 'Disable obfuscation of variable names, function names and names of function parameters that match the passed RegExp patterns (comma separated)', function (val) {
+            this.commands = new commander_1.Command().version(JavaScriptObfuscatorCLI.getBuildVersion(), '-v, --version').usage('<inputPath> [options]').option('-o, --output <path>', 'Output path for obfuscated code').option('--compact <boolean>', 'Disable one line output code compacting', JavaScriptObfuscatorCLI.parseBoolean).option('--debugProtection <boolean>', 'Disable browser Debug panel (can cause DevTools enabled browser freeze)', JavaScriptObfuscatorCLI.parseBoolean).option('--debugProtectionInterval <boolean>', 'Disable browser Debug panel even after page was loaded (can cause DevTools enabled browser freeze)', JavaScriptObfuscatorCLI.parseBoolean).option('--disableConsoleOutput <boolean>', 'Allow console.log, console.info, console.error and console.warn messages output into browser console', JavaScriptObfuscatorCLI.parseBoolean).option('--encodeUnicodeLiterals <boolean>', 'All literals in Unicode array become encoded in Base64 (this option can slightly slow down your code speed)', JavaScriptObfuscatorCLI.parseBoolean).option('--reservedNames <list>', 'Disable obfuscation of variable names, function names and names of function parameters that match the passed RegExp patterns (comma separated)', function (val) {
                 return val.split(',');
             }).option('--rotateUnicodeArray <boolean>', 'Disable rotation of unicode array values during obfuscation', JavaScriptObfuscatorCLI.parseBoolean).option('--selfDefending <boolean>', 'Disables self-defending for obfuscated code', JavaScriptObfuscatorCLI.parseBoolean).option('--sourceMap <boolean>', 'Enables source map generation', JavaScriptObfuscatorCLI.parseBoolean).option('--sourceMapMode <string> [inline, separate]', 'Specify source map output mode', JavaScriptObfuscatorCLI.parseSourceMapMode).option('--unicodeArray <boolean>', 'Disables gathering of all literal strings into an array and replacing every literal string with an array call', JavaScriptObfuscatorCLI.parseBoolean).option('--unicodeArrayThreshold <number>', 'The probability that the literal string will be inserted into unicodeArray (Default: 0.8, Min: 0, Max: 1)', parseFloat).option('--wrapUnicodeArrayCalls <boolean>', 'Disables usage of special access function instead of direct array call', JavaScriptObfuscatorCLI.parseBoolean).parse(this.rawArguments);
             this.commands.on('--help', function () {
@@ -1472,7 +1341,7 @@ var JavaScriptObfuscatorCLI = function () {
 exports.JavaScriptObfuscatorCLI = JavaScriptObfuscatorCLI;
 
 /***/ },
-/* 26 */
+/* 24 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -1487,7 +1356,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__(2);
-var ConsoleOutputDisableExpressionTemplate_1 = __webpack_require__(48);
+var ConsoleOutputDisableExpressionTemplate_1 = __webpack_require__(49);
 var Node_1 = __webpack_require__(3);
 var NodeUtils_1 = __webpack_require__(1);
 
@@ -1527,7 +1396,7 @@ var ConsoleOutputDisableExpressionNode = function (_Node_1$Node) {
 exports.ConsoleOutputDisableExpressionNode = ConsoleOutputDisableExpressionNode;
 
 /***/ },
-/* 27 */
+/* 25 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -1576,7 +1445,7 @@ var DebugProtectionFunctionCallNode = function (_Node_1$Node) {
 exports.DebugProtectionFunctionCallNode = DebugProtectionFunctionCallNode;
 
 /***/ },
-/* 28 */
+/* 26 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -1625,7 +1494,7 @@ var DebugProtectionFunctionIntervalNode = function (_Node_1$Node) {
 exports.DebugProtectionFunctionIntervalNode = DebugProtectionFunctionIntervalNode;
 
 /***/ },
-/* 29 */
+/* 27 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -1640,7 +1509,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__(2);
-var DebugProtectionFunctionTemplate_1 = __webpack_require__(49);
+var DebugProtectionFunctionTemplate_1 = __webpack_require__(50);
 var Node_1 = __webpack_require__(3);
 var NodeUtils_1 = __webpack_require__(1);
 var Utils_1 = __webpack_require__(0);
@@ -1686,7 +1555,7 @@ var DebugProtectionFunctionNode = function (_Node_1$Node) {
 exports.DebugProtectionFunctionNode = DebugProtectionFunctionNode;
 
 /***/ },
-/* 30 */
+/* 28 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -1702,7 +1571,7 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
 
 var AppendState_1 = __webpack_require__(2);
 var NoCustomNodesPreset_1 = __webpack_require__(13);
-var SelfDefendingTemplate_1 = __webpack_require__(50);
+var SelfDefendingTemplate_1 = __webpack_require__(51);
 var JavaScriptObfuscator_1 = __webpack_require__(8);
 var Node_1 = __webpack_require__(3);
 var NodeUtils_1 = __webpack_require__(1);
@@ -1752,7 +1621,7 @@ var SelfDefendingUnicodeNode = function (_Node_1$Node) {
 exports.SelfDefendingUnicodeNode = SelfDefendingUnicodeNode;
 
 /***/ },
-/* 31 */
+/* 29 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -1820,7 +1689,7 @@ var UnicodeArrayCallsWrapper = function (_Node_1$Node) {
 exports.UnicodeArrayCallsWrapper = UnicodeArrayCallsWrapper;
 
 /***/ },
-/* 32 */
+/* 30 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -1837,8 +1706,8 @@ 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__(2);
-var SelfDefendingTemplate_1 = __webpack_require__(51);
-var UnicodeArrayDecodeTemplate_1 = __webpack_require__(52);
+var SelfDefendingTemplate_1 = __webpack_require__(52);
+var UnicodeArrayDecodeTemplate_1 = __webpack_require__(53);
 var Node_1 = __webpack_require__(3);
 var NodeUtils_1 = __webpack_require__(1);
 var Utils_1 = __webpack_require__(0);
@@ -1890,7 +1759,7 @@ var UnicodeArrayDecodeNode = function (_Node_1$Node) {
 exports.UnicodeArrayDecodeNode = UnicodeArrayDecodeNode;
 
 /***/ },
-/* 33 */
+/* 31 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -1972,7 +1841,7 @@ UnicodeArrayNode.UNICODE_ARRAY_RANDOM_LENGTH = 4;
 exports.UnicodeArrayNode = UnicodeArrayNode;
 
 /***/ },
-/* 34 */
+/* 32 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -1990,8 +1859,8 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
 
 var AppendState_1 = __webpack_require__(2);
 var NoCustomNodesPreset_1 = __webpack_require__(13);
-var SelfDefendingTemplate_1 = __webpack_require__(53);
-var UnicodeArrayRotateFunctionTemplate_1 = __webpack_require__(54);
+var SelfDefendingTemplate_1 = __webpack_require__(54);
+var UnicodeArrayRotateFunctionTemplate_1 = __webpack_require__(55);
 var JavaScriptObfuscator_1 = __webpack_require__(8);
 var Node_1 = __webpack_require__(3);
 var NodeUtils_1 = __webpack_require__(1);
@@ -2046,7 +1915,7 @@ var UnicodeArrayRotateFunctionNode = function (_Node_1$Node) {
 exports.UnicodeArrayRotateFunctionNode = UnicodeArrayRotateFunctionNode;
 
 /***/ },
-/* 35 */
+/* 33 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2058,7 +1927,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 ConsoleOutputDisableExpressionNode_1 = __webpack_require__(26);
+var ConsoleOutputDisableExpressionNode_1 = __webpack_require__(24);
 var NodesGroup_1 = __webpack_require__(12);
 
 var ConsoleOutputNodesGroup = function (_NodesGroup_1$NodesGr) {
@@ -2082,7 +1951,7 @@ var ConsoleOutputNodesGroup = function (_NodesGroup_1$NodesGr) {
 exports.ConsoleOutputNodesGroup = ConsoleOutputNodesGroup;
 
 /***/ },
-/* 36 */
+/* 34 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2094,9 +1963,9 @@ 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 DebugProtectionFunctionCallNode_1 = __webpack_require__(27);
-var DebugProtectionFunctionIntervalNode_1 = __webpack_require__(28);
-var DebugProtectionFunctionNode_1 = __webpack_require__(29);
+var DebugProtectionFunctionCallNode_1 = __webpack_require__(25);
+var DebugProtectionFunctionIntervalNode_1 = __webpack_require__(26);
+var DebugProtectionFunctionNode_1 = __webpack_require__(27);
 var NodesGroup_1 = __webpack_require__(12);
 var Utils_1 = __webpack_require__(0);
 
@@ -2126,7 +1995,7 @@ var DebugProtectionNodesGroup = function (_NodesGroup_1$NodesGr) {
 exports.DebugProtectionNodesGroup = DebugProtectionNodesGroup;
 
 /***/ },
-/* 37 */
+/* 35 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2139,7 +2008,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 NodesGroup_1 = __webpack_require__(12);
-var SelfDefendingUnicodeNode_1 = __webpack_require__(30);
+var SelfDefendingUnicodeNode_1 = __webpack_require__(28);
 
 var SelfDefendingNodesGroup = function (_NodesGroup_1$NodesGr) {
     _inherits(SelfDefendingNodesGroup, _NodesGroup_1$NodesGr);
@@ -2162,7 +2031,7 @@ var SelfDefendingNodesGroup = function (_NodesGroup_1$NodesGr) {
 exports.SelfDefendingNodesGroup = SelfDefendingNodesGroup;
 
 /***/ },
-/* 38 */
+/* 36 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2175,10 +2044,10 @@ 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 NodesGroup_1 = __webpack_require__(12);
-var UnicodeArrayCallsWrapper_1 = __webpack_require__(31);
-var UnicodeArrayDecodeNode_1 = __webpack_require__(32);
-var UnicodeArrayNode_1 = __webpack_require__(33);
-var UnicodeArrayRotateFunctionNode_1 = __webpack_require__(34);
+var UnicodeArrayCallsWrapper_1 = __webpack_require__(29);
+var UnicodeArrayDecodeNode_1 = __webpack_require__(30);
+var UnicodeArrayNode_1 = __webpack_require__(31);
+var UnicodeArrayRotateFunctionNode_1 = __webpack_require__(32);
 var Utils_1 = __webpack_require__(0);
 
 var UnicodeArrayNodesGroup = function (_NodesGroup_1$NodesGr) {
@@ -2223,7 +2092,7 @@ var UnicodeArrayNodesGroup = function (_NodesGroup_1$NodesGr) {
 exports.UnicodeArrayNodesGroup = UnicodeArrayNodesGroup;
 
 /***/ },
-/* 39 */
+/* 37 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2294,7 +2163,7 @@ var CatchClauseObfuscator = function (_NodeObfuscator_1$Nod) {
 exports.CatchClauseObfuscator = CatchClauseObfuscator;
 
 /***/ },
-/* 40 */
+/* 38 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2371,7 +2240,7 @@ var FunctionDeclarationObfuscator = function (_NodeObfuscator_1$Nod) {
 exports.FunctionDeclarationObfuscator = FunctionDeclarationObfuscator;
 
 /***/ },
-/* 41 */
+/* 39 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2448,7 +2317,7 @@ var FunctionObfuscator = function (_NodeObfuscator_1$Nod) {
 exports.FunctionObfuscator = FunctionObfuscator;
 
 /***/ },
-/* 42 */
+/* 40 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2513,7 +2382,7 @@ var LiteralObfuscator = function (_NodeObfuscator_1$Nod) {
 exports.LiteralObfuscator = LiteralObfuscator;
 
 /***/ },
-/* 43 */
+/* 41 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2597,7 +2466,7 @@ var MemberExpressionObfuscator = function (_NodeObfuscator_1$Nod) {
 exports.MemberExpressionObfuscator = MemberExpressionObfuscator;
 
 /***/ },
-/* 44 */
+/* 42 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2663,7 +2532,7 @@ var MethodDefinitionObfuscator = function (_NodeObfuscator_1$Nod) {
 exports.MethodDefinitionObfuscator = MethodDefinitionObfuscator;
 
 /***/ },
-/* 45 */
+/* 43 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2746,7 +2615,7 @@ var ObjectExpressionObfuscator = function (_NodeObfuscator_1$Nod) {
 exports.ObjectExpressionObfuscator = ObjectExpressionObfuscator;
 
 /***/ },
-/* 46 */
+/* 44 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2839,6 +2708,156 @@ var VariableDeclarationObfuscator = function (_NodeObfuscator_1$Nod) {
 
 exports.VariableDeclarationObfuscator = VariableDeclarationObfuscator;
 
+/***/ },
+/* 45 */
+/***/ function(module, exports, __webpack_require__) {
+
+"use strict";
+"use strict";
+
+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 __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 class_validator_1 = __webpack_require__(57);
+var DefaultPreset_1 = __webpack_require__(16);
+var OptionsNormalizer_1 = __webpack_require__(46);
+var ValidationErrorsFormatter_1 = __webpack_require__(47);
+
+var Options = function Options(obfuscatorOptions) {
+    _classCallCheck(this, Options);
+
+    Object.assign(this, DefaultPreset_1.DEFAULT_PRESET, obfuscatorOptions);
+    var errors = class_validator_1.validateSync(this, Options.validatorOptions);
+    if (errors.length) {
+        throw new ReferenceError("Validation failed. errors:\n" + ValidationErrorsFormatter_1.ValidationErrorsFormatter.format(errors));
+    }
+    Object.assign(this, OptionsNormalizer_1.OptionsNormalizer.normalizeOptions(this));
+};
+
+Options.validatorOptions = {
+    validationError: {
+        target: false
+    }
+};
+__decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "compact", void 0);
+__decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "debugProtection", void 0);
+__decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "debugProtectionInterval", void 0);
+__decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "disableConsoleOutput", void 0);
+__decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "encodeUnicodeLiterals", void 0);
+__decorate([class_validator_1.IsString({
+    each: true
+}), __metadata('design:type', Array)], Options.prototype, "reservedNames", void 0);
+__decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "rotateUnicodeArray", void 0);
+__decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "selfDefending", void 0);
+__decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "sourceMap", void 0);
+__decorate([class_validator_1.IsIn(['inline', 'separate']), __metadata('design:type', String)], Options.prototype, "sourceMapMode", void 0);
+__decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "unicodeArray", void 0);
+__decorate([class_validator_1.IsNumber(), class_validator_1.Min(0), class_validator_1.Max(1), __metadata('design:type', Number)], Options.prototype, "unicodeArrayThreshold", void 0);
+__decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "wrapUnicodeArrayCalls", void 0);
+exports.Options = Options;
+
+/***/ },
+/* 46 */
+/***/ function(module, exports) {
+
+"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; }; }();
+
+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);
+    }
+
+    _createClass(OptionsNormalizer, null, [{
+        key: "normalizeOptions",
+        value: function normalizeOptions(options) {
+            var normalizedOptions = Object.assign({}, options);
+            var _iteratorNormalCompletion = true;
+            var _didIteratorError = false;
+            var _iteratorError = undefined;
+
+            try {
+                for (var _iterator = OptionsNormalizer.normalizerRules[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+                    var normalizerRule = _step.value;
+
+                    normalizedOptions = normalizerRule(normalizedOptions);
+                }
+            } catch (err) {
+                _didIteratorError = true;
+                _iteratorError = err;
+            } finally {
+                try {
+                    if (!_iteratorNormalCompletion && _iterator.return) {
+                        _iterator.return();
+                    }
+                } finally {
+                    if (_didIteratorError) {
+                        throw _iteratorError;
+                    }
+                }
+            }
+
+            return normalizedOptions;
+        }
+    }, {
+        key: "selfDefendingRule",
+        value: function selfDefendingRule(options) {
+            if (options.selfDefending) {
+                Object.assign(options, OptionsNormalizer.SELF_DEFENDING_OPTIONS);
+            }
+            return options;
+        }
+    }, {
+        key: "unicodeArrayRule",
+        value: function unicodeArrayRule(options) {
+            if (!options.unicodeArray) {
+                Object.assign(options, OptionsNormalizer.DISABLED_UNICODE_ARRAY_OPTIONS);
+            }
+            return options;
+        }
+    }, {
+        key: "unicodeArrayThresholdRule",
+        value: function unicodeArrayThresholdRule(options) {
+            if (options.unicodeArrayThreshold === 0) {
+                Object.assign(options, OptionsNormalizer.DISABLED_UNICODE_ARRAY_OPTIONS);
+            }
+            return options;
+        }
+    }]);
+
+    return OptionsNormalizer;
+}();
+
+OptionsNormalizer.DISABLED_UNICODE_ARRAY_OPTIONS = {
+    encodeUnicodeLiterals: false,
+    rotateUnicodeArray: false,
+    unicodeArray: false,
+    unicodeArrayThreshold: 0,
+    wrapUnicodeArrayCalls: false
+};
+OptionsNormalizer.SELF_DEFENDING_OPTIONS = {
+    compact: true,
+    selfDefending: true
+};
+OptionsNormalizer.normalizerRules = [OptionsNormalizer.unicodeArrayRule, OptionsNormalizer.unicodeArrayThresholdRule, OptionsNormalizer.selfDefendingRule];
+exports.OptionsNormalizer = OptionsNormalizer;
+
 /***/ },
 /* 47 */
 /***/ function(module, exports) {
@@ -2846,13 +2865,80 @@ exports.VariableDeclarationObfuscator = VariableDeclarationObfuscator;
 "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; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var ValidationErrorsFormatter = function () {
+    function ValidationErrorsFormatter() {
+        _classCallCheck(this, ValidationErrorsFormatter);
+    }
+
+    _createClass(ValidationErrorsFormatter, null, [{
+        key: "format",
+        value: function format(validationErrors) {
+            var errorsArray = [];
+            var _iteratorNormalCompletion = true;
+            var _didIteratorError = false;
+            var _iteratorError = undefined;
+
+            try {
+                for (var _iterator = validationErrors[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+                    var error = _step.value;
+
+                    errorsArray.push(ValidationErrorsFormatter.formatError(error));
+                }
+            } catch (err) {
+                _didIteratorError = true;
+                _iteratorError = err;
+            } finally {
+                try {
+                    if (!_iteratorNormalCompletion && _iterator.return) {
+                        _iterator.return();
+                    }
+                } finally {
+                    if (_didIteratorError) {
+                        throw _iteratorError;
+                    }
+                }
+            }
+
+            return errorsArray.join('\n');
+        }
+    }, {
+        key: "formatError",
+        value: function formatError(validationError) {
+            var errorString = "`" + validationError.property + "` errors:\n",
+                constraints = validationError.constraints;
+            for (var constraint in constraints) {
+                if (!constraints.hasOwnProperty(constraint)) {
+                    continue;
+                }
+                errorString += "    - " + constraints[constraint] + "\n";
+            }
+            return errorString;
+        }
+    }]);
+
+    return ValidationErrorsFormatter;
+}();
+
+exports.ValidationErrorsFormatter = ValidationErrorsFormatter;
+
+/***/ },
+/* 48 */
+/***/ function(module, exports) {
+
+"use strict";
+"use strict";
+
 function AtobTemplate() {
     return "\n        (function () {\n            var object = []['filter']['constructor']('return this')();\n            var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';\n\n            object.atob || (\n                object.atob = function(input) {\n                    var str = String(input).replace(/=+$/, '');\n                    for (\n                        var bc = 0, bs, buffer, idx = 0, output = '';\n                        buffer = str.charAt(idx++);\n                        ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,\n                            bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0\n                    ) {\n                        buffer = chars.indexOf(buffer);\n                    }\n                return output;\n            });\n        })();\n    ";
 }
 exports.AtobTemplate = AtobTemplate;
 
 /***/ },
-/* 48 */
+/* 49 */
 /***/ function(module, exports) {
 
 "use strict";
@@ -2864,7 +2950,7 @@ function ConsoleOutputDisableExpressionTemplate() {
 exports.ConsoleOutputDisableExpressionTemplate = ConsoleOutputDisableExpressionTemplate;
 
 /***/ },
-/* 49 */
+/* 50 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2877,7 +2963,7 @@ function DebugProtectionFunctionTemplate(debugProtectionFunctionName) {
 exports.DebugProtectionFunctionTemplate = DebugProtectionFunctionTemplate;
 
 /***/ },
-/* 50 */
+/* 51 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2891,7 +2977,7 @@ function SelfDefendingTemplate() {
 exports.SelfDefendingTemplate = SelfDefendingTemplate;
 
 /***/ },
-/* 51 */
+/* 52 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2906,14 +2992,14 @@ function SelfDefendingTemplate(unicodeArrayName, forLoopFunctionName) {
 exports.SelfDefendingTemplate = SelfDefendingTemplate;
 
 /***/ },
-/* 52 */
+/* 53 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
 "use strict";
 
 var NoCustomNodesPreset_1 = __webpack_require__(13);
-var AtobTemplate_1 = __webpack_require__(47);
+var AtobTemplate_1 = __webpack_require__(48);
 var JavaScriptObfuscator_1 = __webpack_require__(8);
 var Utils_1 = __webpack_require__(0);
 function UnicodeArrayDecodeTemplate(code, unicodeArrayName, forLoopFunctionName) {
@@ -2924,7 +3010,7 @@ function UnicodeArrayDecodeTemplate(code, unicodeArrayName, forLoopFunctionName)
 exports.UnicodeArrayDecodeTemplate = UnicodeArrayDecodeTemplate;
 
 /***/ },
-/* 53 */
+/* 54 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2938,7 +3024,7 @@ function SelfDefendingTemplate(whileFunctionName, timesName) {
 exports.SelfDefendingTemplate = SelfDefendingTemplate;
 
 /***/ },
-/* 54 */
+/* 55 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -2953,37 +3039,37 @@ function UnicodeArrayRotateFunctionTemplate(code, unicodeArrayName, unicodeArray
 exports.UnicodeArrayRotateFunctionTemplate = UnicodeArrayRotateFunctionTemplate;
 
 /***/ },
-/* 55 */
+/* 56 */
 /***/ function(module, exports) {
 
 module.exports = require("chance");
 
 /***/ },
-/* 56 */
+/* 57 */
 /***/ function(module, exports) {
 
-module.exports = require("commander");
+module.exports = require("class-validator");
 
 /***/ },
-/* 57 */
+/* 58 */
 /***/ function(module, exports) {
 
-module.exports = require("fs");
+module.exports = require("commander");
 
 /***/ },
-/* 58 */
+/* 59 */
 /***/ function(module, exports) {
 
-module.exports = require("joi");
+module.exports = require("fs");
 
 /***/ },
-/* 59 */
+/* 60 */
 /***/ function(module, exports) {
 
 module.exports = require("mkdirp");
 
 /***/ },
-/* 60 */
+/* 61 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";

+ 1 - 1
package.json

@@ -22,11 +22,11 @@
   "dependencies": {
     "babel-polyfill": "^6.9.1",
     "chance": "^1.0.3",
+    "class-validator": "^0.5.0-alpha.3",
     "commander": "^2.9.0",
     "escodegen": "^1.8.0",
     "esprima": "^2.7.2",
     "estraverse": "^4.2.0",
-    "joi": "^6.10.0",
     "mkdirp": "^0.5.1",
     "source-map-support": "^0.4.1"
   },

+ 1 - 1
src/JavaScriptObfuscatorInternal.ts

@@ -9,7 +9,7 @@ import { IOptions } from './interfaces/IOptions';
 
 import { ObfuscationResult } from "./ObfuscationResult";
 import { Obfuscator } from "./Obfuscator";
-import { Options } from "./Options";
+import { Options } from "./options/Options";
 import { SourceMapCorrector } from "./SourceMapCorrector";
 
 export class JavaScriptObfuscatorInternal {

+ 41 - 34
src/Options.ts → src/options/Options.ts

@@ -1,112 +1,119 @@
-import * as Joi from 'joi';
+import { IsBoolean, IsIn, IsNumber, IsString, Min, Max, validateSync, ValidationError, ValidatorOptions } from 'class-validator';
 
-import { IObfuscatorOptions } from "./interfaces/IObfuscatorOptions";
-import { IOptions } from "./interfaces/IOptions";
+import { IObfuscatorOptions } from "../interfaces/IObfuscatorOptions";
+import { IOptions } from "../interfaces/IOptions";
 
-import { TSourceMapMode } from "./types/TSourceMapMode";
+import { TSourceMapMode } from "../types/TSourceMapMode";
 
-import { DEFAULT_PRESET } from "./preset-options/DefaultPreset";
+import { DEFAULT_PRESET } from "../preset-options/DefaultPreset";
 
 import { OptionsNormalizer } from "./OptionsNormalizer";
+import { ValidationErrorsFormatter } from "./ValidationErrorsFormatter";
 
 export class Options implements IOptions {
+    /**
+     * @type {ValidatorOptions}
+     */
+    private static validatorOptions: ValidatorOptions = {
+        validationError: {
+            target: false
+        }
+    };
+
     /**
      * @type {boolean}
      */
+    @IsBoolean()
     public readonly compact: boolean;
 
     /**
      * @type {boolean}
      */
+    @IsBoolean()
     public readonly debugProtection: boolean;
 
     /**
      * @type {boolean}
      */
+    @IsBoolean()
     public readonly debugProtectionInterval: boolean;
 
     /**
      * @type {boolean}
      */
+    @IsBoolean()
     public readonly disableConsoleOutput: boolean;
 
     /**
      * @type {boolean}
      */
+    @IsBoolean()
     public readonly encodeUnicodeLiterals: boolean;
 
     /**
      * @type {string[]}
      */
+    @IsString({
+        each: true
+    })
     public readonly reservedNames: string[];
 
     /**
      * @type {boolean}
      */
+    @IsBoolean()
     public readonly rotateUnicodeArray: boolean;
 
     /**
      * @type {boolean}
      */
+    @IsBoolean()
     public readonly selfDefending: boolean;
 
     /**
      * @type {boolean}
      */
+    @IsBoolean()
     public readonly sourceMap: boolean;
 
     /**
      * @type {TSourceMapMode}
      */
+    @IsIn(['inline', 'separate'])
     public readonly sourceMapMode: TSourceMapMode;
 
     /**
      * @type {boolean}
      */
+    @IsBoolean()
     public readonly unicodeArray: boolean;
 
     /**
      * @type {number}
      */
+    @IsNumber()
+    @Min(0)
+    @Max(1)
     public readonly unicodeArrayThreshold: number;
 
     /**
      * @type {boolean}
      */
+    @IsBoolean()
     public readonly wrapUnicodeArrayCalls: boolean;
 
-    /**
-     * @type {Joi.ObjectSchema}
-     */
-    private schema: Joi.ObjectSchema = Joi.object({
-        compact: Joi.boolean(),
-        debugProtection: Joi.boolean(),
-        debugProtectionInterval: Joi.boolean(),
-        disableConsoleOutput: Joi.boolean(),
-        encodeUnicodeLiterals: Joi.boolean(),
-        reservedNames: Joi.array().items(Joi.string()),
-        rotateUnicodeArray: Joi.boolean(),
-        selfDefending: Joi.boolean(),
-        sourceMap: Joi.boolean(),
-        sourceMapMode: Joi.string().valid(['inline', 'separate']),
-        unicodeArray: Joi.boolean(),
-        unicodeArrayThreshold: Joi.number().min(0).max(1),
-        wrapUnicodeArrayCalls: Joi.boolean()
-    });
-
     /**
      * @param obfuscatorOptions
      */
     constructor (obfuscatorOptions: IObfuscatorOptions) {
-        Joi.validate(obfuscatorOptions, this.schema, (error: Joi.ValidationError) => {
-            if (error) {
-                throw error;
-            }
-        });
-
-        Object.assign(
-            this,
-            OptionsNormalizer.normalizeOptions(Object.assign({}, DEFAULT_PRESET, obfuscatorOptions))
-        );
+        Object.assign(this, DEFAULT_PRESET, obfuscatorOptions);
+
+        let errors: ValidationError[] = validateSync(this, Options.validatorOptions);
+
+        if (errors.length) {
+            throw new ReferenceError(`Validation failed. errors:\n${ValidationErrorsFormatter.format(errors)}`);
+        }
+
+        Object.assign(this, OptionsNormalizer.normalizeOptions(this));
     }
 }

+ 2 - 2
src/OptionsNormalizer.ts → src/options/OptionsNormalizer.ts

@@ -1,6 +1,6 @@
-import { IObfuscatorOptions } from "./interfaces/IObfuscatorOptions";
+import { IObfuscatorOptions } from "../interfaces/IObfuscatorOptions";
 
-import { TOptionsNormalizerRule } from "./types/TOptionsNormalizerRule";
+import { TOptionsNormalizerRule } from "../types/TOptionsNormalizerRule";
 
 export class OptionsNormalizer {
     /**

+ 36 - 0
src/options/ValidationErrorsFormatter.ts

@@ -0,0 +1,36 @@
+import { ValidationError } from 'class-validator';
+
+export class ValidationErrorsFormatter {
+    /**
+     * @param validationErrors
+     * @returns {string}
+     */
+    public static format (validationErrors: ValidationError[]): string {
+        let errorsArray: string[] = [];
+
+        for (let error of validationErrors) {
+            errorsArray.push(ValidationErrorsFormatter.formatError(error));
+        }
+
+        return errorsArray.join('\n');
+    }
+
+    /**
+     * @param validationError
+     * @returns {string}
+     */
+    private static formatError (validationError: ValidationError): string {
+        let errorString: string = `\`${validationError.property}\` errors:\n`,
+            constraints: {[type: string]: string} = validationError.constraints;
+
+        for (let constraint in constraints) {
+            if (!constraints.hasOwnProperty(constraint)) {
+                continue;
+            }
+
+            errorString += `    - ${constraints[constraint]}\n`;
+        }
+
+        return errorString;
+    }
+}

+ 1 - 1
test/unit-tests/OptionsNormalizer.spec.ts

@@ -1,6 +1,6 @@
 import { IObfuscatorOptions } from "../../src/interfaces/IObfuscatorOptions";
 
-import { OptionsNormalizer } from '../../src/OptionsNormalizer';
+import { OptionsNormalizer } from '../../src/options/OptionsNormalizer';
 
 import { DEFAULT_PRESET } from '../../src/preset-options/DefaultPreset';
 

+ 1 - 1
test/unit-tests/node-obfuscators/CatchClauseObfuscator.spec.ts

@@ -8,7 +8,7 @@ import { NodeType } from "../../../src/enums/NodeType";
 
 import { CatchClauseObfuscator } from '../../../src/node-obfuscators/CatchClauseObfuscator';
 import { NodeMocks } from "../../mocks/NodeMocks";
-import { Options } from "../../../src/Options";
+import { Options } from "../../../src/options/Options";
 
 const assert: Chai.AssertStatic = require('chai').assert;
 

+ 1 - 1
test/unit-tests/node-obfuscators/FunctionDeclarationObfuscator.spec.ts

@@ -8,7 +8,7 @@ import { DEFAULT_PRESET } from "../../../src/preset-options/DefaultPreset";
 
 import { FunctionDeclarationObfuscator } from '../../../src/node-obfuscators/FunctionDeclarationObfuscator';
 import { NodeMocks } from "../../mocks/NodeMocks";
-import { Options } from "../../../src/Options";
+import { Options } from "../../../src/options/Options";
 
 const assert: Chai.AssertStatic = require('chai').assert;
 

+ 1 - 1
test/unit-tests/node-obfuscators/FunctionObfuscator.spec.ts

@@ -9,7 +9,7 @@ import { DEFAULT_PRESET } from "../../../src/preset-options/DefaultPreset";
 
 import { FunctionObfuscator } from "../../../src/node-obfuscators/FunctionObfuscator";
 import { NodeMocks } from "../../mocks/NodeMocks";
-import { Options } from "../../../src/Options";
+import { Options } from "../../../src/options/Options";
 
 
 const assert: Chai.AssertStatic = require('chai').assert;