all files / semantic-graphql/src/ scalars.js

14.29% Statements 4/28
0% Branches 0/30
0% Functions 0/3
16.67% Lines 4/24
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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117                                                                                                                                                                                                                                  
const { GraphQLID, GraphQLBoolean, GraphQLInt, GraphQLFloat, GraphQLString, Kind } = require('graphql');
 
// https://www.w3.org/TR/xmlschema-2
// http://graphql.org/docs/api-reference-type-system/#graphqlscalartype
const graphqlScalarTypes = {
  Literal: GraphQLString, // refers to rdfs:Literal
  /* --------------------
    Primitive datatypes
  -------------------- */
  string: GraphQLString,
  boolean: GraphQLBoolean,
  decimal: GraphQLFloat,
  float: GraphQLFloat,
  double: GraphQLFloat,
  duration: GraphQLString,
  dateTime: GraphQLString,
  time: GraphQLString,
  date: GraphQLString,
  gYearMonth: GraphQLString,
  gYear: GraphQLString,
  gMonthDay: GraphQLString,
  gDay: GraphQLString,
  gMonth: GraphQLString,
  hexBinary: GraphQLString,
  base64Binary: GraphQLString,
  anyURI: GraphQLString,
  QName: GraphQLString,
  NOTATION: GraphQLString,
  /* ------------------
    Derived datatypes
  ------------------ */
  normalizedString: GraphQLString,
  token: GraphQLString,
  language: GraphQLString,
  NMTOKEN: GraphQLString,
  // NMTOKENS: new GraphQLList(GraphQLString),
  Name: GraphQLString,
  NCName: GraphQLString,
  ID: GraphQLID,
  IDREF: GraphQLID,
  // IDREFS: new GraphQLList(GraphQLID),
  ENTITY: GraphQLString,
  // ENTITIES: new GraphQLList(GraphQLString),
  integer: GraphQLInt,
  nonPositiveInteger: GraphQLInt,
  negativeInteger: GraphQLInt,
  long: GraphQLInt,
  int: GraphQLInt,
  short: GraphQLInt,
  byte: GraphQLInt,
  nonNegativeInteger: GraphQLInt,
  unsignedLong: GraphQLInt,
  unsignedInt: GraphQLInt,
  unsignedShort: GraphQLInt,
  unsignedByte: GraphQLInt,
  positiveInteger: GraphQLInt,
};
 
// Not great
// The most inclusive types must be last
// example: float includes int, so float must be after int
const graphqlScalarMethods = new Map([
  [GraphQLBoolean, {
    isOfType: value => typeof value === 'boolean',
    coerceValue: Boolean,
    parseLiteral: ast => ast.kind === Kind.BOOLEAN ? ast.value : null,
  }],
  [GraphQLString, {
    isOfType: value => typeof value === 'string',
    coerce: String,
    parseLiteral: ast => ast.kind === Kind.STRING ? ast.value : null,
  }],
  [GraphQLInt, {
    isOfType: value => typeof value === 'number' && Math.round(value) === value,
    coerce(value) {
      if (value === '') return null;
 
      const number = Number(value);
 
      if (Math.abs(number) <= Number.MAX_SAFE_INTEGER) return (number < 0 ? Math.ceil : Math.floor)(number);
 
      return null;
    },
    parseLiteral(ast) {
      if (ast.kind === Kind.INT) {
        const number = parseInt(ast.value, 10);
 
        if (Math.abs(number) <= Number.MAX_SAFE_INTEGER) return number;
      }
 
      return null;
    },
  }],
  [GraphQLFloat, {
    isOfType: value => typeof value === 'number',
    coerce(value) {
      if (value === '') return null;
 
      const number = Number(value);
 
      return number === number ? number : null;
    },
    parseLiteral: ast => ast.kind === Kind.FLOAT || ast.kind === Kind.INT ? parseFloat(ast.value) : null,
  }],
  // Must be last because it can be interpreted as either a string or a number
  [GraphQLID, {
    isOfType: value => typeof value === 'string' || typeof value === 'number',
    coerce: String,
    parseLiteral: ast => ast.kind === Kind.STRING || ast.kind === Kind.INT ? ast.value : null,
  }],
]);
 
module.exports = {
  graphqlScalarTypes,
  graphqlScalarMethods,
};