import { injectable } from 'inversify'; import { ArrayUnique, IsBoolean, IsArray, IsIn, IsNumber, IsString, IsUrl, Min, Max, ValidateIf, validateSync, ValidationError, ValidatorOptions } from 'class-validator'; import { IInputOptions } from '../interfaces/IInputOptions'; import { IOptions } from '../interfaces/IOptions'; import { TSourceMapMode } from '../types/TSourceMapMode'; import { TStringArrayEncoding } from '../types/TStringArrayEncoding'; import { DEFAULT_PRESET } from '../preset-options/DefaultPreset'; import { OptionsNormalizer } from './OptionsNormalizer'; import { ValidationErrorsFormatter } from './ValidationErrorsFormatter'; @injectable() export class Options implements IOptions { /** * @type {ValidatorOptions} */ private static validatorOptions: ValidatorOptions = { validationError: { target: false } }; /** * @type {boolean} */ @IsBoolean() public readonly compact: boolean; /** * @type {boolean} */ @IsBoolean() public readonly controlFlowFlattening: boolean; /** * @type {boolean} */ @IsBoolean() public readonly debugProtection: boolean; /** * @type {boolean} */ @IsBoolean() public readonly debugProtectionInterval: boolean; /** * @type {boolean} */ @IsBoolean() public readonly disableConsoleOutput: boolean; /** * @type {string[]} */ @IsArray() @ArrayUnique() @IsString({ each: true }) public readonly domainLock: string[]; /** * @type {string[]} */ @IsArray() @ArrayUnique() @IsString({ each: true }) public readonly reservedNames: string[]; /** * @type {boolean} */ @IsBoolean() public readonly rotateStringArray: boolean; /** * @type {number} */ @IsNumber() public readonly seed: number; /** * @type {boolean} */ @IsBoolean() public readonly selfDefending: boolean; /** * @type {boolean} */ @IsBoolean() public readonly sourceMap: boolean; /** * @type {string} */ @IsString() @ValidateIf((options: IOptions) => Boolean(options.sourceMapBaseUrl)) @IsUrl({ require_protocol: true, require_valid_protocol: true }) public readonly sourceMapBaseUrl: string; /** * @type {string} */ @IsString() public readonly sourceMapFileName: string; /** * @type {TSourceMapMode} */ @IsIn(['inline', 'separate']) public readonly sourceMapMode: TSourceMapMode; /** * @type {boolean} */ @IsBoolean() public readonly stringArray: boolean; /** * @type {TStringArrayEncoding} */ @IsIn([true, false, 'base64', 'rc4']) public readonly stringArrayEncoding: TStringArrayEncoding; /** * @type {number} */ @IsNumber() @Min(0) @Max(1) public readonly stringArrayThreshold: number; /** * @type {boolean} */ @IsBoolean() public readonly unicodeEscapeSequence: boolean; /** * @param inputOptions */ constructor (inputOptions: IInputOptions) { Object.assign(this, DEFAULT_PRESET, inputOptions); const errors: ValidationError[] = validateSync(this, Options.validatorOptions); if (errors.length) { throw new ReferenceError(`Validation failed. errors:\n${ValidationErrorsFormatter.format(errors)}`); } Object.assign(this, OptionsNormalizer.normalizeOptions(this)); } }