234 lines
10 KiB
TypeScript
234 lines
10 KiB
TypeScript
import { Container, interfaces } from 'inversify';
|
|
import { ServiceIdentifiers } from './ServiceIdentifiers';
|
|
|
|
import { analyzersModule } from './modules/analyzers/AnalyzersModule';
|
|
import { codeTransformersModule } from './modules/code-transformers/CodeTransformersModule';
|
|
import { controlFlowTransformersModule } from './modules/node-transformers/ControlFlowTransformersModule';
|
|
import { convertingTransformersModule } from './modules/node-transformers/ConvertingTransformersModule';
|
|
import { customCodeHelpersModule } from './modules/custom-code-helpers/CustomCodeHelpersModule';
|
|
import { customNodesModule } from './modules/custom-nodes/CustomNodesModule';
|
|
import { deadCodeInjectionTransformersModule } from './modules/node-transformers/DeadCodeInjectionTransformersModule';
|
|
import { finalizingTransformersModule } from './modules/node-transformers/FinalizingTransformersModule';
|
|
import { generatorsModule } from './modules/generators/GeneratorsModule';
|
|
import { initializingTransformersModule } from './modules/node-transformers/InitializingTransformersModule';
|
|
import { nodeModule } from './modules/node/NodeModule';
|
|
import { nodeTransformersModule } from './modules/node-transformers/NodeTransformersModule';
|
|
import { optionsModule } from './modules/options/OptionsModule';
|
|
import { preparingTransformersModule } from './modules/node-transformers/PreparingTransformersModule';
|
|
import { renameIdentifiersTransformersModule } from './modules/node-transformers/RenameIdentifiersTransformersModule';
|
|
import { renamePropertiesTransformersModule } from './modules/node-transformers/RenamePropertiesTransformersModule';
|
|
import { simplifyingTransformersModule } from './modules/node-transformers/SimplifyingTransformersModule';
|
|
import { storagesModule } from './modules/storages/StoragesModule';
|
|
import { stringArrayTransformersModule } from './modules/node-transformers/StringArrayTransformersModule';
|
|
import { utilsModule } from './modules/utils/UtilsModule';
|
|
|
|
import { TInputOptions } from '../types/options/TInputOptions';
|
|
|
|
import { ICodeTransformersRunner } from '../interfaces/code-transformers/ICodeTransformersRunner';
|
|
import { IInversifyContainerFacade } from '../interfaces/container/IInversifyContainerFacade';
|
|
import { IJavaScriptObfuscator } from '../interfaces/IJavaScriptObfsucator';
|
|
import { ILogger } from '../interfaces/logger/ILogger';
|
|
import { IObfuscationEventEmitter } from '../interfaces/event-emitters/IObfuscationEventEmitter';
|
|
import { IObfuscatedCode } from '../interfaces/source-code/IObfuscatedCode';
|
|
import { ISourceCode } from '../interfaces/source-code/ISourceCode';
|
|
import { INodeTransformersRunner } from '../interfaces/node-transformers/INodeTransformersRunner';
|
|
|
|
import { CodeTransformersRunner } from '../code-transformers/CodeTransformersRunner';
|
|
import { JavaScriptObfuscator } from '../JavaScriptObfuscator';
|
|
import { Logger } from '../logger/Logger';
|
|
import { NodeTransformersRunner } from '../node-transformers/NodeTransformersRunner';
|
|
import { ObfuscationEventEmitter } from '../event-emitters/ObfuscationEventEmitter';
|
|
import { ObfuscatedCode } from '../source-code/ObfuscatedCode';
|
|
import { SourceCode } from '../source-code/SourceCode';
|
|
|
|
export class InversifyContainerFacade implements IInversifyContainerFacade {
|
|
/**
|
|
* @type {interfaces.Container}
|
|
*/
|
|
private readonly container: interfaces.Container;
|
|
|
|
public constructor () {
|
|
this.container = new Container();
|
|
}
|
|
|
|
/**
|
|
* @param {interfaces.ServiceIdentifier<U>} serviceIdentifier
|
|
* @returns {U}
|
|
*/
|
|
public static getFactory <T extends string, U> (
|
|
serviceIdentifier: interfaces.ServiceIdentifier<U>
|
|
): (context: interfaces.Context) => (bindingName: T) => U {
|
|
return (context: interfaces.Context): (bindingName: T) => U => {
|
|
return (bindingName: T): U => {
|
|
return context.container.getNamed<U>(serviceIdentifier, bindingName);
|
|
};
|
|
};
|
|
}
|
|
|
|
/**
|
|
* @param {interfaces.ServiceIdentifier<U>} serviceIdentifier
|
|
* @returns {U}
|
|
*/
|
|
public static getCacheFactory <T extends string, U> (
|
|
serviceIdentifier: interfaces.ServiceIdentifier<U>
|
|
): (context: interfaces.Context) => (bindingName: T) => U {
|
|
return (context: interfaces.Context): (bindingName: T) => U => {
|
|
const cache: Map <T, U> = new Map();
|
|
|
|
return (bindingName: T): U => {
|
|
if (cache.has(bindingName)) {
|
|
return <U>cache.get(bindingName);
|
|
}
|
|
|
|
const object: U = context.container.getNamed<U>(serviceIdentifier, bindingName);
|
|
|
|
cache.set(bindingName, object);
|
|
|
|
return object;
|
|
};
|
|
};
|
|
}
|
|
|
|
/**
|
|
* @param {interfaces.ServiceIdentifier<interfaces.Newable<U>>} serviceIdentifier
|
|
* @param {interfaces.ServiceIdentifier<interfaces.Newable<Object>>[]} dependencies
|
|
* @returns {U}
|
|
*/
|
|
public static getConstructorFactory <T extends string, U> (
|
|
serviceIdentifier: interfaces.ServiceIdentifier<interfaces.Newable<U>>,
|
|
...dependencies: interfaces.ServiceIdentifier<interfaces.Newable<Record<string, any>>>[]
|
|
): (context: interfaces.Context) => (bindingName: T) => U {
|
|
return (context: interfaces.Context): (bindingName: T) => U => {
|
|
const cache: Map<T, interfaces.Newable<U>> = new Map();
|
|
const cachedDependencies: Record<string, any>[] = [];
|
|
|
|
return (bindingName: T): U => {
|
|
dependencies.forEach((
|
|
dependency: interfaces.ServiceIdentifier<interfaces.Newable<Record<string, any>>>,
|
|
index: number
|
|
) => {
|
|
if (!cachedDependencies[index]) {
|
|
cachedDependencies[index] = context.container.get(dependency);
|
|
}
|
|
});
|
|
|
|
if (cache.has(bindingName)) {
|
|
return new (<interfaces.Newable<U>>cache.get(bindingName))(...cachedDependencies);
|
|
}
|
|
|
|
const constructor: interfaces.Newable<U> = context.container
|
|
.getNamed<interfaces.Newable<U>>(
|
|
serviceIdentifier,
|
|
bindingName
|
|
);
|
|
|
|
cache.set(bindingName, constructor);
|
|
|
|
return new constructor(...cachedDependencies);
|
|
};
|
|
};
|
|
}
|
|
|
|
/**
|
|
* @param {interfaces.ServiceIdentifier<T>} serviceIdentifier
|
|
* @returns {T}
|
|
*/
|
|
public get <T> (serviceIdentifier: interfaces.ServiceIdentifier<T>): T {
|
|
return this.container.get<T>(serviceIdentifier);
|
|
}
|
|
|
|
/**
|
|
* @param {interfaces.ServiceIdentifier<T>} serviceIdentifier
|
|
* @param {string | number | symbol} named
|
|
* @returns {T}
|
|
*/
|
|
public getNamed <T> (serviceIdentifier: interfaces.ServiceIdentifier<T>, named: string | number | symbol): T {
|
|
return this.container.getNamed<T>(serviceIdentifier, named);
|
|
}
|
|
|
|
/**
|
|
* @param {string} sourceCode
|
|
* @param {string} sourceMap
|
|
* @param {TInputOptions} options
|
|
*/
|
|
public load (sourceCode: string, sourceMap: string, options: TInputOptions): void {
|
|
this.container
|
|
.bind<ISourceCode>(ServiceIdentifiers.ISourceCode)
|
|
.toDynamicValue(() => new SourceCode(sourceCode, sourceMap))
|
|
.inSingletonScope();
|
|
|
|
this.container
|
|
.bind<TInputOptions>(ServiceIdentifiers.TInputOptions)
|
|
.toDynamicValue(() => options)
|
|
.inSingletonScope();
|
|
|
|
this.container
|
|
.bind<ILogger>(ServiceIdentifiers.ILogger)
|
|
.to(Logger)
|
|
.inSingletonScope();
|
|
|
|
this.container
|
|
.bind<IJavaScriptObfuscator>(ServiceIdentifiers.IJavaScriptObfuscator)
|
|
.to(JavaScriptObfuscator)
|
|
.inSingletonScope();
|
|
|
|
this.container
|
|
.bind<ICodeTransformersRunner>(ServiceIdentifiers.ICodeTransformersRunner)
|
|
.to(CodeTransformersRunner)
|
|
.inSingletonScope();
|
|
|
|
this.container
|
|
.bind<INodeTransformersRunner>(ServiceIdentifiers.INodeTransformersRunner)
|
|
.to(NodeTransformersRunner)
|
|
.inSingletonScope();
|
|
|
|
this.container
|
|
.bind<IObfuscatedCode>(ServiceIdentifiers.IObfuscatedCode)
|
|
.to(ObfuscatedCode);
|
|
|
|
this.container
|
|
.bind<IObfuscatedCode>(ServiceIdentifiers.Factory__IObfuscatedCode)
|
|
.toFactory<IObfuscatedCode>((context: interfaces.Context) => {
|
|
return (obfuscatedCodeAsString: string, sourceMapAsString: string): IObfuscatedCode => {
|
|
const obfuscatedCode: IObfuscatedCode = context.container
|
|
.get<IObfuscatedCode>(ServiceIdentifiers.IObfuscatedCode);
|
|
|
|
obfuscatedCode.initialize(obfuscatedCodeAsString, sourceMapAsString);
|
|
|
|
return obfuscatedCode;
|
|
};
|
|
});
|
|
|
|
this.container
|
|
.bind<IObfuscationEventEmitter>(ServiceIdentifiers.IObfuscationEventEmitter)
|
|
.to(ObfuscationEventEmitter)
|
|
.inSingletonScope();
|
|
|
|
// modules
|
|
this.container.load(analyzersModule);
|
|
this.container.load(codeTransformersModule);
|
|
this.container.load(controlFlowTransformersModule);
|
|
this.container.load(convertingTransformersModule);
|
|
this.container.load(customCodeHelpersModule);
|
|
this.container.load(customNodesModule);
|
|
this.container.load(deadCodeInjectionTransformersModule);
|
|
this.container.load(finalizingTransformersModule);
|
|
this.container.load(generatorsModule);
|
|
this.container.load(initializingTransformersModule);
|
|
this.container.load(nodeModule);
|
|
this.container.load(nodeTransformersModule);
|
|
this.container.load(optionsModule);
|
|
this.container.load(preparingTransformersModule);
|
|
this.container.load(renameIdentifiersTransformersModule);
|
|
this.container.load(renamePropertiesTransformersModule);
|
|
this.container.load(simplifyingTransformersModule);
|
|
this.container.load(storagesModule);
|
|
this.container.load(stringArrayTransformersModule);
|
|
this.container.load(utilsModule);
|
|
}
|
|
|
|
public unload (): void {
|
|
this.container.unbindAll();
|
|
}
|
|
}
|