# All files / src/custom-nodes/console-output-nodes/group ConsoleOutputCustomNodeGroup.ts

100% Statements 36/36
100% Branches 4/4
100% Functions 3/3
100% Lines 33/33

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    1111x
    1x

    1x

    1x
    1x

    1x
    1x
    1x

    1x

    1812x

    1x

    1812x

    1812x
    1812x

    1809x

    1809x
    515x

    1809x
    515x

    515x
    513x

    2x

    515x

    1809x

    1809x
    1294x

    515x

    515x
    515x

    515x
    515x

    515x
    515x

     import { injectable, inject } from 'inversify';
    import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';

    import { TCustomNodeFactory } from '../../../types/container/TCustomNodeFactory';
    import { TNodeWithBlockStatement } from '../../../types/node/TNodeWithBlockStatement';
    import { TObfuscationEvent } from '../../../types/event-emitters/TObfuscationEvent';

    import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
    import { IObfuscationEventEmitter } from '../../../interfaces/event-emitters/IObfuscationEventEmitter';
    import { IOptions } from '../../../interfaces/options/IOptions';
    import { IStackTraceData } from '../../../interfaces/stack-trace-analyzer/IStackTraceData';

    import { initializable } from '../../../decorators/Initializable';

    import { CustomNodes } from '../../../enums/container/CustomNodes';
    import { ObfuscationEvents } from '../../../enums/ObfuscationEvents';

    import { AbstractCustomNodeGroup } from '../../AbstractCustomNodeGroup';
    import { NodeAppender } from '../../../node/NodeAppender';
    import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils';

    @injectable()
    export class ConsoleOutputCustomNodeGroup extends AbstractCustomNodeGroup {
        /**
         * @type {TObfuscationEvent}
         */
        protected readonly appendEvent: TObfuscationEvent = ObfuscationEvents.BeforeObfuscation;

        /**
         * @type {TCustomNodeFactory}
         */
        private readonly customNodeFactory: TCustomNodeFactory;

        /**
         * @type {Map<CustomNodes, ICustomNode>}
         */
        @initializable()
        protected customNodes: Map <CustomNodes, ICustomNode>;

        /**
         * @type {IObfuscationEventEmitter}
         */
        private readonly obfuscationEventEmitter: IObfuscationEventEmitter;

        /**
         * @param customNodeFactory
         * @param obfuscationEventEmitter
         * @param options
         */
        constructor (
            @inject(ServiceIdentifiers['Factory<ICustomNode>']) customNodeFactory: TCustomNodeFactory,
            @inject(ServiceIdentifiers.IObfuscationEventEmitter) obfuscationEventEmitter: IObfuscationEventEmitter,
            @inject(ServiceIdentifiers.IOptions) options: IOptions
        ) {
            super(options);

            this.customNodeFactory = customNodeFactory;
            this.obfuscationEventEmitter = obfuscationEventEmitter;
        }

        /**
         * @param blockScopeNode
         * @param stackTraceData
         */
        public appendCustomNodes (blockScopeNode: TNodeWithBlockStatement, stackTraceData: IStackTraceData[]): void {
            const randomStackTraceIndex: number = NodeAppender.getRandomStackTraceIndex(stackTraceData.length);

            // consoleOutputDisableExpressionNode append
            this.appendCustomNodeIfExist(CustomNodes.ConsoleOutputDisableExpressionNode, (customNode: ICustomNode) => {
                NodeAppender.appendNodeToOptimalBlockScope(
                    stackTraceData,
                    blockScopeNode,
                    customNode.getNode(),
                    randomStackTraceIndex
                );
            });

            // nodeCallsControllerFunctionNode append
            this.appendCustomNodeIfExist(CustomNodes.NodeCallsControllerFunctionNode, (customNode: ICustomNode) => {
                let targetBlockScope: TNodeWithBlockStatement;

                if (stackTraceData.length) {
                    targetBlockScope = NodeAppender.getOptimalBlockScope(stackTraceData, randomStackTraceIndex, 1);
                } else {
                    targetBlockScope = blockScopeNode;
                }

                NodeAppender.prependNode(targetBlockScope, customNode.getNode());
            });
        }

        public initialize (): void {
            this.customNodes = new Map <CustomNodes, ICustomNode> ();

            if (!this.options.disableConsoleOutput) {
                return;
            }

            const callsControllerFunctionName: string = RandomGeneratorUtils.getRandomVariableName();

            const consoleOutputDisableExpressionNode: ICustomNode = this.customNodeFactory(CustomNodes.ConsoleOutputDisableExpressionNode);
            const nodeCallsControllerFunctionNode: ICustomNode = this.customNodeFactory(CustomNodes.NodeCallsControllerFunctionNode);

            consoleOutputDisableExpressionNode.initialize(callsControllerFunctionName);
            nodeCallsControllerFunctionNode.initialize(this.appendEvent, callsControllerFunctionName);

            this.customNodes.set(CustomNodes.ConsoleOutputDisableExpressionNode, consoleOutputDisableExpressionNode);
            this.customNodes.set(CustomNodes.NodeCallsControllerFunctionNode, nodeCallsControllerFunctionNode);
        }
    }