import {Type, IType, ITypeParams} from "./Type"; import {isObject, isNaN, invalidValuesAsString} from "../utils"; import { ConflictNullAndEmptyStringParameterError, ConflictLowerUpperParameterError, InvalidStringError } from "../errors"; export interface IStringTypeParams extends ITypeParams { nullAsEmpty?: boolean; emptyAsNull?: boolean; trim?: boolean; lower?: boolean; upper?: boolean; prepare?: (value: any, key: string, model: any) => string; validate?: ((value: string, key: string) => boolean) | RegExp ; enum?: string[]; default?: string | (() => string); } export interface IStringType extends IType { (params: IStringTypeParams): IStringType; TOutput: string; TInput: string; TJson: string; } export class StringType extends Type { nullAsEmpty: boolean; emptyAsNull: boolean; trim: boolean; lower: boolean; upper: boolean; constructor({ nullAsEmpty = false, emptyAsNull = false, trim = false, lower = false, upper = false, ...otherParams }: IStringTypeParams) { super(otherParams); this.nullAsEmpty = nullAsEmpty; this.emptyAsNull = emptyAsNull; this.trim = trim; this.lower = lower; this.upper = upper; if ( nullAsEmpty && emptyAsNull ) { throw new ConflictNullAndEmptyStringParameterError({}); } if ( lower && upper ) { throw new ConflictLowerUpperParameterError({}); } } prepare(value: any, key: string) { if ( value == null ) { if ( this.nullAsEmpty ) { return ""; } return null; } if ( isNaN(value) || typeof value === "boolean" || isObject(value) || Array.isArray(value) || // infinity value === 1 / 0 || value === -1 / 0 ) { const valueAsString = invalidValuesAsString( value ); throw new InvalidStringError({ key, invalidValue: valueAsString }); } // convert to string value += ""; if ( this.trim ) { value = value.trim(); } if ( this.emptyAsNull ) { if ( value === "" ) { value = null; } } if ( this.lower ) { value = value.toLowerCase(); } else if ( this.upper ) { value = value.toUpperCase(); } return value; } }