sanex3339 7 rokov pred
rodič
commit
6819ba675a
58 zmenil súbory, kde vykonal 718 pridanie a 594 odobranie
  1. 0 0
      dist/index.js
  2. 1 1
      index.ts
  3. 277 21
      src/JavaScriptObfuscator.ts
  4. 45 0
      src/JavaScriptObfuscatorFacade.ts
  5. 0 152
      src/JavaScriptObfuscatorInternal.ts
  6. 0 270
      src/Obfuscator.ts
  7. 111 0
      src/TransformersRunner.ts
  8. 1 1
      src/cli/JavaScriptObfuscatorCLI.ts
  9. 6 6
      src/container/InversifyContainerFacade.ts
  10. 1 1
      src/container/ServiceIdentifiers.ts
  11. 11 0
      src/container/modules/node-transformers/NodeTransformersModule.ts
  12. 1 1
      src/custom-nodes/node-calls-controller-nodes/NodeCallsControllerFunctionNode.ts
  13. 1 1
      src/custom-nodes/self-defending-nodes/SelfDefendingUnicodeNode.ts
  14. 1 1
      src/custom-nodes/string-array-nodes/StringArrayCallsWrapper.ts
  15. 1 1
      src/custom-nodes/string-array-nodes/StringArrayRotateFunctionNode.ts
  16. 1 0
      src/declarations/ESTree.d.ts
  17. 2 0
      src/enums/container/node-transformers/NodeTransformer.ts
  18. 1 0
      src/enums/logger/LoggingMessage.ts
  19. 0 9
      src/interfaces/IObfuscator.d.ts
  20. 12 0
      src/interfaces/ITransformersRunner.d.ts
  21. 3 2
      src/interfaces/IVisitor.d.ts
  22. 11 4
      src/interfaces/node-transformers/INodeTransformer.d.ts
  23. 13 13
      src/node-guards/ConditionalCommentNodeGuard.ts
  24. 3 2
      src/node-transformers/AbstractNodeTransformer.ts
  25. 56 51
      src/node-transformers/dead-code-injection-transformers/DeadCodeInjectionTransformer.ts
  26. 72 0
      src/node-transformers/preparing-transformers/NodeGuardTransformer.ts
  27. 50 0
      src/node-transformers/preparing-transformers/ParentizeTransformer.ts
  28. 7 23
      src/node/NodeUtils.ts
  29. 1 0
      test/dev/dev.ts
  30. 1 1
      test/functional-tests/cli/JavaScriptObfuscatorCLI.spec.ts
  31. 1 1
      test/functional-tests/custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode.spec.ts
  32. 1 1
      test/functional-tests/custom-nodes/domain-lock-nodes/DomainLockNode.spec.ts
  33. 1 1
      test/functional-tests/custom-nodes/string-array-nodes/StringArrayCallsWrapper.spec.ts
  34. 1 1
      test/functional-tests/custom-nodes/string-array-nodes/StringArrayNode.spec.ts
  35. 1 1
      test/functional-tests/custom-nodes/string-array-nodes/StringArrayRotateFunctionNode.spec.ts
  36. 1 1
      test/functional-tests/javascript-obfuscator/JavaScriptObfuscator.spec.ts
  37. 1 1
      test/functional-tests/node-guards/black-list-node-guard/BlackListNodeGuard.spec.ts
  38. 1 1
      test/functional-tests/node-transformers/control-flow-transformers/block-statement-control-flow-transformer/BlockStatementControlFlowTransformer.spec.ts
  39. 1 1
      test/functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/binary-expression-control-flow-replacer/BinaryExpressionControlFlowReplacer.spec.ts
  40. 1 1
      test/functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/call-expression-control-flow-replacer/CallExpressionControlFlowReplacer.spec.ts
  41. 1 1
      test/functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/logical-expression-control-flow-replacer/LogicalExpressionControlFlowReplacer.spec.ts
  42. 1 1
      test/functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/string-litertal-control-flow-replacer/StringLiteralControlFlowReplacer.spec.ts
  43. 1 1
      test/functional-tests/node-transformers/control-flow-transformers/function-control-flow-transformer/FunctionControlFlowTransformer.spec.ts
  44. 1 1
      test/functional-tests/node-transformers/converting-transformers/member-expression-transformer/MemberExpressionTransformer.spec.ts
  45. 1 1
      test/functional-tests/node-transformers/converting-transformers/method-definition-transformer/MethodDefinitionTransformer.spec.ts
  46. 1 1
      test/functional-tests/node-transformers/converting-transformers/template-literal-transformer/TemplateLiteralTransformer.spec.ts
  47. 1 1
      test/functional-tests/node-transformers/dead-code-injection-transformers/DeadCodeInjectionTransformer.spec.ts
  48. 1 1
      test/functional-tests/node-transformers/obfuscating-transformers/catch-clause-transformer/CatchClauseTransformer.spec.ts
  49. 1 1
      test/functional-tests/node-transformers/obfuscating-transformers/class-declaration-transformer/ClassDeclarationTransformer.spec.ts
  50. 1 1
      test/functional-tests/node-transformers/obfuscating-transformers/function-declaration-transformer/FunctionDeclarationTransformer.spec.ts
  51. 1 1
      test/functional-tests/node-transformers/obfuscating-transformers/function-transformer/FunctionTransformer.spec.ts
  52. 1 1
      test/functional-tests/node-transformers/obfuscating-transformers/labeled-statement-transformer/LabeledStatementTransformer.spec.ts
  53. 1 1
      test/functional-tests/node-transformers/obfuscating-transformers/literal-transformer/LiteralTransformer.spec.ts
  54. 1 1
      test/functional-tests/node-transformers/obfuscating-transformers/object-expression-transformer/ObjectExpressionTransformer.spec.ts
  55. 1 1
      test/functional-tests/node-transformers/obfuscating-transformers/variable-declaration-transformer/VariableDeclarationTransformer.spec.ts
  56. 1 1
      test/performance-tests/JavaScriptObfuscatorPerformance.spec.ts
  57. 1 1
      test/runtime-tests/JavaScriptObfuscatorRuntime.spec.ts
  58. 1 6
      test/unit-tests/node/node-utils/NodeUtils.spec.ts

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 0 - 0
dist/index.js


+ 1 - 1
index.ts

@@ -1,5 +1,5 @@
 "use strict";
 
-import { JavaScriptObfuscator } from './src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from './src/JavaScriptObfuscatorFacade';
 
 module.exports = JavaScriptObfuscator;

+ 277 - 21
src/JavaScriptObfuscator.ts

@@ -1,43 +1,299 @@
-import 'reflect-metadata';
-
+import { injectable, inject } from 'inversify';
 import { ServiceIdentifiers } from './container/ServiceIdentifiers';
 
-import { TInputOptions } from './types/options/TInputOptions';
+import * as esprima from 'esprima';
+import * as escodegen from 'escodegen-wallaby';
+import * as esmangle from 'esmangle';
+import * as ESTree from 'estree';
 
-import { IInversifyContainerFacade } from './interfaces/container/IInversifyContainerFacade';
+import { ICustomNodeGroup } from './interfaces/custom-nodes/ICustomNodeGroup';
+import { IGeneratorOutput } from './interfaces/IGeneratorOutput';
 import { IJavaScriptObfuscator } from './interfaces/IJavaScriptObfsucator';
+import { ILogger } from './interfaces/logger/ILogger';
+import { IObfuscationEventEmitter } from './interfaces/event-emitters/IObfuscationEventEmitter';
 import { IObfuscationResult } from './interfaces/IObfuscationResult';
