• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

javascript-obfuscator / javascript-obfuscator / 19907815758

03 Dec 2025 08:27PM UTC coverage: 97.319%. Remained the same
19907815758

push

github

sanex3339
Adjust precommit hook

1770 of 1891 branches covered (93.6%)

Branch coverage included in aggregate %.

5671 of 5755 relevant lines covered (98.54%)

34102965.58 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.5
/src/node-transformers/NodeTransformersRunner.ts
1
import { inject, injectable } from 'inversify';
6✔
2

3
import { ServiceIdentifiers } from '../container/ServiceIdentifiers';
6✔
4

5
import * as estraverse from '@javascript-obfuscator/estraverse';
6✔
6
import * as ESTree from 'estree';
7

8
import { TNodeTransformerFactory } from '../types/container/node-transformers/TNodeTransformerFactory';
9
import { TDictionary } from '../types/TDictionary';
10
import { TVisitorDirection } from '../types/node-transformers/TVisitorDirection';
11
import { TVisitorFunction } from '../types/node-transformers/TVisitorFunction';
12
import { TVisitorResult } from '../types/node-transformers/TVisitorResult';
13

14
import { INodeTransformer } from '../interfaces/node-transformers/INodeTransformer';
15
import { INodeTransformersRunner } from '../interfaces/node-transformers/INodeTransformersRunner';
16
import { ITransformerNamesGroupsBuilder } from '../interfaces/utils/ITransformerNamesGroupsBuilder';
17
import { IVisitor } from '../interfaces/node-transformers/IVisitor';
18

19
import { NodeTransformer } from '../enums/node-transformers/NodeTransformer';
20
import { NodeTransformationStage } from '../enums/node-transformers/NodeTransformationStage';
21
import { VisitorDirection } from '../enums/node-transformers/VisitorDirection';
6✔
22

23
import { NodeGuards } from '../node/NodeGuards';
6✔
24
import { NodeMetadata } from '../node/NodeMetadata';
6✔
25

