feat: defining a custom scalar DateTime

This commit is contained in:
Kristof Van Miegem 2019-02-09 16:02:08 +01:00
parent 971e366a1b
commit 7ce4e4a7bc
3 changed files with 75 additions and 6 deletions

View File

@ -1,5 +1,6 @@
const { UserInputError } = require('apollo-server');
const yup = require('yup');
const dateTimeScalar = require('./scalars/dateTime');
const data = require('./data');
const uuidSchema = yup.string().min(36).max(36);
@ -76,5 +77,6 @@ module.exports = {
const { reservationProducts } = input;
return data.createReservation({ reservationProducts });
}
}
},
DateTime: dateTimeScalar,
};

65
src/scalars/dateTime.js Normal file
View File

@ -0,0 +1,65 @@
const { GraphQLScalarType } = require('graphql');
const { GraphQLError } = require('graphql/error')
const { Kind } = require('graphql/language');
module.exports = new GraphQLScalarType({
name: 'DateTime',
description: 'Use JavaScript Date object for date/time fields.',
serialize(value) {
let v = value;
if (!(v instanceof Date) && typeof v !== 'string' && typeof v !== 'number') {
throw new TypeError(
`Value is not an instance of Date, Date string or number: ${v}`,
);
}
if (typeof v === 'string') {
v = new Date();
v.setTime(Date.parse(value));
} else if (typeof v === 'number') {
v = new Date(v);
}
if (Number.isNaN(v.getTime())) {
throw new TypeError(`Value is not a valid Date: ${v}`);
}
return v.toJSON();
},
parseValue(value) {
const date = new Date(value);
if (Number.isNaN(date.getTime())) {
throw new TypeError(`Value is not a valid Date: ${value}`);
}
return date;
},
parseLiteral(ast) {
if (ast.kind !== Kind.STRING && ast.kind !== Kind.INT) {
throw new GraphQLError(
`Can only parse strings & integers to dates but got a: ${ast.kind}`,
);
}
const result = new Date(ast.kind === Kind.INT ? Number(ast.value) : ast.value);
if (Number.isNaN(result.getTime())) {
throw new GraphQLError(`Value is not a valid Date: ${ast.value}`);
}
if (ast.kind === Kind.STRING && ast.value !== result.toJSON()) {
throw new GraphQLError(
`Value is not a valid Date format (YYYY-MM-DDTHH:MM:SS.SSSZ): ${
ast.value
}`,
);
}
return result;
},
});

View File

@ -3,11 +3,13 @@ const { gql } = require('apollo-server');
// Type definitions define the "shape" of your data and specify
// which ways the data can be fetched from the GraphQL server.
module.exports = gql`
scalar DateTime
# Comments in GraphQL are defined with the hash (#) symbol.
type Product {
description: String
id: String
id: ID
name: String
price: Float
}
@ -15,7 +17,7 @@ module.exports = gql`
# This "Store" type can be used in other type declarations.
type Store {
city: String
id: String
id: ID
name: String
number: Int
postalCode: String
@ -29,8 +31,8 @@ module.exports = gql`
}
type Reservation {
date: String
id: String
date: DateTime
id: ID
reservationProducts: [ReservationProduct]
}
@ -38,7 +40,7 @@ module.exports = gql`
# (A "Mutation" type will be covered later on.)
type Query {
stores: [Store]
store(id: String): Store
store(id: ID): Store
}
input StoreInput {