InversifyContainerFacade.ts 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. import { Container, interfaces } from 'inversify';
  2. import { ServiceIdentifiers } from './ServiceIdentifiers';
  3. import { analyzersModule } from './modules/analyzers/AnalyzersModule';
  4. import { controlFlowTransformersModule } from './modules/node-transformers/ControlFlowTransformersModule';
  5. import { convertingTransformersModule } from './modules/node-transformers/ConvertingTransformersModule';
  6. import { customNodesModule } from './modules/custom-nodes/CustomNodesModule';
  7. import { finalizingTransformersModule } from './modules/node-transformers/FinalizingTransformersModule';
  8. import { generatorsModule } from './modules/generators/GeneratorsModule';
  9. import { nodeTransformersModule } from './modules/node-transformers/NodeTransformersModule';
  10. import { obfuscatingTransformersModule } from './modules/node-transformers/ObfuscatingTransformersModule';
  11. import { optionsModule } from './modules/options/OptionsModule';
  12. import { preparingTransformersModule } from './modules/node-transformers/PreparingTransformersModule';
  13. import { storagesModule } from './modules/storages/StoragesModule';
  14. import { utilsModule } from './modules/utils/UtilsModule';
  15. import { TInputOptions } from '../types/options/TInputOptions';
  16. import { IInversifyContainerFacade } from '../interfaces/container/IInversifyContainerFacade';
  17. import { IJavaScriptObfuscator } from '../interfaces/IJavaScriptObfsucator';
  18. import { ILogger } from '../interfaces/logger/ILogger';
  19. import { IObfuscationEventEmitter } from '../interfaces/event-emitters/IObfuscationEventEmitter';
  20. import { IObfuscatedCode } from '../interfaces/source-code/IObfuscatedCode';
  21. import { ISourceCode } from '../interfaces/source-code/ISourceCode';
  22. import { ITransformersRunner } from '../interfaces/node-transformers/ITransformersRunner';
  23. import { JavaScriptObfuscator } from '../JavaScriptObfuscator';
  24. import { Logger } from '../logger/Logger';
  25. import { ObfuscationEventEmitter } from '../event-emitters/ObfuscationEventEmitter';
  26. import { ObfuscatedCode } from '../source-code/ObfuscatedCode';
  27. import { SourceCode } from '../source-code/SourceCode';
  28. import { TransformersRunner } from '../node-transformers/TransformersRunner';
  29. export class InversifyContainerFacade implements IInversifyContainerFacade {
  30. /**
  31. * @type {interfaces.Container}
  32. */
  33. private readonly container: interfaces.Container;
  34. public constructor () {
  35. this.container = new Container();
  36. }
  37. /**
  38. * @param {interfaces.ServiceIdentifier<U>} serviceIdentifier
  39. * @returns {U}
  40. */
  41. public static getFactory <T extends string, U> (
  42. serviceIdentifier: interfaces.ServiceIdentifier<U>
  43. ): (context: interfaces.Context) => (bindingName: T) => U {
  44. return (context: interfaces.Context): (bindingName: T) => U => {
  45. return (bindingName: T): U => {
  46. return context.container.getNamed<U>(serviceIdentifier, bindingName);
  47. };
  48. };
  49. }
  50. /**
  51. * @param {interfaces.ServiceIdentifier<U>} serviceIdentifier
  52. * @returns {U}
  53. */
  54. public static getCacheFactory <T extends string, U> (
  55. serviceIdentifier: interfaces.ServiceIdentifier<U>
  56. ): (context: interfaces.Context) => (bindingName: T) => U {
  57. return (context: interfaces.Context): (bindingName: T) => U => {
  58. const cache: Map <T, U> = new Map();
  59. return (bindingName: T): U => {
  60. if (cache.has(bindingName)) {
  61. return <U>cache.get(bindingName);
  62. }
  63. const object: U = context.container.getNamed<U>(serviceIdentifier, bindingName);
  64. cache.set(bindingName, object);
  65. return object;
  66. };
  67. };
  68. }
  69. /**
  70. * @param {interfaces.ServiceIdentifier<interfaces.Newable<U>>} serviceIdentifier
  71. * @param {interfaces.ServiceIdentifier<interfaces.Newable<Object>>[]} dependencies
  72. * @returns {U}
  73. */
  74. public static getConstructorFactory <T extends string, U> (
  75. serviceIdentifier: interfaces.ServiceIdentifier<interfaces.Newable<U>>,
  76. ...dependencies: interfaces.ServiceIdentifier<interfaces.Newable<Record<string, any>>>[]
  77. ): (context: interfaces.Context) => (bindingName: T) => U {
  78. return (context: interfaces.Context): (bindingName: T) => U => {
  79. const cache: Map<T, interfaces.Newable<U>> = new Map();
  80. const cachedDependencies: Record<string, any>[] = [];
  81. return (bindingName: T): U => {
  82. dependencies.forEach((
  83. dependency: interfaces.ServiceIdentifier<interfaces.Newable<Record<string, any>>>,
  84. index: number
  85. ) => {
  86. if (!cachedDependencies[index]) {
  87. cachedDependencies[index] = context.container.get(dependency);
  88. }
  89. });
  90. if (cache.has(bindingName)) {
  91. return new (<interfaces.Newable<U>>cache.get(bindingName))(...cachedDependencies);
  92. }
  93. const constructor: interfaces.Newable<U> = context.container
  94. .getNamed<interfaces.Newable<U>>(
  95. serviceIdentifier,
  96. bindingName
  97. );
  98. cache.set(bindingName, constructor);
  99. return new constructor(...cachedDependencies);
  100. };
  101. };
  102. }
  103. /**
  104. * @param {interfaces.ServiceIdentifier<T>} serviceIdentifier
  105. * @returns {T}
  106. */
  107. public get <T> (serviceIdentifier: interfaces.ServiceIdentifier<T>): T {
  108. return this.container.get<T>(serviceIdentifier);
  109. }
  110. /**
  111. * @param {interfaces.ServiceIdentifier<T>} serviceIdentifier
  112. * @param {string | number | symbol} named
  113. * @returns {T}
  114. */
  115. public getNamed <T> (serviceIdentifier: interfaces.ServiceIdentifier<T>, named: string | number | symbol): T {
  116. return this.container.getNamed<T>(serviceIdentifier, named);
  117. }
  118. /**
  119. * @param {string} sourceCode
  120. * @param {string} sourceMap
  121. * @param {TInputOptions} options
  122. */
  123. public load (sourceCode: string, sourceMap: string, options: TInputOptions): void {
  124. this.container
  125. .bind<ISourceCode>(ServiceIdentifiers.ISourceCode)
  126. .toDynamicValue(() => new SourceCode(sourceCode, sourceMap))
  127. .inSingletonScope();
  128. this.container
  129. .bind<TInputOptions>(ServiceIdentifiers.TInputOptions)
  130. .toDynamicValue(() => options)
  131. .inSingletonScope();
  132. this.container
  133. .bind<ILogger>(ServiceIdentifiers.ILogger)
  134. .to(Logger)
  135. .inSingletonScope();
  136. this.container
  137. .bind<IJavaScriptObfuscator>(ServiceIdentifiers.IJavaScriptObfuscator)
  138. .to(JavaScriptObfuscator)
  139. .inSingletonScope();
  140. this.container
  141. .bind<ITransformersRunner>(ServiceIdentifiers.ITransformersRunner)
  142. .to(TransformersRunner)
  143. .inSingletonScope();
  144. this.container
  145. .bind<IObfuscatedCode>(ServiceIdentifiers.IObfuscatedCode)
  146. .to(ObfuscatedCode);
  147. this.container
  148. .bind<IObfuscatedCode>(ServiceIdentifiers.Factory__IObfuscatedCode)
  149. .toFactory<IObfuscatedCode>((context: interfaces.Context) => {
  150. return (obfuscatedCodeAsString: string, sourceMapAsString: string): IObfuscatedCode => {
  151. const obfuscatedCode: IObfuscatedCode = context.container
  152. .get<IObfuscatedCode>(ServiceIdentifiers.IObfuscatedCode);
  153. obfuscatedCode.initialize(obfuscatedCodeAsString, sourceMapAsString);
  154. return obfuscatedCode;
  155. };
  156. });
  157. this.container
  158. .bind<IObfuscationEventEmitter>(ServiceIdentifiers.IObfuscationEventEmitter)
  159. .to(ObfuscationEventEmitter)
  160. .inSingletonScope();
  161. // modules
  162. this.container.load(analyzersModule);
  163. this.container.load(controlFlowTransformersModule);
  164. this.container.load(convertingTransformersModule);
  165. this.container.load(customNodesModule);
  166. this.container.load(finalizingTransformersModule);
  167. this.container.load(generatorsModule);
  168. this.container.load(nodeTransformersModule);
  169. this.container.load(obfuscatingTransformersModule);
  170. this.container.load(optionsModule);
  171. this.container.load(preparingTransformersModule);
  172. this.container.load(storagesModule);
  173. this.container.load(utilsModule);
  174. }
  175. public unload (): void {
  176. this.container.unbindAll();
  177. }
  178. }