diff --git a/flow-typed/npm/jest_v22.x.x.js b/flow-typed/npm/jest_v22.x.x.js index b107890..2ade5dc 100644 --- a/flow-typed/npm/jest_v22.x.x.js +++ b/flow-typed/npm/jest_v22.x.x.js @@ -436,24 +436,29 @@ type JestSpyType = { calls: JestCallsType }; +type JestDoneFn = { + (): void, + fail: (error: Error) => void, +}; + /** Runs this function after every test inside this context */ declare function afterEach( - fn: (done: () => void) => ?Promise, + fn: (done: JestDoneFn) => ?Promise, timeout?: number ): void; /** Runs this function before every test inside this context */ declare function beforeEach( - fn: (done: () => void) => ?Promise, + fn: (done: JestDoneFn) => ?Promise, timeout?: number ): void; /** Runs this function after all tests have finished inside this context */ declare function afterAll( - fn: (done: () => void) => ?Promise, + fn: (done: JestDoneFn) => ?Promise, timeout?: number ): void; /** Runs this function before any tests have started inside this context */ declare function beforeAll( - fn: (done: () => void) => ?Promise, + fn: (done: JestDoneFn) => ?Promise, timeout?: number ): void; @@ -486,7 +491,7 @@ declare var it: { */ ( name: string, - fn?: (done: () => void) => ?Promise, + fn?: (done: JestDoneFn) => ?Promise, timeout?: number ): void, /** @@ -498,7 +503,7 @@ declare var it: { */ only( name: string, - fn?: (done: () => void) => ?Promise, + fn?: (done: JestDoneFn) => ?Promise, timeout?: number ): void, /** @@ -510,7 +515,7 @@ declare var it: { */ skip( name: string, - fn?: (done: () => void) => ?Promise, + fn?: (done: JestDoneFn) => ?Promise, timeout?: number ): void, /** @@ -522,13 +527,13 @@ declare var it: { */ concurrent( name: string, - fn?: (done: () => void) => ?Promise, + fn?: (done: JestDoneFn) => ?Promise, timeout?: number ): void }; declare function fit( name: string, - fn: (done: () => void) => ?Promise, + fn: (done: JestDoneFn) => ?Promise, timeout?: number ): void; /** An individual test unit */ diff --git a/package.json b/package.json index 88f0e84..2aa6dcb 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "README.md" ], "peerDependencies": { - "graphql": "^0.5.0 || ^0.6.0 || ^0.7.0 || ^0.8.0-b || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0" + "graphql": "^0.5.0 || ^0.6.0 || ^0.7.0 || ^0.8.0-b || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^14.2.0" }, "devDependencies": { "babel-cli": "^6.26.0", @@ -51,8 +51,8 @@ "babel-preset-stage-2": "^6.24.1", "codecov": "^3.0.0", "eslint-plugin-flowtype": "^2.50.0", - "flow-bin": "^0.81.0", - "graphql": "^14.0.2", + "flow-bin": "^0.107.0", + "graphql": "^14.2.1", "jest": "^23.6.0", "mockdate": "^2.0.2", "standard": "^12.0.1" diff --git a/src/date/__snapshots__/index.test.js.snap b/src/date/__snapshots__/index.test.js.snap index d032655..dd6c89b 100644 --- a/src/date/__snapshots__/index.test.js.snap +++ b/src/date/__snapshots__/index.test.js.snap @@ -39,3 +39,5 @@ exports[`GraphQLDate value parsing throws an error when parsing 4566 1`] = `"Dat exports[`GraphQLDate value parsing throws an error when parsing null 1`] = `"Date cannot represent non string type null"`; exports[`GraphQLDate value parsing throws an error when parsing true 1`] = `"Date cannot represent non string type true"`; + +exports[`GraphQLDate value parsing throws an error when parsing undefined 1`] = `"Date cannot represent non string type undefined"`; diff --git a/src/date/index.js b/src/date/index.js index 02c83d3..85a02a1 100644 --- a/src/date/index.js +++ b/src/date/index.js @@ -37,22 +37,24 @@ const config: GraphQLScalarTypeConfig = { throw new TypeError('Date cannot represent an invalid Date instance') } else if (typeof value === 'string' || value instanceof String) { if (validateDate(value)) { - return value + return value.toString() } throw new TypeError( - `Date cannot represent an invalid date-string ${value}.` + `Date cannot represent an invalid date-string ${value.toString()}.` ) } else { + let parsedValue: string = JSON.stringify(value) || 'undefined' throw new TypeError( 'Date cannot represent a non string, or non Date type ' + - JSON.stringify(value) + parsedValue ) } }, parseValue (value) { if (!(typeof value === 'string' || value instanceof String)) { + let parsedValue: string = JSON.stringify(value) || 'undefined' throw new TypeError( - `Date cannot represent non string type ${JSON.stringify(value)}` + `Date cannot represent non string type ${parsedValue}` ) } @@ -60,7 +62,7 @@ const config: GraphQLScalarTypeConfig = { return parseDate(value) } throw new TypeError( - `Date cannot represent an invalid date-string ${value}.` + `Date cannot represent an invalid date-string ${value.toString()}.` ) }, parseLiteral (ast) { diff --git a/src/date/index.test.js b/src/date/index.test.js index 0051bac..2b32f3a 100644 --- a/src/date/index.test.js +++ b/src/date/index.test.js @@ -93,7 +93,8 @@ describe('GraphQLDate', () => { {}, [], true, - null + null, + undefined ].forEach(invalidInput => { it(`throws an error when parsing ${stringify(invalidInput)}`, () => { expect(() => diff --git a/src/dateTime/__snapshots__/index.test.js.snap b/src/dateTime/__snapshots__/index.test.js.snap index cdcd2eb..3b75d52 100644 --- a/src/dateTime/__snapshots__/index.test.js.snap +++ b/src/dateTime/__snapshots__/index.test.js.snap @@ -73,3 +73,5 @@ exports[`GraphQLDateTime value parsing throws an error when parsing 4566 1`] = ` exports[`GraphQLDateTime value parsing throws an error when parsing null 1`] = `"DateTime cannot represent non string type null"`; exports[`GraphQLDateTime value parsing throws an error when parsing true 1`] = `"DateTime cannot represent non string type true"`; + +exports[`GraphQLDateTime value parsing throws an error when parsing undefined 1`] = `"DateTime cannot represent non string type undefined"`; diff --git a/src/dateTime/index.js b/src/dateTime/index.js index 38872b3..41b5def 100644 --- a/src/dateTime/index.js +++ b/src/dateTime/index.js @@ -49,26 +49,28 @@ const config: GraphQLScalarTypeConfig = { return serializeDateTimeString(value) } throw new TypeError( - `DateTime cannot represent an invalid date-time-string ${value}.` + `DateTime cannot represent an invalid date-time-string ${value.toString()}.` ) } else if (typeof value === 'number' || value instanceof Number) { if (validateUnixTimestamp(value)) { return serializeUnixTimestamp(value) } throw new TypeError( - 'DateTime cannot represent an invalid Unix timestamp ' + value + 'DateTime cannot represent an invalid Unix timestamp ' + value.valueOf() ) } else { + let parsedValue: string = JSON.stringify(value) || 'undefined' throw new TypeError( 'DateTime cannot be serialized from a non string, ' + - 'non numeric or non Date type ' + JSON.stringify(value) + 'non numeric or non Date type ' + parsedValue ) } }, parseValue (value) { if (!(typeof value === 'string' || value instanceof String)) { + let parsedValue: string = JSON.stringify(value) || 'undefined' throw new TypeError( - `DateTime cannot represent non string type ${JSON.stringify(value)}` + `DateTime cannot represent non string type ${parsedValue}` ) } @@ -76,7 +78,7 @@ const config: GraphQLScalarTypeConfig = { return parseDateTime(value) } throw new TypeError( - `DateTime cannot represent an invalid date-time-string ${value}.` + `DateTime cannot represent an invalid date-time-string ${value.toString()}.` ) }, parseLiteral (ast) { diff --git a/src/dateTime/index.test.js b/src/dateTime/index.test.js index 148eadb..6006a99 100644 --- a/src/dateTime/index.test.js +++ b/src/dateTime/index.test.js @@ -146,7 +146,8 @@ describe('GraphQLDateTime', () => { {}, [], true, - null + null, + undefined ].forEach(invalidInput => { it(`throws an error when parsing ${stringify(invalidInput)}`, () => { expect(() => diff --git a/src/time/__snapshots__/index.test.js.snap b/src/time/__snapshots__/index.test.js.snap index 83f205c..aefc226 100644 --- a/src/time/__snapshots__/index.test.js.snap +++ b/src/time/__snapshots__/index.test.js.snap @@ -53,3 +53,5 @@ exports[`GraphQLTime value parsing throws an error when parsing 4566 1`] = `"Tim exports[`GraphQLTime value parsing throws an error when parsing null 1`] = `"Time cannot represent non string type null"`; exports[`GraphQLTime value parsing throws an error when parsing true 1`] = `"Time cannot represent non string type true"`; + +exports[`GraphQLTime value parsing throws an error when parsing undefined 1`] = `"Time cannot represent non string type undefined"`; diff --git a/src/time/index.js b/src/time/index.js index bad791d..94df33e 100644 --- a/src/time/index.js +++ b/src/time/index.js @@ -47,19 +47,21 @@ const config: GraphQLScalarTypeConfig = { return serializeTimeString(value) } throw new TypeError( - `Time cannot represent an invalid time-string ${value}.` + `Time cannot represent an invalid time-string ${value.toString()}.` ) } else { + let parsedValue: string = JSON.stringify(value) || 'undefined' throw new TypeError( 'Time cannot be serialized from a non string, ' + - 'or non Date type ' + JSON.stringify(value) + 'or non Date type ' + parsedValue ) } }, parseValue (value: mixed): Date { if (!(typeof value === 'string' || value instanceof String)) { + let parsedValue: string = JSON.stringify(value) || 'undefined' throw new TypeError( - `Time cannot represent non string type ${JSON.stringify(value)}` + `Time cannot represent non string type ${parsedValue}` ) } @@ -67,7 +69,7 @@ const config: GraphQLScalarTypeConfig = { return parseTime(value) } throw new TypeError( - `Time cannot represent an invalid time-string ${value}.` + `Time cannot represent an invalid time-string ${value.toString()}.` ) }, parseLiteral (ast): ?Date { diff --git a/src/time/index.test.js b/src/time/index.test.js index f219fa8..a7ad5d8 100644 --- a/src/time/index.test.js +++ b/src/time/index.test.js @@ -112,7 +112,8 @@ describe('GraphQLTime', () => { {}, [], true, - null + null, + undefined ].forEach(invalidInput => { it(`throws an error when parsing ${stringify(invalidInput)}`, () => { expect(() => diff --git a/src/utils/formatter.js b/src/utils/formatter.js index a9cce5c..f785a27 100644 --- a/src/utils/formatter.js +++ b/src/utils/formatter.js @@ -16,9 +16,9 @@ // Suppose the current date is 2016-01-01, then // parseTime('11:00:12Z') parses to a Date corresponding to // 2016-01-01T11:00:12Z. -export const parseTime = (time: string): Date => { +export const parseTime = (time: string | String): Date => { const currentDateString = new Date().toISOString() - return new Date(currentDateString.substr(0, currentDateString.indexOf('T') + 1) + time) + return new Date(currentDateString.substr(0, currentDateString.indexOf('T') + 1) + time.toString()) } // Serializes a Date into an RFC 3339 compliant time-string in the @@ -30,10 +30,10 @@ export const serializeTime = (date: Date): string => { // Serializes an RFC 3339 compliant time-string by shifting // it to UTC. -export const serializeTimeString = (time: string): string => { +export const serializeTimeString = (time: string | String): string => { // If already formatted to UTC then return the time string if (time.indexOf('Z') !== -1) { - return time + return time.toString() } else { // These are time-strings with timezone information, // these need to be shifted to UTC. @@ -72,8 +72,8 @@ export const serializeTimeString = (time: string): string => { // Example: // parseDate('2016-01-01') parses to a Date corresponding to // 2016-01-01T00:00:00.000Z. -export const parseDate = (date: string): Date => { - return new Date(date) +export const parseDate = (date: string | String): Date => { + return new Date(date.toString()) } // Serializes a Date into a RFC 3339 compliant date-string @@ -83,8 +83,8 @@ export const serializeDate = (date: Date): string => { } // Parses an RFC 3339 compliant date-time-string into a Date. -export const parseDateTime = (dateTime: string): Date => { - return new Date(dateTime) +export const parseDateTime = (dateTime: string | String): Date => { + return new Date(dateTime.toString()) } // Serializes a Date into an RFC 3339 compliant date-time-string @@ -95,7 +95,8 @@ export const serializeDateTime = (dateTime: Date): string => { // Serializes an RFC 3339 compliant date-time-string by shifting // it to UTC. -export const serializeDateTimeString = (dateTime: string): string => { +export const serializeDateTimeString = (dateTime: string | String): string => { + dateTime = dateTime.toString() // If already formatted to UTC then return the time string if (dateTime.indexOf('Z') !== -1) { return dateTime @@ -132,6 +133,6 @@ export const serializeDateTimeString = (dateTime: string): string => { // Serializes a Unix timestamp to an RFC 3339 compliant date-time-string // in the format YYYY-MM-DDThh:mm:ss.sssZ -export const serializeUnixTimestamp = (timestamp: number): string => { - return new Date(timestamp * 1000).toISOString() +export const serializeUnixTimestamp = (timestamp: number | Number): string => { + return new Date(timestamp.valueOf() * 1000).toISOString() } diff --git a/src/utils/validator.js b/src/utils/validator.js index 7562fb6..214c9db 100644 --- a/src/utils/validator.js +++ b/src/utils/validator.js @@ -44,8 +44,9 @@ const leapYear = (year: number): boolean => { // equals NaN. // - Leap seconds cannot be known in advance. // -export const validateTime = (time: string): boolean => { +export const validateTime = (time: string | String): boolean => { const TIME_REGEX = /^([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])(\.\d{1,})?(([Z])|([+|-]([01][0-9]|2[0-3]):[0-5][0-9]))$/ + time = time.toString() return TIME_REGEX.test(time) } @@ -72,8 +73,9 @@ export const validateTime = (time: string): boolean => { // 11 November 30 // 12 December 31 // -export const validateDate = (datestring: string): boolean => { +export const validateDate = (datestring: string | String): boolean => { const RFC_3339_REGEX = /^(\d{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01]))$/ + datestring = datestring.toString() if (!RFC_3339_REGEX.test(datestring)) { return false @@ -117,8 +119,9 @@ export const validateDate = (datestring: string): boolean => { // // Where *s is a fraction of seconds with at least 1 digit. // -export const validateDateTime = (dateTimeString: string): boolean => { +export const validateDateTime = (dateTimeString: string | String): boolean => { const RFC_3339_REGEX = /^(\d{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60))(\.\d{1,})?(([Z])|([+|-]([01][0-9]|2[0-3]):[0-5][0-9]))$/ + dateTimeString = dateTimeString.toString() // Validate the structure of the date-string if (!RFC_3339_REGEX.test(dateTimeString)) { @@ -144,7 +147,8 @@ export const validateDateTime = (dateTimeString: string): boolean => { // Unix timestamps are signed 32-bit integers. They are interpreted // as the number of seconds since 00:00:00 UTC on 1 January 1970. // -export const validateUnixTimestamp = (timestamp: number): boolean => { +export const validateUnixTimestamp = (timestamp: number | Number): boolean => { + timestamp = timestamp.valueOf() const MAX_INT = 2147483647 const MIN_INT = -2147483648 return (timestamp === timestamp && timestamp <= MAX_INT && timestamp >= MIN_INT) // eslint-disable-line diff --git a/yarn.lock b/yarn.lock index dba4432..68f68ec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1889,9 +1889,10 @@ flat-cache@^1.2.1: graceful-fs "^4.1.2" write "^0.2.1" -flow-bin@^0.81.0: - version "0.81.0" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.81.0.tgz#7f0a733dce1dad3cb1447c692639292dc3d60bf5" +flow-bin@^0.107.0: + version "0.107.0" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.107.0.tgz#b37bfcce51204d35d58f8eb93b3a76b52291e4cc" + integrity sha512-hsmwO5Q0+XUXaO2kIKLpleUNNBSFcsGEQGBOTEC/KR/4Ez695I1fweX/ioSjbU4RWhPZhkIqnpbF9opVAauCHg== for-in@^0.1.5: version "0.1.6" @@ -2108,9 +2109,10 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4: version "1.0.1" resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" -graphql@^14.0.2: - version "14.0.2" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.0.2.tgz#7dded337a4c3fd2d075692323384034b357f5650" +graphql@^14.2.1: + version "14.2.1" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.2.1.tgz#779529bf9a01e7207b977a54c20670b48ca6e95c" + integrity sha512-2PL1UbvKeSjy/lUeJqHk+eR9CvuErXoCNwJI4jm3oNFEeY+9ELqHNKO1ZuSxAkasPkpWbmT/iMRMFxd3cEL3tQ== dependencies: iterall "^1.2.2"