### File

`src/lib/validators/is-complex.ts`

### Index

###### Properties
alphaNumeric digit lowercase special uppercase upperLower

### Properties

alphaNumeric
`alphaNumeric: `string``
Type : `string`

digit
`digit: `string``
Type : `string`

lowercase
`lowercase: `string``
Type : `string`

special
`special: `string``
Type : `string`

uppercase
`uppercase: `string``
Type : `string`

upperLower
`upperLower: `string``
Type : `string`

    import {
      AbstractControl,
      ValidationErrors,
    } from '@angular/forms';
    import { IsString } from './is-string';
    import { isNumber } from './is-number';

    export interface ComplexityOptions {
      uppercase?: number;
      special?: number;
      digit?: number;
      lowercase?: number;
      upperLower?: number;
      alphaNumeric?: number;
      min?: number,
      max?: number,
      range?: number,
      exact?: number,
    }

    interface RegexOptions {
      uppercase: string;
      special: string;
      digit: string;
      lowercase: string;
      upperLower: string;
      alphaNumeric: string;
    }

    const regexOptions: RegexOptions = {
      uppercase: '.*[A-Z]',
      special: '.*[^A-Za-z0-9]',
      digit: '.*[0-9]',
      lowercase: '.*[a-z]',
      upperLower: '.*[a-zA-Z]',
      alphaNumeric: '.*[a-zA-Z0-9]',
    };

    interface LengthOptions {
      min: string,
      max: string,
      range: string,
      exact: string,
      no_limit: string;
    }

    const lengthOptions: LengthOptions = {
      min: '.{n,}',
      max: '.{0,n}',
      range: '.{min,max}',
      exact: '.{n}',
      no_limit: '.*',
    };

    type Discriminate<U, K extends PropertyKey> =
      U extends any
        ? K extends keyof U ? U : U & Record<K, unknown>
        : never;

    function inOperator<K extends PropertyKey, T extends object>(k: K, o: T): o is Discriminate<T, K> {
      return k in o;
    }

    function create(options: ComplexityOptions): string {
      let regex = '^';
      for (const [ key, value ] of Object.entries(regexOptions)) {
        if (inOperator(key, options) && isNumber(options[key])) {
          regex += '(?=' + value.repeat(options[key]) + ')';
        }
      }
      if (isNumber(options.min) && isNumber(options.max)) {
        regex += lengthOptions.range.replace('min', options.min.toFixed(0)).replace('max', options.max.toFixed(0));
      } else if (isNumber(options.max)) {
        regex += lengthOptions.max.replace('n', options.max.toFixed(0));
      } else if (isNumber(options.min)) {
        regex += lengthOptions.min.replace('n', options.min.toFixed(0));
      } else if (isNumber(options.exact)) {
        regex += lengthOptions.exact.replace('n', options.exact.toFixed(0));
      } else {
        regex += lengthOptions.no_limit;
      }
      regex += '$';
      return regex;
    }

    function check(str: string, regexStringOrOptions: string | ComplexityOptions) {
      let regexString: string;
      if (typeof regexStringOrOptions === 'object') {
        regexString = create(regexStringOrOptions);
      } else {
        regexString = regexStringOrOptions;
      }
      return new RegExp(regexString).test(str);
    }

    function checkError(str: string, options: ComplexityOptions) {
      const returnObject: Record<string, boolean> = {};
      for (const [ key, value ] of Object.entries(options)) {
        returnObject[key] = check(str, { [key]: value });
      }
      return returnObject;
    }

    export function IsComplex({
                                message,
                                options,
                              }: { message?: string, options: ComplexityOptions }) {
      return (control: AbstractControl): ValidationErrors | null => {
        if (control.value === null) {
          return null;
        }
        const isNotString = IsString({ message })(control);
        if (isNotString !== null) {
          return isNotString;
        }
        const errors = checkError(control.value, options);
        if (Object.keys(errors).length && Object.values(errors).some(item => !item)) {
          return {
            isComplex: {
              expected: options,
              actual: errors,
              message,
            },
          };
        }
        return null;
      };
    }

# results matching ""

# No results matching ""