+import { IOptions } from './interfaces/options/IOptions';
+import { IRandomGenerator } from './interfaces/utils/IRandomGenerator';
+import { ISourceMapCorrector } from './interfaces/ISourceMapCorrector';
+import { IStackTraceAnalyzer } from './interfaces/analyzers/stack-trace-analyzer/IStackTraceAnalyzer';
+import { IStackTraceData } from './interfaces/analyzers/stack-trace-analyzer/IStackTraceData';
+import { IStorage } from './interfaces/storages/IStorage';
+import { ITransformersRunner } from './interfaces/ITransformersRunner';
+
+import { LoggingMessage } from './enums/logger/LoggingMessage';
+import { NodeTransformer } from './enums/container/node-transformers/NodeTransformer';
+import { ObfuscationEvent } from './enums/event-emitters/ObfuscationEvent';
+
+import { Node } from './node/Node';
+
+@injectable()
+export class JavaScriptObfuscator implements IJavaScriptObfuscator {
+    /**
+     * @type {GenerateOptions}
+     */
+    private static readonly escodegenParams: escodegen.GenerateOptions = {
+        verbatim: 'x-verbatim-property',
+        sourceMapWithCode: true
+    };
+
+    /**
+     * @type {NodeTransformer[]}
+     */
+    private static readonly controlFlowTransformersList: NodeTransformer[] = [
+        NodeTransformer.BlockStatementControlFlowTransformer,
+        NodeTransformer.FunctionControlFlowTransformer
+    ];
+
+    /**
+     * @type {NodeTransformer[]}
+     */
+    private static readonly convertingTransformersList: NodeTransformer[] = [
+        NodeTransformer.MemberExpressionTransformer,
+        NodeTransformer.MethodDefinitionTransformer,
+        NodeTransformer.TemplateLiteralTransformer
+    ];
+
+    /**
+     * @type {NodeTransformer[]}
+     */
+    private static readonly deadCodeInjectionTransformersList: NodeTransformer[] = [
+        NodeTransformer.DeadCodeInjectionTransformer
+    ];
+
+    /**
+     * @type {NodeTransformer[]}
+     */
+    private static readonly obfuscatingTransformersList: NodeTransformer[] = [
+        NodeTransformer.CatchClauseTransformer,
+        NodeTransformer.ClassDeclarationTransformer,
+        NodeTransformer.FunctionDeclarationTransformer,
+        NodeTransformer.FunctionTransformer,
+        NodeTransformer.LabeledStatementTransformer,
+        NodeTransformer.LiteralTransformer,
+        NodeTransformer.ObjectExpressionTransformer,
+        NodeTransformer.VariableDeclarationTransformer
+    ];
+
+    /**
+     * @type {NodeTransformer[]}
+     */
+    private static readonly preparingTransformersList: NodeTransformer[] = [
+        NodeTransformer.ParentizeTransformer,
+        NodeTransformer.NodeGuardTransformer
+    ];
 
-import { InversifyContainerFacade } from './container/InversifyContainerFacade';
-import { JavaScriptObfuscatorCLI } from './cli/JavaScriptObfuscatorCLI';
+    /**
+     * @type {IStorage<ICustomNodeGroup>}
+     */
+    private readonly customNodeGroupStorage: IStorage<ICustomNodeGroup>;
+
+    /**
+     * @type {ILogger}
+     */
+    private readonly logger: ILogger;
+
+    /**
+     * @type {IObfuscationEventEmitter}
+     */
+    private readonly obfuscationEventEmitter: IObfuscationEventEmitter;
+
+    /**
+     * @type {IOptions}
+     */
+    private readonly options: IOptions;
+
+    /**
+     * @type {IRandomGenerator}
+     */
+    private readonly randomGenerator: IRandomGenerator;
+
+    /**
+     * @type {ISourceMapCorrector}
+     */
+    private readonly sourceMapCorrector: ISourceMapCorrector;
+
+    /**
+     * @type {IStackTraceAnalyzer}
+     */
+    private readonly stackTraceAnalyzer: IStackTraceAnalyzer;
+
+    /**
+     * @type {ITransformersRunner}
+     */
+    private readonly transformersRunner: ITransformersRunner;
+
+    /**
+     * @param {IStackTraceAnalyzer} stackTraceAnalyzer
+     * @param {IObfuscationEventEmitter} obfuscationEventEmitter
+     * @param {IStorage<ICustomNodeGroup>} customNodeGroupStorage
+     * @param {ITransformersRunner} transformersRunner
+     * @param {ISourceMapCorrector} sourceMapCorrector
+     * @param {IRandomGenerator} randomGenerator
+     * @param {ILogger} logger
+     * @param {IOptions} options
+     */
+    constructor (
+        @inject(ServiceIdentifiers.IStackTraceAnalyzer) stackTraceAnalyzer: IStackTraceAnalyzer,
+        @inject(ServiceIdentifiers.IObfuscationEventEmitter) obfuscationEventEmitter: IObfuscationEventEmitter,
+        @inject(ServiceIdentifiers.TCustomNodeGroupStorage) customNodeGroupStorage: IStorage<ICustomNodeGroup>,
+        @inject(ServiceIdentifiers.ITransformersRunner) transformersRunner: ITransformersRunner,
+        @inject(ServiceIdentifiers.ISourceMapCorrector) sourceMapCorrector: ISourceMapCorrector,
+        @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
+        @inject(ServiceIdentifiers.ILogger) logger: ILogger,
+        @inject(ServiceIdentifiers.IOptions) options: IOptions
+    ) {
+        this.stackTraceAnalyzer = stackTraceAnalyzer;
+        this.obfuscationEventEmitter = obfuscationEventEmitter;
+        this.customNodeGroupStorage = customNodeGroupStorage;
+        this.transformersRunner = transformersRunner;
+        this.sourceMapCorrector = sourceMapCorrector;
+        this.randomGenerator = randomGenerator;
+        this.logger = logger;
+        this.options = options;
+    }
 
-export class JavaScriptObfuscator {
     /**
      * @param {string} sourceCode
-     * @param {TInputOptions} inputOptions
      * @returns {IObfuscationResult}
      */
-    public static obfuscate (sourceCode: string, inputOptions: TInputOptions = {}): IObfuscationResult {
-        const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
+    public obfuscate (sourceCode: string): IObfuscationResult {
+        const timeStart: number = Date.now();
+        this.logger.info(LoggingMessage.ObfuscationStarted);
+        this.logger.info(LoggingMessage.RandomGeneratorSeed, this.randomGenerator.getSeed());
+
+        // parse AST tree
+        const astTree: ESTree.Program = this.parseCode(sourceCode);
+
+        // obfuscate AST tree
+        const obfuscatedAstTree: ESTree.Program = this.transformAstTree(astTree);
+
+        // generate code
+        const generatorOutput: IGeneratorOutput = this.generateCode(sourceCode, obfuscatedAstTree);
+
+        const obfuscationTime: number = (Date.now() - timeStart) / 1000;
+        this.logger.success(LoggingMessage.ObfuscationCompleted, obfuscationTime);
+
+        return this.getObfuscationResult(generatorOutput);
+    }
+
+    /**
+     * @param {string} sourceCode
+     * @returns {Program}
+     */
+    private parseCode (sourceCode: string): ESTree.Program {
+        return esprima.parseScript(sourceCode, {
+            attachComment: true,
+            loc: this.options.sourceMap
+        });
+    }
+
+    /**
+     * @param {Program} astTree
+     * @returns {Program}
+     */
+    private transformAstTree (astTree: ESTree.Program): ESTree.Program {
+        if (Node.isProgramNode(astTree) && !astTree.body.length) {
+            this.logger.warn(LoggingMessage.EmptySourceCode);
+
+            return astTree;
+        }
+
+        // first pass: AST-tree preparation
+        this.logger.info(LoggingMessage.StagePreparingASTTree);
+        astTree = this.transformersRunner.transform(
+            astTree,
+            JavaScriptObfuscator.preparingTransformersList
+        );
+
+        // second pass: AST-tree analyzing
+        this.logger.info(LoggingMessage.StageAnalyzingASTTree);
+        const stackTraceData: IStackTraceData[] = this.stackTraceAnalyzer.analyze(astTree);
+
+        // initialize custom node groups and configure custom nodes
+        this.customNodeGroupStorage
+            .getStorage()
+            .forEach((customNodeGroup: ICustomNodeGroup) => {
+                customNodeGroup.initialize();
+
+                this.obfuscationEventEmitter.once(
+                    customNodeGroup.getAppendEvent(),
+                    customNodeGroup.appendCustomNodes.bind(customNodeGroup)
+                );
+            });
+
+        this.obfuscationEventEmitter.emit(ObfuscationEvent.BeforeObfuscation, astTree, stackTraceData);
+
+        // third pass: dead code injection transformer
+        if (this.options.deadCodeInjection) {
+            this.logger.info(LoggingMessage.StageDeadCodeInjection);
+
+            astTree = this.transformersRunner.transform(
+                astTree,
+                JavaScriptObfuscator.deadCodeInjectionTransformersList
+            );
+        }
+
+        // fourth pass: control flow flattening transformers
+        if (this.options.controlFlowFlattening) {
+            this.logger.info(LoggingMessage.StageControlFlowFlattening);
 
-        inversifyContainerFacade.load(sourceCode, inputOptions);
+            astTree = this.transformersRunner.transform(
+                astTree,
+                JavaScriptObfuscator.controlFlowTransformersList
+            );
+        }
 
-        const javaScriptObfuscator: IJavaScriptObfuscator = inversifyContainerFacade
-            .get<IJavaScriptObfuscator>(ServiceIdentifiers.IJavaScriptObfuscator);
-        const obfuscationResult: IObfuscationResult = javaScriptObfuscator.obfuscate(sourceCode);
+        // fifth pass: converting and obfuscating transformers
+        this.logger.info(LoggingMessage.StageObfuscation);
+        astTree = this.transformersRunner.transform(astTree, [
+            ...JavaScriptObfuscator.convertingTransformersList,
+            ...JavaScriptObfuscator.obfuscatingTransformersList
+        ]);
 
-        inversifyContainerFacade.unload();
+        this.obfuscationEventEmitter.emit(ObfuscationEvent.AfterObfuscation, astTree, stackTraceData);
 
-        return obfuscationResult;
+        return astTree;
     }
 
     /**
-     * @param {string[]} argv
+     * @param {string} sourceCode
+     * @param {Program} astTree
+     * @returns {IGeneratorOutput}
      */
-    public static runCLI (argv: string[]): void {
-        const javaScriptObfuscatorCLI: JavaScriptObfuscatorCLI = new JavaScriptObfuscatorCLI(argv);
+    private generateCode (sourceCode: string, astTree: ESTree.Program): IGeneratorOutput {
+        const escodegenParams: escodegen.GenerateOptions = {
+            ...JavaScriptObfuscator.escodegenParams
+        };
+
+        if (this.options.sourceMap) {
+            escodegenParams.sourceMap = 'sourceMap';
+            escodegenParams.sourceContent = sourceCode;
+        }
+
+        if (this.options.mangle) {
+            astTree = esmangle.mangle(astTree);
+        }
+
+        const generatorOutput: IGeneratorOutput = escodegen.generate(astTree, {
+            ...escodegenParams,
+            format: {
+                compact: this.options.compact
+            }
+        });
+
+        generatorOutput.map = generatorOutput.map ? generatorOutput.map.toString() : '';
 
-        javaScriptObfuscatorCLI.initialize();
-        javaScriptObfuscatorCLI.run();
+        return generatorOutput;
+    }
+
+    /**
+     * @param {IGeneratorOutput} generatorOutput
+     * @returns {IObfuscationResult}
+     */
+    private getObfuscationResult (generatorOutput: IGeneratorOutput): IObfuscationResult {
+        return this.sourceMapCorrector.correct(
+            generatorOutput.code,
+            generatorOutput.map
+        );
     }
 }

+ 45 - 0
src/JavaScriptObfuscatorFacade.ts

@@ -0,0 +1,45 @@
+import 'reflect-metadata';
+
+import { ServiceIdentifiers } from './container/ServiceIdentifiers';
+
+import { TInputOptions } from './types/options/TInputOptions';
+
+import { IInversifyContainerFacade } from './interfaces/container/IInversifyContainerFacade';
+import { IJavaScriptObfuscator } from './interfaces/IJavaScriptObfsucator';
+import { IObfuscationResult } from './interfaces/IObfuscationResult';
+
+import { InversifyContainerFacade } from './container/InversifyContainerFacade';
+import { JavaScriptObfuscatorCLI } from './cli/JavaScriptObfuscatorCLI';
+
+class JavaScriptObfuscatorFacade {
+    /**
+     * @param {string} sourceCode
+     * @param {TInputOptions} inputOptions
+     * @returns {IObfuscationResult}
+     */
+    public static obfuscate (sourceCode: string, inputOptions: TInputOptions = {}): IObfuscationResult {
+        const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
+
+        inversifyContainerFacade.load(sourceCode, inputOptions);
+
+        const javaScriptObfuscator: IJavaScriptObfuscator = inversifyContainerFacade
+            .get<IJavaScriptObfuscator>(ServiceIdentifiers.IJavaScriptObfuscator);
+        const obfuscationResult: IObfuscationResult = javaScriptObfuscator.obfuscate(sourceCode);
+
+        inversifyContainerFacade.unload();
+
+        return obfuscationResult;
+    }
+
+    /**
+     * @param {string[]} argv
+     */
+    public static runCLI (argv: string[]): void {
+        const javaScriptObfuscatorCLI: JavaScriptObfuscatorCLI = new JavaScriptObfuscatorCLI(argv);
+
+        javaScriptObfuscatorCLI.initialize();
+        javaScriptObfuscatorCLI.run();
+    }
+}
+
+export { JavaScriptObfuscatorFacade as JavaScriptObfuscator };

+ 0 - 152
src/JavaScriptObfuscatorInternal.ts

@@ -1,152 +0,0 @@
-import { injectable, inject } from 'inversify';
-import { ServiceIdentifiers } from './container/ServiceIdentifiers';
-
-import * as esprima from 'esprima';
-import * as escodegen from 'escodegen-wallaby';
-import * as esmangle from 'esmangle';
-import * as ESTree from 'estree';
-
-import { IGeneratorOutput } from './interfaces/IGeneratorOutput';
-import { IJavaScriptObfuscator } from './interfaces/IJavaScriptObfsucator';
-import { ILogger } from './interfaces/logger/ILogger';
-import { IObfuscationResult } from './interfaces/IObfuscationResult';
-import { IObfuscator } from './interfaces/IObfuscator';
-import { IOptions } from './interfaces/options/IOptions';
-import { IRandomGenerator } from './interfaces/utils/IRandomGenerator';
-import { ISourceMapCorrector } from './interfaces/ISourceMapCorrector';
-
-import { LoggingMessage } from './enums/logger/LoggingMessage';
-
-@injectable()
-export class JavaScriptObfuscatorInternal implements IJavaScriptObfuscator {
-    /**
-     * @type {GenerateOptions}
-     */
-    private static readonly escodegenParams: escodegen.GenerateOptions = {
-        verbatim: 'x-verbatim-property',
-        sourceMapWithCode: true
-    };
-
-    /**
-     * @type {ILogger}
-     */
-    private readonly logger: ILogger;
-
-    /**
-     * @type {IObfuscator}
-     */
-    private readonly obfuscator: IObfuscator;
-
-    /**
-     * @type {IOptions}
-     */
-    private readonly options: IOptions;
-
-    /**
-     * @type {IRandomGenerator}
-     */
-    private readonly randomGenerator: IRandomGenerator;
-
-    /**
-     * @type {ISourceMapCorrector}
-     */
-    private readonly sourceMapCorrector: ISourceMapCorrector;
-
-    /**
-     * @param {IObfuscator} obfuscator
-     * @param {ISourceMapCorrector} sourceMapCorrector
-     * @param {IRandomGenerator} randomGenerator
-     * @param {ILogger} logger
-     * @param {IOptions} options
-     */
-    constructor (
-        @inject(ServiceIdentifiers.IObfuscator) obfuscator: IObfuscator,
-        @inject(ServiceIdentifiers.ISourceMapCorrector) sourceMapCorrector: ISourceMapCorrector,
-        @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
-        @inject(ServiceIdentifiers.ILogger) logger: ILogger,
-        @inject(ServiceIdentifiers.IOptions) options: IOptions
-    ) {
-        this.obfuscator = obfuscator;
-        this.sourceMapCorrector = sourceMapCorrector;
-        this.randomGenerator = randomGenerator;
-        this.logger = logger;
-        this.options = options;
-    }
-
-    /**
-     * @param {string} sourceCode
-     * @returns {IObfuscationResult}
-     */
-    public obfuscate (sourceCode: string): IObfuscationResult {
-        const timeStart: number = Date.now();
-        this.logger.info(LoggingMessage.ObfuscationStarted);
-        this.logger.info(LoggingMessage.RandomGeneratorSeed, this.randomGenerator.getSeed());
-
-        // parse AST tree
-        const astTree: ESTree.Program = this.parseCode(sourceCode);
-
-        // obfuscate AST tree
-        const obfuscatedAstTree: ESTree.Program = this.obfuscator.obfuscateAstTree(astTree);
-
-        // generate code
-        const generatorOutput: IGeneratorOutput = this.generateCode(sourceCode, obfuscatedAstTree);
-
-        const obfuscationTime: number = (Date.now() - timeStart) / 1000;
-        this.logger.success(LoggingMessage.ObfuscationCompleted, obfuscationTime);
-
-        return this.getObfuscationResult(generatorOutput);
-    }
-
-    /**
-     * @param {string} sourceCode
-     * @returns {Program}
-     */
-    private parseCode (sourceCode: string): ESTree.Program {
-        return esprima.parseScript(sourceCode, {
-            attachComment: true,
-            loc: this.options.sourceMap
-        });
-    }
-
-    /**
-     * @param {string} sourceCode
-     * @param {Program} astTree
-     * @returns {IGeneratorOutput}
-     */
-    private generateCode (sourceCode: string, astTree: ESTree.Program): IGeneratorOutput {
-        const escodegenParams: escodegen.GenerateOptions = {
-            ...JavaScriptObfuscatorInternal.escodegenParams
-        };
-
-        if (this.options.sourceMap) {
-            escodegenParams.sourceMap = 'sourceMap';
-            escodegenParams.sourceContent = sourceCode;
-        }
-
-        if (this.options.mangle) {
-            astTree = esmangle.mangle(astTree);
-        }
-
-        const generatorOutput: IGeneratorOutput = escodegen.generate(astTree, {
-            ...escodegenParams,
-            format: {
-                compact: this.options.compact
-            }
-        });
-
-        generatorOutput.map = generatorOutput.map ? generatorOutput.map.toString() : '';
-
-        return generatorOutput;
-    }
-
-    /**
-     * @param {IGeneratorOutput} generatorOutput
-     * @returns {IObfuscationResult}
-     */
-    private getObfuscationResult (generatorOutput: IGeneratorOutput): IObfuscationResult {
-        return this.sourceMapCorrector.correct(
-            generatorOutput.code,
-            generatorOutput.map
-        );
-    }
-}

+ 0 - 270
src/Obfuscator.ts

@@ -1,270 +0,0 @@
-import { injectable, inject } from 'inversify';
-import { ServiceIdentifiers } from './container/ServiceIdentifiers';
-
-import * as estraverse from 'estraverse';
-import * as ESTree from 'estree';
-
-import { TNodeGuardFactory } from './types/container/node-guards/TNodeGuardFactory';
-import { TNodeTransformerFactory } from './types/container/node-transformers/TNodeTransformerFactory';
-import { TVisitorDirection } from './types/TVisitorDirection';
-import { TVisitorFunction } from './types/TVisitorFunction';
-import { TVisitorResult } from './types/TVisitorResult';
-
-import { ICustomNodeGroup } from './interfaces/custom-nodes/ICustomNodeGroup';
-import { ILogger } from './interfaces/logger/ILogger';
-import { IObfuscationEventEmitter } from './interfaces/event-emitters/IObfuscationEventEmitter';
-import { IObfuscator } from './interfaces/IObfuscator';
-import { IOptions } from './interfaces/options/IOptions';
-import { IStackTraceAnalyzer } from './interfaces/analyzers/stack-trace-analyzer/IStackTraceAnalyzer';
-import { IStackTraceData } from './interfaces/analyzers/stack-trace-analyzer/IStackTraceData';
-import { IStorage } from './interfaces/storages/IStorage';
-import { IVisitor } from './interfaces/IVisitor';
-
-import { LoggingMessage } from './enums/logger/LoggingMessage';
-import { NodeGuard } from './enums/container/node-guards/NodeGuard';
-import { NodeTransformer } from './enums/container/node-transformers/NodeTransformer';
-import { ObfuscationEvent } from './enums/event-emitters/ObfuscationEvent';
-import { VisitorDirection } from './enums/VisitorDirection';
-
-import { Node } from './node/Node';
-import { NodeUtils } from './node/NodeUtils';
-
-@injectable()
-export class Obfuscator implements IObfuscator {
-    /**
-     * @type {NodeTransformer[]}
-     */
-    private static readonly controlFlowTransformersList: NodeTransformer[] = [
-        NodeTransformer.BlockStatementControlFlowTransformer,
-        NodeTransformer.FunctionControlFlowTransformer
-    ];
-
-    /**
-     * @type {NodeTransformer[]}
-     */
-    private static readonly convertingTransformersList: NodeTransformer[] = [
-        NodeTransformer.MemberExpressionTransformer,
-        NodeTransformer.MethodDefinitionTransformer,
-        NodeTransformer.TemplateLiteralTransformer
-    ];
-
-    /**
-     * @type {NodeTransformer[]}
-     */
-    private static readonly deadCodeInjectionTransformersList: NodeTransformer[] = [
-        NodeTransformer.DeadCodeInjectionTransformer
-    ];
-
-    /**
-     * @type {NodeTransformer[]}
-     */
-    private static readonly obfuscatingTransformersList: NodeTransformer[] = [
-        NodeTransformer.CatchClauseTransformer,
-        NodeTransformer.ClassDeclarationTransformer,
-        NodeTransformer.FunctionDeclarationTransformer,
-        NodeTransformer.FunctionTransformer,
-        NodeTransformer.LabeledStatementTransformer,
-        NodeTransformer.LiteralTransformer,
-        NodeTransformer.ObjectExpressionTransformer,
-        NodeTransformer.VariableDeclarationTransformer
-    ];
-
-    private static readonly nodeGuardsList: NodeGuard[] = [
-        NodeGuard.BlackListNodeGuard,
-        NodeGuard.ConditionalCommentNodeGuard
-    ];
-
-    /**
-     * @type {IStorage<ICustomNodeGroup>}
-     */
-    private readonly customNodeGroupStorage: IStorage<ICustomNodeGroup>;
-
-    /**
-     * @type {Ilogger}
-     */
-    private readonly logger: ILogger;
-
-    /**
-     * @type {TNodeGuardFactory}
-     */
-    private readonly nodeGuardFactory: TNodeGuardFactory;
-
-    /**
-     * @type {TNodeTransformerFactory}
-     */
-    private readonly nodeTransformerFactory: TNodeTransformerFactory;
-
-    /**
-     * @type {IObfuscationEventEmitter}
-     */
-    private readonly obfuscationEventEmitter: IObfuscationEventEmitter;
-
-    /**
-     * @type {IOptions}
-     */
-    private readonly options: IOptions;
-
-    /**
-     * @type {IStackTraceAnalyzer}
-     */
-    private readonly stackTraceAnalyzer: IStackTraceAnalyzer;
-
-    /**
-     * @param {IStackTraceAnalyzer} stackTraceAnalyzer
-     * @param {IObfuscationEventEmitter} obfuscationEventEmitter
-     * @param {IStorage<ICustomNodeGroup>} customNodeGroupStorage
-     * @param {TNodeGuardFactory} nodeGuardFactory
-     * @param {TNodeTransformerFactory} nodeTransformerFactory
-     * @param {ILogger} logger
-     * @param {IOptions} options
-     */
-    constructor (
-        @inject(ServiceIdentifiers.IStackTraceAnalyzer) stackTraceAnalyzer: IStackTraceAnalyzer,
-        @inject(ServiceIdentifiers.IObfuscationEventEmitter) obfuscationEventEmitter: IObfuscationEventEmitter,
-        @inject(ServiceIdentifiers.TCustomNodeGroupStorage) customNodeGroupStorage: IStorage<ICustomNodeGroup>,
-        @inject(ServiceIdentifiers.Factory__INodeGuard) nodeGuardFactory: TNodeGuardFactory,
-        @inject(ServiceIdentifiers.Factory__INodeTransformer) nodeTransformerFactory: TNodeTransformerFactory,
-        @inject(ServiceIdentifiers.ILogger) logger: ILogger,
-        @inject(ServiceIdentifiers.IOptions) options: IOptions
-    ) {
-        this.stackTraceAnalyzer = stackTraceAnalyzer;
-        this.obfuscationEventEmitter = obfuscationEventEmitter;
-        this.customNodeGroupStorage = customNodeGroupStorage;
-        this.nodeGuardFactory = nodeGuardFactory;
-        this.nodeTransformerFactory = nodeTransformerFactory;
-        this.logger = logger;
-        this.options = options;
-    }
-
-    /**
-     * @param {Program} astTree
-     * @returns {Program}
-     */
-    public obfuscateAstTree (astTree: ESTree.Program): ESTree.Program {
-        if (Node.isProgramNode(astTree) && !astTree.body.length) {
-            this.logger.warn(LoggingMessage.EmptySourceCode);
-
-            return astTree;
-        }
-
-        astTree = <ESTree.Program>NodeUtils.parentize(astTree);
-
-        this.logger.info(LoggingMessage.StageAnalyzingASTTree);
-        const stackTraceData: IStackTraceData[] = this.stackTraceAnalyzer.analyze(astTree);
-
-        // initialize custom node groups and configure custom nodes
-        this.customNodeGroupStorage
-            .getStorage()
-            .forEach((customNodeGroup: ICustomNodeGroup) => {
-                customNodeGroup.initialize();
-
-                this.obfuscationEventEmitter.once(
-                    customNodeGroup.getAppendEvent(),
-                    customNodeGroup.appendCustomNodes.bind(customNodeGroup)
-                );
-            });
-
-        this.obfuscationEventEmitter.emit(ObfuscationEvent.BeforeObfuscation, astTree, stackTraceData);
-
-        // first pass transformers: dead code injection transformer
-        if (this.options.deadCodeInjection) {
-            this.logger.info(LoggingMessage.StageDeadCodeInjection);
-
-            astTree = this.transformAstTree(astTree, Obfuscator.deadCodeInjectionTransformersList);
-        }
-
-        // second pass transformers: control flow flattening transformers
-        if (this.options.controlFlowFlattening) {
-            this.logger.info(LoggingMessage.StageControlFlowFlattening);
-
-            astTree = this.transformAstTree(astTree, Obfuscator.controlFlowTransformersList);
-        }
-
-        // third pass: converting and obfuscating transformers
-        this.logger.info(LoggingMessage.StageObfuscation);
-        astTree = this.transformAstTree(astTree, [
-            ...Obfuscator.convertingTransformersList,
-            ...Obfuscator.obfuscatingTransformersList
-        ]);
-
-        this.obfuscationEventEmitter.emit(ObfuscationEvent.AfterObfuscation, astTree, stackTraceData);
-
-        return astTree;
-    }
-
-    /**
-     * @param {Program} astTree
-     * @param {NodeTransformer[]} nodeTransformers
-     * @returns {Program}
-     */
-    private transformAstTree (astTree: ESTree.Program, nodeTransformers: NodeTransformer[]): ESTree.Program {
-        if (!nodeTransformers.length) {
-            return astTree;
-        }
-
-        const enterVisitors: IVisitor[] = [];
-        const leaveVisitors: IVisitor[] = [];
-        const nodeTransformersLength: number = nodeTransformers.length;
-
-        let visitor: IVisitor;
-
-        for (let i: number = 0; i < nodeTransformersLength; i++) {
-            visitor = this.nodeTransformerFactory(nodeTransformers[i]).getVisitor();
-
-            if (visitor.enter) {
-                enterVisitors.push(visitor);
-            }
-
-            if (visitor.leave) {
-                leaveVisitors.push(visitor);
-            }
-        }
-
-        estraverse.replace(astTree, {
-            enter: this.mergeVisitorsForDirection(enterVisitors, VisitorDirection.Enter),
-            leave: this.mergeVisitorsForDirection(leaveVisitors, VisitorDirection.Leave)
-        });
-
-        return astTree;
-    }
-
-    /**
-     * @param {IVisitor[]} visitors
-     * @param {TVisitorDirection} direction
-     * @returns {TVisitorFunction}
-     */
-    private mergeVisitorsForDirection (visitors: IVisitor[], direction: TVisitorDirection): TVisitorFunction {
-        const visitorsLength: number = visitors.length;
-
-        if (!visitorsLength) {
-            return (node: ESTree.Node, parentNode: ESTree.Node) => node;
-        }
-
-        return (node: ESTree.Node, parentNode: ESTree.Node) => {
-            const obfuscationEnabled: boolean = Obfuscator.nodeGuardsList
-                .every((nodeGuardName: NodeGuard) => this.nodeGuardFactory(nodeGuardName).check(node));
-
-            if (!obfuscationEnabled) {
-                return estraverse.VisitorOption.Skip;
-            }
-
-            for (let i: number = 0; i < visitorsLength; i++) {
-                const visitorFunction: TVisitorFunction | undefined = visitors[i][direction];
-
-                if (!visitorFunction) {
-                    continue;
-                }
-
-                const visitorResult: TVisitorResult = visitorFunction(node, parentNode);
-
-                if (!visitorResult || !Node.isNode(visitorResult)) {
-                    continue;
-                }
-
-                node = visitorResult;
-            }
-
-            return node;
-        };
-    }
-}

+ 111 - 0
src/TransformersRunner.ts

@@ -0,0 +1,111 @@
+import { injectable, inject } from 'inversify';
+import { ServiceIdentifiers } from './container/ServiceIdentifiers';
+
+import * as estraverse from 'estraverse';
+import * as ESTree from 'estree';
+
+import { TNodeTransformerFactory } from './types/container/node-transformers/TNodeTransformerFactory';
+import { TVisitorDirection } from './types/TVisitorDirection';
+import { TVisitorFunction } from './types/TVisitorFunction';
+import { TVisitorResult } from './types/TVisitorResult';
+
+import { ITransformersRunner } from './interfaces/ITransformersRunner';
+import { IVisitor } from './interfaces/IVisitor';
+
+import { NodeTransformer } from './enums/container/node-transformers/NodeTransformer';
+import { VisitorDirection } from './enums/VisitorDirection';
+
+import { Node } from './node/Node';
+
+@injectable()
+export class TransformersRunner implements ITransformersRunner {
+    /**
+     * @type {TNodeTransformerFactory}
+     */
+    private readonly nodeTransformerFactory: TNodeTransformerFactory;
+
+    /**
+     * @param {TNodeTransformerFactory} nodeTransformerFactory
+     */
+    constructor (
+        @inject(ServiceIdentifiers.Factory__INodeTransformer) nodeTransformerFactory: TNodeTransformerFactory,
+    ) {
+        this.nodeTransformerFactory = nodeTransformerFactory;
+    }
+
+    /**
+     * @param {T} astTree
+     * @param {NodeTransformer[]} nodeTransformers
+     * @returns {T}
+     */
+    public transform <T extends ESTree.Node = ESTree.Program> (
+        astTree: T,
+        nodeTransformers: NodeTransformer[]
+    ): T {
+        if (!nodeTransformers.length) {
+            return astTree;
+        }
+
+        const enterVisitors: IVisitor[] = [];
+        const leaveVisitors: IVisitor[] = [];
+        const nodeTransformersLength: number = nodeTransformers.length;
+
+        let visitor: IVisitor;
+
+        for (let i: number = 0; i < nodeTransformersLength; i++) {
+            visitor = this.nodeTransformerFactory(nodeTransformers[i]).getVisitor();
+
+            if (visitor.enter) {
+                enterVisitors.push(visitor);
+            }
+
+            if (visitor.leave) {
+                leaveVisitors.push(visitor);
+            }
+        }
+
+        estraverse.replace(astTree, {
+            enter: this.mergeVisitorsForDirection(enterVisitors, VisitorDirection.Enter),
+            leave: this.mergeVisitorsForDirection(leaveVisitors, VisitorDirection.Leave)
+        });
+
+        return astTree;
+    }
+
+    /**
+     * @param {IVisitor[]} visitors
+     * @param {TVisitorDirection} direction
+     * @returns {TVisitorFunction}
+     */
+    private mergeVisitorsForDirection (visitors: IVisitor[], direction: TVisitorDirection): TVisitorFunction {
+        const visitorsLength: number = visitors.length;
+
+        if (!visitorsLength) {
+            return (node: ESTree.Node, parentNode: ESTree.Node) => node;
+        }
+
+        return (node: ESTree.Node, parentNode: ESTree.Node) => {
+            if (node.ignoredNode) {
+                return estraverse.VisitorOption.Skip;
+            }
+
+            for (let i: number = 0; i < visitorsLength; i++) {
+                const visitorFunction: TVisitorFunction | undefined = visitors[i][direction];
+
+                if (!visitorFunction) {
+                    continue;
+                }
+
+                const visitorResult: TVisitorResult = visitorFunction(node, parentNode);
+
+                if (!visitorResult || !Node.isNode(visitorResult)) {
+                    continue;
+                }
+
+                node = visitorResult;
+            }
+
+            return node;
+        };
+    }
+}

+ 1 - 1
src/cli/JavaScriptObfuscatorCLI.ts

@@ -18,7 +18,7 @@ import { SourceMapModeSanitizer } from './sanitizers/SourceMapModeSanitizer';
 import { StringArrayEncodingSanitizer } from './sanitizers/StringArrayEncodingSanitizer';
 
 import { CLIUtils } from './utils/CLIUtils';
-import { JavaScriptObfuscator } from '../JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../JavaScriptObfuscatorFacade';
 
 export class JavaScriptObfuscatorCLI implements IInitializable {
     /**

+ 6 - 6
src/container/InversifyContainerFacade.ts

@@ -17,19 +17,19 @@ import { IJavaScriptObfuscator } from '../interfaces/IJavaScriptObfsucator';
 import { ILogger } from '../interfaces/logger/ILogger';
 import { IObfuscationEventEmitter } from '../interfaces/event-emitters/IObfuscationEventEmitter';
 import { IObfuscationResult } from '../interfaces/IObfuscationResult';
-import { IObfuscator } from '../interfaces/IObfuscator';
 import { IOptions } from '../interfaces/options/IOptions';
 import { ISourceCode } from '../interfaces/ISourceCode';
 import { ISourceMapCorrector } from '../interfaces/ISourceMapCorrector';
+import { ITransformersRunner } from '../interfaces/ITransformersRunner';
 
-import { JavaScriptObfuscatorInternal } from '../JavaScriptObfuscatorInternal';
+import { JavaScriptObfuscator } from '../JavaScriptObfuscator';
 import { Logger } from '../logger/Logger';
 import { ObfuscationEventEmitter } from '../event-emitters/ObfuscationEventEmitter';
 import { ObfuscationResult } from '../ObfuscationResult';
-import { Obfuscator } from '../Obfuscator';
 import { Options } from "../options/Options";
 import { SourceCode } from '../SourceCode';
 import { SourceMapCorrector } from '../SourceMapCorrector';
+import { TransformersRunner } from '../TransformersRunner';
 
 export class InversifyContainerFacade implements IInversifyContainerFacade {
     /**
@@ -155,12 +155,12 @@ export class InversifyContainerFacade implements IInversifyContainerFacade {
 
         this.container
             .bind<IJavaScriptObfuscator>(ServiceIdentifiers.IJavaScriptObfuscator)
-            .to(JavaScriptObfuscatorInternal)
+            .to(JavaScriptObfuscator)
             .inSingletonScope();
 
         this.container
-            .bind<IObfuscator>(ServiceIdentifiers.IObfuscator)
-            .to(Obfuscator)
+            .bind<ITransformersRunner>(ServiceIdentifiers.ITransformersRunner)
+            .to(TransformersRunner)
             .inSingletonScope();
 
         this.container

+ 1 - 1
src/container/ServiceIdentifiers.ts

@@ -25,13 +25,13 @@ export enum ServiceIdentifiers {
     INodeTransformer = 'INodeTransformer',
     IObfuscationEventEmitter = 'IObfuscationEventEmitter',
     IObfuscationResult = 'IObfuscationResult',
-    IObfuscator = 'IObfuscator',
     IOptions = 'IOptions',
     IObfuscatingReplacer = 'IObfuscatingReplacer',
     IRandomGenerator = 'IRandomGenerator',
     ISourceCode = 'ISourceCode',
     ISourceMapCorrector = 'ISourceMapCorrector',
     IStackTraceAnalyzer = 'IStackTraceAnalyzer',
+    ITransformersRunner = 'ITransformersRunner',
     Newable__ICustomNode = 'Newable<ICustomNode>',
     Newable__TControlFlowStorage = 'Newable<TControlFlowStorage>',
     TCustomNodeGroupStorage = 'TCustomNodeGroupStorage',

+ 11 - 0
src/container/modules/node-transformers/NodeTransformersModule.ts

@@ -19,10 +19,21 @@ import { LiteralTransformer } from '../../../node-transformers/obfuscating-trans
 import { MemberExpressionTransformer } from '../../../node-transformers/converting-transformers/MemberExpressionTransformer';
 import { MethodDefinitionTransformer } from '../../../node-transformers/converting-transformers/MethodDefinitionTransformer';
 import { ObjectExpressionTransformer } from '../../../node-transformers/obfuscating-transformers/ObjectExpressionTransformer';
+import { ParentizeTransformer } from '../../../node-transformers/preparing-transformers/ParentizeTransformer';
 import { TemplateLiteralTransformer } from '../../../node-transformers/converting-transformers/TemplateLiteralTransformer';
 import { VariableDeclarationTransformer } from '../../../node-transformers/obfuscating-transformers/VariableDeclarationTransformer';
+import { NodeGuardTransformer } from '../../../node-transformers/preparing-transformers/NodeGuardTransformer';
 
 export const nodeTransformersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
+    // preparing transformers
+    bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
+        .to(ParentizeTransformer)
+        .whenTargetNamed(NodeTransformer.ParentizeTransformer);
+
+    bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
+        .to(NodeGuardTransformer)
+        .whenTargetNamed(NodeTransformer.NodeGuardTransformer);
+
     // control flow transformers
     bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
         .to(BlockStatementControlFlowTransformer)

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

@@ -16,7 +16,7 @@ import { SingleNodeCallControllerTemplate } from '../../templates/custom-nodes/S
 import { NO_CUSTOM_NODES_PRESET } from '../../options/presets/NoCustomNodes';
 
 import { AbstractCustomNode } from '../AbstractCustomNode';
-import { JavaScriptObfuscator } from '../../JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../JavaScriptObfuscatorFacade';
 import { NodeUtils } from '../../node/NodeUtils';
 
 @injectable()

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

@@ -16,7 +16,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../options/presets/NoCustomNodes';
 import { SelfDefendingTemplate } from '../../templates/custom-nodes/self-defending-nodes/self-defending-unicode-node/SelfDefendingTemplate';
 
 import { AbstractCustomNode } from '../AbstractCustomNode';
-import { JavaScriptObfuscator } from '../../JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../JavaScriptObfuscatorFacade';
 import { NodeUtils } from '../../node/NodeUtils';
 
 @injectable()

+ 1 - 1
src/custom-nodes/string-array-nodes/StringArrayCallsWrapper.ts

@@ -23,7 +23,7 @@ import { StringArrayCallsWrapperTemplate } from '../../templates/custom-nodes/st
 import { StringArrayRc4DecodeNodeTemplate } from '../../templates/custom-nodes/string-array-nodes/string-array-calls-wrapper/StringArrayRC4DecodeNodeTemplate';
 
 import { AbstractCustomNode } from '../AbstractCustomNode';
-import { JavaScriptObfuscator } from '../../JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../JavaScriptObfuscatorFacade';
 import { NodeUtils } from '../../node/NodeUtils';
 
 @injectable()

+ 1 - 1
src/custom-nodes/string-array-nodes/StringArrayRotateFunctionNode.ts

@@ -18,7 +18,7 @@ import { SelfDefendingTemplate } from '../../templates/custom-nodes/string-array
 import { StringArrayRotateFunctionTemplate } from '../../templates/custom-nodes/string-array-nodes/string-array-rotate-function-node/StringArrayRotateFunctionTemplate';
 
 import { AbstractCustomNode } from '../AbstractCustomNode';
-import { JavaScriptObfuscator } from '../../JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../JavaScriptObfuscatorFacade';
 import { NodeUtils } from '../../node/NodeUtils';
 import { Utils } from '../../utils/Utils';
 

+ 1 - 0
src/declarations/ESTree.d.ts

@@ -4,6 +4,7 @@ import * as ESTree from 'estree';
 
 declare module 'estree' {
     interface BaseNode {
+        ignoredNode?: boolean;
         obfuscatedNode?: boolean;
         parentNode?: ESTree.Node;
     }

+ 2 - 0
src/enums/container/node-transformers/NodeTransformer.ts

@@ -10,7 +10,9 @@ export enum NodeTransformer {
     LiteralTransformer,
     MemberExpressionTransformer,
     MethodDefinitionTransformer,
+    NodeGuardTransformer,
     ObjectExpressionTransformer,
+    ParentizeTransformer,
     TemplateLiteralTransformer,
     VariableDeclarationTransformer
 }

+ 1 - 0
src/enums/logger/LoggingMessage.ts

@@ -3,6 +3,7 @@ export enum LoggingMessage {
     ObfuscationCompleted = 'Obfuscation completed. Total time: %s sec.',
     ObfuscationStarted = 'Obfuscation started...',
     RandomGeneratorSeed = 'Random generator seed: %s...',
+    StagePreparingASTTree = 'Stage: preparing AST-tree...',
     StageAnalyzingASTTree = 'Stage: analyzing AST-tree...',
     StageControlFlowFlattening = 'Stage: control flow flattening...',
     StageDeadCodeInjection = 'Stage: dead code injection...',

+ 0 - 9
src/interfaces/IObfuscator.d.ts

@@ -1,9 +0,0 @@
-import * as ESTree from 'estree';
-
-export interface IObfuscator {
-    /**
-     * @param astTree
-     * @returns ESTree.Program
-     */
-    obfuscateAstTree (astTree: ESTree.Program): ESTree.Program;
-}

+ 12 - 0
src/interfaces/ITransformersRunner.d.ts

@@ -0,0 +1,12 @@
+import * as ESTree from 'estree';
+
+import { NodeTransformer } from '../enums/container/node-transformers/NodeTransformer';
+
+export interface ITransformersRunner {
+    /**
+     * @param {T} astTree
+     * @param {NodeTransformer[]} nodeTransformers
+     * @returns {T}
+     */
+    transform <T extends ESTree.Program> (astTree: T, nodeTransformers: NodeTransformer[]): T;
+}

+ 3 - 2
src/interfaces/IVisitor.d.ts

@@ -1,6 +1,7 @@
+import * as estraverse from 'estraverse';
 import * as ESTree from 'estree';
 
 export interface IVisitor {
-    enter?: (node: ESTree.Node, parentNode: ESTree.Node | null) => ESTree.Node | void;
-    leave?: (node: ESTree.Node, parentNode: ESTree.Node | null) => ESTree.Node | void;
+    enter?: (node: ESTree.Node, parentNode: ESTree.Node | null) => ESTree.Node | estraverse.VisitorOption | void;
+    leave?: (node: ESTree.Node, parentNode: ESTree.Node | null) => ESTree.Node | estraverse.VisitorOption | void;
 }

+ 11 - 4
src/interfaces/node-transformers/INodeTransformer.d.ts

@@ -1,3 +1,4 @@
+import * as estraverse from 'estraverse';
 import * as ESTree from 'estree';
 
 import { IVisitor } from '../IVisitor';
@@ -9,9 +10,15 @@ export interface INodeTransformer {
     getVisitor (): IVisitor;
 
     /**
-     * @param node
-     * @param parentNode
-     * @returns {ESTree.Node}
+     * @param {Node} node
+     * @param {Node} parentNode
      */
-    transformNode (node: ESTree.Node, parentNode: ESTree.Node): ESTree.Node;
+    analyzeNode ? (node: ESTree.Node, parentNode: ESTree.Node): void;
+
+    /**
+     * @param {Node} node
+     * @param {Node} parentNode
+     * @returns {Node | VisitorOption}
+     */
+    transformNode (node: ESTree.Node, parentNode: ESTree.Node): ESTree.Node | estraverse.VisitorOption;
 }

+ 13 - 13
src/node-guards/ConditionalCommentNodeGuard.ts

@@ -19,39 +19,39 @@ export class ConditionalCommentNodeGuard implements INodeGuard {
     /**
      * @type {boolean}
      */
-    private obfuscationEnabledForCurrentNode: boolean = true;
+    private obfuscationAllowedForCurrentNode: boolean = true;
 
     /**
      * @type {boolean}
      */
-    private obfuscationEnabledForNextNode: boolean | null = null;
+    private obfuscationAllowedForNextNode: boolean | null = null;
 
     /**
      * @returns {boolean}
      * @param node
      */
     public check (node: ESTree.Node): boolean {
-        if (this.obfuscationEnabledForNextNode) {
-            this.obfuscationEnabledForCurrentNode = this.obfuscationEnabledForNextNode;
-            this.obfuscationEnabledForNextNode = null;
+        if (this.obfuscationAllowedForNextNode) {
+            this.obfuscationAllowedForCurrentNode = this.obfuscationAllowedForNextNode;
+            this.obfuscationAllowedForNextNode = null;
         }
 
         if (!node.leadingComments && !node.trailingComments) {
-            return this.obfuscationEnabledForCurrentNode;
+            return this.obfuscationAllowedForCurrentNode;
         }
 
         const leadingComments: ESTree.Comment[] | undefined = node.leadingComments;
         const trailingComments: ESTree.Comment[] | undefined = node.trailingComments;
 
         if (leadingComments) {
-            this.obfuscationEnabledForCurrentNode = this.checkComments(leadingComments);
+            this.obfuscationAllowedForCurrentNode = this.checkComments(leadingComments);
         }
 
         if (trailingComments) {
-            this.obfuscationEnabledForNextNode = this.checkComments(trailingComments);
+            this.obfuscationAllowedForNextNode = this.checkComments(trailingComments);
         }
 
-        return this.obfuscationEnabledForCurrentNode;
+        return this.obfuscationAllowedForCurrentNode;
     }
 
     /**
@@ -61,22 +61,22 @@ export class ConditionalCommentNodeGuard implements INodeGuard {
     private checkComments (comments: ESTree.Comment[]): boolean {
         const commentsLength: number = comments.length;
 
-        let obfuscationEnabled: boolean = this.obfuscationEnabledForCurrentNode;
+        let obfuscationAllowed: boolean = this.obfuscationAllowedForCurrentNode;
 
         for (let i: number = 0; i < commentsLength; i++) {
             const comment: ESTree.Comment = comments[i];
 
             if (ConditionalCommentNodeGuard.obfuscationEnableCommentRegExp.test(comment.value)) {
-                obfuscationEnabled = true;
+                obfuscationAllowed = true;
 
                 continue;
             }
 
             if (ConditionalCommentNodeGuard.obfuscationDisableCommentRegExp.test(comment.value)) {
-                obfuscationEnabled = false;
+                obfuscationAllowed = false;
             }
         }
 
-        return obfuscationEnabled;
+        return obfuscationAllowed;
     }
 }

+ 3 - 2
src/node-transformers/AbstractNodeTransformer.ts

@@ -1,6 +1,7 @@
 import { injectable, inject, postConstruct } from 'inversify';
 import { ServiceIdentifiers } from '../container/ServiceIdentifiers';
 
+import * as estraverse from 'estraverse';
 import * as ESTree from 'estree';
 
 import { IInitializable } from '../interfaces/IInitializable';
@@ -54,7 +55,7 @@ export abstract class AbstractNodeTransformer implements INodeTransformer, IInit
     /**
      * @param {Node} node
      * @param {Node} parentNode
-     * @returns {Node}
+     * @returns {Node | VisitorOption}
      */
-    public abstract transformNode (node: ESTree.Node, parentNode: ESTree.Node): ESTree.Node;
+    public abstract transformNode (node: ESTree.Node, parentNode: ESTree.Node): ESTree.Node | estraverse.VisitorOption;
 }

+ 56 - 51
src/node-transformers/dead-code-injection-transformers/DeadCodeInjectionTransformer.ts

@@ -30,6 +30,11 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
      */
     private readonly collectedBlockStatements: ESTree.BlockStatement[] = [];
 
+    /**
+     * @type {number}
+     */
+    private collectedBlockStatementsLength: number;
+
     /**
      * @param {IRandomGenerator} randomGenerator
      * @param {IOptions} options
@@ -46,8 +51,15 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
      */
     public getVisitor (): IVisitor {
         return {
-            leave: (node: ESTree.Node, parentNode: ESTree.Node) => {
+            enter: (node: ESTree.Node, parentNode: ESTree.Node) => {
                 if (Node.isProgramNode(node)) {
+                    this.analyzeNode(node, parentNode);
+
+                    return node;
+                }
+            },
+            leave: (node: ESTree.Node, parentNode: ESTree.Node) => {
+                if (Node.isBlockStatementNode(node)) {
                     return this.transformNode(node, parentNode);
                 }
             }
@@ -55,14 +67,52 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
     }
 
     /**
-     * @param {Program} programNode
+     * @param {Node} programNode
      * @param {Node} parentNode
-     * @returns {Node}
      */
-    public transformNode (programNode: ESTree.Program, parentNode: ESTree.Node): ESTree.Node {
-        this.transformProgramNode(programNode);
+    public analyzeNode (programNode: ESTree.Node, parentNode: ESTree.Node): void {
+        estraverse.traverse(programNode, {
+            enter: (node: ESTree.Node): any => {
+                if (Node.isBlockStatementNode(node)) {
+                    this.collectBlockStatementNodes(node, this.collectedBlockStatements);
+                }
+            }
+        });
 
-        return programNode;
+        this.collectedBlockStatementsLength = this.collectedBlockStatements.length;
+    }
+
+    /**
+     * @param {BlockStatement} blockStatementNode
+     * @param {Node} parentNode
+     * @returns {Node | VisitorOption}
+     */
+    public transformNode (
+        blockStatementNode: ESTree.BlockStatement,
+        parentNode: ESTree.Node
+    ): ESTree.Node | estraverse.VisitorOption {
+        if (this.collectedBlockStatementsLength < DeadCodeInjectionTransformer.minCollectedBlockStatementsCount) {
+            return estraverse.VisitorOption.Break;
+        }
+
+        if (!this.collectedBlockStatements.length) {
+            return estraverse.VisitorOption.Break;
+        }
+
+        if (this.randomGenerator.getMathRandom() > this.options.deadCodeInjectionThreshold) {
+            return blockStatementNode;
+        }
+
+        const minInteger: number = 0;
+        const maxInteger: number = this.collectedBlockStatements.length - 1;
+        const randomIndex: number = this.randomGenerator.getRandomInteger(minInteger, maxInteger);
+        const randomBlockStatementNode: ESTree.BlockStatement = this.collectedBlockStatements.splice(randomIndex, 1)[0];
+
+        if (randomBlockStatementNode === blockStatementNode) {
+            return blockStatementNode;
+        }
+
+        return this.replaceBlockStatementNode(blockStatementNode, randomBlockStatementNode);
     }
 
     /**
@@ -163,49 +213,4 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
 
         return newBlockStatementNode;
     }
-
-    /**
-     * @param {Program} programNode
-     */
-    private transformProgramNode (programNode: ESTree.Program): void {
-        estraverse.traverse(programNode, {
-            enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
-                if (!Node.isBlockStatementNode(node)) {
-                    return;
-                }
-
-                this.collectBlockStatementNodes(node, this.collectedBlockStatements);
-            }
-        });
-
-        if (this.collectedBlockStatements.length < DeadCodeInjectionTransformer.minCollectedBlockStatementsCount) {
-            return;
-        }
-
-        estraverse.replace(programNode, {
-            leave: (node: ESTree.Node, parentNode: ESTree.Node): any => {
-                if (!this.collectedBlockStatements.length) {
-                    return estraverse.VisitorOption.Break;
-                }
-
-                if (
-                    !Node.isBlockStatementNode(node) ||
-                    this.randomGenerator.getMathRandom() > this.options.deadCodeInjectionThreshold
-                ) {
-                    return node;
-                }
-
-                const minInteger: number = 0;
-                const maxInteger: number = this.collectedBlockStatements.length - 1;
-                const randomIndex: number = this.randomGenerator.getRandomInteger(minInteger, maxInteger);
-                const randomBlockStatementNode: ESTree.BlockStatement = this.collectedBlockStatements.splice(randomIndex, 1)[0];
-
-                if (randomBlockStatementNode === node) {
-                    return node;
-                }
-
-                return this.replaceBlockStatementNode(node, randomBlockStatementNode);
-            }
-        });
-    }
 }

+ 72 - 0
src/node-transformers/preparing-transformers/NodeGuardTransformer.ts

@@ -0,0 +1,72 @@
+import { injectable, inject } from 'inversify';
+import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
+
+import * as ESTree from 'estree';
+
+import { IOptions } from '../../interfaces/options/IOptions';
+import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
+import { IVisitor } from '../../interfaces/IVisitor';
+
+import { NodeGuard } from '../../enums/container/node-guards/NodeGuard';
+
+import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
+import { TNodeGuardFactory } from '../../types/container/node-guards/TNodeGuardFactory';
+import { INodeGuard } from '../../interfaces/node-guards/INodeGuard';
+
+/**
+ * Adds `parentNode` properties to each node
+ */
+@injectable()
+export class NodeGuardTransformer extends AbstractNodeTransformer {
+    /**
+     * @type {NodeGuard[]}
+     */
+    private static readonly nodeGuardsList: NodeGuard[] = [
+        NodeGuard.BlackListNodeGuard,
+        NodeGuard.ConditionalCommentNodeGuard
+    ];
+
+    /**
+     * @type {INodeGuard[]}
+     */
+    private readonly nodeGuards: INodeGuard[];
+
+    /**
+     * @param {TNodeGuardFactory} nodeGuardFactory
+     * @param {IRandomGenerator} randomGenerator
+     * @param {IOptions} options
+     */
+    constructor (
+        @inject(ServiceIdentifiers.Factory__INodeGuard) nodeGuardFactory: TNodeGuardFactory,
+        @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
+        @inject(ServiceIdentifiers.IOptions) options: IOptions
+    ) {
+        super(randomGenerator, options);
+
+        this.nodeGuards = NodeGuardTransformer.nodeGuardsList.map(nodeGuardFactory);
+    }
+
+    /**
+     * @return {IVisitor}
+     */
+    public getVisitor (): IVisitor {
+        return {
+            enter: (node: ESTree.Node, parentNode: ESTree.Node) => {
+                return this.transformNode(node, parentNode);
+            }
+        };
+    }
+
+    /**
+     * @param {Node} node
+     * @param {Node} parentNode
+     * @returns {Node}
+     */
+    public transformNode (node: ESTree.Node, parentNode: ESTree.Node): ESTree.Node {
+        const obfuscationAllowed: boolean = this.nodeGuards.every((nodeGuard: INodeGuard) => nodeGuard.check(node));
+
+        node.ignoredNode = !obfuscationAllowed;
+
+        return node;
+    }
+}

+ 50 - 0
src/node-transformers/preparing-transformers/ParentizeTransformer.ts

@@ -0,0 +1,50 @@
+import { injectable, inject } from 'inversify';
+import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
+
+import * as ESTree from 'estree';
+
+import { IOptions } from '../../interfaces/options/IOptions';
+import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
+import { IVisitor } from '../../interfaces/IVisitor';
+
+import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
+
+/**
+ * Adds `parentNode` properties to each node
+ */
+@injectable()
+export class ParentizeTransformer extends AbstractNodeTransformer {
+    /**
+     * @param {IRandomGenerator} randomGenerator
+     * @param {IOptions} options
+     */
+    constructor (
+        @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
+        @inject(ServiceIdentifiers.IOptions) options: IOptions
+    ) {
+        super(randomGenerator, options);
+    }
+
+    /**
+     * @return {IVisitor}
+     */
+    public getVisitor (): IVisitor {
+        return {
+            enter: (node: ESTree.Node, parentNode: ESTree.Node) => {
+                return this.transformNode(node, parentNode);
+            }
+        };
+    }
+
+    /**
+     * @param {Node} node
+     * @param {Node} parentNode
+     * @returns {Node}
+     */
+    public transformNode (node: ESTree.Node, parentNode: ESTree.Node): ESTree.Node {
+        node.parentNode = parentNode || node;
+        node.obfuscatedNode = false;
+
+        return node;
+    }
+}

+ 7 - 23
src/node/NodeUtils.ts

@@ -9,7 +9,6 @@ import { TStatement } from '../types/node/TStatement';
 import { NodeType } from '../enums/NodeType';
 
 import { Node } from './Node';
-import { Nodes } from './Nodes';
 
 export class NodeUtils {
     /**
@@ -44,7 +43,7 @@ export class NodeUtils {
      * @param {T} astTree
      * @returns {T}
      */
-    public static clone <T extends ESTree.Node> (astTree: T): T {
+    public static clone <T extends ESTree.Node = ESTree.Node> (astTree: T): T {
         /**
          * @param {T} node
          * @returns {T}
@@ -151,11 +150,13 @@ export class NodeUtils {
             }
         }
 
-        if (!Node.isProgramNode(parentNode)) {
+        if (node !== parentNode) {
             return NodeUtils.getBlockScopesOfNode(parentNode, blockScopes);
         }
 
-        blockScopes.push(parentNode);
+        if (Node.isNodeHasBlockStatement(parentNode)) {
+            blockScopes.push(parentNode);
+        }
 
         return blockScopes;
     }
@@ -199,27 +200,10 @@ export class NodeUtils {
      * @param {T} astTree
      * @returns {T}
      */
-    public static parentize <T extends ESTree.Node> (astTree: T): T {
-        let isRootNode: boolean = true;
-
+    public static parentize <T extends ESTree.Node = ESTree.Program> (astTree: T): T {
         estraverse.traverse(astTree, {
             enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
-                let value: ESTree.Node;
-
-                if (isRootNode) {
-                    if (node.type === NodeType.Program) {
-                        value = node;
-                    } else {
-                        value = Nodes.getProgramNode(<TStatement[]>[node]);
-                        value.parentNode = value;
-                    }
-
-                    isRootNode = false;
-                } else {
-                    value = parentNode || node;
-                }
-
-                node.parentNode = value;
+                node.parentNode = parentNode || node;
                 node.obfuscatedNode = false;
             }
         });

+ 1 - 0
test/dev/dev.ts

@@ -11,6 +11,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../src/options/presets/NoCustomNodes'
                 var foo = function () {
                     console.log('abc');
                 };
+                // javascript-obfuscator:disable
                 var bar = function () {
                     console.log('def');
                 };

+ 1 - 1
test/functional-tests/cli/JavaScriptObfuscatorCLI.spec.ts

@@ -6,7 +6,7 @@ import { assert } from 'chai';
 
 import { StdoutWriteMock } from '../../mocks/StdoutWriteMock';
 
-import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscatorFacade';
 
 describe('JavaScriptObfuscatorCLI', function (): void {
     this.timeout(100000);

+ 1 - 1
test/functional-tests/custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode.spec.ts

@@ -6,7 +6,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../../../src/options/presets/NoCustom
 
 import { readFileAsString } from '../../../helpers/readFileAsString';
 
-import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscatorFacade';
 
 describe('ConsoleOutputDisableExpressionNode', () => {
     const consoleLogRegExp: RegExp = /_0x([a-f0-9]){4,6}\['console'\]\['log'\] *= *_0x([a-f0-9]){4,6};/u;

+ 1 - 1
test/functional-tests/custom-nodes/domain-lock-nodes/DomainLockNode.spec.ts

@@ -6,7 +6,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../../../src/options/presets/NoCustom
 
 import { readFileAsString } from '../../../helpers/readFileAsString';
 
-import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscatorFacade';
 
 describe('DomainLockNode', () => {
     const regExp: RegExp = /var _0x([a-f0-9]){4,6} *= *new RegExp/;

+ 1 - 1
test/functional-tests/custom-nodes/string-array-nodes/StringArrayCallsWrapper.spec.ts

@@ -6,7 +6,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../../../src/options/presets/NoCustom
 
 import { readFileAsString } from '../../../helpers/readFileAsString';
 
-import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscatorFacade';
 
 describe('StringArrayCallsWrapper', () => {
     const regExp: RegExp = /_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6} *- *0x0\;/;

+ 1 - 1
test/functional-tests/custom-nodes/string-array-nodes/StringArrayNode.spec.ts

@@ -6,7 +6,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../../../src/options/presets/NoCustom
 
 import { readFileAsString } from '../../../helpers/readFileAsString';
 
-import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscatorFacade';
 
 describe('StringArrayNode', () => {
     const regExp: RegExp = /^var _0x([a-f0-9]){4} *= *\[/;

+ 1 - 1
test/functional-tests/custom-nodes/string-array-nodes/StringArrayRotateFunctionNode.spec.ts

@@ -6,7 +6,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../../../src/options/presets/NoCustom
 
 import { readFileAsString } from '../../../helpers/readFileAsString';
 
-import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscatorFacade';
 
 describe('StringArrayRotateFunctionNode', () => {
     const regExp: RegExp = /while *\(-- *_0x([a-f0-9]){4,6}\) *\{/;

+ 1 - 1
test/functional-tests/javascript-obfuscator/JavaScriptObfuscator.spec.ts

@@ -2,7 +2,7 @@ import { assert } from 'chai';
 
 import { IObfuscationResult } from '../../../src/interfaces/IObfuscationResult';
 
-import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscatorFacade';
 
 import { NO_CUSTOM_NODES_PRESET } from '../../../src/options/presets/NoCustomNodes';
 

+ 1 - 1
test/functional-tests/node-guards/black-list-node-guard/BlackListNodeGuard.spec.ts

@@ -2,7 +2,7 @@ import { assert } from 'chai';
 
 import { IObfuscationResult } from '../../../../src/interfaces/IObfuscationResult';
 
-import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscatorFacade';
 
 import { NO_CUSTOM_NODES_PRESET } from '../../../../src/options/presets/NoCustomNodes';
 

+ 1 - 1
test/functional-tests/node-transformers/control-flow-transformers/block-statement-control-flow-transformer/BlockStatementControlFlowTransformer.spec.ts

@@ -7,7 +7,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../../../../src/options/presets/NoCus
 import { getRegExpMatch } from '../../../../helpers/getRegExpMatch';
 import { readFileAsString } from '../../../../helpers/readFileAsString';
 
-import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
 
 /**
  * @param hexNumber

+ 1 - 1
test/functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/binary-expression-control-flow-replacer/BinaryExpressionControlFlowReplacer.spec.ts

@@ -6,7 +6,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../../../../../src/options/presets/No
 
 import { readFileAsString } from '../../../../../helpers/readFileAsString';
 
-import { JavaScriptObfuscator } from '../../../../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../../../../src/JavaScriptObfuscatorFacade';
 
 describe('BinaryExpressionControlFlowReplacer', function () {
     this.timeout(100000);

+ 1 - 1
test/functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/call-expression-control-flow-replacer/CallExpressionControlFlowReplacer.spec.ts

@@ -6,7 +6,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../../../../../src/options/presets/No
 
 import { readFileAsString } from '../../../../../helpers/readFileAsString';
 
-import { JavaScriptObfuscator } from '../../../../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../../../../src/JavaScriptObfuscatorFacade';
 
 describe('CallExpressionControlFlowReplacer', function () {
     this.timeout(100000);

+ 1 - 1
test/functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/logical-expression-control-flow-replacer/LogicalExpressionControlFlowReplacer.spec.ts

@@ -6,7 +6,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../../../../../src/options/presets/No
 
 import { readFileAsString } from '../../../../../helpers/readFileAsString';
 
-import { JavaScriptObfuscator } from '../../../../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../../../../src/JavaScriptObfuscatorFacade';
 
 describe('LogicalExpressionControlFlowReplacer', function () {
     this.timeout(100000);

+ 1 - 1
test/functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/string-litertal-control-flow-replacer/StringLiteralControlFlowReplacer.spec.ts

@@ -6,7 +6,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../../../../../src/options/presets/No
 
 import { readFileAsString } from '../../../../../helpers/readFileAsString';
 
-import { JavaScriptObfuscator } from '../../../../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../../../../src/JavaScriptObfuscatorFacade';
 
 describe('StringLiteralControlFlowReplacer', () => {
     describe('replace (literalNode: ESTree.Literal,parentNode: ESTree.Node,controlFlowStorage: IStorage <ICustomNode>)', () => {

+ 1 - 1
test/functional-tests/node-transformers/control-flow-transformers/function-control-flow-transformer/FunctionControlFlowTransformer.spec.ts

@@ -6,7 +6,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../../../../src/options/presets/NoCus
 
 import { readFileAsString } from '../../../../helpers/readFileAsString';
 
-import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
 
 describe('FunctionControlFlowTransformer', function () {
     this.timeout(100000);

+ 1 - 1
test/functional-tests/node-transformers/converting-transformers/member-expression-transformer/MemberExpressionTransformer.spec.ts

@@ -6,7 +6,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../../../../src/options/presets/NoCus
 
 import { readFileAsString } from '../../../../helpers/readFileAsString';
 
-import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
 
 describe('MemberExpressionTransformer', () => {
     describe('transformation of member expression node with dot notation', () => {

+ 1 - 1
test/functional-tests/node-transformers/converting-transformers/method-definition-transformer/MethodDefinitionTransformer.spec.ts

@@ -6,7 +6,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../../../../src/options/presets/NoCus
 
 import { readFileAsString } from '../../../../helpers/readFileAsString';
 
-import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
 
 describe('MethodDefinitionTransformer', () => {
     const code: string = readFileAsString(__dirname + '/fixtures/input.js');

+ 1 - 1
test/functional-tests/node-transformers/converting-transformers/template-literal-transformer/TemplateLiteralTransformer.spec.ts

@@ -6,7 +6,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../../../../src/options/presets/NoCus
 
 import { readFileAsString } from '../../../../helpers/readFileAsString';
 
-import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
 
 describe('TemplateLiteralTransformer', () => {
     describe('variant #1: simple template literal', () => {

+ 1 - 1
test/functional-tests/node-transformers/dead-code-injection-transformers/DeadCodeInjectionTransformer.spec.ts

@@ -6,7 +6,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../../../src/options/presets/NoCustom
 
 import { readFileAsString } from '../../../helpers/readFileAsString';
 
-import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscatorFacade';
 
 describe('DeadCodeInjectionTransformer', () => {
     const variableMatch: string = '_0x([a-f0-9]){4,6}';

+ 1 - 1
test/functional-tests/node-transformers/obfuscating-transformers/catch-clause-transformer/CatchClauseTransformer.spec.ts

@@ -7,7 +7,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../../../../src/options/presets/NoCus
 import { getRegExpMatch } from '../../../../helpers/getRegExpMatch';
 import { readFileAsString } from '../../../../helpers/readFileAsString';
 
-import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
 
 describe('CatchClauseTransformer', () => {
     let obfuscatedCode: string;

+ 1 - 1
test/functional-tests/node-transformers/obfuscating-transformers/class-declaration-transformer/ClassDeclarationTransformer.spec.ts

@@ -7,7 +7,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../../../../src/options/presets/NoCus
 import { getRegExpMatch } from '../../../../helpers/getRegExpMatch';
 import { readFileAsString } from '../../../../helpers/readFileAsString';
 
-import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
 
 describe('ClassDeclarationTransformer', () => {
     describe('transformation of `classDeclaration` node names', () => {

+ 1 - 1
test/functional-tests/node-transformers/obfuscating-transformers/function-declaration-transformer/FunctionDeclarationTransformer.spec.ts

@@ -7,7 +7,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../../../../src/options/presets/NoCus
 import { getRegExpMatch } from '../../../../helpers/getRegExpMatch';
 import { readFileAsString } from '../../../../helpers/readFileAsString';
 
-import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
 
 describe('FunctionDeclarationTransformer', () => {
     describe('transformation of `functionDeclaration` node names', () => {

+ 1 - 1
test/functional-tests/node-transformers/obfuscating-transformers/function-transformer/FunctionTransformer.spec.ts

@@ -6,7 +6,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../../../../src/options/presets/NoCus
 
 import { readFileAsString } from '../../../../helpers/readFileAsString';
 
-import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
 import { getRegExpMatch } from '../../../../helpers/getRegExpMatch';
 
 describe('FunctionTransformer', () => {

+ 1 - 1
test/functional-tests/node-transformers/obfuscating-transformers/labeled-statement-transformer/LabeledStatementTransformer.spec.ts

@@ -7,7 +7,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../../../../src/options/presets/NoCus
 import { getRegExpMatch } from '../../../../helpers/getRegExpMatch';
 import { readFileAsString } from '../../../../helpers/readFileAsString';
 
-import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
 
 describe('LabeledStatementTransformer', () => {
     describe('changeControlFlow (labeledStatementNode: ESTree.LabeledStatement): void', () => {

+ 1 - 1
test/functional-tests/node-transformers/obfuscating-transformers/literal-transformer/LiteralTransformer.spec.ts

@@ -6,7 +6,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../../../../src/options/presets/NoCus
 
 import { readFileAsString } from '../../../../helpers/readFileAsString';
 
-import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
 
 describe('LiteralTransformer', () => {
     describe('transformation of literal node with string value', () => {

+ 1 - 1
test/functional-tests/node-transformers/obfuscating-transformers/object-expression-transformer/ObjectExpressionTransformer.spec.ts

@@ -6,7 +6,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../../../../src/options/presets/NoCus
 
 import { readFileAsString } from '../../../../helpers/readFileAsString';
 
-import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
 
 describe('ObjectExpressionTransformer', () => {
     describe('default behaviour', () => {

+ 1 - 1
test/functional-tests/node-transformers/obfuscating-transformers/variable-declaration-transformer/VariableDeclarationTransformer.spec.ts

@@ -7,7 +7,7 @@ import { NO_CUSTOM_NODES_PRESET } from '../../../../../src/options/presets/NoCus
 import { getRegExpMatch } from '../../../../helpers/getRegExpMatch';
 import { readFileAsString } from '../../../../helpers/readFileAsString';
 
-import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
 
 describe('VariableDeclarationTransformer', () => {
     describe('variant #1: default behaviour', () => {

+ 1 - 1
test/performance-tests/JavaScriptObfuscatorPerformance.spec.ts

@@ -2,7 +2,7 @@ import { assert } from 'chai';
 
 import { readFileAsString } from '../helpers/readFileAsString';
 
-import { JavaScriptObfuscator } from '../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../src/JavaScriptObfuscatorFacade';
 
 describe('JavaScriptObfuscator performance', function () {
     const iterationsCount: number = 500;

+ 1 - 1
test/runtime-tests/JavaScriptObfuscatorRuntime.spec.ts

@@ -4,7 +4,7 @@ import { IObfuscationResult } from '../../src/interfaces/IObfuscationResult';
 
 import { readFileAsString } from '../helpers/readFileAsString';
 
-import { JavaScriptObfuscator } from '../../src/JavaScriptObfuscator';
+import { JavaScriptObfuscator } from '../../src/JavaScriptObfuscatorFacade';
 
 describe('JavaScriptObfuscator runtime eval', function () {
     this.timeout(100000);

+ 1 - 6
test/unit-tests/node/node-utils/NodeUtils.spec.ts

@@ -525,16 +525,11 @@ describe('NodeUtils', () => {
 
         describe('parentize AST-tree', () => {
             beforeEach(() => {
-                programNode = Nodes.getProgramNode([
-                    ifStatementNode
-                ]);
-                programNode.parentNode = programNode;
-
                 ifStatementNode = NodeUtils.parentize(ifStatementNode);
             });
 
             it('should parentize `ifStatement` node', () => {
-                assert.deepEqual(ifStatementNode.parentNode, programNode);
+                assert.deepEqual(ifStatementNode.parentNode, ifStatementNode);
             });
 
             it('should parentize `ifStatement blockStatement` node', () => {

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov