mirror of
https://github.com/javascript-obfuscator/javascript-obfuscator
synced 2026-08-09 12:42:29 +00:00
Merge pull request #180 from javascript-obfuscator/identifirs-prefix
`identifiersPrefix` option
This commit is contained in:
@@ -2,6 +2,7 @@ Change Log
|
||||
===
|
||||
v0.14.0
|
||||
---
|
||||
* **New option:** `identifiersPrefix` sets prefix for all generated identifiers.
|
||||
* **New option:** `transformObjectKeys` enables object keys transformation and obfuscation.
|
||||
* **New feature:** `eval` expressions obfuscation.
|
||||
* **Breaking change:** Now CLI obfuscating directory recursively. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/157
|
||||
|
||||
@@ -277,6 +277,7 @@ Following options are available for the JS Obfuscator:
|
||||
disableConsoleOutput: false,
|
||||
domainLock: [],
|
||||
identifierNamesGenerator: 'hexadecimal',
|
||||
identifiersPrefix: '',
|
||||
log: false,
|
||||
renameGlobals: false,
|
||||
reservedNames: [],
|
||||
@@ -314,6 +315,7 @@ Following options are available for the JS Obfuscator:
|
||||
--disable-console-output <boolean>
|
||||
--domain-lock '<list>' (comma separated)
|
||||
--identifier-names-generator <string> [hexadecimal, mangled]
|
||||
--identifiers-prefix <string>
|
||||
--log <boolean>
|
||||
--rename-globals <boolean>
|
||||
--reserved-names '<list>' (comma separated)
|
||||
@@ -570,6 +572,13 @@ Available values:
|
||||
* `hexadecimal`: identifier names like `_0xabc123`
|
||||
* `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`
|
||||
Type: `boolean` Default: `false`
|
||||
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+11
-11
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "javascript-obfuscator",
|
||||
"version": "0.14.0-beta.2",
|
||||
"version": "0.14.0-beta.3",
|
||||
"description": "JavaScript obfuscator",
|
||||
"keywords": [
|
||||
"obfuscator",
|
||||
@@ -21,9 +21,9 @@
|
||||
"dependencies": {
|
||||
"chalk": "2.3.0",
|
||||
"chance": "1.0.13",
|
||||
"class-validator": "0.7.3",
|
||||
"class-validator": "0.8.1",
|
||||
"commander": "2.13.0",
|
||||
"escodegen-wallaby": "1.6.16",
|
||||
"escodegen-wallaby": "1.6.17",
|
||||
"esprima": "4.0.0",
|
||||
"estraverse": "4.2.0",
|
||||
"inversify": "4.9.0",
|
||||
@@ -32,13 +32,13 @@
|
||||
"mkdirp": "0.5.1",
|
||||
"opencollective": "1.0.3",
|
||||
"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",
|
||||
"tslib": "1.8.1"
|
||||
"tslib": "1.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chai": "4.1.0",
|
||||
"@types/chai": "4.1.2",
|
||||
"@types/chance": "0.7.36",
|
||||
"@types/escodegen": "0.0.6",
|
||||
"@types/esprima": "4.0.1",
|
||||
@@ -46,7 +46,7 @@
|
||||
"@types/estree": "0.0.38",
|
||||
"@types/md5": "2.1.32",
|
||||
"@types/mkdirp": "0.5.2",
|
||||
"@types/mocha": "2.2.46",
|
||||
"@types/mocha": "2.2.47",
|
||||
"@types/node": "9.3.0",
|
||||
"@types/rimraf": "2.0.2",
|
||||
"@types/sinon": "4.1.3",
|
||||
@@ -60,11 +60,11 @@
|
||||
"chai": "4.1.2",
|
||||
"coveralls": "3.0.0",
|
||||
"istanbul": "1.1.0-alpha.1",
|
||||
"mocha": "4.1.0",
|
||||
"mocha": "5.0.0",
|
||||
"pre-commit": "1.2.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",
|
||||
"tslint": "5.9.1",
|
||||
"tslint-eslint-rules": "4.1.1",
|
||||
|
||||
@@ -44,6 +44,11 @@ export class JavaScriptObfuscatorCLI implements IInitializable {
|
||||
*/
|
||||
public static obfuscatedFilePrefix: string = '-obfuscated';
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
private static readonly baseIdentifiersPrefix: string = 'a';
|
||||
|
||||
/**
|
||||
* @type {string[]}
|
||||
*/
|
||||
@@ -244,6 +249,10 @@ export class JavaScriptObfuscatorCLI implements IInitializable {
|
||||
'--identifier-names-generator <string> [hexadecimal, mangled]', 'Sets identifier names generator (Default: hexadecimal)',
|
||||
IdentifierNamesGeneratorSanitizer
|
||||
)
|
||||
.option(
|
||||
'--identifiers-prefix <string>',
|
||||
'Sets prefix for all generated identifiers.'
|
||||
)
|
||||
.option(
|
||||
'--log <boolean>', 'Enables logging of the information to the console',
|
||||
BooleanSanitizer
|
||||
@@ -295,7 +304,7 @@ export class JavaScriptObfuscatorCLI implements IInitializable {
|
||||
BooleanSanitizer
|
||||
)
|
||||
.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',
|
||||
StringArrayEncodingSanitizer
|
||||
)
|
||||
@@ -343,14 +352,14 @@ export class JavaScriptObfuscatorCLI implements IInitializable {
|
||||
if (!Array.isArray(sourceCodeData)) {
|
||||
const outputCodePath: string = outputPath || CLIUtils.getOutputCodePath(this.inputPath);
|
||||
|
||||
this.processSourceCode(sourceCodeData, outputCodePath);
|
||||
this.processSourceCode(sourceCodeData, outputCodePath, null);
|
||||
} else {
|
||||
sourceCodeData.forEach(({ filePath, content }: IFileData) => {
|
||||
sourceCodeData.forEach(({ filePath, content }: IFileData, index: number) => {
|
||||
const outputCodePath: string = outputPath
|
||||
? path.join(outputPath, 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} 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) {
|
||||
JavaScriptObfuscatorCLI.processSourceCodeWithSourceMap(sourceCode, outputCodePath, options);
|
||||
|
||||
@@ -9,6 +9,7 @@ import { finalizingTransformersModule } from './modules/node-transformers/Finali
|
||||
import { generatorsModule } from './modules/generators/GeneratorsModule';
|
||||
import { nodeTransformersModule } from './modules/node-transformers/NodeTransformersModule';
|
||||
import { obfuscatingTransformersModule } from './modules/node-transformers/ObfuscatingTransformersModule';
|
||||
import { optionsModule } from './modules/options/OptionsModule';
|
||||
import { preparingTransformersModule } from './modules/node-transformers/PreparingTransformersModule';
|
||||
import { storagesModule } from './modules/storages/StoragesModule';
|
||||
import { utilsModule } from './modules/utils/UtilsModule';
|
||||
@@ -20,7 +21,6 @@ import { IJavaScriptObfuscator } from '../interfaces/IJavaScriptObfsucator';
|
||||
import { ILogger } from '../interfaces/logger/ILogger';
|
||||
import { IObfuscationEventEmitter } from '../interfaces/event-emitters/IObfuscationEventEmitter';
|
||||
import { IObfuscationResult } from '../interfaces/IObfuscationResult';
|
||||
import { IOptions } from '../interfaces/options/IOptions';
|
||||
import { ISourceCode } from '../interfaces/ISourceCode';
|
||||
import { ISourceMapCorrector } from '../interfaces/source-map/ISourceMapCorrector';
|
||||
import { ITransformersRunner } from '../interfaces/node-transformers/ITransformersRunner';
|
||||
@@ -29,7 +29,6 @@ import { JavaScriptObfuscator } from '../JavaScriptObfuscator';
|
||||
import { Logger } from '../logger/Logger';
|
||||
import { ObfuscationEventEmitter } from '../event-emitters/ObfuscationEventEmitter';
|
||||
import { ObfuscationResult } from '../ObfuscationResult';
|
||||
import { Options } from "../options/Options";
|
||||
import { SourceCode } from '../SourceCode';
|
||||
import { SourceMapCorrector } from '../source-map/SourceMapCorrector';
|
||||
import { TransformersRunner } from '../node-transformers/TransformersRunner';
|
||||
@@ -147,8 +146,8 @@ export class InversifyContainerFacade implements IInversifyContainerFacade {
|
||||
.inSingletonScope();
|
||||
|
||||
this.container
|
||||
.bind<IOptions>(ServiceIdentifiers.IOptions)
|
||||
.toDynamicValue(() => new Options(options))
|
||||
.bind<TInputOptions>(ServiceIdentifiers.TInputOptions)
|
||||
.toDynamicValue(() => options)
|
||||
.inSingletonScope();
|
||||
|
||||
this.container
|
||||
@@ -203,6 +202,7 @@ export class InversifyContainerFacade implements IInversifyContainerFacade {
|
||||
this.container.load(generatorsModule);
|
||||
this.container.load(nodeTransformersModule);
|
||||
this.container.load(obfuscatingTransformersModule);
|
||||
this.container.load(optionsModule);
|
||||
this.container.load(preparingTransformersModule);
|
||||
this.container.load(storagesModule);
|
||||
this.container.load(utilsModule);
|
||||
|
||||
@@ -28,6 +28,7 @@ export enum ServiceIdentifiers {
|
||||
IObfuscationEventEmitter = 'IObfuscationEventEmitter',
|
||||
IObfuscationResult = 'IObfuscationResult',
|
||||
IOptions = 'IOptions',
|
||||
IOptionsNormalizer = 'IOptionsNormalizer',
|
||||
IObfuscatingReplacer = 'IObfuscatingReplacer',
|
||||
IRandomGenerator = 'IRandomGenerator',
|
||||
ISourceCode = 'ISourceCode',
|
||||
@@ -37,5 +38,6 @@ export enum ServiceIdentifiers {
|
||||
Newable__ICustomNode = 'Newable<ICustomNode>',
|
||||
Newable__TControlFlowStorage = 'Newable<TControlFlowStorage>',
|
||||
TCustomNodeGroupStorage = 'TCustomNodeGroupStorage',
|
||||
TInputOptions = 'TInputOptions',
|
||||
TStringArrayStorage = 'TStringArrayStorage'
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
@@ -64,7 +64,7 @@ export class ConsoleOutputDisableExpressionNode extends AbstractCustomNode {
|
||||
: GlobalVariableNoEvalTemplate();
|
||||
|
||||
return format(ConsoleOutputDisableExpressionTemplate(), {
|
||||
consoleLogDisableFunctionName: this.identifierNamesGenerator.generate(6),
|
||||
consoleLogDisableFunctionName: this.identifierNamesGenerator.generate(),
|
||||
globalVariableTemplate,
|
||||
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
|
||||
});
|
||||
|
||||
@@ -92,7 +92,7 @@ export class ConsoleOutputCustomNodeGroup extends AbstractCustomNodeGroup {
|
||||
return;
|
||||
}
|
||||
|
||||
const callsControllerFunctionName: string = this.identifierNamesGenerator.generate(6);
|
||||
const callsControllerFunctionName: string = this.identifierNamesGenerator.generate();
|
||||
|
||||
const consoleOutputDisableExpressionNode: ICustomNode = this.customNodeFactory(CustomNode.ConsoleOutputDisableExpressionNode);
|
||||
const nodeCallsControllerFunctionNode: ICustomNode = this.customNodeFactory(CustomNode.NodeCallsControllerFunctionNode);
|
||||
|
||||
@@ -105,8 +105,8 @@ export class DebugProtectionCustomNodeGroup extends AbstractCustomNodeGroup {
|
||||
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 debugProtectionFunctionCallNode: ICustomNode = this.customNodeFactory(CustomNode.DebugProtectionFunctionCallNode);
|
||||
|
||||
@@ -79,7 +79,7 @@ export class DomainLockNode extends AbstractCustomNode {
|
||||
: GlobalVariableNoEvalTemplate();
|
||||
|
||||
return format(DomainLockNodeTemplate(), {
|
||||
domainLockFunctionName: this.identifierNamesGenerator.generate(6),
|
||||
domainLockFunctionName: this.identifierNamesGenerator.generate(),
|
||||
diff: diff,
|
||||
domains: hiddenDomainsString,
|
||||
globalVariableTemplate,
|
||||
|
||||
@@ -92,7 +92,7 @@ export class DomainLockCustomNodeGroup extends AbstractCustomNodeGroup {
|
||||
return;
|
||||
}
|
||||
|
||||
const callsControllerFunctionName: string = this.identifierNamesGenerator.generate(6);
|
||||
const callsControllerFunctionName: string = this.identifierNamesGenerator.generate();
|
||||
|
||||
const domainLockNode: ICustomNode = this.customNodeFactory(CustomNode.DomainLockNode);
|
||||
const nodeCallsControllerFunctionNode: ICustomNode = this.customNodeFactory(CustomNode.NodeCallsControllerFunctionNode);
|
||||
|
||||
@@ -71,7 +71,7 @@ export class SelfDefendingUnicodeNode extends AbstractCustomNode {
|
||||
protected getTemplate (): string {
|
||||
return JavaScriptObfuscator.obfuscate(
|
||||
format(SelfDefendingTemplate(this.escapeSequenceEncoder), {
|
||||
selfDefendingFunctionName: this.identifierNamesGenerator.generate(6),
|
||||
selfDefendingFunctionName: this.identifierNamesGenerator.generate(),
|
||||
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
|
||||
}),
|
||||
{
|
||||
|
||||
@@ -92,7 +92,7 @@ export class SelfDefendingCustomNodeGroup extends AbstractCustomNodeGroup {
|
||||
return;
|
||||
}
|
||||
|
||||
const callsControllerFunctionName: string = this.identifierNamesGenerator.generate(6);
|
||||
const callsControllerFunctionName: string = this.identifierNamesGenerator.generate();
|
||||
|
||||
const selfDefendingUnicodeNode: ICustomNode = this.customNodeFactory(CustomNode.SelfDefendingUnicodeNode);
|
||||
const nodeCallsControllerFunctionNode: ICustomNode = this.customNodeFactory(CustomNode.NodeCallsControllerFunctionNode);
|
||||
|
||||
@@ -82,8 +82,8 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode {
|
||||
* @returns {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 = '';
|
||||
|
||||
|
||||
@@ -30,8 +30,12 @@ export abstract class AbstractIdentifierNamesGenerator implements IIdentifierNam
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} length
|
||||
* @returns {string}
|
||||
*/
|
||||
public abstract generate (length: number): string;
|
||||
public abstract generate (): string;
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
public abstract generateWithPrefix (): string;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,11 @@ import { Utils } from '../../utils/Utils';
|
||||
|
||||
@injectable()
|
||||
export class HexadecimalIdentifierNamesGenerator extends AbstractIdentifierNamesGenerator {
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
private static baseIdentifierNameLength: number = 6;
|
||||
|
||||
/**
|
||||
* @type {Set<string>}
|
||||
*/
|
||||
@@ -26,23 +31,31 @@ export class HexadecimalIdentifierNamesGenerator extends AbstractIdentifierNames
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} length
|
||||
* @returns {string}
|
||||
*/
|
||||
public generate (length: number): string {
|
||||
const prefix: string = `_${Utils.hexadecimalPrefix}`;
|
||||
public generate (): string {
|
||||
const rangeMinInteger: number = 10000;
|
||||
const rangeMaxInteger: number = 99999999;
|
||||
const randomInteger: number = this.randomGenerator.getRandomInteger(rangeMinInteger, rangeMaxInteger);
|
||||
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 randomVariableName;
|
||||
return identifierName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
public generateWithPrefix (): string {
|
||||
const identifierName: string = this.generate();
|
||||
|
||||
return `${this.options.identifiersPrefix}${identifierName}`.replace('__', '_');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,14 +98,25 @@ export class MangledIdentifierNamesGenerator extends AbstractIdentifierNamesGene
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} length
|
||||
* @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
@@ -1,7 +1,11 @@
|
||||
export interface IIdentifierNamesGenerator {
|
||||
/**
|
||||
* @param {number} length
|
||||
* @returns {string}
|
||||
*/
|
||||
generate (length: number): string;
|
||||
generate (): string;
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
generateWithPrefix (): string;
|
||||
}
|
||||
|
||||
+8
-2
@@ -4,8 +4,14 @@ import { IObfuscatingReplacer } from './IObfuscatingReplacer';
|
||||
|
||||
export interface IIdentifierObfuscatingReplacer extends IObfuscatingReplacer <ESTree.Identifier> {
|
||||
/**
|
||||
* @param nodeValue
|
||||
* @param {string} nodeValue
|
||||
* @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;
|
||||
}
|
||||
|
||||
Vendored
+1
@@ -15,6 +15,7 @@ export interface IOptions {
|
||||
readonly disableConsoleOutput: boolean;
|
||||
readonly domainLock: string[];
|
||||
readonly identifierNamesGenerator: IdentifierNamesGenerator;
|
||||
readonly identifiersPrefix: string;
|
||||
readonly log: boolean;
|
||||
readonly renameGlobals: boolean;
|
||||
readonly reservedNames: string[];
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import { IOptions } from './IOptions';
|
||||
|
||||
export interface IOptionsNormalizer {
|
||||
/**
|
||||
* @param {IOptions} options
|
||||
* @returns {IOptions}
|
||||
*/
|
||||
normalize (options: IOptions): IOptions;
|
||||
}
|
||||
@@ -90,7 +90,7 @@ export class CatchClauseTransformer extends AbstractNodeTransformer {
|
||||
*/
|
||||
private storeCatchClauseParam (catchClauseNode: ESTree.CatchClause, nodeIdentifier: number): void {
|
||||
if (NodeGuards.isIdentifierNode(catchClauseNode.param)) {
|
||||
this.identifierObfuscatingReplacer.storeNames(catchClauseNode.param.name, nodeIdentifier);
|
||||
this.identifierObfuscatingReplacer.storeLocalName(catchClauseNode.param.name, nodeIdentifier);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -86,14 +86,14 @@ export class ClassDeclarationTransformer extends AbstractNodeTransformer {
|
||||
*/
|
||||
public transformNode (classDeclarationNode: ESTree.ClassDeclaration, parentNode: ESTree.Node): ESTree.Node {
|
||||
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;
|
||||
}
|
||||
|
||||
this.storeClassName(classDeclarationNode, nodeIdentifier);
|
||||
this.storeClassName(classDeclarationNode, isGlobalDeclaration, nodeIdentifier);
|
||||
|
||||
// check for cached identifiers for current scope node. If exist - loop through them.
|
||||
if (this.replaceableIdentifiers.has(blockScopeNode)) {
|
||||
@@ -107,10 +107,19 @@ export class ClassDeclarationTransformer extends AbstractNodeTransformer {
|
||||
|
||||
/**
|
||||
* @param {ClassDeclaration} classDeclarationNode
|
||||
* @param {boolean} isGlobalDeclaration
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -88,14 +88,14 @@ export class FunctionDeclarationTransformer extends AbstractNodeTransformer {
|
||||
*/
|
||||
public transformNode (functionDeclarationNode: ESTree.FunctionDeclaration, parentNode: ESTree.Node): ESTree.Node {
|
||||
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;
|
||||
}
|
||||
|
||||
this.storeFunctionName(functionDeclarationNode, nodeIdentifier);
|
||||
this.storeFunctionName(functionDeclarationNode, isGlobalDeclaration, nodeIdentifier);
|
||||
|
||||
// check for cached identifiers for current scope node. If exist - loop through them.
|
||||
if (this.replaceableIdentifiers.has(blockScopeNode)) {
|
||||
@@ -109,10 +109,19 @@ export class FunctionDeclarationTransformer extends AbstractNodeTransformer {
|
||||
|
||||
/**
|
||||
* @param {FunctionDeclaration} functionDeclarationNode
|
||||
* @param {boolean} isGlobalDeclaration
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -104,13 +104,13 @@ export class FunctionTransformer extends AbstractNodeTransformer {
|
||||
estraverse.traverse(paramsNode, {
|
||||
enter: (node: ESTree.Node): any => {
|
||||
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;
|
||||
}
|
||||
|
||||
if (NodeGuards.isIdentifierNode(node)) {
|
||||
this.identifierObfuscatingReplacer.storeNames(node.name, nodeIdentifier);
|
||||
this.identifierObfuscatingReplacer.storeLocalName(node.name, nodeIdentifier);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -97,8 +97,7 @@ export class LabeledStatementTransformer extends AbstractNodeTransformer {
|
||||
* @param {number} nodeIdentifier
|
||||
*/
|
||||
private storeLabeledStatementName (labeledStatementNode: ESTree.LabeledStatement, nodeIdentifier: number): void {
|
||||
this.identifierObfuscatingReplacer
|
||||
.storeNames(labeledStatementNode.label.name, nodeIdentifier);
|
||||
this.identifierObfuscatingReplacer.storeLocalName(labeledStatementNode.label.name, nodeIdentifier);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -88,10 +88,10 @@ export class VariableDeclarationTransformer extends AbstractNodeTransformer {
|
||||
* @returns {NodeGuards}
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ export class VariableDeclarationTransformer extends AbstractNodeTransformer {
|
||||
? blockScopeNode
|
||||
: parentNode;
|
||||
|
||||
this.storeVariableNames(variableDeclarationNode, nodeIdentifier);
|
||||
this.storeVariableNames(variableDeclarationNode, isGlobalDeclaration, nodeIdentifier);
|
||||
|
||||
// check for cached identifiers for current scope node. If exist - loop through them.
|
||||
if (this.replaceableIdentifiers.has(scopeNode)) {
|
||||
@@ -114,11 +114,20 @@ export class VariableDeclarationTransformer extends AbstractNodeTransformer {
|
||||
|
||||
/**
|
||||
* @param {VariableDeclaration} variableDeclarationNode
|
||||
* @param {boolean} isGlobalDeclaration
|
||||
* @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.identifierObfuscatingReplacer.storeNames(identifierNode.name, nodeIdentifier);
|
||||
if (isGlobalDeclaration) {
|
||||
this.identifierObfuscatingReplacer.storeGlobalName(identifierNode.name, nodeIdentifier);
|
||||
} else {
|
||||
this.identifierObfuscatingReplacer.storeLocalName(identifierNode.name, nodeIdentifier);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+23
-4
@@ -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 {number} nodeIdentifier
|
||||
*/
|
||||
public storeNames (nodeName: string, nodeIdentifier: number): void {
|
||||
public storeGlobalName (nodeName: string, nodeIdentifier: number): void {
|
||||
if (this.isReservedName(nodeName)) {
|
||||
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
@@ -1,4 +1,5 @@
|
||||
import { injectable } from 'inversify';
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { ServiceIdentifiers } from '../container/ServiceIdentifiers';
|
||||
|
||||
import {
|
||||
ArrayUnique,
|
||||
@@ -20,6 +21,7 @@ import { TInputOptions } from '../types/options/TInputOptions';
|
||||
import { TStringArrayEncoding } from '../types/options/TStringArrayEncoding';
|
||||
|
||||
import { IOptions } from '../interfaces/options/IOptions';
|
||||
import { IOptionsNormalizer } from '../interfaces/options/IOptionsNormalizer';
|
||||
|
||||
import { IdentifierNamesGenerator } from '../enums/generators/identifier-names-generators/IdentifierNamesGenerator';
|
||||
import { ObfuscationTarget } from '../enums/ObfuscationTarget';
|
||||
@@ -28,7 +30,6 @@ import { StringArrayEncoding } from '../enums/StringArrayEncoding';
|
||||
|
||||
import { DEFAULT_PRESET } from './presets/Default';
|
||||
|
||||
import { OptionsNormalizer } from './OptionsNormalizer';
|
||||
import { ValidationErrorsFormatter } from './ValidationErrorsFormatter';
|
||||
|
||||
@injectable()
|
||||
@@ -111,6 +112,12 @@ export class Options implements IOptions {
|
||||
])
|
||||
public readonly identifierNamesGenerator: IdentifierNamesGenerator;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
@IsString()
|
||||
public readonly identifiersPrefix: string;
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
@@ -164,6 +171,7 @@ export class Options implements IOptions {
|
||||
@ValidateIf((options: IOptions) => Boolean(options.sourceMapBaseUrl))
|
||||
@IsUrl({
|
||||
require_protocol: true,
|
||||
require_tld: false,
|
||||
require_valid_protocol: true
|
||||
})
|
||||
public readonly sourceMapBaseUrl: string;
|
||||
@@ -220,8 +228,12 @@ export class Options implements IOptions {
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
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)}`);
|
||||
}
|
||||
|
||||
Object.assign(this, OptionsNormalizer.normalizeOptions(this));
|
||||
Object.assign(this, optionsNormalizer.normalize(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { injectable } from 'inversify';
|
||||
|
||||
import { TOptionsNormalizerRule } from '../types/options/TOptionsNormalizerRule';
|
||||
|
||||
import { IOptions } from '../interfaces/options/IOptions';
|
||||
import { IOptionsNormalizer } from '../interfaces/options/IOptionsNormalizer';
|
||||
|
||||
import { ControlFlowFlatteningThresholdRule } from './normalizer-rules/ControlFlowFlatteningThresholdRule';
|
||||
import { DeadCodeInjectionRule } from './normalizer-rules/DeadCodeInjectionRule';
|
||||
@@ -13,7 +16,8 @@ import { StringArrayRule } from './normalizer-rules/StringArrayRule';
|
||||
import { StringArrayEncodingRule } from './normalizer-rules/StringArrayEncodingRule';
|
||||
import { StringArrayThresholdRule } from './normalizer-rules/StringArrayThresholdRule';
|
||||
|
||||
export class OptionsNormalizer {
|
||||
@injectable()
|
||||
export class OptionsNormalizer implements IOptionsNormalizer {
|
||||
/**
|
||||
* @type {TOptionsNormalizerRule[]}
|
||||
*/
|
||||
@@ -34,7 +38,7 @@ export class OptionsNormalizer {
|
||||
* @param {IOptions} options
|
||||
* @returns {IOptions}
|
||||
*/
|
||||
public static normalizeOptions (options: IOptions): IOptions {
|
||||
public normalize (options: IOptions): IOptions {
|
||||
let normalizedOptions: IOptions = {
|
||||
...options
|
||||
};
|
||||
|
||||
@@ -16,6 +16,7 @@ export const DEFAULT_PRESET: TInputOptions = Object.freeze({
|
||||
disableConsoleOutput: false,
|
||||
domainLock: [],
|
||||
identifierNamesGenerator: IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator,
|
||||
identifiersPrefix: '',
|
||||
log: false,
|
||||
renameGlobals: false,
|
||||
reservedNames: [],
|
||||
|
||||
@@ -15,6 +15,7 @@ export const NO_ADDITIONAL_NODES_PRESET: TInputOptions = Object.freeze({
|
||||
disableConsoleOutput: false,
|
||||
domainLock: [],
|
||||
identifierNamesGenerator: IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator,
|
||||
identifiersPrefix: '',
|
||||
log: false,
|
||||
renameGlobals: false,
|
||||
reservedNames: [],
|
||||
|
||||
@@ -12,6 +12,11 @@ import { ArrayStorage } from '../ArrayStorage';
|
||||
|
||||
@injectable()
|
||||
export class StringArrayStorage extends ArrayStorage <string> {
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
private static readonly stringArrayNameLength: number = 7;
|
||||
|
||||
/**
|
||||
* @type {IArrayUtils}
|
||||
*/
|
||||
@@ -45,8 +50,14 @@ export class StringArrayStorage extends ArrayStorage <string> {
|
||||
public initialize (): void {
|
||||
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}`;
|
||||
}
|
||||
|
||||
+7
-6
@@ -6,17 +6,18 @@ import { NO_ADDITIONAL_NODES_PRESET } from '../../src/options/presets/NoCustomNo
|
||||
|
||||
let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
|
||||
`
|
||||
var bar = 1;
|
||||
var baz = 2;
|
||||
(function(){
|
||||
function foo () {
|
||||
eval('var s = 1;');
|
||||
}
|
||||
|
||||
foo();
|
||||
var bark = bar + baz;
|
||||
})();
|
||||
`,
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
compact: false
|
||||
compact: false,
|
||||
identifiersPrefix: 'foo',
|
||||
identifierNamesGenerator: 'mangled',
|
||||
renameGlobals: true
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
|
||||
|
||||
@@ -134,13 +134,18 @@ describe('JavaScriptObfuscatorCLI', function (): void {
|
||||
const outputFileName1: string = 'foo-obfuscated.js';
|
||||
const outputFileName2: string = 'bar-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,
|
||||
outputFixturesFilePath2: string,
|
||||
outputFixturesFilePath3: string,
|
||||
isFileExist1: boolean,
|
||||
isFileExist2: boolean,
|
||||
isFileExist3: boolean;
|
||||
isFileExist3: boolean,
|
||||
fileContent1: string,
|
||||
fileContent2: string;
|
||||
|
||||
before(() => {
|
||||
outputFixturesFilePath1 = `${directoryPath}/${outputFileName1}`;
|
||||
@@ -150,12 +155,17 @@ describe('JavaScriptObfuscatorCLI', function (): void {
|
||||
JavaScriptObfuscator.runCLI([
|
||||
'node',
|
||||
'javascript-obfuscator',
|
||||
directoryPath
|
||||
directoryPath,
|
||||
'--rename-globals',
|
||||
'true'
|
||||
]);
|
||||
|
||||
isFileExist1 = fs.existsSync(outputFixturesFilePath1);
|
||||
isFileExist2 = fs.existsSync(outputFixturesFilePath2);
|
||||
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`, () => {
|
||||
@@ -170,13 +180,80 @@ describe('JavaScriptObfuscatorCLI', function (): void {
|
||||
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 `output` option', () => {
|
||||
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(() => {
|
||||
rimraf.sync(outputFixturesFilePath1);
|
||||
rimraf.sync(outputFixturesFilePath2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #4: obfuscation of directory with `output` option', () => {
|
||||
const directoryPath: string = `${fixturesDirName}/directory-obfuscation`;
|
||||
const outputDirectoryName: string = 'obfuscated';
|
||||
const outputDirectoryPath: string = `${directoryPath}/${outputDirectoryName}`;
|
||||
|
||||
@@ -186,28 +186,108 @@ describe('JavaScriptObfuscator', () => {
|
||||
});
|
||||
|
||||
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+; *\}(\(\)\)|\)\(\));?$/;
|
||||
|
||||
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', () => {
|
||||
const stringArrayLatinRegExp: RegExp = /^var _0x(\w){4} *= *\['abc'\];/;
|
||||
const stringArrayCallRegExp: RegExp = /var *test *= *_0x(\w){4}\('0x0'\);$/;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
var foo = 1;
|
||||
var bar = 2;
|
||||
var baz = function () {
|
||||
var bark = foo + bar;
|
||||
|
||||
return bark;
|
||||
};
|
||||
+17
-5
@@ -1,28 +1,40 @@
|
||||
import 'reflect-metadata';
|
||||
|
||||
import { ServiceIdentifiers } from '../../../src/container/ServiceIdentifiers';
|
||||
|
||||
import { assert } from 'chai';
|
||||
|
||||
import { TInputOptions } from '../../../src/types/options/TInputOptions';
|
||||
|
||||
import { IInversifyContainerFacade } from '../../../src/interfaces/container/IInversifyContainerFacade';
|
||||
import { IOptions } from '../../../src/interfaces/options/IOptions';
|
||||
import { IOptionsNormalizer } from '../../../src/interfaces/options/IOptionsNormalizer';
|
||||
|
||||
import { StringArrayEncoding } from '../../../src/enums/StringArrayEncoding';
|
||||
|
||||
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
|
||||
* @returns {IOptions}
|
||||
*/
|
||||
function getNormalizedOptions (optionsPreset: TInputOptions): TInputOptions {
|
||||
const options: IOptions = new Options(optionsPreset);
|
||||
const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
|
||||
|
||||
return OptionsNormalizer.normalizeOptions(options);
|
||||
inversifyContainerFacade.load('', optionsPreset);
|
||||
|
||||
const options: IOptions = inversifyContainerFacade
|
||||
.get<IOptions>(ServiceIdentifiers.IOptions);
|
||||
const optionsNormalizer: IOptionsNormalizer = inversifyContainerFacade
|
||||
.get<IOptionsNormalizer>(ServiceIdentifiers.IOptionsNormalizer);
|
||||
|
||||
return optionsNormalizer.normalize(options);
|
||||
}
|
||||
|
||||
describe('OptionsNormalizer', () => {
|
||||
describe('normalizeOptions (options: IObfuscatorOptions): IObfuscatorOptions', () => {
|
||||
describe('normalize (options: IObfuscatorOptions): IObfuscatorOptions', () => {
|
||||
let optionsPreset: TInputOptions,
|
||||
expectedOptionsPreset: TInputOptions;
|
||||
|
||||
+1
-1
@@ -24,7 +24,6 @@ import './unit-tests/node/node-guards/NodeGuards.spec';
|
||||
import './unit-tests/node/node-utils/NodeUtils.spec';
|
||||
import './unit-tests/node-transformers/preparing-transformers/ObfuscatingGuardsTransformer.spec';
|
||||
import './unit-tests/obfuscation-result/ObfuscationResult.spec';
|
||||
import './unit-tests/options/OptionsNormalizer.spec';
|
||||
import './unit-tests/options/ValidationErrorsFormatter.spec';
|
||||
import './unit-tests/source-map/SourceMapCorrector.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/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/options/OptionsNormalizer.spec';
|
||||
import './functional-tests/templates/debug-protection-nodes/DebugProtectionFunctionCallTemplate.spec';
|
||||
import './functional-tests/templates/domain-lock-nodes/DomainLockNodeTemplate.spec';
|
||||
import './functional-tests/templates/GlobalVariableNoEvalTemplate.spec';
|
||||
|
||||
+29
-19
@@ -12,7 +12,7 @@ import { IdentifierNamesGenerator } from '../../../../src/enums/generators/ident
|
||||
import { InversifyContainerFacade } from '../../../../src/container/InversifyContainerFacade';
|
||||
|
||||
describe('HexadecimalIdentifierNamesGenerator', () => {
|
||||
describe('generate (length: number): string', () => {
|
||||
describe('generate (): string', () => {
|
||||
let identifierNamesGenerator: IIdentifierNamesGenerator,
|
||||
hexadecimalIdentifierName: string,
|
||||
regExp: RegExp;
|
||||
@@ -24,29 +24,39 @@ describe('HexadecimalIdentifierNamesGenerator', () => {
|
||||
identifierNamesGenerator = inversifyContainerFacade.getNamed<IIdentifierNamesGenerator>(
|
||||
ServiceIdentifiers.IIdentifierNamesGenerator,
|
||||
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);
|
||||
})
|
||||
});
|
||||
|
||||
describe('generateWithPrefix (): string', () => {
|
||||
const regExp: RegExp = /^foo_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();
|
||||
});
|
||||
|
||||
describe('variant #2: hexadecimal name with length `6`', () => {
|
||||
before(() => {
|
||||
hexadecimalIdentifierName = identifierNamesGenerator.generate(6);
|
||||
regExp = /^_0x(\w){4,6}$/;
|
||||
});
|
||||
|
||||
it('should return hexadecimal name', () => {
|
||||
assert.match(hexadecimalIdentifierName, regExp);
|
||||
})
|
||||
});
|
||||
it('should return hexadecimal name with prefix', () => {
|
||||
assert.match(hexadecimalIdentifierName, regExp);
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
+48
-7
@@ -12,7 +12,7 @@ import { IdentifierNamesGenerator } from '../../../../src/enums/generators/ident
|
||||
import { InversifyContainerFacade } from '../../../../src/container/InversifyContainerFacade';
|
||||
|
||||
describe('MangledIdentifierNamesGenerator', () => {
|
||||
describe('generate (length: number): string', () => {
|
||||
describe('generate (): string', () => {
|
||||
let identifierNamesGenerator: IIdentifierNamesGenerator,
|
||||
mangledIdentifierName: string;
|
||||
|
||||
@@ -30,7 +30,7 @@ describe('MangledIdentifierNamesGenerator', () => {
|
||||
const expectedMangledIdentifierName: string = 'a';
|
||||
|
||||
beforeEach(() => {
|
||||
mangledIdentifierName = identifierNamesGenerator.generate(4);
|
||||
mangledIdentifierName = identifierNamesGenerator.generate();
|
||||
});
|
||||
|
||||
it('should return mangled name', () => {
|
||||
@@ -44,7 +44,7 @@ describe('MangledIdentifierNamesGenerator', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
for (let i: number = 0; i <= expectedMangledIdentifierPosition; i++) {
|
||||
mangledIdentifierName = identifierNamesGenerator.generate(6);
|
||||
mangledIdentifierName = identifierNamesGenerator.generate();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -59,7 +59,7 @@ describe('MangledIdentifierNamesGenerator', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
for (let i: number = 0; i <= expectedMangledIdentifierPosition; i++) {
|
||||
mangledIdentifierName = identifierNamesGenerator.generate(6);
|
||||
mangledIdentifierName = identifierNamesGenerator.generate();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -74,7 +74,7 @@ describe('MangledIdentifierNamesGenerator', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
for (let i: number = 0; i <= expectedMangledIdentifierPosition; i++) {
|
||||
mangledIdentifierName = identifierNamesGenerator.generate(6);
|
||||
mangledIdentifierName = identifierNamesGenerator.generate();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -89,7 +89,7 @@ describe('MangledIdentifierNamesGenerator', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
for (let i: number = 0; i <= expectedMangledIdentifierPosition; i++) {
|
||||
mangledIdentifierName = identifierNamesGenerator.generate(6);
|
||||
mangledIdentifierName = identifierNamesGenerator.generate();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -109,7 +109,7 @@ describe('MangledIdentifierNamesGenerator', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
for (let i: number = 0; i <= expectedMangledIdentifierPosition2; i++) {
|
||||
mangledIdentifierName = identifierNamesGenerator.generate(6);
|
||||
mangledIdentifierName = identifierNamesGenerator.generate();
|
||||
|
||||
if (i === expectedMangledIdentifierPosition1) {
|
||||
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);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@types/chai@4.1.0":
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.0.tgz#d9008fa4c06f6801f93396d121f0227cd4244ac6"
|
||||
"@types/chai@4.1.2":
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.2.tgz#f1af664769cfb50af805431c407425ed619daa21"
|
||||
|
||||
"@types/chance@0.7.36":
|
||||
version "0.7.36"
|
||||
@@ -58,9 +58,9 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/mocha@2.2.46":
|
||||
version "2.2.46"
|
||||
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.46.tgz#b04713f7759d1cf752effdaae7b3969e285ebc16"
|
||||
"@types/mocha@2.2.47":
|
||||
version "2.2.47"
|
||||
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.47.tgz#30bbd880834d4af0f609025f282a69b8d4458f06"
|
||||
|
||||
"@types/node@*":
|
||||
version "8.0.53"
|
||||
@@ -1016,11 +1016,11 @@ class-utils@^0.3.5:
|
||||
lazy-cache "^2.0.2"
|
||||
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:
|
||||
validator "^7.0.0"
|
||||
validator "9.2.0"
|
||||
|
||||
cli-cursor@^2.1.0:
|
||||
version "2.1.0"
|
||||
@@ -1446,9 +1446,9 @@ escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
|
||||
escodegen-wallaby@1.6.16:
|
||||
version "1.6.16"
|
||||
resolved "https://registry.yarnpkg.com/escodegen-wallaby/-/escodegen-wallaby-1.6.16.tgz#f55b65d1a846d98584f1be18a2bf463f96280527"
|
||||
escodegen-wallaby@1.6.17:
|
||||
version "1.6.17"
|
||||
resolved "https://registry.yarnpkg.com/escodegen-wallaby/-/escodegen-wallaby-1.6.17.tgz#3e1f334884d4214c94309cf734ec7cfa0b3d438d"
|
||||
dependencies:
|
||||
esprima "^2.7.1"
|
||||
estraverse "^1.9.1"
|
||||
@@ -2566,9 +2566,9 @@ mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.1, mkdirp@~0.5.0:
|
||||
dependencies:
|
||||
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:
|
||||
browser-stdout "1.3.0"
|
||||
commander "2.11.0"
|
||||
@@ -3107,9 +3107,9 @@ readdirp@^2.0.0:
|
||||
readable-stream "^2.0.2"
|
||||
set-immediate-shim "^1.0.1"
|
||||
|
||||
reflect-metadata@0.1.10:
|
||||
version "0.1.10"
|
||||
resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.10.tgz#b4f83704416acad89988c9b15635d47e03b9344a"
|
||||
reflect-metadata@0.1.12:
|
||||
version "0.1.12"
|
||||
resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.12.tgz#311bf0c6b63cd782f228a81abe146a2bfa9c56f2"
|
||||
|
||||
regenerate@^1.2.1:
|
||||
version "1.3.3"
|
||||
@@ -3329,16 +3329,16 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
|
||||
version "3.0.2"
|
||||
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:
|
||||
diff "^3.1.0"
|
||||
formatio "1.2.0"
|
||||
lodash.get "^4.4.2"
|
||||
lolex "^2.2.0"
|
||||
nise "^1.2.0"
|
||||
supports-color "^4.4.0"
|
||||
supports-color "^5.1.0"
|
||||
type-detect "^4.0.5"
|
||||
|
||||
slash@^1.0.0:
|
||||
@@ -3392,9 +3392,9 @@ source-map-resolve@^0.5.0:
|
||||
source-map-url "^0.4.0"
|
||||
urix "^0.1.0"
|
||||
|
||||
source-map-support@0.5.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"
|
||||
source-map-support@0.5.2:
|
||||
version "0.5.2"
|
||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.2.tgz#1a6297fd5b2e762b39688c7fc91233b60984f0a5"
|
||||
dependencies:
|
||||
source-map "^0.6.0"
|
||||
|
||||
@@ -3404,6 +3404,12 @@ source-map-support@^0.4.15:
|
||||
dependencies:
|
||||
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:
|
||||
version "0.4.0"
|
||||
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:
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b"
|
||||
dependencies:
|
||||
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:
|
||||
version "0.2.8"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19"
|
||||
|
||||
threads@0.10.0:
|
||||
version "0.10.0"
|
||||
resolved "https://registry.yarnpkg.com/threads/-/threads-0.10.0.tgz#a6b0bc5d916fa75434b166c612769684b65fead5"
|
||||
threads@0.10.1:
|
||||
version "0.10.1"
|
||||
resolved "https://registry.yarnpkg.com/threads/-/threads-0.10.1.tgz#637765dc434ab3373d3c14754c8f7ac6515d6815"
|
||||
dependencies:
|
||||
eventemitter3 "^2.0.2"
|
||||
native-promise-only "^0.8.1"
|
||||
@@ -3697,7 +3709,11 @@ tsconfig@^7.0.0:
|
||||
strip-bom "^3.0.0"
|
||||
strip-json-comments "^2.0.0"
|
||||
|
||||
tslib@1.8.1, tslib@^1.0.0, tslib@^1.7.1, tslib@^1.8.0:
|
||||
tslib@1.9.0:
|
||||
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"
|
||||
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-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"
|
||||
|
||||
verror@1.10.0:
|
||||
version "1.10.0"
|
||||
|
||||
Reference in New Issue
Block a user