Skip to content

Instantly share code, notes, and snippets.

@rijvirajib
Last active January 22, 2022 09:16
Show Gist options
  • Save rijvirajib/2f4dbd808185e73d69ed2bfae759b51b to your computer and use it in GitHub Desktop.
Save rijvirajib/2f4dbd808185e73d69ed2bfae759b51b to your computer and use it in GitHub Desktop.
A GraphQL Date type using Moment as the parser allowing for any date input, formatted using moment.format()
import moment from 'moment';
import {GraphQLScalarType, GraphQLError, Kind} from 'graphql';
module.exports = new GraphQLScalarType({
name: 'Date',
/**
* Serialize date value into string
* @param {moment} value date value
* @return {String} date as string
*/
serialize: function (value) {
let date = moment(value);
if(!date.isValid()) {
throw new GraphQLError('Field serialize error: value is an invalid Date');
}
return date.format();
},
/**
* Parse value into date
* @param {*} value serialized date value
* @return {moment} date value
*/
parseValue: function (value) {
let date = moment(value);
if(!date.isValid()) {
throw new GraphQLError('Field parse error: value is an invalid Date');
}
return date;
},
/**
* Parse ast literal to date
* @param {Object} ast graphql ast
* @return {moment} date value
*/
parseLiteral: (ast) => {
if(ast.kind !== Kind.STRING) {
throw new GraphQLError('Query error: Can only parse strings to date but got: ' + ast.kind);
}
let date = moment(ast.value);
if(!date.isValid()) {
throw new GraphQLError('Query error: Invalid date');
}
return date;
}
});
import {expect} from 'chai';
import {Kind} from 'graphql';
import GraphQLMoment from './GraphQLMoment';
import moment from 'moment';
describe('GraphQLMoment', () => {
let validDate = '2016-08-15T10:00:32.030Z';
let invalidDate = '2016-04-31'; // This date doesn't exist
describe('serialize', () => {
it('should error when serializing an invalid date', () => {
expect(
GraphQLMoment.serialize.bind(GraphQLMoment, invalidDate)
).to.throw(/Field serialize error: value is an invalid Date/);
});
it('should serialize a valid date', () => {
expect(
GraphQLMoment.serialize(validDate)
).to.equal(moment(validDate).toISOString());
});
});
describe('parseValue', () => {
it('should error when serializing an invalid date', () => {
expect(
GraphQLMoment.parseValue.bind(GraphQLMoment, invalidDate)
).to.throw(/Field parse error: value is an invalid Date/);
});
it('should parse a value to date', () => {
expect(
GraphQLMoment.parseValue(validDate)
).to.deep.equal(moment(validDate, moment.ISO_8601).utc());
});
});
describe('parseLiteral', () => {
it('should error when parsing an ast int', () => {
let ast = {
kind: Kind.INT
};
expect(
GraphQLMoment.parseLiteral.bind(GraphQLMoment, ast)
).to.throw(/Query error: Can only parse strings to date but got: IntValue/);
});
it('should error when parsing ast with invalid value', () => {
let ast = {
kind: Kind.STRING,
value: invalidDate
};
expect(
GraphQLMoment.parseLiteral.bind(GraphQLMoment, ast)
).to.throw(/Query error: Invalid date/);
})
it('should parse a ast literal', () => {
let ast = {
kind: Kind.STRING,
value: validDate
};
let date = GraphQLMoment.parseLiteral(ast)
expect(moment.isMoment(date)).to.be.true;
expect(date.toJSON()).to.equal(ast.value)
});
});
});
@naturalethic
Copy link

This was very useful to me, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment