# All files / src/app/shared/decorators cd-encode.ts

89.66% Statements 26/29
85.71% Branches 6/7
100% Functions 5/5
88.46% Lines 23/26

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
    8039x

    155x

    50x

    1x

    39x
    44x

    44x

    695x
    695x

    695x

    43x

    652x
    652x

    653x

    653x
    290x
    290x
    290x

    290x

    118x

    29x

    290x
    290x

     import * as _ from 'lodash';

    /**
     * This decorator can be used in a class or method.
     * It will encode all the string parameters of all the methods of a class
     * or, if applied on a method, the specified method.
     *
     * @export
     * @param {Function} [target=null]
     * @returns {*}
     */
    export function cdEncode(...args: any[]): any {
      switch (args.length) {
        case 1:
          return encodeClass.apply(this, args);
        case 3:
          return encodeMethod.apply(this, args);
        default:
          throw new Error();
      }
    }

    /**
     * This decorator can be used in parameters only.
     * It will exclude the parameter from being encode.
     * This should be used in parameters that are going
     * to be sent in the request's body.
     *
     * @export
     * @param {Object} target
     * @param {string} propertyKey
     * @param {number} index
     */
    export function cdEncodeNot(target: Object, propertyKey: string, index: number) {
      const metadataKey = `__ignore_${propertyKey}`;
      if (Array.isArray(target[metadataKey])) {
        target[metadataKey].push(index);
      } else {
        target[metadataKey] = [index];
      }
    }

    function encodeClass(target: Function) {
      for (const propertyName of Object.keys(target.prototype)) {
        const descriptor = Object.getOwnPropertyDescriptor(target.prototype, propertyName);

        const isMethod = descriptor.value instanceof Function;
        if (!isMethod) {
          continue;
        }

        encodeMethod(target.prototype, propertyName, descriptor);
        Object.defineProperty(target.prototype, propertyName, descriptor);
      }
    }

    function encodeMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
      if (descriptor === undefined) {
        descriptor = Object.getOwnPropertyDescriptor(target, propertyKey);
      }
      const originalMethod = descriptor.value;

      descriptor.value = function() {
        const metadataKey = `__ignore_${propertyKey}`;
        const indices: number[] = target[metadataKey] || [];
        const args = [];

        for (let i = 0; i < arguments.length; i++) {
          if (_.isString(arguments[i]) && indices.indexOf(i) === -1) {
            args[i] = encodeURIComponent(arguments[i]);
          } else {
            args[i] = arguments[i];
          }
        }

        const result = originalMethod.apply(this, args);
        return result;
      };
    }