Browse Source

Merge pull request #180 from javascript-obfuscator/identifirs-prefix

`identifiersPrefix` option
Timofey Kachalov 7 years ago
parent
commit
2b2cc13429
44 changed files with 635 additions and 173 deletions
  1. 1 0
      CHANGELOG.md
  2. 9 0
      README.md
  3. 0 0
      dist/index.js
  4. 11 11
      package.json
  5. 31 6
      src/cli/JavaScriptObfuscatorCLI.ts
  6. 4 4
      src/container/InversifyContainerFacade.ts
  7. 2 0
      src/container/ServiceIdentifiers.ts
  8. 18 0
      src/container/modules/options/OptionsModule.ts
  9. 1 1
      src/custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode.ts
  10. 1 1
      src/custom-nodes/console-output-nodes/group/ConsoleOutputCustomNodeGroup.ts
  11. 2 2
      src/custom-nodes/debug-protection-nodes/group/DebugProtectionCustomNodeGroup.ts
  12. 1 1
      src/custom-nodes/domain-lock-nodes/DomainLockNode.ts
  13. 1 1
      src/custom-nodes/domain-lock-nodes/group/DomainLockCustomNodeGroup.ts
  14. 1 1
      src/custom-nodes/self-defending-nodes/SelfDefendingUnicodeNode.ts
  15. 1 1
      src/custom-nodes/self-defending-nodes/group/SelfDefendingCustomNodeGroup.ts
  16. 2 2
      src/custom-nodes/string-array-nodes/StringArrayRotateFunctionNode.ts
  17. 6 2
      src/generators/identifier-names-generators/AbstractIdentifierNamesGenerator.ts
  18. 21 8
      src/generators/identifier-names-generators/HexadecimalIdentifierNamesGenerator.ts
  19. 16 5
      src/generators/identifier-names-generators/MangledIdentifierNamesGenerator.ts
  20. 6 2
      src/interfaces/generators/identifier-names-generators/IIdentifierNamesGenerator.d.ts
  21. 8 2
      src/interfaces/node-transformers/obfuscating-transformers/obfuscating-replacers/IIdentifierObfuscatingReplacer.d.ts
  22. 1 0
      src/interfaces/options/IOptions.d.ts
  23. 9 0
      src/interfaces/options/IOptionsNormalizer.d.ts
  24. 1 1
      src/node-transformers/obfuscating-transformers/CatchClauseTransformer.ts
  25. 15 6
      src/node-transformers/obfuscating-transformers/ClassDeclarationTransformer.ts
  26. 15 6
      src/node-transformers/obfuscating-transformers/FunctionDeclarationTransformer.ts
  27. 2 2
      src/node-transformers/obfuscating-transformers/FunctionTransformer.ts
  28. 1 2
      src/node-transformers/obfuscating-transformers/LabeledStatementTransformer.ts
  29. 15 6
      src/node-transformers/obfuscating-transformers/VariableDeclarationTransformer.ts
  30. 23 4
      src/node-transformers/obfuscating-transformers/obfuscating-replacers/identifier-obfuscating-replacers/BaseIdentifierObfuscatingReplacer.ts
  31. 16 4
      src/options/Options.ts
  32. 6 2
      src/options/OptionsNormalizer.ts
  33. 1 0
      src/options/presets/Default.ts
  34. 1 0
      src/options/presets/NoCustomNodes.ts
  35. 13 2
      src/storages/string-array/StringArrayStorage.ts
  36. 7 6
      test/dev/dev.ts
  37. 80 3
      test/functional-tests/cli/JavaScriptObfuscatorCLI.spec.ts
  38. 135 14
      test/functional-tests/javascript-obfuscator/JavaScriptObfuscator.spec.ts
  39. 7 0
      test/functional-tests/javascript-obfuscator/fixtures/identifiers-prefix.js
  40. 17 5
      test/functional-tests/options/OptionsNormalizer.spec.ts
  41. 1 1
      test/index.spec.ts
  42. 28 18
      test/unit-tests/generators/identifier-names-generators/HexadecimalIdentifierNamesGenerator.spec.ts
  43. 48 7
      test/unit-tests/generators/identifier-names-generators/MangledlIdentifierNamesGenerator.spec.ts
  44. 50 34
      yarn.lock

+ 1 - 0
CHANGELOG.md

@@ -2,6 +2,7 @@ Change Log
 ===
 ===
 v0.14.0
 v0.14.0
 ---
 ---
+* **New option:** `identifiersPrefix` sets prefix for all generated identifiers.
 * **New option:** `transformObjectKeys` enables object keys transformation and obfuscation.
 * **New option:** `transformObjectKeys` enables object keys transformation and obfuscation.
 * **New feature:** `eval` expressions obfuscation.
 * **New feature:** `eval` expressions obfuscation.
 * **Breaking change:** Now CLI obfuscating directory recursively. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/157
 * **Breaking change:** Now CLI obfuscating directory recursively. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/157

+ 9 - 0
README.md

@@ -277,6 +277,7 @@ Following options are available for the JS Obfuscator:
     disableConsoleOutput: false,
     disableConsoleOutput: false,
     domainLock: [],
     domainLock: [],
     identifierNamesGenerator: 'hexadecimal',
     identifierNamesGenerator: 'hexadecimal',
+    identifiersPrefix: '',
     log: false,
     log: false,
     renameGlobals: false,
     renameGlobals: false,
     reservedNames: [],
     reservedNames: [],
@@ -314,6 +315,7 @@ Following options are available for the JS Obfuscator:
     --disable-console-output <boolean>
     --disable-console-output <boolean>
     --domain-lock '<list>' (comma separated)
     --domain-lock '<list>' (comma separated)
     --identifier-names-generator <string> [hexadecimal, mangled]
     --identifier-names-generator <string> [hexadecimal, mangled]
+    --identifiers-prefix <string>
     --log <boolean>
     --log <boolean>
     --rename-globals <boolean>
     --rename-globals <boolean>
     --reserved-names '<list>' (comma separated)
     --reserved-names '<list>' (comma separated)
@@ -570,6 +572,13 @@ Available values:
 * `hexadecimal`: identifier names like `_0xabc123`
 * `hexadecimal`: identifier names like `_0xabc123`
 * `mangled`: short identifier names like `a`, `b`, `c`
 * `mangled`: short identifier names like `a`, `b`, `c`
 
 
+### `identifiersPrefix`
+Type: `string` Default: `''`
+
+Sets prefix for all generated identifiers.
+
+Use this option when you want to obfuscate multiple files. This option helps to avoid conflicts between identifiers of these files. Prefix should be different for every file.
+
 ### `log`
 ### `log`
 Type: `boolean` Default: `false`
 Type: `boolean` Default: `false`
 
 

File diff suppressed because it is too large
+ 0 - 0
dist/index.js


+ 11 - 11
package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "javascript-obfuscator",
   "name": "javascript-obfuscator",