26
@injectable()
27
export class NodeTransformersRunner implements INodeTransformersRunner {
6✔
28
    /**
29
     * @type {TNodeTransformerFactory}
30
     */
31
    private readonly nodeTransformerFactory: TNodeTransformerFactory;
32

33
    /**
34
     * @type {ITransformerNamesGroupsBuilder}
35
     */
36
    private readonly nodeTransformerNamesGroupsBuilder: ITransformerNamesGroupsBuilder<
37
        NodeTransformer,
38
        INodeTransformer
39
    >;
40

41
    /**
42
     * @param {TNodeTransformerFactory} nodeTransformerFactory
43
     * @param {ITransformerNamesGroupsBuilder} nodeTransformerNamesGroupsBuilder
44
     */
45
    public constructor(
46
        @inject(ServiceIdentifiers.Factory__INodeTransformer)
47
        nodeTransformerFactory: TNodeTransformerFactory,
48
        @inject(ServiceIdentifiers.INodeTransformerNamesGroupsBuilder)
49
        nodeTransformerNamesGroupsBuilder: ITransformerNamesGroupsBuilder<NodeTransformer, INodeTransformer>
50
    ) {
51
        this.nodeTransformerFactory = nodeTransformerFactory;
197,880✔
52
        this.nodeTransformerNamesGroupsBuilder = nodeTransformerNamesGroupsBuilder;
197,880✔
53
    }
54

55
    /**
56
     * @param {T} astTree
57
     * @param {NodeTransformer[]} nodeTransformerNames
58
     * @param {NodeTransformationStage} nodeTransformationStage
59
     * @returns {T}
60
     */
61
    public transform<T extends ESTree.Node = ESTree.Program>(
62
        astTree: T,
63
        nodeTransformerNames: NodeTransformer[],
64
        nodeTransformationStage: NodeTransformationStage
65
    ): T {
66
        if (!nodeTransformerNames.length) {
1,642,167!
67
            return astTree;
×
68
        }
69

70
        const normalizedNodeTransformers: TDictionary<INodeTransformer> = this.buildNormalizedNodeTransformers(
1,642,167✔
71
            nodeTransformerNames,
72
            nodeTransformationStage
73
        );
74
        const nodeTransformerNamesGroups: NodeTransformer[][] =
75
            this.nodeTransformerNamesGroupsBuilder.build(normalizedNodeTransformers);
1,642,167✔
76

77
        for (const nodeTransformerNamesGroup of nodeTransformerNamesGroups) {
1,642,167✔
78
            const enterVisitors: IVisitor[] = [];
3,052,749✔
79
            const leaveVisitors: IVisitor[] = [];
3,052,749✔
80

81
            for (const nodeTransformerName of nodeTransformerNamesGroup) {
3,052,749✔
82
                const nodeTransformer: INodeTransformer = normalizedNodeTransformers[nodeTransformerName];
7,518,753✔
83
                const visitor: IVisitor | null = nodeTransformer.getVisitor(nodeTransformationStage);
7,518,753✔
84

85
                if (!visitor) {
7,518,753!
86
                    continue;
×
87
                }
88

89
                if (visitor.enter) {
7,518,753✔
90
                    enterVisitors.push({ enter: visitor.enter });
5,356,941✔
91
                }
92

93
                if (visitor.leave) {
7,518,753✔
94
                    leaveVisitors.push({ leave: visitor.leave });
2,199,552✔
95
                }
96
            }
97

98
            if (!enterVisitors.length && !leaveVisitors.length) {
3,052,749!
99
                continue;
×
100
            }
101

102
            estraverse.replace(astTree, {
3,052,749✔
103
                enter: this.mergeVisitorsForDirection(enterVisitors, VisitorDirection.Enter),
104
                leave: this.mergeVisitorsForDirection(leaveVisitors, VisitorDirection.Leave)
105
            });
106
        }
107

108
        return astTree;
1,642,167✔
109
    }
110

111
    /**
112
     * @param {NodeTransformer[]} nodeTransformerNames
113
     * @param {NodeTransformationStage} nodeTransformationStage
114
     * @returns {TDictionary<INodeTransformer>}
115
     */
116
    private buildNormalizedNodeTransformers(
117
        nodeTransformerNames: NodeTransformer[],
118
        nodeTransformationStage: NodeTransformationStage
119
    ): TDictionary<INodeTransformer> {
120
        return nodeTransformerNames.reduce<TDictionary<INodeTransformer>>(
1,642,167✔
121
            (acc: TDictionary<INodeTransformer>, nodeTransformerName: NodeTransformer) => {
122
                const nodeTransformer: INodeTransformer = this.nodeTransformerFactory(nodeTransformerName);
50,424,453✔
123

124
                if (!nodeTransformer.getVisitor(nodeTransformationStage)) {
50,424,453✔
125
                    return acc;
42,905,700✔
126
                }
127

128
                return <TDictionary<INodeTransformer>>{
7,518,753✔
129
                    ...acc,
130
                    [nodeTransformerName]: nodeTransformer
131
                };
132
            },
133
            {}
134
        );
135
    }
136

137
    /**
138
     * @param {IVisitor[]} visitors
139
     * @param {TVisitorDirection} direction
140
     * @returns {TVisitorFunction}
141
     */
142
    private mergeVisitorsForDirection(visitors: IVisitor[], direction: TVisitorDirection): TVisitorFunction {
143
        const visitorsLength: number = visitors.length;
6,105,498✔
144

145
        if (!visitorsLength) {
6,105,498✔
146
            return (node: ESTree.Node, parentNode: ESTree.Node | null): ESTree.Node => node;
2,182,811,931✔
147
        }
148

149
        return (node: ESTree.Node, parentNode: ESTree.Node | null): ESTree.Node | estraverse.VisitorOption => {
3,474,495✔
150
            if (NodeMetadata.isIgnoredNode(node)) {
2,653,686,449✔
151
                return estraverse.VisitorOption.Skip;
523,501✔
152
            }
153

154
            for (let i: number = 0; i < visitorsLength; i++) {
2,653,162,948✔
155
                const visitorFunction: TVisitorFunction | undefined = visitors[i][direction];
5,181,400,064✔
156

157
                if (!visitorFunction) {
5,181,400,064!
158
                    continue;
×
159
                }
160

161
                const visitorResult: TVisitorResult = visitorFunction(node, parentNode);
5,181,400,064✔
162
                const isValidVisitorResult = visitorResult && NodeGuards.isNode(visitorResult);
5,181,400,064✔
163

164
                if (!isValidVisitorResult) {
5,181,400,064✔
165
                    continue;
3,626,653,256✔
166
                }
167

168
                node = visitorResult;
1,554,746,808✔
169
            }
170

171
            return node;
2,653,162,948✔
172
        };
173
    }
174
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc