Options.ts 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. import { TypeFromEnum } from '@gradecam/tsenum';
  2. import { inject, injectable } from 'inversify';
  3. import { ServiceIdentifiers } from '../container/ServiceIdentifiers';
  4. import {
  5. ArrayNotEmpty,
  6. ArrayUnique,
  7. IsArray,
  8. IsBoolean,
  9. IsIn,
  10. IsNumber,
  11. IsString,
  12. IsUrl,
  13. Max,
  14. Min,
  15. ValidateIf,
  16. validateSync,
  17. ValidationError,
  18. ValidatorOptions
  19. } from 'class-validator';
  20. import { TInputOptions } from '../types/options/TInputOptions';
  21. import { TStringArrayEncoding } from '../types/options/TStringArrayEncoding';
  22. import { IOptions } from '../interfaces/options/IOptions';
  23. import { IOptionsNormalizer } from '../interfaces/options/IOptionsNormalizer';
  24. import { IdentifierNamesGenerator } from '../enums/generators/identifier-names-generators/IdentifierNamesGenerator';
  25. import { ObfuscationTarget } from '../enums/ObfuscationTarget';
  26. import { SourceMapMode } from '../enums/source-map/SourceMapMode';
  27. import { StringArrayEncoding } from '../enums/StringArrayEncoding';
  28. import { DEFAULT_PRESET } from './presets/Default';
  29. import { ValidationErrorsFormatter } from './ValidationErrorsFormatter';
  30. import { IsAllowedForObfuscationTargets } from './validators/IsAllowedForObfuscationTargets';
  31. @injectable()
  32. export class Options implements IOptions {
  33. /**
  34. * @type {ValidatorOptions}
  35. */
  36. private static readonly validatorOptions: ValidatorOptions = {
  37. validationError: {
  38. target: false
  39. }
  40. };
  41. /**
  42. * @type {boolean}
  43. */
  44. @IsBoolean()
  45. public readonly compact!: boolean;
  46. /**
  47. * @type {boolean}
  48. */
  49. @IsBoolean()
  50. public readonly controlFlowFlattening!: boolean;
  51. /**
  52. * @type {boolean}
  53. */
  54. @IsNumber()
  55. @Min(0)
  56. @Max(1)
  57. public readonly controlFlowFlatteningThreshold!: number;
  58. /**
  59. * @type {boolean}
  60. */
  61. @IsBoolean()
  62. public readonly deadCodeInjection!: boolean;
  63. /**
  64. * @type {number}
  65. */
  66. @IsNumber()
  67. public readonly deadCodeInjectionThreshold!: number;
  68. /**
  69. * @type {boolean}
  70. */
  71. @IsBoolean()
  72. public readonly debugProtection!: boolean;
  73. /**
  74. * @type {boolean}
  75. */
  76. @IsBoolean()
  77. public readonly debugProtectionInterval!: boolean;
  78. /**
  79. * @type {boolean}
  80. */
  81. @IsBoolean()
  82. public readonly disableConsoleOutput!: boolean;
  83. /**
  84. * @type {string[]}
  85. */
  86. @IsArray()
  87. @ArrayUnique()
  88. @IsString({
  89. each: true
  90. })
  91. @IsAllowedForObfuscationTargets([
  92. ObfuscationTarget.Browser,
  93. ObfuscationTarget.BrowserNoEval,
  94. ])
  95. public readonly domainLock!: string[];
  96. /**
  97. * @type {IdentifierNamesGenerator}
  98. */
  99. @IsIn([
  100. IdentifierNamesGenerator.DictionaryIdentifierNamesGenerator,
  101. IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator,
  102. IdentifierNamesGenerator.MangledIdentifierNamesGenerator
  103. ])
  104. public readonly identifierNamesGenerator!: TypeFromEnum<typeof IdentifierNamesGenerator>;
  105. /**
  106. * @type {string}
  107. */
  108. @IsString()
  109. public readonly identifiersPrefix!: string;
  110. @IsArray()
  111. @ArrayUnique()
  112. @IsString({
  113. each: true
  114. })
  115. @ValidateIf((options: IOptions) =>
  116. options.identifierNamesGenerator === IdentifierNamesGenerator.DictionaryIdentifierNamesGenerator
  117. )
  118. @ArrayNotEmpty()
  119. public readonly identifiersDictionary!: string[];
  120. /**
  121. * @type {string}
  122. */
  123. @IsString()
  124. public readonly inputFileName!: string;
  125. /**
  126. * @type {boolean}
  127. */
  128. @IsBoolean()
  129. public readonly log!: boolean;
  130. /**
  131. * @type {boolean}
  132. */
  133. @IsBoolean()
  134. public readonly minify!: boolean;
  135. /**
  136. * @type {boolean}
  137. */
  138. @IsBoolean()
  139. public readonly renameGlobals!: boolean;
  140. /**
  141. * @type {boolean}
  142. */
  143. @IsBoolean()
  144. public readonly renameProperties!: boolean;
  145. /**
  146. * @type {string[]}
  147. */
  148. @IsArray()
  149. @ArrayUnique()
  150. @IsString({
  151. each: true
  152. })
  153. public readonly reservedNames!: string[];
  154. /**
  155. * @type {string[]}
  156. */
  157. @IsArray()
  158. @ArrayUnique()
  159. @IsString({
  160. each: true
  161. })
  162. public readonly reservedStrings!: string[];
  163. /**
  164. * @type {boolean}
  165. */
  166. @IsBoolean()
  167. public readonly rotateStringArray!: boolean;
  168. /**
  169. * @type {boolean}
  170. */
  171. @IsBoolean()
  172. public readonly selfDefending!: boolean;
  173. /**
  174. * @type {boolean}
  175. */
  176. @IsBoolean()
  177. public readonly shuffleStringArray!: boolean;
  178. /**
  179. * @type {boolean}
  180. */
  181. @IsBoolean()
  182. public readonly sourceMap!: boolean;
  183. /**
  184. * @type {string}
  185. */
  186. @IsString()
  187. @ValidateIf((options: IOptions) => Boolean(options.sourceMapBaseUrl))
  188. @IsUrl({
  189. require_protocol: true,
  190. require_tld: false,
  191. require_valid_protocol: true
  192. })
  193. public readonly sourceMapBaseUrl!: string;
  194. /**
  195. * @type {string}
  196. */
  197. @IsString()
  198. public readonly sourceMapFileName!: string;
  199. /**
  200. * @type {SourceMapMode}
  201. */
  202. @IsIn([SourceMapMode.Inline, SourceMapMode.Separate])
  203. public readonly sourceMapMode!: TypeFromEnum<typeof SourceMapMode>;
  204. /**
  205. * @type {boolean}
  206. */
  207. @IsBoolean()
  208. public readonly splitStrings!: boolean;
  209. /**
  210. * @type {number}
  211. */
  212. @IsNumber()
  213. @ValidateIf((options: IOptions) => Boolean(options.splitStrings))
  214. @Min(1)
  215. public readonly splitStringsChunkLength!: number;
  216. /**
  217. * @type {boolean}
  218. */
  219. @IsBoolean()
  220. public readonly stringArray!: boolean;
  221. /**
  222. * @type {TStringArrayEncoding}
  223. */
  224. @IsIn([true, false, StringArrayEncoding.Base64, StringArrayEncoding.Rc4])
  225. public readonly stringArrayEncoding!: TStringArrayEncoding;
  226. /**
  227. * @type {number}
  228. */
  229. @IsNumber()
  230. @Min(0)
  231. @Max(1)
  232. public readonly stringArrayThreshold!: number;
  233. /**
  234. * @type {ObfuscationTarget}
  235. */
  236. @IsIn([ObfuscationTarget.Browser, ObfuscationTarget.BrowserNoEval, ObfuscationTarget.Node])
  237. public readonly target!: TypeFromEnum<typeof ObfuscationTarget>;
  238. /**
  239. * @type {boolean}
  240. */
  241. @IsBoolean()
  242. public readonly transformObjectKeys!: boolean;
  243. /**
  244. * @type {boolean}
  245. */
  246. @IsBoolean()
  247. public readonly unicodeEscapeSequence!: boolean;
  248. /**
  249. * @type {string | number}
  250. */
  251. public readonly seed!: string | number;
  252. /**
  253. * @param {TInputOptions} inputOptions
  254. * @param {IOptionsNormalizer} optionsNormalizer
  255. */
  256. public constructor (
  257. @inject(ServiceIdentifiers.TInputOptions) inputOptions: TInputOptions,
  258. @inject(ServiceIdentifiers.IOptionsNormalizer) optionsNormalizer: IOptionsNormalizer
  259. ) {
  260. Object.assign(this, DEFAULT_PRESET, inputOptions);
  261. const errors: ValidationError[] = validateSync(this, Options.validatorOptions);
  262. if (errors.length) {
  263. throw new ReferenceError(`Validation failed. errors:\n${ValidationErrorsFormatter.format(errors)}`);
  264. }
  265. Object.assign(this, optionsNormalizer.normalize(this));
  266. }
  267. }