-  "version": "0.14.0-beta.2",
+  "version": "0.14.0-beta.3",
   "description": "JavaScript obfuscator",
   "description": "JavaScript obfuscator",
   "keywords": [
   "keywords": [
     "obfuscator",
     "obfuscator",
@@ -21,9 +21,9 @@
   "dependencies": {
   "dependencies": {
     "chalk": "2.3.0",
     "chalk": "2.3.0",
     "chance": "1.0.13",
     "chance": "1.0.13",
-    "class-validator": "0.7.3",
+    "class-validator": "0.8.1",
     "commander": "2.13.0",
     "commander": "2.13.0",
-    "escodegen-wallaby": "1.6.16",
+    "escodegen-wallaby": "1.6.17",
     "esprima": "4.0.0",
     "esprima": "4.0.0",
     "estraverse": "4.2.0",
     "estraverse": "4.2.0",
     "inversify": "4.9.0",
     "inversify": "4.9.0",
@@ -32,13 +32,13 @@
     "mkdirp": "0.5.1",
     "mkdirp": "0.5.1",
     "opencollective": "1.0.3",
     "opencollective": "1.0.3",
     "pjson": "1.0.9",
     "pjson": "1.0.9",
-    "reflect-metadata": "0.1.10",
-    "source-map-support": "0.5.0",
+    "reflect-metadata": "0.1.12",
+    "source-map-support": "0.5.2",
     "string-template": "1.0.0",
     "string-template": "1.0.0",
-    "tslib": "1.8.1"
+    "tslib": "1.9.0"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@types/chai": "4.1.0",
+    "@types/chai": "4.1.2",
     "@types/chance": "0.7.36",
     "@types/chance": "0.7.36",
     "@types/escodegen": "0.0.6",
     "@types/escodegen": "0.0.6",
     "@types/esprima": "4.0.1",
     "@types/esprima": "4.0.1",
@@ -46,7 +46,7 @@
     "@types/estree": "0.0.38",
     "@types/estree": "0.0.38",
     "@types/md5": "2.1.32",
     "@types/md5": "2.1.32",
     "@types/mkdirp": "0.5.2",
     "@types/mkdirp": "0.5.2",
-    "@types/mocha": "2.2.46",
+    "@types/mocha": "2.2.47",
     "@types/node": "9.3.0",
     "@types/node": "9.3.0",
     "@types/rimraf": "2.0.2",
     "@types/rimraf": "2.0.2",
     "@types/sinon": "4.1.3",
     "@types/sinon": "4.1.3",
@@ -60,11 +60,11 @@
     "chai": "4.1.2",
     "chai": "4.1.2",
     "coveralls": "3.0.0",
     "coveralls": "3.0.0",
     "istanbul": "1.1.0-alpha.1",
     "istanbul": "1.1.0-alpha.1",
-    "mocha": "4.1.0",
+    "mocha": "5.0.0",
     "pre-commit": "1.2.2",
     "pre-commit": "1.2.2",
     "rimraf": "2.6.2",
     "rimraf": "2.6.2",
-    "sinon": "4.1.5",
-    "threads": "0.10.0",
+    "sinon": "4.2.1",
+    "threads": "0.10.1",
     "ts-node": "4.1.0",
     "ts-node": "4.1.0",
     "tslint": "5.9.1",
     "tslint": "5.9.1",
     "tslint-eslint-rules": "4.1.1",
     "tslint-eslint-rules": "4.1.1",

+ 31 - 6
src/cli/JavaScriptObfuscatorCLI.ts

@@ -44,6 +44,11 @@ export class JavaScriptObfuscatorCLI implements IInitializable {
      */
      */
     public static obfuscatedFilePrefix: string = '-obfuscated';
     public static obfuscatedFilePrefix: string = '-obfuscated';
 
 
+    /**
+     * @type {string}
+     */
+    private static readonly baseIdentifiersPrefix: string = 'a';
+
     /**
     /**
      * @type {string[]}
      * @type {string[]}
      */
      */
@@ -244,6 +249,10 @@ export class JavaScriptObfuscatorCLI implements IInitializable {
                 '--identifier-names-generator <string> [hexadecimal, mangled]', 'Sets identifier names generator (Default: hexadecimal)',
                 '--identifier-names-generator <string> [hexadecimal, mangled]', 'Sets identifier names generator (Default: hexadecimal)',
                 IdentifierNamesGeneratorSanitizer
                 IdentifierNamesGeneratorSanitizer
             )
             )
+            .option(
+                '--identifiers-prefix <string>',
+                'Sets prefix for all generated identifiers.'
+            )
             .option(
             .option(
                 '--log <boolean>', 'Enables logging of the information to the console',
                 '--log <boolean>', 'Enables logging of the information to the console',
                 BooleanSanitizer
                 BooleanSanitizer
@@ -295,7 +304,7 @@ export class JavaScriptObfuscatorCLI implements IInitializable {
                 BooleanSanitizer
                 BooleanSanitizer
             )
             )
             .option(
             .option(
-                '--string-array-encoding <boolean|string> [true, false, base64, rc4]',
+                '--string-array-encoding <string|boolean> [true, false, base64, rc4]',
                 'Encodes all strings in strings array using base64 or rc4 (this option can slow down your code speed',
                 'Encodes all strings in strings array using base64 or rc4 (this option can slow down your code speed',
                 StringArrayEncodingSanitizer
                 StringArrayEncodingSanitizer
             )
             )
@@ -343,14 +352,14 @@ export class JavaScriptObfuscatorCLI implements IInitializable {
         if (!Array.isArray(sourceCodeData)) {
         if (!Array.isArray(sourceCodeData)) {
             const outputCodePath: string = outputPath || CLIUtils.getOutputCodePath(this.inputPath);
             const outputCodePath: string = outputPath || CLIUtils.getOutputCodePath(this.inputPath);
 
 
-            this.processSourceCode(sourceCodeData, outputCodePath);
+            this.processSourceCode(sourceCodeData, outputCodePath, null);
         } else {
         } else {
-            sourceCodeData.forEach(({ filePath, content }: IFileData) => {
+            sourceCodeData.forEach(({ filePath, content }: IFileData, index: number) => {
                 const outputCodePath: string = outputPath
                 const outputCodePath: string = outputPath
                     ? path.join(outputPath, filePath)
                     ? path.join(outputPath, filePath)
                     : CLIUtils.getOutputCodePath(filePath);
                     : CLIUtils.getOutputCodePath(filePath);
 
 
-                this.processSourceCode(content, outputCodePath);
+                this.processSourceCode(content, outputCodePath, index);
             });
             });
         }
         }
     }
     }
@@ -358,9 +367,25 @@ export class JavaScriptObfuscatorCLI implements IInitializable {
     /**
     /**
      * @param {string} sourceCode
      * @param {string} sourceCode
      * @param {string} outputCodePath
      * @param {string} outputCodePath
+     * @param {number | null} sourceCodeIndex
      */
      */
-    private processSourceCode (sourceCode: string, outputCodePath: string): void {
-        const options: TInputOptions = this.buildOptions();
+    private processSourceCode (
+        sourceCode: string,
+        outputCodePath: string,
+        sourceCodeIndex: number | null
+    ): void {
+        let options: TInputOptions = this.buildOptions();
+
+        if (sourceCodeIndex !== null) {
+            const baseIdentifiersPrefix: string = this.inputCLIOptions.identifiersPrefix
+                || JavaScriptObfuscatorCLI.baseIdentifiersPrefix;
+            const identifiersPrefix: string = `${baseIdentifiersPrefix}${sourceCodeIndex}`;
+
+            options = {
+                ...options,
+                identifiersPrefix
+            };
+        }
 
 
         if (options.sourceMap) {
         if (options.sourceMap) {
             JavaScriptObfuscatorCLI.processSourceCodeWithSourceMap(sourceCode, outputCodePath, options);
             JavaScriptObfuscatorCLI.processSourceCodeWithSourceMap(sourceCode, outputCodePath, options);

+ 4 - 4
src/container/InversifyContainerFacade.ts

@@ -9,6 +9,7 @@ import { finalizingTransformersModule } from './modules/node-transformers/Finali
 import { generatorsModule } from './modules/generators/GeneratorsModule';
 import { generatorsModule } from './modules/generators/GeneratorsModule';
 import { nodeTransformersModule } from './modules/node-transformers/NodeTransformersModule';
 import { nodeTransformersModule } from './modules/node-transformers/NodeTransformersModule';
 import { obfuscatingTransformersModule } from './modules/node-transformers/ObfuscatingTransformersModule';
 import { obfuscatingTransformersModule } from './modules/node-transformers/ObfuscatingTransformersModule';
+import { optionsModule } from './modules/options/OptionsModule';
 import { preparingTransformersModule } from './modules/node-transformers/PreparingTransformersModule';
 import { preparingTransformersModule } from './modules/node-transformers/PreparingTransformersModule';
 import { storagesModule } from './modules/storages/StoragesModule';
 import { storagesModule } from './modules/storages/StoragesModule';
 import { utilsModule } from './modules/utils/UtilsModule';
 import { utilsModule } from './modules/utils/UtilsModule';
@@ -20,7 +21,6 @@ import { IJavaScriptObfuscator } from '../interfaces/IJavaScriptObfsucator';
 import { ILogger } from '../interfaces/logger/ILogger';
 import { ILogger } from '../interfaces/logger/ILogger';
 import { IObfuscationEventEmitter } from '../interfaces/event-emitters/IObfuscationEventEmitter';
 import { IObfuscationEventEmitter } from '../interfaces/event-emitters/IObfuscationEventEmitter';
 import { IObfuscationResult } from '../interfaces/IObfuscationResult';
 import { IObfuscationResult } from '../interfaces/IObfuscationResult';
-import { IOptions } from '../interfaces/options/IOptions';
 import { ISourceCode } from '../interfaces/ISourceCode';
 import { ISourceCode } from '../interfaces/ISourceCode';
 import { ISourceMapCorrector } from '../interfaces/source-map/ISourceMapCorrector';
 import { ISourceMapCorrector } from '../interfaces/source-map/ISourceMapCorrector';
 import { ITransformersRunner } from '../interfaces/node-transformers/ITransformersRunner';
 import { ITransformersRunner } from '../interfaces/node-transformers/ITransformersRunner';
@@ -29,7 +29,6 @@ import { JavaScriptObfuscator } from '../JavaScriptObfuscator';
 import { Logger } from '../logger/Logger';
 import { Logger } from '../logger/Logger';
 import { ObfuscationEventEmitter } from '../event-emitters/ObfuscationEventEmitter';
 import { ObfuscationEventEmitter } from '../event-emitters/ObfuscationEventEmitter';
 import { ObfuscationResult } from '../ObfuscationResult';
 import { ObfuscationResult } from '../ObfuscationResult';
-import { Options } from "../options/Options";
 import { SourceCode } from '../SourceCode';
 import { SourceCode } from '../SourceCode';
 import { SourceMapCorrector } from '../source-map/SourceMapCorrector';
 import { SourceMapCorrector } from '../source-map/SourceMapCorrector';
 import { TransformersRunner } from '../node-transformers/TransformersRunner';
 import { TransformersRunner } from '../node-transformers/TransformersRunner';
@@ -147,8 +146,8 @@ export class InversifyContainerFacade implements IInversifyContainerFacade {
             .inSingletonScope();
             .inSingletonScope();
 
 
         this.container
         this.container
-            .bind<IOptions>(ServiceIdentifiers.IOptions)
-            .toDynamicValue(() => new Options(options))
+            .bind<TInputOptions>(ServiceIdentifiers.TInputOptions)
+            .toDynamicValue(() => options)
             .inSingletonScope();
             .inSingletonScope();
 
 
         this.container
         this.container
@@ -203,6 +202,7 @@ export class InversifyContainerFacade implements IInversifyContainerFacade {
         this.container.load(generatorsModule);
         this.container.load(generatorsModule);
         this.container.load(nodeTransformersModule);
         this.container.load(nodeTransformersModule);
         this.container.load(obfuscatingTransformersModule);
         this.container.load(obfuscatingTransformersModule);
+        this.container.load(optionsModule);
         this.container.load(preparingTransformersModule);
         this.container.load(preparingTransformersModule);
         this.container.load(storagesModule);
         this.container.load(storagesModule);
         this.container.load(utilsModule);
         this.container.load(utilsModule);

+ 2 - 0
src/container/ServiceIdentifiers.ts

@@ -28,6 +28,7 @@ export enum ServiceIdentifiers {
     IObfuscationEventEmitter = 'IObfuscationEventEmitter',
     IObfuscationEventEmitter = 'IObfuscationEventEmitter',
     IObfuscationResult = 'IObfuscationResult',
     IObfuscationResult = 'IObfuscationResult',
     IOptions = 'IOptions',
     IOptions = 'IOptions',
+    IOptionsNormalizer = 'IOptionsNormalizer',
     IObfuscatingReplacer = 'IObfuscatingReplacer',
     IObfuscatingReplacer = 'IObfuscatingReplacer',
     IRandomGenerator = 'IRandomGenerator',
     IRandomGenerator = 'IRandomGenerator',
     ISourceCode = 'ISourceCode',
     ISourceCode = 'ISourceCode',
@@ -37,5 +38,6 @@ export enum ServiceIdentifiers {
     Newable__ICustomNode = 'Newable<ICustomNode>',
     Newable__ICustomNode = 'Newable<ICustomNode>',
     Newable__TControlFlowStorage = 'Newable<TControlFlowStorage>',
     Newable__TControlFlowStorage = 'Newable<TControlFlowStorage>',
     TCustomNodeGroupStorage = 'TCustomNodeGroupStorage',
     TCustomNodeGroupStorage = 'TCustomNodeGroupStorage',
+    TInputOptions = 'TInputOptions',
     TStringArrayStorage = 'TStringArrayStorage'
     TStringArrayStorage = 'TStringArrayStorage'
 }
 }

+ 18 - 0
src/container/modules/options/OptionsModule.ts

@@ -0,0 +1,18 @@
+import { ContainerModule, interfaces } from 'inversify';
+import { ServiceIdentifiers } from '../../ServiceIdentifiers';
+
+import { IOptions } from '../../../interfaces/options/IOptions';
+import { IOptionsNormalizer } from '../../../interfaces/options/IOptionsNormalizer';
+
+import { Options } from '../../../options/Options';
+import { OptionsNormalizer } from '../../../options/OptionsNormalizer';
+
+export const optionsModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
+    bind<IOptions>(ServiceIdentifiers.IOptions)
+        .to(Options)
+        .inSingletonScope();
+
+    bind<IOptionsNormalizer>(ServiceIdentifiers.IOptionsNormalizer)
+        .to(OptionsNormalizer)
+        .inSingletonScope();
+});

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

@@ -64,7 +64,7 @@ export class ConsoleOutputDisableExpressionNode extends AbstractCustomNode {
             : GlobalVariableNoEvalTemplate();
             : GlobalVariableNoEvalTemplate();
 
 
         return format(ConsoleOutputDisableExpressionTemplate(), {
         return format(ConsoleOutputDisableExpressionTemplate(), {
-            consoleLogDisableFunctionName: this.identifierNamesGenerator.generate(6),
+            consoleLogDisableFunctionName: this.identifierNamesGenerator.generate(),
             globalVariableTemplate,
             globalVariableTemplate,
             singleNodeCallControllerFunctionName: this.callsControllerFunctionName
             singleNodeCallControllerFunctionName: this.callsControllerFunctionName
         });
         });

+ 1 - 1
src/custom-nodes/console-output-nodes/group/ConsoleOutputCustomNodeGroup.ts

@@ -92,7 +92,7 @@ export class ConsoleOutputCustomNodeGroup extends AbstractCustomNodeGroup {
             return;
             return;
         }
         }
 
 
-        const callsControllerFunctionName: string = this.identifierNamesGenerator.generate(6);
+        const callsControllerFunctionName: string = this.identifierNamesGenerator.generate();
 
 
         const consoleOutputDisableExpressionNode: ICustomNode = this.customNodeFactory(CustomNode.ConsoleOutputDisableExpressionNode);
         const consoleOutputDisableExpressionNode: ICustomNode = this.customNodeFactory(CustomNode.ConsoleOutputDisableExpressionNode);
         const nodeCallsControllerFunctionNode: ICustomNode = this.customNodeFactory(CustomNode.NodeCallsControllerFunctionNode);
         const nodeCallsControllerFunctionNode: ICustomNode = this.customNodeFactory(CustomNode.NodeCallsControllerFunctionNode);

+ 2 - 2
src/custom-nodes/debug-protection-nodes/group/DebugProtectionCustomNodeGroup.ts

@@ -105,8 +105,8 @@ export class DebugProtectionCustomNodeGroup extends AbstractCustomNodeGroup {
             return;
             return;
         }
         }
 
 
-        const debugProtectionFunctionName: string = this.identifierNamesGenerator.generate(6);
-        const callsControllerFunctionName: string = this.identifierNamesGenerator.generate(6);
+        const debugProtectionFunctionName: string = this.identifierNamesGenerator.generate();
+        const callsControllerFunctionName: string = this.identifierNamesGenerator.generate();
 
 
         const debugProtectionFunctionNode: ICustomNode = this.customNodeFactory(CustomNode.DebugProtectionFunctionNode);
         const debugProtectionFunctionNode: ICustomNode = this.customNodeFactory(CustomNode.DebugProtectionFunctionNode);
         const debugProtectionFunctionCallNode: ICustomNode = this.customNodeFactory(CustomNode.DebugProtectionFunctionCallNode);
         const debugProtectionFunctionCallNode: ICustomNode = this.customNodeFactory(CustomNode.DebugProtectionFunctionCallNode);

+ 1 - 1
src/custom-nodes/domain-lock-nodes/DomainLockNode.ts

@@ -79,7 +79,7 @@ export class DomainLockNode extends AbstractCustomNode {
             : GlobalVariableNoEvalTemplate();
             : GlobalVariableNoEvalTemplate();
 
 
         return format(DomainLockNodeTemplate(), {
         return format(DomainLockNodeTemplate(), {
-            domainLockFunctionName: this.identifierNamesGenerator.generate(6),
+            domainLockFunctionName: this.identifierNamesGenerator.generate(),
             diff: diff,
             diff: diff,
             domains: hiddenDomainsString,
             domains: hiddenDomainsString,
             globalVariableTemplate,
             globalVariableTemplate,

+ 1 - 1
src/custom-nodes/domain-lock-nodes/group/DomainLockCustomNodeGroup.ts

@@ -92,7 +92,7 @@ export class DomainLockCustomNodeGroup extends AbstractCustomNodeGroup {
             return;
             return;
         }
         }
 
 
-        const callsControllerFunctionName: string = this.identifierNamesGenerator.generate(6);
+        const callsControllerFunctionName: string = this.identifierNamesGenerator.generate();
 
 
         const domainLockNode: ICustomNode = this.customNodeFactory(CustomNode.DomainLockNode);
         const domainLockNode: ICustomNode = this.customNodeFactory(CustomNode.DomainLockNode);
         const nodeCallsControllerFunctionNode: ICustomNode = this.customNodeFactory(CustomNode.NodeCallsControllerFunctionNode);
         const nodeCallsControllerFunctionNode: ICustomNode = this.customNodeFactory(CustomNode.NodeCallsControllerFunctionNode);

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

@@ -71,7 +71,7 @@ export class SelfDefendingUnicodeNode extends AbstractCustomNode {
     protected getTemplate (): string {
     protected getTemplate (): string {
         return JavaScriptObfuscator.obfuscate(
         return JavaScriptObfuscator.obfuscate(
             format(SelfDefendingTemplate(this.escapeSequenceEncoder), {
             format(SelfDefendingTemplate(this.escapeSequenceEncoder), {
-                selfDefendingFunctionName: this.identifierNamesGenerator.generate(6),
+                selfDefendingFunctionName: this.identifierNamesGenerator.generate(),
                 singleNodeCallControllerFunctionName: this.callsControllerFunctionName
                 singleNodeCallControllerFunctionName: this.callsControllerFunctionName
             }),
             }),
             {
             {

+ 1 - 1
src/custom-nodes/self-defending-nodes/group/SelfDefendingCustomNodeGroup.ts

@@ -92,7 +92,7 @@ export class SelfDefendingCustomNodeGroup extends AbstractCustomNodeGroup {
             return;
             return;
         }
         }
 
 
-        const callsControllerFunctionName: string = this.identifierNamesGenerator.generate(6);
+        const callsControllerFunctionName: string = this.identifierNamesGenerator.generate();
 
 
         const selfDefendingUnicodeNode: ICustomNode = this.customNodeFactory(CustomNode.SelfDefendingUnicodeNode);
         const selfDefendingUnicodeNode: ICustomNode = this.customNodeFactory(CustomNode.SelfDefendingUnicodeNode);
         const nodeCallsControllerFunctionNode: ICustomNode = this.customNodeFactory(CustomNode.NodeCallsControllerFunctionNode);
         const nodeCallsControllerFunctionNode: ICustomNode = this.customNodeFactory(CustomNode.NodeCallsControllerFunctionNode);

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

@@ -82,8 +82,8 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode {
      * @returns {string}
      * @returns {string}
      */
      */
     protected getTemplate (): string {
     protected getTemplate (): string {
-        const timesName: string = this.identifierNamesGenerator.generate(6);
-        const whileFunctionName: string = this.identifierNamesGenerator.generate(6);
+        const timesName: string = this.identifierNamesGenerator.generate();
+        const whileFunctionName: string = this.identifierNamesGenerator.generate();
 
 
         let code: string = '';
         let code: string = '';
 
 

+ 6 - 2
src/generators/identifier-names-generators/AbstractIdentifierNamesGenerator.ts

@@ -30,8 +30,12 @@ export abstract class AbstractIdentifierNamesGenerator implements IIdentifierNam
     }
     }
 
 
     /**
     /**
-     * @param {number} length
      * @returns {string}
      * @returns {string}
      */
      */
-    public abstract generate (length: number): string;
+    public abstract generate (): string;
+
+    /**
+     * @returns {string}
+     */
+    public abstract generateWithPrefix (): string;
 }
 }

+ 21 - 8
src/generators/identifier-names-generators/HexadecimalIdentifierNamesGenerator.ts

@@ -9,6 +9,11 @@ import { Utils } from '../../utils/Utils';
 
 
 @injectable()
 @injectable()
 export class HexadecimalIdentifierNamesGenerator extends AbstractIdentifierNamesGenerator {
 export class HexadecimalIdentifierNamesGenerator extends AbstractIdentifierNamesGenerator {
+    /**
+     * @type {number}
+     */
+    private static baseIdentifierNameLength: number = 6;
+
     /**
     /**
      * @type {Set<string>}
      * @type {Set<string>}
      */
      */
@@ -26,23 +31,31 @@ export class HexadecimalIdentifierNamesGenerator extends AbstractIdentifierNames
     }
     }
 
 
     /**
     /**
-     * @param {number} length
      * @returns {string}
      * @returns {string}
      */
      */
-    public generate (length: number): string {
-        const prefix: string = `_${Utils.hexadecimalPrefix}`;
+    public generate (): string {
         const rangeMinInteger: number = 10000;
         const rangeMinInteger: number = 10000;
         const rangeMaxInteger: number = 99999999;
         const rangeMaxInteger: number = 99999999;
         const randomInteger: number = this.randomGenerator.getRandomInteger(rangeMinInteger, rangeMaxInteger);
         const randomInteger: number = this.randomGenerator.getRandomInteger(rangeMinInteger, rangeMaxInteger);
         const hexadecimalNumber: string = Utils.decToHex(randomInteger);
         const hexadecimalNumber: string = Utils.decToHex(randomInteger);
-        const randomVariableName: string = `${prefix}${hexadecimalNumber.substr(0, length)}`;
+        const baseIdentifierName: string = hexadecimalNumber.substr(0, HexadecimalIdentifierNamesGenerator.baseIdentifierNameLength);
+        const identifierName: string = `_${Utils.hexadecimalPrefix}${baseIdentifierName}`;
 
 
-        if (this.randomVariableNameSet.has(randomVariableName)) {
-            return this.generate(length);
+        if (this.randomVariableNameSet.has(identifierName)) {
+            return this.generate();
         }
         }
 
 
-        this.randomVariableNameSet.add(randomVariableName);
+        this.randomVariableNameSet.add(identifierName);
+
+        return identifierName;
+    }
+
+    /**
+     * @returns {string}
+     */
+    public generateWithPrefix (): string {
+        const identifierName: string = this.generate();
 
 
-        return randomVariableName;
+        return `${this.options.identifiersPrefix}${identifierName}`.replace('__', '_');
     }
     }
 }
 }

+ 16 - 5
src/generators/identifier-names-generators/MangledIdentifierNamesGenerator.ts

@@ -98,14 +98,25 @@ export class MangledIdentifierNamesGenerator extends AbstractIdentifierNamesGene
     }
     }
 
 
     /**
     /**
-     * @param {number} length
      * @returns {string}
      * @returns {string}
      */
      */
-    public generate (length: number): string {
-        const newName: string = MangledIdentifierNamesGenerator.generateNewMangledName(this.previousMangledName);
+    public generate (): string {
+        const identifierName: string = MangledIdentifierNamesGenerator.generateNewMangledName(this.previousMangledName);
 
 
-        this.previousMangledName = newName;
+        this.previousMangledName = identifierName;
 
 
-        return newName;
+        return identifierName;
+    }
+
+    /**
+     * @returns {string}
+     */
+    public generateWithPrefix (): string {
+        const prefix: string = this.options.identifiersPrefix ?
+            `${this.options.identifiersPrefix}_`
+            : '';
+        const identifierName: string = this.generate();
+
+        return `${prefix}${identifierName}`;
     }
     }
 }
 }

+ 6 - 2
src/interfaces/generators/identifier-names-generators/IIdentifierNamesGenerator.d.ts

@@ -1,7 +1,11 @@
 export interface IIdentifierNamesGenerator {
 export interface IIdentifierNamesGenerator {
     /**
     /**
-     * @param {number} length
      * @returns {string}
      * @returns {string}
      */
      */
-    generate (length: number): string;
+    generate (): string;
+
+    /**
+     * @returns {string}
+     */
+    generateWithPrefix (): string;
 }
 }

+ 8 - 2
src/interfaces/node-transformers/obfuscating-transformers/obfuscating-replacers/IIdentifierObfuscatingReplacer.d.ts

@@ -4,8 +4,14 @@ import { IObfuscatingReplacer } from './IObfuscatingReplacer';
 
 
 export interface IIdentifierObfuscatingReplacer extends IObfuscatingReplacer <ESTree.Identifier> {
 export interface IIdentifierObfuscatingReplacer extends IObfuscatingReplacer <ESTree.Identifier> {
     /**
     /**
-     * @param nodeValue
+     * @param {string} nodeValue
      * @param {number} nodeIdentifier
      * @param {number} nodeIdentifier
      */
      */
-    storeNames (nodeValue: any, nodeIdentifier: number): void;
+    storeGlobalName (nodeValue: string, nodeIdentifier: number): void;
+
+    /**
+     * @param {string} nodeValue
+     * @param {number} nodeIdentifier
+     */
+    storeLocalName (nodeValue: string, nodeIdentifier: number): void;
 }
 }

+ 1 - 0
src/interfaces/options/IOptions.d.ts

@@ -15,6 +15,7 @@ export interface IOptions {
     readonly disableConsoleOutput: boolean;
     readonly disableConsoleOutput: boolean;
     readonly domainLock: string[];
     readonly domainLock: string[];
     readonly identifierNamesGenerator: IdentifierNamesGenerator;
     readonly identifierNamesGenerator: IdentifierNamesGenerator;
+    readonly identifiersPrefix: string;
     readonly log: boolean;
     readonly log: boolean;
     readonly renameGlobals: boolean;
     readonly renameGlobals: boolean;
     readonly reservedNames: string[];
     readonly reservedNames: string[];

+ 9 - 0
src/interfaces/options/IOptionsNormalizer.d.ts

@@ -0,0 +1,9 @@
+import { IOptions } from './IOptions';
+
+export interface IOptionsNormalizer {
+    /**
+     * @param {IOptions} options
+     * @returns {IOptions}
+     */
+    normalize (options: IOptions): IOptions;
+}

+ 1 - 1
src/node-transformers/obfuscating-transformers/CatchClauseTransformer.ts

@@ -90,7 +90,7 @@ export class CatchClauseTransformer extends AbstractNodeTransformer {
      */
      */
     private storeCatchClauseParam (catchClauseNode: ESTree.CatchClause, nodeIdentifier: number): void {
     private storeCatchClauseParam (catchClauseNode: ESTree.CatchClause, nodeIdentifier: number): void {
         if (NodeGuards.isIdentifierNode(catchClauseNode.param)) {
         if (NodeGuards.isIdentifierNode(catchClauseNode.param)) {
-            this.identifierObfuscatingReplacer.storeNames(catchClauseNode.param.name, nodeIdentifier);
+            this.identifierObfuscatingReplacer.storeLocalName(catchClauseNode.param.name, nodeIdentifier);
         }
         }
     }
     }
 
 

+ 15 - 6
src/node-transformers/obfuscating-transformers/ClassDeclarationTransformer.ts

@@ -86,14 +86,14 @@ export class ClassDeclarationTransformer extends AbstractNodeTransformer {
      */
      */
     public transformNode (classDeclarationNode: ESTree.ClassDeclaration, parentNode: ESTree.Node): ESTree.Node {
     public transformNode (classDeclarationNode: ESTree.ClassDeclaration, parentNode: ESTree.Node): ESTree.Node {
         const nodeIdentifier: number = this.nodeIdentifier++;
         const nodeIdentifier: number = this.nodeIdentifier++;
-        const blockScopeNode: TNodeWithBlockScope = NodeUtils
-            .getBlockScopesOfNode(classDeclarationNode)[0];
+        const blockScopeNode: TNodeWithBlockScope = NodeUtils.getBlockScopesOfNode(classDeclarationNode)[0];
+        const isGlobalDeclaration: boolean = blockScopeNode.type === NodeType.Program;
 
 
-        if (!this.options.renameGlobals && blockScopeNode.type === NodeType.Program) {
+        if (!this.options.renameGlobals && isGlobalDeclaration) {
             return classDeclarationNode;
             return classDeclarationNode;
         }
         }
 
 
-        this.storeClassName(classDeclarationNode, nodeIdentifier);
+        this.storeClassName(classDeclarationNode, isGlobalDeclaration, nodeIdentifier);
 
 
         // check for cached identifiers for current scope node. If exist - loop through them.
         // check for cached identifiers for current scope node. If exist - loop through them.
         if (this.replaceableIdentifiers.has(blockScopeNode)) {
         if (this.replaceableIdentifiers.has(blockScopeNode)) {
@@ -107,10 +107,19 @@ export class ClassDeclarationTransformer extends AbstractNodeTransformer {
 
 
     /**
     /**
      * @param {ClassDeclaration} classDeclarationNode
      * @param {ClassDeclaration} classDeclarationNode
+     * @param {boolean} isGlobalDeclaration
      * @param {number} nodeIdentifier
      * @param {number} nodeIdentifier
      */
      */
-    private storeClassName (classDeclarationNode: ESTree.ClassDeclaration, nodeIdentifier: number): void {
-        this.identifierObfuscatingReplacer.storeNames(classDeclarationNode.id.name, nodeIdentifier);
+    private storeClassName (
+        classDeclarationNode: ESTree.ClassDeclaration,
+        isGlobalDeclaration: boolean,
+        nodeIdentifier: number
+    ): void {
+        if (isGlobalDeclaration) {
+            this.identifierObfuscatingReplacer.storeGlobalName(classDeclarationNode.id.name, nodeIdentifier);
+        } else {
+            this.identifierObfuscatingReplacer.storeLocalName(classDeclarationNode.id.name, nodeIdentifier);
+        }
     }
     }
 
 
     /**
     /**

+ 15 - 6
src/node-transformers/obfuscating-transformers/FunctionDeclarationTransformer.ts

@@ -88,14 +88,14 @@ export class FunctionDeclarationTransformer extends AbstractNodeTransformer {
      */
      */
     public transformNode (functionDeclarationNode: ESTree.FunctionDeclaration, parentNode: ESTree.Node): ESTree.Node {
     public transformNode (functionDeclarationNode: ESTree.FunctionDeclaration, parentNode: ESTree.Node): ESTree.Node {
         const nodeIdentifier: number = this.nodeIdentifier++;
         const nodeIdentifier: number = this.nodeIdentifier++;
-        const blockScopeNode: TNodeWithBlockScope = NodeUtils
-            .getBlockScopesOfNode(functionDeclarationNode)[0];
+        const blockScopeNode: TNodeWithBlockScope = NodeUtils.getBlockScopesOfNode(functionDeclarationNode)[0];
+        const isGlobalDeclaration: boolean = blockScopeNode.type === NodeType.Program;
 
 
-        if (!this.options.renameGlobals && blockScopeNode.type === NodeType.Program) {
+        if (!this.options.renameGlobals && isGlobalDeclaration) {
             return functionDeclarationNode;
             return functionDeclarationNode;
         }
         }
 
 
-        this.storeFunctionName(functionDeclarationNode, nodeIdentifier);
+        this.storeFunctionName(functionDeclarationNode, isGlobalDeclaration, nodeIdentifier);
 
 
         // check for cached identifiers for current scope node. If exist - loop through them.
         // check for cached identifiers for current scope node. If exist - loop through them.
         if (this.replaceableIdentifiers.has(blockScopeNode)) {
         if (this.replaceableIdentifiers.has(blockScopeNode)) {
@@ -109,10 +109,19 @@ export class FunctionDeclarationTransformer extends AbstractNodeTransformer {
 
 
     /**
     /**
      * @param {FunctionDeclaration} functionDeclarationNode
      * @param {FunctionDeclaration} functionDeclarationNode
+     * @param {boolean} isGlobalDeclaration
      * @param {number} nodeIdentifier
      * @param {number} nodeIdentifier
      */
      */
-    private storeFunctionName (functionDeclarationNode: ESTree.FunctionDeclaration, nodeIdentifier: number): void {
-        this.identifierObfuscatingReplacer.storeNames(functionDeclarationNode.id.name, nodeIdentifier);
+    private storeFunctionName (
+        functionDeclarationNode: ESTree.FunctionDeclaration,
+        isGlobalDeclaration: boolean,
+        nodeIdentifier: number
+    ): void {
+        if (isGlobalDeclaration) {
+            this.identifierObfuscatingReplacer.storeGlobalName(functionDeclarationNode.id.name, nodeIdentifier);
+        } else {
+            this.identifierObfuscatingReplacer.storeLocalName(functionDeclarationNode.id.name, nodeIdentifier);
+        }
     }
     }
 
 
     /**
     /**

+ 2 - 2
src/node-transformers/obfuscating-transformers/FunctionTransformer.ts

@@ -104,13 +104,13 @@ export class FunctionTransformer extends AbstractNodeTransformer {
                 estraverse.traverse(paramsNode, {
                 estraverse.traverse(paramsNode, {
                     enter: (node: ESTree.Node): any => {
                     enter: (node: ESTree.Node): any => {
                         if (NodeGuards.isAssignmentPatternNode(node) && NodeGuards.isIdentifierNode(node.left)) {
                         if (NodeGuards.isAssignmentPatternNode(node) && NodeGuards.isIdentifierNode(node.left)) {
-                            this.identifierObfuscatingReplacer.storeNames(node.left.name, nodeIdentifier);
+                            this.identifierObfuscatingReplacer.storeLocalName(node.left.name, nodeIdentifier);
 
 
                             return estraverse.VisitorOption.Skip;
                             return estraverse.VisitorOption.Skip;
                         }
                         }
 
 
                         if (NodeGuards.isIdentifierNode(node)) {
                         if (NodeGuards.isIdentifierNode(node)) {
-                            this.identifierObfuscatingReplacer.storeNames(node.name, nodeIdentifier);
+                            this.identifierObfuscatingReplacer.storeLocalName(node.name, nodeIdentifier);
                         }
                         }
                     }
                     }
                 });
                 });

+ 1 - 2
src/node-transformers/obfuscating-transformers/LabeledStatementTransformer.ts

@@ -97,8 +97,7 @@ export class LabeledStatementTransformer extends AbstractNodeTransformer {
      * @param {number} nodeIdentifier
      * @param {number} nodeIdentifier
      */
      */
     private storeLabeledStatementName (labeledStatementNode: ESTree.LabeledStatement, nodeIdentifier: number): void {
     private storeLabeledStatementName (labeledStatementNode: ESTree.LabeledStatement, nodeIdentifier: number): void {
-        this.identifierObfuscatingReplacer
-            .storeNames(labeledStatementNode.label.name, nodeIdentifier);
+        this.identifierObfuscatingReplacer.storeLocalName(labeledStatementNode.label.name, nodeIdentifier);
     }
     }
 
 
     /**
     /**

+ 15 - 6
src/node-transformers/obfuscating-transformers/VariableDeclarationTransformer.ts

@@ -88,10 +88,10 @@ export class VariableDeclarationTransformer extends AbstractNodeTransformer {
      * @returns {NodeGuards}
      * @returns {NodeGuards}
      */
      */
     public transformNode (variableDeclarationNode: ESTree.VariableDeclaration, parentNode: ESTree.Node): ESTree.Node {
     public transformNode (variableDeclarationNode: ESTree.VariableDeclaration, parentNode: ESTree.Node): ESTree.Node {
-        const blockScopeNode: TNodeWithBlockScope = NodeUtils
-            .getBlockScopesOfNode(variableDeclarationNode)[0];
+        const blockScopeNode: TNodeWithBlockScope = NodeUtils.getBlockScopesOfNode(variableDeclarationNode)[0];
+        const isGlobalDeclaration: boolean = blockScopeNode.type === NodeType.Program;
 
 
-        if (!this.options.renameGlobals && blockScopeNode.type === NodeType.Program) {
+        if (!this.options.renameGlobals && isGlobalDeclaration) {
             return variableDeclarationNode;
             return variableDeclarationNode;
         }
         }
 
 
@@ -100,7 +100,7 @@ export class VariableDeclarationTransformer extends AbstractNodeTransformer {
             ? blockScopeNode
             ? blockScopeNode
             : parentNode;
             : parentNode;
 
 
-        this.storeVariableNames(variableDeclarationNode, nodeIdentifier);
+        this.storeVariableNames(variableDeclarationNode, isGlobalDeclaration, nodeIdentifier);
 
 
         // check for cached identifiers for current scope node. If exist - loop through them.
         // check for cached identifiers for current scope node. If exist - loop through them.
         if (this.replaceableIdentifiers.has(scopeNode)) {
         if (this.replaceableIdentifiers.has(scopeNode)) {
@@ -114,11 +114,20 @@ export class VariableDeclarationTransformer extends AbstractNodeTransformer {
 
 
     /**
     /**
      * @param {VariableDeclaration} variableDeclarationNode
      * @param {VariableDeclaration} variableDeclarationNode
+     * @param {boolean} isGlobalDeclaration
      * @param {number} nodeIdentifier
      * @param {number} nodeIdentifier
      */
      */
-    private storeVariableNames (variableDeclarationNode: ESTree.VariableDeclaration, nodeIdentifier: number): void {
+    private storeVariableNames (
+        variableDeclarationNode: ESTree.VariableDeclaration,
+        isGlobalDeclaration: boolean,
+        nodeIdentifier: number
+    ): void {
         this.traverseDeclarationIdentifiers(variableDeclarationNode, (identifierNode: ESTree.Identifier) => {
         this.traverseDeclarationIdentifiers(variableDeclarationNode, (identifierNode: ESTree.Identifier) => {
-            this.identifierObfuscatingReplacer.storeNames(identifierNode.name, nodeIdentifier);
+            if (isGlobalDeclaration) {
+                this.identifierObfuscatingReplacer.storeGlobalName(identifierNode.name, nodeIdentifier);
+            } else {
+                this.identifierObfuscatingReplacer.storeLocalName(identifierNode.name, nodeIdentifier);
+            }
         });
         });
     }
     }
 
 

+ 23 - 4
src/node-transformers/obfuscating-transformers/obfuscating-replacers/identifier-obfuscating-replacers/BaseIdentifierObfuscatingReplacer.ts

@@ -54,18 +54,37 @@ export class BaseIdentifierObfuscatingReplacer extends AbstractObfuscatingReplac
     }
     }
 
 
     /**
     /**
-     * Store all `nodeIdentifier`'s as keys in given `namesMap` with random names as value.
-     * Reserved names will be ignored.
+     * Store `nodeName` of global identifiers as key in map with random name as value.
+     * Reserved name will be ignored.
      *
      *
      * @param {string} nodeName
      * @param {string} nodeName
      * @param {number} nodeIdentifier
      * @param {number} nodeIdentifier
      */
      */
-    public storeNames (nodeName: string, nodeIdentifier: number): void {
+    public storeGlobalName (nodeName: string, nodeIdentifier: number): void {
         if (this.isReservedName(nodeName)) {
         if (this.isReservedName(nodeName)) {
             return;
             return;
         }
         }
 
 
-        this.namesMap.set(`${nodeName}-${String(nodeIdentifier)}`, this.identifierNamesGenerator.generate(6));
+        const identifierName: string = this.identifierNamesGenerator.generateWithPrefix();
+
+        this.namesMap.set(`${nodeName}-${String(nodeIdentifier)}`, identifierName);
+    }
+
+    /**
+     * Store `nodeName` of local identifier as key in map with random name as value.
+     * Reserved name will be ignored.
+     *
+     * @param {string} nodeName
+     * @param {number} nodeIdentifier
+     */
+    public storeLocalName (nodeName: string, nodeIdentifier: number): void {
+        if (this.isReservedName(nodeName)) {
+            return;
+        }
+
+        const identifierName: string = this.identifierNamesGenerator.generate();
+
+        this.namesMap.set(`${nodeName}-${String(nodeIdentifier)}`, identifierName);
     }
     }
 
 
     /**
     /**

+ 16 - 4
src/options/Options.ts

@@ -1,4 +1,5 @@
-import { injectable } from 'inversify';
+import { inject, injectable } from 'inversify';
+import { ServiceIdentifiers } from '../container/ServiceIdentifiers';
 
 
 import {
 import {
     ArrayUnique,
     ArrayUnique,
@@ -20,6 +21,7 @@ import { TInputOptions } from '../types/options/TInputOptions';
 import { TStringArrayEncoding } from '../types/options/TStringArrayEncoding';
 import { TStringArrayEncoding } from '../types/options/TStringArrayEncoding';
 
 
 import { IOptions } from '../interfaces/options/IOptions';
 import { IOptions } from '../interfaces/options/IOptions';
+import { IOptionsNormalizer } from '../interfaces/options/IOptionsNormalizer';
 
 
 import { IdentifierNamesGenerator } from '../enums/generators/identifier-names-generators/IdentifierNamesGenerator';
 import { IdentifierNamesGenerator } from '../enums/generators/identifier-names-generators/IdentifierNamesGenerator';
 import { ObfuscationTarget } from '../enums/ObfuscationTarget';
 import { ObfuscationTarget } from '../enums/ObfuscationTarget';
@@ -28,7 +30,6 @@ import { StringArrayEncoding } from '../enums/StringArrayEncoding';
 
 
 import { DEFAULT_PRESET } from './presets/Default';
 import { DEFAULT_PRESET } from './presets/Default';
 
 
-import { OptionsNormalizer } from './OptionsNormalizer';
 import { ValidationErrorsFormatter } from './ValidationErrorsFormatter';
 import { ValidationErrorsFormatter } from './ValidationErrorsFormatter';
 
 
 @injectable()
 @injectable()
@@ -111,6 +112,12 @@ export class Options implements IOptions {
     ])
     ])
     public readonly identifierNamesGenerator: IdentifierNamesGenerator;
     public readonly identifierNamesGenerator: IdentifierNamesGenerator;
 
 
+    /**
+     * @type {string}
+     */
+    @IsString()
+    public readonly identifiersPrefix: string;
+
     /**
     /**
      * @type {boolean}
      * @type {boolean}
      */
      */
@@ -164,6 +171,7 @@ export class Options implements IOptions {
     @ValidateIf((options: IOptions) => Boolean(options.sourceMapBaseUrl))
     @ValidateIf((options: IOptions) => Boolean(options.sourceMapBaseUrl))
     @IsUrl({
     @IsUrl({
         require_protocol: true,
         require_protocol: true,
+        require_tld: false,
         require_valid_protocol: true
         require_valid_protocol: true
     })
     })
     public readonly sourceMapBaseUrl: string;
     public readonly sourceMapBaseUrl: string;
@@ -220,8 +228,12 @@ export class Options implements IOptions {
 
 
     /**
     /**
      * @param {TInputOptions} inputOptions
      * @param {TInputOptions} inputOptions
+     * @param {IOptionsNormalizer} optionsNormalizer
      */
      */
-    constructor (inputOptions: TInputOptions) {
+    constructor (
+        @inject(ServiceIdentifiers.TInputOptions) inputOptions: TInputOptions,
+        @inject(ServiceIdentifiers.IOptionsNormalizer) optionsNormalizer: IOptionsNormalizer
+    ) {
         Object.assign(this, DEFAULT_PRESET, inputOptions);
         Object.assign(this, DEFAULT_PRESET, inputOptions);
 
 
         const errors: ValidationError[] = validateSync(this, Options.validatorOptions);
         const errors: ValidationError[] = validateSync(this, Options.validatorOptions);
@@ -230,6 +242,6 @@ export class Options implements IOptions {
             throw new ReferenceError(`Validation failed. errors:\n${ValidationErrorsFormatter.format(errors)}`);
             throw new ReferenceError(`Validation failed. errors:\n${ValidationErrorsFormatter.format(errors)}`);
         }
         }
 
 
-        Object.assign(this, OptionsNormalizer.normalizeOptions(this));
+        Object.assign(this, optionsNormalizer.normalize(this));
     }
     }
 }
 }

+ 6 - 2
src/options/OptionsNormalizer.ts

@@ -1,6 +1,9 @@
+import { injectable } from 'inversify';
+
 import { TOptionsNormalizerRule } from '../types/options/TOptionsNormalizerRule';
 import { TOptionsNormalizerRule } from '../types/options/TOptionsNormalizerRule';
 
 
 import { IOptions } from '../interfaces/options/IOptions';
 import { IOptions } from '../interfaces/options/IOptions';
+import { IOptionsNormalizer } from '../interfaces/options/IOptionsNormalizer';
 
 
 import { ControlFlowFlatteningThresholdRule } from './normalizer-rules/ControlFlowFlatteningThresholdRule';
 import { ControlFlowFlatteningThresholdRule } from './normalizer-rules/ControlFlowFlatteningThresholdRule';
 import { DeadCodeInjectionRule } from './normalizer-rules/DeadCodeInjectionRule';
 import { DeadCodeInjectionRule } from './normalizer-rules/DeadCodeInjectionRule';
@@ -13,7 +16,8 @@ import { StringArrayRule } from './normalizer-rules/StringArrayRule';
 import { StringArrayEncodingRule } from './normalizer-rules/StringArrayEncodingRule';
 import { StringArrayEncodingRule } from './normalizer-rules/StringArrayEncodingRule';
 import { StringArrayThresholdRule } from './normalizer-rules/StringArrayThresholdRule';
 import { StringArrayThresholdRule } from './normalizer-rules/StringArrayThresholdRule';
 
 
-export class OptionsNormalizer {
+@injectable()
+export class OptionsNormalizer implements IOptionsNormalizer {
     /**
     /**
      * @type {TOptionsNormalizerRule[]}
      * @type {TOptionsNormalizerRule[]}
      */
      */
@@ -34,7 +38,7 @@ export class OptionsNormalizer {
      * @param {IOptions} options
      * @param {IOptions} options
      * @returns {IOptions}
      * @returns {IOptions}
      */
      */
-    public static normalizeOptions (options: IOptions): IOptions {
+    public normalize (options: IOptions): IOptions {
         let normalizedOptions: IOptions = {
         let normalizedOptions: IOptions = {
             ...options
             ...options
         };
         };

+ 1 - 0
src/options/presets/Default.ts

@@ -16,6 +16,7 @@ export const DEFAULT_PRESET: TInputOptions = Object.freeze({
     disableConsoleOutput: false,
     disableConsoleOutput: false,
     domainLock: [],
     domainLock: [],
     identifierNamesGenerator: IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator,
     identifierNamesGenerator: IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator,
+    identifiersPrefix: '',
     log: false,
     log: false,
     renameGlobals: false,
     renameGlobals: false,
     reservedNames: [],
     reservedNames: [],

+ 1 - 0
src/options/presets/NoCustomNodes.ts

@@ -15,6 +15,7 @@ export const NO_ADDITIONAL_NODES_PRESET: TInputOptions = Object.freeze({
     disableConsoleOutput: false,
     disableConsoleOutput: false,
     domainLock: [],
     domainLock: [],
     identifierNamesGenerator: IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator,
     identifierNamesGenerator: IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator,
+    identifiersPrefix: '',
     log: false,
     log: false,
     renameGlobals: false,
     renameGlobals: false,
     reservedNames: [],
     reservedNames: [],

+ 13 - 2
src/storages/string-array/StringArrayStorage.ts

@@ -12,6 +12,11 @@ import { ArrayStorage } from '../ArrayStorage';
 
 
 @injectable()
 @injectable()
 export class StringArrayStorage extends ArrayStorage <string> {
 export class StringArrayStorage extends ArrayStorage <string> {
+    /**
+     * @type {number}
+     */
+    private static readonly stringArrayNameLength: number = 7;
+
     /**
     /**
      * @type {IArrayUtils}
      * @type {IArrayUtils}
      */
      */
@@ -45,8 +50,14 @@ export class StringArrayStorage extends ArrayStorage <string> {
     public initialize (): void {
     public initialize (): void {
         super.initialize();
         super.initialize();
 
 
-        const stringArrayName: string = this.identifierNamesGenerator.generate(4);
-        const stringArrayCallsWrapperName: string = this.identifierNamesGenerator.generate(4);
+        const baseStringArrayName: string = this.identifierNamesGenerator
+            .generate()
+            .slice(0, StringArrayStorage.stringArrayNameLength);
+        const baseStringArrayCallsWrapperName: string = this.identifierNamesGenerator
+            .generate()
+            .slice(0, StringArrayStorage.stringArrayNameLength);
+        const stringArrayName: string = `${this.options.identifiersPrefix}${baseStringArrayName}`;
+        const stringArrayCallsWrapperName: string = `${this.options.identifiersPrefix}${baseStringArrayCallsWrapperName}`;
 
 
         this.storageId = `${stringArrayName}|${stringArrayCallsWrapperName}`;
         this.storageId = `${stringArrayName}|${stringArrayCallsWrapperName}`;
     }
     }

+ 7 - 6
test/dev/dev.ts

@@ -6,17 +6,18 @@ import { NO_ADDITIONAL_NODES_PRESET } from '../../src/options/presets/NoCustomNo
 
 
     let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
     let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
         `
         `
+        var bar = 1;
+        var baz = 2;
         (function(){
         (function(){
-            function foo () {
-                eval('var s = 1;');
-            }
-        
-            foo();
+            var bark = bar + baz;
         })();
         })();
         `,
         `,
         {
         {
             ...NO_ADDITIONAL_NODES_PRESET,
             ...NO_ADDITIONAL_NODES_PRESET,
-            compact: false
+            compact: false,
+            identifiersPrefix: 'foo',
+            identifierNamesGenerator: 'mangled',
+            renameGlobals: true
         }
         }
     ).getObfuscatedCode();
     ).getObfuscatedCode();
 
 

+ 80 - 3
test/functional-tests/cli/JavaScriptObfuscatorCLI.spec.ts

@@ -134,13 +134,18 @@ describe('JavaScriptObfuscatorCLI', function (): void {
             const outputFileName1: string = 'foo-obfuscated.js';
             const outputFileName1: string = 'foo-obfuscated.js';
             const outputFileName2: string = 'bar-obfuscated.js';
             const outputFileName2: string = 'bar-obfuscated.js';
             const outputFileName3: string = 'baz-obfuscated.js';
             const outputFileName3: string = 'baz-obfuscated.js';
+            const readFileEncoding: string = 'utf8';
+            const regExp1: RegExp = /^var *a1_0x(\w){4,6} *= *0x1;$/;
+            const regExp2: RegExp = /^var *a0_0x(\w){4,6} *= *0x2;$/;
 
 
             let outputFixturesFilePath1: string,
             let outputFixturesFilePath1: string,
                 outputFixturesFilePath2: string,
                 outputFixturesFilePath2: string,
                 outputFixturesFilePath3: string,
                 outputFixturesFilePath3: string,
                 isFileExist1: boolean,
                 isFileExist1: boolean,
                 isFileExist2: boolean,
                 isFileExist2: boolean,
-                isFileExist3: boolean;
+                isFileExist3: boolean,
+                fileContent1: string,
+                fileContent2: string;
 
 
             before(() => {
             before(() => {
                 outputFixturesFilePath1 = `${directoryPath}/${outputFileName1}`;
                 outputFixturesFilePath1 = `${directoryPath}/${outputFileName1}`;
@@ -150,12 +155,17 @@ describe('JavaScriptObfuscatorCLI', function (): void {
                 JavaScriptObfuscator.runCLI([
                 JavaScriptObfuscator.runCLI([
                     'node',
                     'node',
                     'javascript-obfuscator',
                     'javascript-obfuscator',
-                    directoryPath
+                    directoryPath,
+                    '--rename-globals',
+                    'true'
                 ]);
                 ]);
 
 
                 isFileExist1 = fs.existsSync(outputFixturesFilePath1);
                 isFileExist1 = fs.existsSync(outputFixturesFilePath1);
                 isFileExist2 = fs.existsSync(outputFixturesFilePath2);
                 isFileExist2 = fs.existsSync(outputFixturesFilePath2);
                 isFileExist3 = fs.existsSync(outputFixturesFilePath3);
                 isFileExist3 = fs.existsSync(outputFixturesFilePath3);
+
+                fileContent1 = fs.readFileSync(outputFixturesFilePath1, readFileEncoding);
+                fileContent2 = fs.readFileSync(outputFixturesFilePath2, readFileEncoding);
             });
             });
 
 
             it(`should create file \`${outputFileName1}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => {
             it(`should create file \`${outputFileName1}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => {
@@ -170,13 +180,80 @@ describe('JavaScriptObfuscatorCLI', function (): void {
                 assert.equal(isFileExist3, false);
                 assert.equal(isFileExist3, false);
             });
             });
 
 
+            it(`match #1: should create file with obfuscated code with prefixed identifier`, () => {
+                assert.match(fileContent1, regExp1);
+            });
+
+            it(`match #2: should create file with obfuscated code with prefixed identifier`, () => {
+                assert.match(fileContent2, regExp2);
+            });
+
+            after(() => {
+                rimraf.sync(outputFixturesFilePath1);
+                rimraf.sync(outputFixturesFilePath2);
+            });
+        });
+
+        describe('Variant #3: obfuscation of directory with `identifiersPrefix` option value', () => {
+            const directoryPath: string = `${fixturesDirName}/directory-obfuscation`;
+            const identifiersPrefix: string = 'foo';
+            const outputFileName1: string = 'foo-obfuscated.js';
+            const outputFileName2: string = 'bar-obfuscated.js';
+            const readFileEncoding: string = 'utf8';
+            const regExp1: RegExp = /^var *foo1_0x(\w){4,6} *= *0x1;$/;
+            const regExp2: RegExp = /^var *foo0_0x(\w){4,6} *= *0x2;$/;
+
+            let outputFixturesFilePath1: string,
+                outputFixturesFilePath2: string,
+                isFileExist1: boolean,
+                isFileExist2: boolean,
+                fileContent1: string,
+                fileContent2: string;
+
+            before(() => {
+                outputFixturesFilePath1 = `${directoryPath}/${outputFileName1}`;
+                outputFixturesFilePath2 = `${directoryPath}/${outputFileName2}`;
+
+                JavaScriptObfuscator.runCLI([
+                    'node',
+                    'javascript-obfuscator',
+                    directoryPath,
+                    '--identifiers-prefix',
+                    identifiersPrefix,
+                    '--rename-globals',
+                    'true'
+                ]);
+
+                isFileExist1 = fs.existsSync(outputFixturesFilePath1);
+                isFileExist2 = fs.existsSync(outputFixturesFilePath2);
+
+                fileContent1 = fs.readFileSync(outputFixturesFilePath1, readFileEncoding);
+                fileContent2 = fs.readFileSync(outputFixturesFilePath2, readFileEncoding);
+            });
+
+            it(`should create file \`${outputFileName1}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => {
+                assert.equal(isFileExist1, true);
+            });
+
+            it(`should create file \`${outputFileName2}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => {
+                assert.equal(isFileExist2, true);
+            });
+
+            it(`match #1: should create file with obfuscated code with prefixed identifier`, () => {
+                assert.match(fileContent1, regExp1);
+            });
+
+            it(`match #2: should create file with obfuscated code with prefixed identifier`, () => {
+                assert.match(fileContent2, regExp2);
+            });
+
             after(() => {
             after(() => {
                 rimraf.sync(outputFixturesFilePath1);
                 rimraf.sync(outputFixturesFilePath1);
                 rimraf.sync(outputFixturesFilePath2);
                 rimraf.sync(outputFixturesFilePath2);
             });
             });
         });
         });
 
 
-        describe('Variant #3: obfuscation of directory with `output` option', () => {
+        describe('Variant #4: obfuscation of directory with `output` option', () => {
             const directoryPath: string = `${fixturesDirName}/directory-obfuscation`;
             const directoryPath: string = `${fixturesDirName}/directory-obfuscation`;
             const outputDirectoryName: string = 'obfuscated';
             const outputDirectoryName: string = 'obfuscated';
             const outputDirectoryPath: string = `${directoryPath}/${outputDirectoryName}`;
             const outputDirectoryPath: string = `${directoryPath}/${outputDirectoryName}`;

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

@@ -186,28 +186,108 @@ describe('JavaScriptObfuscator', () => {
         });
         });
 
 
         describe('variable inside global scope', () => {
         describe('variable inside global scope', () => {
-            const regExp: RegExp = /^var *test *= *0x\d+;$/;
+            describe('variant #1: without `renameGlobals` option', () => {
+                const regExp: RegExp = /^var *test *= *0x\d+;$/;
 
 
-            let obfuscatedCode: string;
+                let obfuscatedCode: string;
 
 
-            beforeEach(() => {
-                const code: string = readFileAsString(__dirname + '/fixtures/simple-input-1.js');
-                const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
-                    code,
-                    {
-                        ...NO_ADDITIONAL_NODES_PRESET
-                    }
-                );
+                beforeEach(() => {
+                    const code: string = readFileAsString(__dirname + '/fixtures/simple-input-1.js');
+                    const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                        code,
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET
+                        }
+                    );
 
 
-                obfuscatedCode = obfuscationResult.getObfuscatedCode();
+                    obfuscatedCode = obfuscationResult.getObfuscatedCode();
+                });
+
+                it('should return correct obfuscated code', () => {
+                    assert.match(obfuscatedCode, regExp);
+                });
             });
             });
 
 
-            it('should return correct obfuscated code', () => {
-                assert.match(obfuscatedCode, regExp);
+            describe('variant #2: with `renameGlobals` option', () => {
+                const regExp: RegExp = /^var *_0x(\w){4,6} *= *0x\d+;$/;
+
+                let obfuscatedCode: string;
+
+                beforeEach(() => {
+                    const code: string = readFileAsString(__dirname + '/fixtures/simple-input-1.js');
+                    const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                        code,
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET,
+                            renameGlobals: true
+                        }
+                    );
+
+                    obfuscatedCode = obfuscationResult.getObfuscatedCode();
+                });
+
+                it('should return correct obfuscated code', () => {
+                    assert.match(obfuscatedCode, regExp);
+                });
+            });
+
+            describe('variant #3: with `renameGlobals` and `identifiersPrefix` options', () => {
+                const regExp: RegExp = /^var *foo_0x(\w){4,6} *= *0x\d+;$/;
+
+                let obfuscatedCode: string;
+
+                beforeEach(() => {
+                    const code: string = readFileAsString(__dirname + '/fixtures/simple-input-1.js');
+                    const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                        code,
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET,
+                            renameGlobals: true,
+                            identifiersPrefix: 'foo'
+                        }
+                    );
+
+                    obfuscatedCode = obfuscationResult.getObfuscatedCode();
+                });
+
+                it('should return correct obfuscated code', () => {
+                    assert.match(obfuscatedCode, regExp);
+                });
+            });
+
+            describe('variant #4: with `stringArray`, `renameGlobals` and `identifiersPrefix` options', () => {
+                const stringArrayRegExp: RegExp = /^var foo_0x(\w){4} *= *\['abc'\];/;
+                const stringArrayCallRegExp: RegExp = /var *foo_0x(\w){4,6} *= *foo_0x(\w){4}\('0x0'\);$/;
+
+                let obfuscatedCode: string;
+
+                beforeEach(() => {
+                    const code: string = readFileAsString(__dirname + '/fixtures/simple-input-2.js');
+                    const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                        code,
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET,
+                            renameGlobals: true,
+                            identifiersPrefix: 'foo',
+                            stringArray: true,
+                            stringArrayThreshold: 1
+                        }
+                    );
+
+                    obfuscatedCode = obfuscationResult.getObfuscatedCode();
+                });
+
+                it('match #1: should return correct obfuscated code', () => {
+                    assert.match(obfuscatedCode, stringArrayRegExp);
+                });
+
+                it('match #2: should return correct obfuscated code', () => {
+                    assert.match(obfuscatedCode, stringArrayCallRegExp);
+                });
             });
             });
         });
         });
 
 
-        describe('variable inside global scope', () => {
+        describe('variable inside block scope', () => {
             const regExp: RegExp = /^\(function *\(\) *\{ *var *_0x[\w]+ *= *0x\d+; *\}(\(\)\)|\)\(\));?$/;
             const regExp: RegExp = /^\(function *\(\) *\{ *var *_0x[\w]+ *= *0x\d+; *\}(\(\)\)|\)\(\));?$/;
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;
@@ -229,6 +309,47 @@ describe('JavaScriptObfuscator', () => {
             });
             });
         });
         });
 
 
+        describe('variables inside global and block scopes', () => {
+            describe('variant #1: with `renameGlobals` and `identifiersPrefix` options', () => {
+                const variableDeclaration1: RegExp = /var foo_0x(\w){4,6} *= *0x1;/;
+                const variableDeclaration2: RegExp = /var foo_0x(\w){4,6} *= *0x2;/;
+                const variableDeclaration3: RegExp = /var _0x(\w){4,6} *= *foo_0x(\w){4,6} *\+ *foo_0x(\w){4,6}/;
+                const functionDeclaration: RegExp = /var foo_0x(\w){4,6} *= *function/;
+
+                let obfuscatedCode: string;
+
+                beforeEach(() => {
+                    const code: string = readFileAsString(__dirname + '/fixtures/identifiers-prefix.js');
+                    const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                        code,
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET,
+                            renameGlobals: true,
+                            identifiersPrefix: 'foo'
+                        }
+                    );
+
+                    obfuscatedCode = obfuscationResult.getObfuscatedCode();
+                });
+
+                it('match #1: should return correct obfuscated code', () => {
+                    assert.match(obfuscatedCode, variableDeclaration1);
+                });
+
+                it('match #2: should return correct obfuscated code', () => {
+                    assert.match(obfuscatedCode, variableDeclaration2);
+                });
+
+                it('match #3: should return correct obfuscated code', () => {
+                    assert.match(obfuscatedCode, variableDeclaration3);
+                });
+
+                it('match #4: should return correct obfuscated code', () => {
+                    assert.match(obfuscatedCode, functionDeclaration);
+                });
+            });
+        });
+
         describe('latin literal variable value', () => {
         describe('latin literal variable value', () => {
             const stringArrayLatinRegExp: RegExp = /^var _0x(\w){4} *= *\['abc'\];/;
             const stringArrayLatinRegExp: RegExp = /^var _0x(\w){4} *= *\['abc'\];/;
             const stringArrayCallRegExp: RegExp = /var *test *= *_0x(\w){4}\('0x0'\);$/;
             const stringArrayCallRegExp: RegExp = /var *test *= *_0x(\w){4}\('0x0'\);$/;

+ 7 - 0
test/functional-tests/javascript-obfuscator/fixtures/identifiers-prefix.js

@@ -0,0 +1,7 @@
+var foo = 1;
+var bar = 2;
+var baz = function () {
+    var bark = foo + bar;
+
+    return bark;
+};

+ 17 - 5
test/unit-tests/options/OptionsNormalizer.spec.ts → test/functional-tests/options/OptionsNormalizer.spec.ts

@@ -1,28 +1,40 @@
+import 'reflect-metadata';
+
+import { ServiceIdentifiers } from '../../../src/container/ServiceIdentifiers';
+
 import { assert } from 'chai';
 import { assert } from 'chai';
 
 
 import { TInputOptions } from '../../../src/types/options/TInputOptions';
 import { TInputOptions } from '../../../src/types/options/TInputOptions';
 
 
+import { IInversifyContainerFacade } from '../../../src/interfaces/container/IInversifyContainerFacade';
 import { IOptions } from '../../../src/interfaces/options/IOptions';
 import { IOptions } from '../../../src/interfaces/options/IOptions';
+import { IOptionsNormalizer } from '../../../src/interfaces/options/IOptionsNormalizer';
 
 
 import { StringArrayEncoding } from '../../../src/enums/StringArrayEncoding';
 import { StringArrayEncoding } from '../../../src/enums/StringArrayEncoding';
 
 
 import { DEFAULT_PRESET } from '../../../src/options/presets/Default';
 import { DEFAULT_PRESET } from '../../../src/options/presets/Default';
 
 
-import { Options } from '../../../src/options/Options';
-import { OptionsNormalizer } from '../../../src/options/OptionsNormalizer';
+import { InversifyContainerFacade } from '../../../src/container/InversifyContainerFacade';
 
 
 /**
 /**
  * @param optionsPreset
  * @param optionsPreset
  * @returns {IOptions}
  * @returns {IOptions}
  */
  */
 function getNormalizedOptions (optionsPreset: TInputOptions): TInputOptions {
 function getNormalizedOptions (optionsPreset: TInputOptions): TInputOptions {
-    const options: IOptions = new Options(optionsPreset);
+    const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
+
+    inversifyContainerFacade.load('', optionsPreset);
+
+    const options: IOptions = inversifyContainerFacade
+        .get<IOptions>(ServiceIdentifiers.IOptions);
+    const optionsNormalizer: IOptionsNormalizer = inversifyContainerFacade
+        .get<IOptionsNormalizer>(ServiceIdentifiers.IOptionsNormalizer);
 
 
-    return OptionsNormalizer.normalizeOptions(options);
+    return optionsNormalizer.normalize(options);
 }
 }
 
 
 describe('OptionsNormalizer', () => {
 describe('OptionsNormalizer', () => {
-    describe('normalizeOptions (options: IObfuscatorOptions): IObfuscatorOptions', () => {
+    describe('normalize (options: IObfuscatorOptions): IObfuscatorOptions', () => {
         let optionsPreset: TInputOptions,
         let optionsPreset: TInputOptions,
             expectedOptionsPreset: TInputOptions;
             expectedOptionsPreset: TInputOptions;
 
 

+ 1 - 1
test/index.spec.ts

@@ -24,7 +24,6 @@ import './unit-tests/node/node-guards/NodeGuards.spec';
 import './unit-tests/node/node-utils/NodeUtils.spec';
 import './unit-tests/node/node-utils/NodeUtils.spec';
 import './unit-tests/node-transformers/preparing-transformers/ObfuscatingGuardsTransformer.spec';
 import './unit-tests/node-transformers/preparing-transformers/ObfuscatingGuardsTransformer.spec';
 import './unit-tests/obfuscation-result/ObfuscationResult.spec';
 import './unit-tests/obfuscation-result/ObfuscationResult.spec';
-import './unit-tests/options/OptionsNormalizer.spec';
 import './unit-tests/options/ValidationErrorsFormatter.spec';
 import './unit-tests/options/ValidationErrorsFormatter.spec';
 import './unit-tests/source-map/SourceMapCorrector.spec';
 import './unit-tests/source-map/SourceMapCorrector.spec';
 import './unit-tests/storages/ArrayStorage.spec';
 import './unit-tests/storages/ArrayStorage.spec';
@@ -68,6 +67,7 @@ import './functional-tests/node-transformers/preparing-transformers/eval-call-ex
 import './functional-tests/node-transformers/preparing-transformers/comments-transformer/CommentsTransformer.spec';
 import './functional-tests/node-transformers/preparing-transformers/comments-transformer/CommentsTransformer.spec';
 import './functional-tests/node-transformers/preparing-transformers/obfuscating-guards/black-list-obfuscating-guard/BlackListObfuscatingGuard.spec';
 import './functional-tests/node-transformers/preparing-transformers/obfuscating-guards/black-list-obfuscating-guard/BlackListObfuscatingGuard.spec';
 import './functional-tests/node-transformers/preparing-transformers/obfuscating-guards/conditional-comment-obfuscating-guard/ConditionalCommentObfuscatingGuard.spec';
 import './functional-tests/node-transformers/preparing-transformers/obfuscating-guards/conditional-comment-obfuscating-guard/ConditionalCommentObfuscatingGuard.spec';
+import './functional-tests/options/OptionsNormalizer.spec';
 import './functional-tests/templates/debug-protection-nodes/DebugProtectionFunctionCallTemplate.spec';
 import './functional-tests/templates/debug-protection-nodes/DebugProtectionFunctionCallTemplate.spec';
 import './functional-tests/templates/domain-lock-nodes/DomainLockNodeTemplate.spec';
 import './functional-tests/templates/domain-lock-nodes/DomainLockNodeTemplate.spec';
 import './functional-tests/templates/GlobalVariableNoEvalTemplate.spec';
 import './functional-tests/templates/GlobalVariableNoEvalTemplate.spec';

+ 28 - 18
test/unit-tests/generators/identifier-names-generators/HexadecimalIdentifierNamesGenerator.spec.ts

@@ -12,7 +12,7 @@ import { IdentifierNamesGenerator } from '../../../../src/enums/generators/ident
 import { InversifyContainerFacade } from '../../../../src/container/InversifyContainerFacade';
 import { InversifyContainerFacade } from '../../../../src/container/InversifyContainerFacade';
 
 
 describe('HexadecimalIdentifierNamesGenerator', () => {
 describe('HexadecimalIdentifierNamesGenerator', () => {
-    describe('generate (length: number): string', () => {
+    describe('generate (): string', () => {
         let identifierNamesGenerator: IIdentifierNamesGenerator,
         let identifierNamesGenerator: IIdentifierNamesGenerator,
             hexadecimalIdentifierName: string,
             hexadecimalIdentifierName: string,
             regExp: RegExp;
             regExp: RegExp;
@@ -24,29 +24,39 @@ describe('HexadecimalIdentifierNamesGenerator', () => {
             identifierNamesGenerator = inversifyContainerFacade.getNamed<IIdentifierNamesGenerator>(
             identifierNamesGenerator = inversifyContainerFacade.getNamed<IIdentifierNamesGenerator>(
                 ServiceIdentifiers.IIdentifierNamesGenerator,
                 ServiceIdentifiers.IIdentifierNamesGenerator,
                 IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator
                 IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator
-            )
+            );
+
+            hexadecimalIdentifierName = identifierNamesGenerator.generate();
+            regExp = /^_0x(\w){4,6}$/;
         });
         });
 
 
-        describe('variant #1: hexadecimal name with length `4`', () => {
-            before(() => {
-                hexadecimalIdentifierName = identifierNamesGenerator.generate(4);
-                regExp = /^_0x(\w){4}$/;
-            });
+        it('should return hexadecimal name', () => {
+            assert.match(hexadecimalIdentifierName, regExp);
+        })
+    });
 
 
-            it('should return hexadecimal name', () => {
-                assert.match(hexadecimalIdentifierName, regExp);
-            })
-        });
+    describe('generateWithPrefix (): string', () => {
+        const regExp: RegExp = /^foo_0x(\w){4,6}$/;
 
 
-        describe('variant #2: hexadecimal name with length `6`', () => {
-            before(() => {
-                hexadecimalIdentifierName = identifierNamesGenerator.generate(6);
-                regExp = /^_0x(\w){4,6}$/;
+        let identifierNamesGenerator: IIdentifierNamesGenerator,
+            hexadecimalIdentifierName: string;
+
+        before(() => {
+            const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
+
+            inversifyContainerFacade.load('', {
+                identifiersPrefix: 'foo'
             });
             });
+            identifierNamesGenerator = inversifyContainerFacade.getNamed<IIdentifierNamesGenerator>(
+                ServiceIdentifiers.IIdentifierNamesGenerator,
+                IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator
+            );
 
 
-            it('should return hexadecimal name', () => {
-                assert.match(hexadecimalIdentifierName, regExp);
-            })
+            hexadecimalIdentifierName = identifierNamesGenerator.generateWithPrefix();
         });
         });
+
+        it('should return hexadecimal name with prefix', () => {
+            assert.match(hexadecimalIdentifierName, regExp);
+        })
     });
     });
 });
 });

+ 48 - 7
test/unit-tests/generators/identifier-names-generators/MangledlIdentifierNamesGenerator.spec.ts

@@ -12,7 +12,7 @@ import { IdentifierNamesGenerator } from '../../../../src/enums/generators/ident
 import { InversifyContainerFacade } from '../../../../src/container/InversifyContainerFacade';
 import { InversifyContainerFacade } from '../../../../src/container/InversifyContainerFacade';
 
 
 describe('MangledIdentifierNamesGenerator', () => {
 describe('MangledIdentifierNamesGenerator', () => {
-    describe('generate (length: number): string', () => {
+    describe('generate (): string', () => {
         let identifierNamesGenerator: IIdentifierNamesGenerator,
         let identifierNamesGenerator: IIdentifierNamesGenerator,
             mangledIdentifierName: string;
             mangledIdentifierName: string;
 
 
@@ -30,7 +30,7 @@ describe('MangledIdentifierNamesGenerator', () => {
             const expectedMangledIdentifierName: string = 'a';
             const expectedMangledIdentifierName: string = 'a';
 
 
             beforeEach(() => {
             beforeEach(() => {
-                mangledIdentifierName = identifierNamesGenerator.generate(4);
+                mangledIdentifierName = identifierNamesGenerator.generate();
             });
             });
 
 
             it('should return mangled name', () => {
             it('should return mangled name', () => {
@@ -44,7 +44,7 @@ describe('MangledIdentifierNamesGenerator', () => {
 
 
             beforeEach(() => {
             beforeEach(() => {
                 for (let i: number = 0; i <= expectedMangledIdentifierPosition; i++) {
                 for (let i: number = 0; i <= expectedMangledIdentifierPosition; i++) {
-                    mangledIdentifierName = identifierNamesGenerator.generate(6);
+                    mangledIdentifierName = identifierNamesGenerator.generate();
                 }
                 }
             });
             });
 
 
@@ -59,7 +59,7 @@ describe('MangledIdentifierNamesGenerator', () => {
 
 
             beforeEach(() => {
             beforeEach(() => {
                 for (let i: number = 0; i <= expectedMangledIdentifierPosition; i++) {
                 for (let i: number = 0; i <= expectedMangledIdentifierPosition; i++) {
-                    mangledIdentifierName = identifierNamesGenerator.generate(6);
+                    mangledIdentifierName = identifierNamesGenerator.generate();
                 }
                 }
             });
             });
 
 
@@ -74,7 +74,7 @@ describe('MangledIdentifierNamesGenerator', () => {
 
 
             beforeEach(() => {
             beforeEach(() => {
                 for (let i: number = 0; i <= expectedMangledIdentifierPosition; i++) {
                 for (let i: number = 0; i <= expectedMangledIdentifierPosition; i++) {
-                    mangledIdentifierName = identifierNamesGenerator.generate(6);
+                    mangledIdentifierName = identifierNamesGenerator.generate();
                 }
                 }
             });
             });
 
 
@@ -89,7 +89,7 @@ describe('MangledIdentifierNamesGenerator', () => {
 
 
             beforeEach(() => {
             beforeEach(() => {
                 for (let i: number = 0; i <= expectedMangledIdentifierPosition; i++) {
                 for (let i: number = 0; i <= expectedMangledIdentifierPosition; i++) {
-                    mangledIdentifierName = identifierNamesGenerator.generate(6);
+                    mangledIdentifierName = identifierNamesGenerator.generate();
                 }
                 }
             });
             });
 
 
@@ -109,7 +109,7 @@ describe('MangledIdentifierNamesGenerator', () => {
 
 
             beforeEach(() => {
             beforeEach(() => {
                 for (let i: number = 0; i <= expectedMangledIdentifierPosition2; i++) {
                 for (let i: number = 0; i <= expectedMangledIdentifierPosition2; i++) {
-                    mangledIdentifierName = identifierNamesGenerator.generate(6);
+                    mangledIdentifierName = identifierNamesGenerator.generate();
 
 
                     if (i === expectedMangledIdentifierPosition1) {
                     if (i === expectedMangledIdentifierPosition1) {
                         mangledIdentifierName1 = mangledIdentifierName;
                         mangledIdentifierName1 = mangledIdentifierName;
@@ -128,4 +128,45 @@ describe('MangledIdentifierNamesGenerator', () => {
             });
             });
         });
         });
     });
     });
+
+    describe('generateWithPrefix (): string', () => {
+        let identifierNamesGenerator: IIdentifierNamesGenerator,
+            mangledIdentifierName: string;
+
+        before(() => {
+            const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
+
+            inversifyContainerFacade.load('', {
+                identifiersPrefix: 'foo'
+            });
+            identifierNamesGenerator = inversifyContainerFacade.getNamed<IIdentifierNamesGenerator>(
+                ServiceIdentifiers.IIdentifierNamesGenerator,
+                IdentifierNamesGenerator.MangledIdentifierNamesGenerator
+            );
+        });
+
+        describe('variant #1: initial mangled name', () => {
+            const expectedMangledIdentifierName: string = 'foo_a';
+
+            beforeEach(() => {
+                mangledIdentifierName = identifierNamesGenerator.generateWithPrefix();
+            });
+
+            it('should return mangled name with prefix', () => {
+                assert.equal(mangledIdentifierName, expectedMangledIdentifierName);
+            });
+        });
+
+        describe('variant #2: second mangled name', () => {
+            const expectedMangledIdentifierName: string = 'foo_b';
+
+            beforeEach(() => {
+                mangledIdentifierName = identifierNamesGenerator.generateWithPrefix();
+            });
+
+            it('should return mangled name with prefix', () => {
+                assert.equal(mangledIdentifierName, expectedMangledIdentifierName);
+            });
+        });
+    });
 });
 });

+ 50 - 34
yarn.lock

@@ -2,9 +2,9 @@
 # yarn lockfile v1
 # yarn lockfile v1
 
 
 
 
-"@types/[email protected].0":
-  version "4.1.0"
-  resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.0.tgz#d9008fa4c06f6801f93396d121f0227cd4244ac6"
+"@types/[email protected].2":
+  version "4.1.2"
+  resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.2.tgz#f1af664769cfb50af805431c407425ed619daa21"
 
 
 "@types/[email protected]":
 "@types/[email protected]":
   version "0.7.36"
   version "0.7.36"
@@ -58,9 +58,9 @@
   dependencies:
   dependencies:
     "@types/node" "*"
     "@types/node" "*"
 
 
-"@types/[email protected]6":
-  version "2.2.46"
-  resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.46.tgz#b04713f7759d1cf752effdaae7b3969e285ebc16"
+"@types/[email protected]7":
+  version "2.2.47"
+  resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.47.tgz#30bbd880834d4af0f609025f282a69b8d4458f06"
 
 
 "@types/node@*":
 "@types/node@*":
   version "8.0.53"
   version "8.0.53"
@@ -1016,11 +1016,11 @@ class-utils@^0.3.5:
     lazy-cache "^2.0.2"
     lazy-cache "^2.0.2"
     static-extend "^0.1.1"
     static-extend "^0.1.1"
 
 
-class-validator@0.7.3:
-  version "0.7.3"
-  resolved "https://registry.yarnpkg.com/class-validator/-/class-validator-0.7.3.tgz#3c2821b8cf35fd8d5f4fcb8063bc57fb50049e7e"
+class-validator@0.8.1:
+  version "0.8.1"
+  resolved "https://registry.yarnpkg.com/class-validator/-/class-validator-0.8.1.tgz#f5efd5c613927e3c2f68692e8f14d53a2644fb2f"
   dependencies:
   dependencies:
-    validator "^7.0.0"
+    validator "9.2.0"
 
 
 cli-cursor@^2.1.0:
 cli-cursor@^2.1.0:
   version "2.1.0"
   version "2.1.0"
@@ -1446,9 +1446,9 @@ [email protected], escape-string-regexp@^1.0.2, escape-string-regexp@^1
   version "1.0.5"
   version "1.0.5"
   resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
   resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
 
 
[email protected]6:
-  version "1.6.16"
-  resolved "https://registry.yarnpkg.com/escodegen-wallaby/-/escodegen-wallaby-1.6.16.tgz#f55b65d1a846d98584f1be18a2bf463f96280527"
[email protected]7:
+  version "1.6.17"
+  resolved "https://registry.yarnpkg.com/escodegen-wallaby/-/escodegen-wallaby-1.6.17.tgz#3e1f334884d4214c94309cf734ec7cfa0b3d438d"
   dependencies:
   dependencies:
     esprima "^2.7.1"
     esprima "^2.7.1"
     estraverse "^1.9.1"
     estraverse "^1.9.1"
@@ -2566,9 +2566,9 @@ [email protected], [email protected], "mkdirp@>=0.5 0", mkdirp@^0.5.1, mkdirp@~0.5.0:
   dependencies:
   dependencies:
     minimist "0.0.8"
     minimist "0.0.8"
 
 
-mocha@4.1.0:
-  version "4.1.0"
-  resolved "https://registry.yarnpkg.com/mocha/-/mocha-4.1.0.tgz#7d86cfbcf35cb829e2754c32e17355ec05338794"
+mocha@5.0.0:
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.0.0.tgz#cccac988b0bc5477119cba0e43de7af6d6ad8f4e"
   dependencies:
   dependencies:
     browser-stdout "1.3.0"
     browser-stdout "1.3.0"
     commander "2.11.0"
     commander "2.11.0"
@@ -3107,9 +3107,9 @@ readdirp@^2.0.0:
     readable-stream "^2.0.2"
     readable-stream "^2.0.2"
     set-immediate-shim "^1.0.1"
     set-immediate-shim "^1.0.1"
 
 
[email protected]0:
-  version "0.1.10"
-  resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.10.tgz#b4f83704416acad89988c9b15635d47e03b9344a"
[email protected]2:
+  version "0.1.12"
+  resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.12.tgz#311bf0c6b63cd782f228a81abe146a2bfa9c56f2"
 
 
 regenerate@^1.2.1:
 regenerate@^1.2.1:
   version "1.3.3"
   version "1.3.3"
@@ -3329,16 +3329,16 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
   version "3.0.2"
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
   resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
 
 
-sinon@4.1.4:
-  version "4.1.4"
-  resolved "https://registry.yarnpkg.com/sinon/-/sinon-4.1.4.tgz#36bb237bae38ddf9cc92dcc1b16c51e7785bbc9c"
+sinon@4.2.1:
+  version "4.2.1"
+  resolved "https://registry.yarnpkg.com/sinon/-/sinon-4.2.1.tgz#3664e90ea4bccec6ebde3c06e3da8179983371d9"
   dependencies:
   dependencies:
     diff "^3.1.0"
     diff "^3.1.0"
     formatio "1.2.0"
     formatio "1.2.0"
     lodash.get "^4.4.2"
     lodash.get "^4.4.2"
     lolex "^2.2.0"
     lolex "^2.2.0"
     nise "^1.2.0"
     nise "^1.2.0"
-    supports-color "^4.4.0"
+    supports-color "^5.1.0"
     type-detect "^4.0.5"
     type-detect "^4.0.5"
 
 
 slash@^1.0.0:
 slash@^1.0.0:
@@ -3392,9 +3392,9 @@ source-map-resolve@^0.5.0:
     source-map-url "^0.4.0"
     source-map-url "^0.4.0"
     urix "^0.1.0"
     urix "^0.1.0"
 
 
[email protected].0, source-map-support@^0.5.0:
-  version "0.5.0"
-  resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.0.tgz#2018a7ad2bdf8faf2691e5fddab26bed5a2bacab"
[email protected].2:
+  version "0.5.2"
+  resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.2.tgz#1a6297fd5b2e762b39688c7fc91233b60984f0a5"
   dependencies:
   dependencies:
     source-map "^0.6.0"
     source-map "^0.6.0"
 
 
@@ -3404,6 +3404,12 @@ source-map-support@^0.4.15:
   dependencies:
   dependencies:
     source-map "^0.5.6"
     source-map "^0.5.6"
 
 
+source-map-support@^0.5.0:
+  version "0.5.0"
+  resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.0.tgz#2018a7ad2bdf8faf2691e5fddab26bed5a2bacab"
+  dependencies:
+    source-map "^0.6.0"
+
 source-map-url@^0.4.0:
 source-map-url@^0.4.0:
   version "0.4.0"
   version "0.4.0"
   resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
   resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
@@ -3576,12 +3582,18 @@ supports-color@^3.1.2:
   dependencies:
   dependencies:
     has-flag "^1.0.0"
     has-flag "^1.0.0"
 
 
-supports-color@^4.0.0, supports-color@^4.2.1, supports-color@^4.4.0:
+supports-color@^4.0.0, supports-color@^4.2.1:
   version "4.5.0"
   version "4.5.0"
   resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b"
   resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b"
   dependencies:
   dependencies:
     has-flag "^2.0.0"
     has-flag "^2.0.0"
 
 
+supports-color@^5.1.0:
+  version "5.1.0"
+  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.1.0.tgz#058a021d1b619f7ddf3980d712ea3590ce7de3d5"
+  dependencies:
+    has-flag "^2.0.0"
+
 tapable@^0.2.5, tapable@^0.2.7:
 tapable@^0.2.5, tapable@^0.2.7:
   version "0.2.8"
   version "0.2.8"
   resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.8.tgz#99372a5c999bf2df160afc0d74bed4f47948cd22"
   resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.8.tgz#99372a5c999bf2df160afc0d74bed4f47948cd22"
@@ -3611,9 +3623,9 @@ text-encoding@^0.6.4:
   version "0.6.4"
   version "0.6.4"
   resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19"
   resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19"
 
 
[email protected].0:
-  version "0.10.0"
-  resolved "https://registry.yarnpkg.com/threads/-/threads-0.10.0.tgz#a6b0bc5d916fa75434b166c612769684b65fead5"
[email protected].1:
+  version "0.10.1"
+  resolved "https://registry.yarnpkg.com/threads/-/threads-0.10.1.tgz#637765dc434ab3373d3c14754c8f7ac6515d6815"
   dependencies:
   dependencies:
     eventemitter3 "^2.0.2"
     eventemitter3 "^2.0.2"
     native-promise-only "^0.8.1"
     native-promise-only "^0.8.1"
@@ -3697,7 +3709,11 @@ tsconfig@^7.0.0:
     strip-bom "^3.0.0"
     strip-bom "^3.0.0"
     strip-json-comments "^2.0.0"
     strip-json-comments "^2.0.0"
 
 
[email protected], tslib@^1.0.0, tslib@^1.7.1, tslib@^1.8.0:
[email protected]:
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8"
+
+tslib@^1.0.0, tslib@^1.7.1, tslib@^1.8.0:
   version "1.8.1"
   version "1.8.1"
   resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.8.1.tgz#6946af2d1d651a7b1863b531d6e5afa41aa44eac"
   resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.8.1.tgz#6946af2d1d651a7b1863b531d6e5afa41aa44eac"
 
 
@@ -3879,9 +3895,9 @@ validate-npm-package-license@^3.0.1:
     spdx-correct "~1.0.0"
     spdx-correct "~1.0.0"
     spdx-expression-parse "~1.0.0"
     spdx-expression-parse "~1.0.0"
 
 
-validator@^7.0.0:
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/validator/-/validator-7.2.0.tgz#a63dcbaba51d4350bf8df20988e0d5a54d711791"
+validator@9.2.0:
+  version "9.2.0"
+  resolved "https://registry.yarnpkg.com/validator/-/validator-9.2.0.tgz#ad216eed5f37cac31a6fe00ceab1f6b88bded03e"
 
 
 [email protected]:
 [email protected]:
   version "1.10.0"
   version "1.10.0"

Some files were not shown because too many files changed in this diff