types/GQLJSON.js

import { GQLScalar } from '../GQLScalar'
import { Schema } from '../decorators/Schema'
import { Kind } from 'graphql/language'

@Schema('scalar JSON')
export class GQLJSON extends GQLScalar {
  /**
   * Since JSON stands for JavaScript Object Notation, its values need no
   * direct conversion. Simply pass back what is passed in.
   *
   * @memberof GQLJSON
   * @method serialize
   * @static
   *
   * @param {mixed|Null} value a valid JavaScript object
   * @return {mixed|Null} the same value that was passed in.
   */
  static serialize(value: mixed): mixed {
    return value;
  }
  
  /**
   * All processing by GraphQL Lattice uses the Class.name property. We want 
   * to report JSON and not GQLJSON so this is what we do.
   *
   * @memberof GQLJSON
   * @method name 
   * @static
   * @type {String}
   */
  static get name() {
    return 'JSON';
  }

  /**
   * Since JSON stands for JavaScript Object Notation, its values need no
   * direct conversion. Simply pass back what is passed in.
   *
   * @memberof GQLJSON
   * @method parseValue
   * @static
   *
   * @param {mixed|Null} value a valid JavaScript object
   * @return {mixed|Null} the same value that was passed in.
   */
  static parseValue(value: ?mixed): ?mixed {
    return value;
  }

  /**
   * Given literal values, `parseLiteral` will walk the object and build
   * up an equivalent version of itself as an object that should `parse()`
   * and `stringify()` accordingly.
   *
   * @memberof GQLJSON
   * @method parseLiteral
   * @static
   *
   * @param {Object} ast the Abstract Syntax Tree representing the JSON
   * type to parse.
   * @return {String|Array|Object|Number|Null} valid JSON types converted as
   * expected.
   */
  static parseLiteral(ast: Object): ?mixed {
    switch (ast.kind) {
      case Kind.STRING:
      case Kind.BOOLEAN:
        return ast.value;

      case Kind.INT:
        return parseInt(ast.value, 10);
      case Kind.FLOAT:
        return parseFloat(ast.value);

      case Kind.OBJECT: {
        const value = Object.create(null);
        ast.fields.forEach(field => {
          value[field.name.value] = GQLJSON.parseLiteral(field.value)
        })

        return value;
      }

      case Kind.LIST:
        return ast.values.map(GQLJSON.parseLiteral)

      default:
        return null;
    }
  }

  /** @inheritdoc */
  static apiDocs(): Object {
    const { DOC_CLASS, joinLines } = this;

    return joinLines`
      The \`JSON\` scalar type represents JSON values as specified by
      [ECMA-404](http://www.ecma-international.org/publications/files${
      'ECMA-ST/ECMA-404.pdf'})
    `
  }
}