All files / lib/dynamic-form-expression dynamic-form-expression.builder.ts

100% Statements 38/38
100% Branches 12/12
100% Functions 11/11
100% Lines 38/38

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98                                      1x 105x     9x 9x 4x 4x         64x 64x 4x 4x         12x 12x 4x 4x             4x 2x 2x   2x 1x   1x           4x 2x 2x   2x 1x   1x           4x 2x 2x   2x 1x   1x         6x 6x   3x 3x 3x 3x        
import { Injectable } from '@angular/core';
import { DynamicFormAction } from '../dynamic-form-action/dynamic-form-action';
import { DynamicFormActionExpression } from '../dynamic-form-action/dynamic-form-action-expression';
import { DynamicFormActionExpressionFunc } from '../dynamic-form-action/dynamic-form-action-expression-func';
import { DynamicFormActionExpressions } from '../dynamic-form-action/dynamic-form-action-expressions';
import { DynamicFormElement } from '../dynamic-form-element/dynamic-form-element';
import { DynamicFormElementExpression } from '../dynamic-form-element/dynamic-form-element-expression';
import { DynamicFormElementExpressionFunc } from '../dynamic-form-element/dynamic-form-element-expression-func';
import { DynamicFormElementExpressions } from '../dynamic-form-element/dynamic-form-element-expressions';
import { DynamicFormField } from '../dynamic-form-field/dynamic-form-field';
import { DynamicFormFieldExpression } from '../dynamic-form-field/dynamic-form-field-expression';
import { DynamicFormFieldExpressionFunc } from '../dynamic-form-field/dynamic-form-field-expression-func';
import { DynamicFormFieldExpressions } from '../dynamic-form-field/dynamic-form-field-expressions';
import { DynamicFormErrorHandler } from '../dynamic-form-error/dynamic-form-error.handler';
import { DynamicFormError } from '../dynamic-form-error/dynamic-form-error';
import { DynamicFormErrorType } from '../dynamic-form-error/dynamic-form-error-type';
import { dynamicFormExpressionArgs } from './dynamic-form-expression';
 
@Injectable()
export class DynamicFormExpressionBuilder {
  constructor(private errorHandler: DynamicFormErrorHandler) {}
 
  createElementExpressions(element: DynamicFormElement): DynamicFormElementExpressions {
    const expressions = element.definition.expressions;
    return expressions ? Object.keys(expressions).reduce((result, key) => {
      result[key] = this.createElementExpression(key, element, expressions[key]);
      return result;
    }, {}) : null;
  }
 
  createFieldExpressions(field: DynamicFormField): DynamicFormFieldExpressions {
    const expressions = field.definition.expressions;
    return expressions ? Object.keys(expressions).reduce((result, key) => {
      result[key] = this.createFieldExpression(key, field, expressions[key]);
      return result;
    }, {}) : null;
  }
 
  createActionExpressions(action: DynamicFormAction): DynamicFormActionExpressions {
    const expressions = action.definition.expressions;
    return expressions ? Object.keys(expressions).reduce((result, key) => {
      result[key] = this.createActionExpression(key, action, expressions[key]);
      return result;
    }, {}) : null;
  }
 
  private createElementExpression(
    key: string, element: DynamicFormElement, expression: string | DynamicFormElementExpressionFunc,
  ): DynamicFormElementExpression {
    if (typeof expression === 'string') {
      const func = this.createExpressionFunction<DynamicFormElementExpressionFunc>(expression);
      return new DynamicFormElementExpression(key, element, func, this.errorHandler);
    }
    if (typeof expression === 'function') {
      return new DynamicFormElementExpression(key, element, expression, this.errorHandler);
    }
    return undefined;
  }
 
  private createFieldExpression(
    key: string, field: DynamicFormField, expression: string | DynamicFormFieldExpressionFunc,
  ): DynamicFormFieldExpression {
    if (typeof expression === 'string') {
      const func = this.createExpressionFunction<DynamicFormFieldExpressionFunc>(expression);
      return new DynamicFormFieldExpression(key, field, func, this.errorHandler);
    }
    if (typeof expression === 'function') {
      return new DynamicFormFieldExpression(key, field, expression, this.errorHandler);
    }
    return undefined;
  }
 
  private createActionExpression(
    key: string, action: DynamicFormAction, expression: string | DynamicFormActionExpressionFunc,
  ): DynamicFormActionExpression {
    if (typeof expression === 'string') {
      const func = this.createExpressionFunction<DynamicFormActionExpressionFunc>(expression);
      return new DynamicFormActionExpression(key, action, func, this.errorHandler);
    }
    if (typeof expression === 'function') {
      return new DynamicFormActionExpression(key, action, expression, this.errorHandler);
    }
    return undefined;
  }
 
  // eslint-disable-next-line @typescript-eslint/ban-types
  private createExpressionFunction<Func extends Function>(expression: string): Func {
    try {
      return new Function(...dynamicFormExpressionArgs, `"use strict"; return ${ expression };`) as Func;
    } catch (error) {
      const type = DynamicFormErrorType.ExpressionCreation;
      const message = `Expression creation for "${expression} failed"`;
      this.errorHandler.handle(new DynamicFormError(type, message, error));
      return new Function(...dynamicFormExpressionArgs, 'return undefined;') as Func;
    }
  }
}