private buildObject()

in app/src/app/services/json-parser.service.ts [20:103]


  private buildObject(node: EsTreeNode) {
    switch (node.type) {
      case 'ObjectExpression': {
        const obj: any = {};
        for (const prop of node.properties) {
          let name;
          if (prop.key.type === "Identifier") {
            name = prop.key.name;
          } else if (prop.key.type === "Literal") {
            name = prop.key.value;
          } else {
            this.reportError(`Expected "Identifier" but received: ${prop.key.type}`);
            return null;
          }

          obj[name] = this.buildObject(prop.value);
        }
        return obj;
      }

      case 'ArrayExpression': {
        const obj: any[] = [];
        for (const prop of node.elements) {
          obj.push(this.buildObject(prop));
        }
        return obj;
      }

      case 'Literal': {
        if (node.value instanceof RegExp) {
          return {
            $type: "RegExp",
            $value: {
              $pattern: node.value.source,
              $flags:   node.value.flags
            }
          }
        }

        return node.value;
      }

      case 'UnaryExpression': {
        let arg = this.buildObject(node.argument);
        let exp = node.prefix
          ? `${node.operator}${arg}`
          : `${arg}${node.operator}`;

        return eval(exp);
      }

      case 'NewExpression':
      case 'CallExpression': {
        const authorizedCalls = [ 'ObjectId', 'Date', 'RegExp' ];
        const callee = node.callee.type === 'Identifier'
          ? node.callee.name
          : null;
        if (callee && authorizedCalls.includes(callee)) {
          if (callee === 'RegExp') {
            const [pattern, flags] = node.arguments.map(this.buildObject.bind(this));
            return {
              $type:  'RegExp',
              $value: {
                $pattern: pattern,
                $flags:   flags
              }
            }
          }

          return {
            $type:  callee,
            $value: this.buildObject(node.arguments[0])
          }
        } else {
          this.reportError(`Unknown ${node.type}: ${callee}`);
          return null;
        }
      }

      default:
        this.reportError(`Sorry but ${node.type} are not authorized`);
        return null;
    }
  }