/** * A CLI option. Supports basic comparative, and set-based validation. * @class */ export abstract class CLIOption { /** * Do we use the whitelist? * @type {boolean} * @private */ protected _useWhitelist: boolean = false /** * Do we use the blacklist? * @type {boolean} * @private */ protected _useBlacklist: boolean = false /** * Do we use the less-than comparison? * @type {boolean} * @private */ protected _useLessThan: boolean = false /** * Do we use the greater-than comparison? * @type {boolean} * @private */ protected _useGreaterThan: boolean = false /** * Do we use the equality operator? * @type {boolean} * @private */ protected _useEquality: boolean = false /** * Is this option optional? * @type {boolean} * @private */ protected _optional: boolean = false /** * Whitelisted values. * @type {Array<*>} * @private */ protected _whitelist: T[] = [] /** * Blacklisted values. * @type {Array<*>} * @private */ protected _blacklist: T[] = [] /** * Value to be compared in less than. * @type {*} * @private */ protected _lessThanValue?: T /** * If true, the less than will be less than or equal to. * @type {boolean} * @private */ protected _lessThanBit: boolean = false /** * Value to be compared in greater than. * @type {*} * @private */ protected _greaterThanValue?: T /** * If true, the greater than will be greater than or equal to. * @type {boolean} * @private */ protected _greateerThanBit: boolean = false /** * The value to be used to check equality. * @type {*} * @private */ protected _equalityValue?: T /** * Whitelist the specified item or items and enable the whitelist. * @param {...*} items - the items to whitelist */ whitelist(...items: T[]) { this._useWhitelist = true items.forEach(item => this._whitelist.push(item)) } /** * Blacklist the specified item or items and enable the blacklist. * @param {...*} items - the items to blacklist */ blacklist(...items: T[]) { this._useBlacklist = true items.forEach(item => this._blacklist.push(item)) } /** * Specifies the value to be used in less-than comparison and enables less-than comparison. * @param {*} value */ lessThan(value: T) { this._useLessThan = true this._lessThanValue = value } /** * Specifies the value to be used in less-than or equal-to comparison and enables that comparison. * @param {*} value */ lessThanOrEqualTo(value: T) { this._lessThanBit = true this.lessThan(value) } /** * Specifies the value to be used in greater-than comparison and enables that comparison. * @param {*} value */ greaterThan(value: T) { this._useGreaterThan = true this._greaterThanValue = value } /** * Specifies the value to be used in greater-than or equal-to comparison and enables that comparison. * @param {*} value */ greaterThanOrEqualTo(value: T) { this._greateerThanBit = true this.greaterThan(value) } /** * Specifies the value to be used in equality comparison and enables that comparison. * @param {*} value */ equals(value: T) { this._useEquality = true this._equalityValue = value } /** * Checks if the specified value passes the configured comparisons. * @param {*} value * @returns {boolean} */ validate(value: any) { let is_valid = true if ( this._useEquality ) { is_valid = is_valid && (this._equalityValue === value) } if ( this._useLessThan && typeof this._lessThanValue !== 'undefined' ) { if ( this._lessThanBit ) { is_valid = is_valid && (value <= this._lessThanValue) } else { is_valid = is_valid && (value < this._lessThanValue) } } if ( this._useGreaterThan && typeof this._greaterThanValue !== 'undefined' ) { if ( this._greateerThanBit ) { is_valid = is_valid && (value >= this._greaterThanValue) } else { is_valid = is_valid && (value > this._greaterThanValue) } } if ( this._useWhitelist ) { is_valid = is_valid && this._whitelist.some(x => { return x === value }) } if ( this._useBlacklist ) { is_valid = is_valid && !(this._blacklist.some(x => x === value)) } return is_valid } /** * Sets the Option as optional. */ optional() { this._optional = true return this } /** * Get the argument name. Should be overridden by child classes. * @returns {string} */ abstract getArgumentName(): string /** * Get an array of strings denoting the human-readable requirements for this option to be valid. * @returns {Array} */ getRequirementDisplays() { const clauses = [] if ( this._useBlacklist ) { clauses.push(`must not be one of: ${this._blacklist.map(x => String(x)).join(', ')}`) } if ( this._useWhitelist ) { clauses.push(`must be one of: ${this._whitelist.map(x => String(x)).join(', ')}`) } if ( this._useGreaterThan ) { clauses.push(`must be greater than${this._greateerThanBit ? ' or equal to' : ''}: ${String(this._greaterThanValue)}`) } if ( this._useLessThan ) { clauses.push(`must be less than${this._lessThanBit ? ' or equal to' : ''}: ${String(this._lessThanValue)}`) } if ( this._useEquality ) { clauses.push(`must be equal to: ${String(this._equalityValue)}`) } return clauses } }