Skip to content

Commit

Permalink
chore(gatsby): migrate date to TypeScript (#22430)
Browse files Browse the repository at this point in the history
* chore(gatsby): migrate date to TypeScript

* chore: format

* fix pointer out

* fix format

Co-authored-by: gatsbybot <mathews.kyle+gatsbybot@gmail.com>
  • Loading branch information
sasurau4 and gatsbybot authored Jul 15, 2020
1 parent 1fa5d0f commit f1b3a66
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 22 deletions.
2 changes: 1 addition & 1 deletion packages/gatsby/src/schema/extensions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const {
} = require(`graphql`)

const { link, fileByPath } = require(`../resolvers`)
const { getDateResolver } = require(`../types/date`)
import { getDateResolver } from "../types/date"

import type { GraphQLFieldConfigArgumentMap, GraphQLFieldConfig } from "graphql"
import type { ComposeFieldConfig, ComposeOutputType } from "graphql-compose"
Expand Down
2 changes: 1 addition & 1 deletion packages/gatsby/src/schema/infer/add-inferred-fields.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const invariant = require(`invariant`)
const report = require(`gatsby-cli/lib/reporter`)

import { isFile } from "./is-file"
const { isDate } = require(`../types/date`)
import { isDate } from "../types/date"
const { addDerivedType } = require(`../types/derived-types`)
import { is32BitInteger } from "../../utils/is-32-bit-integer"
const { getNode, getNodes } = require(`../../redux/nodes`)
Expand Down
2 changes: 1 addition & 1 deletion packages/gatsby/src/schema/schema-composer.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { SchemaComposer, GraphQLJSON } = require(`graphql-compose`)
const { getNodeInterface } = require(`./types/node-interface`)
const { GraphQLDate } = require(`./types/date`)
import { GraphQLDate } from "./types/date"
const { addDirectives } = require(`./extensions`)

const createSchemaComposer = ({ fieldExtensions } = {}) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/gatsby/src/schema/types/__tests__/date.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const { actions } = require(`../../../redux/actions`)
const { build } = require(`../..`)
const withResolverContext = require(`../../context`)
const { defaultResolver } = require(`../../resolvers`)
const { isDate, looksLikeADate } = require(`../date`)
import { isDate, looksLikeADate } from "../date"

jest.mock(`gatsby-cli/lib/reporter`, () => {
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const {
GraphQLInputObjectType,
Kind,
} = require(`graphql`)
const { GraphQLDate } = require(`../date`)
import { GraphQLDate } from "../date"
const { GraphQLJSON } = require(`graphql-compose`)

const getInferredFields = fields => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,29 @@
const moment = require(`moment`)
const { GraphQLScalarType, Kind } = require(`graphql`)
const { oneLine } = require(`common-tags`)
import moment, { MomentInput, unitOfTime, LocaleSpecifier } from "moment"
import { GraphQLScalarType, Kind, GraphQLFieldConfig } from "graphql"
import { oneLine } from "common-tags"

interface IFormatDateArgs {
date?: Date
fromNow?: boolean
formatString?: string
difference?: unitOfTime.Diff
locale?: LocaleSpecifier
}
interface IDateResolverOption {
locale?: string
formatString?: string
fromNow?: string
difference?: string
from?: string
fromNode?: { type: string; defaultValue: boolean }
}
type DateResolverFieldConfig = GraphQLFieldConfig<any, any, any>
type DateResolver = (
source: any,
args: any,
context: any,
info: any
) => Promise<null | string | number | (string | number)[]>

const ISO_8601_FORMAT = [
`YYYY`,
Expand Down Expand Up @@ -79,14 +102,14 @@ const ISO_8601_FORMAT = [
`YYYYDDDD`,
]

const GraphQLDate = new GraphQLScalarType({
export const GraphQLDate = new GraphQLScalarType({
name: `Date`,
description: oneLine`
A date string, such as 2007-12-03, compliant with the ISO 8601 standard
for representation of dates and times using the Gregorian calendar.`,
serialize: String,
parseValue: String,
parseLiteral(ast) {
parseLiteral(ast): string | undefined {
return ast.kind === Kind.STRING ? ast.value : undefined
},
})
Expand All @@ -109,20 +132,22 @@ const momentFormattingRegexes = {
".": `\\.`,
Z: `(Z|[+-]\\d\\d(?::?\\d\\d)?)`,
}
const ISO_8601_FORMAT_AS_REGEX = ISO_8601_FORMAT.map(format =>
const ISO_8601_FORMAT_AS_REGEX = ISO_8601_FORMAT.map(format => {
const matchedFormat = format.match(momentFormattingTokens)
if (matchedFormat === null) return ``
// convert ISO string to a map of momentTokens ([YYYY, MM, DD])
[...format.match(momentFormattingTokens)]
return [...matchedFormat]
.map(token =>
// see if the token (YYYY or ss) is found, else we just return the value
momentFormattingRegexes[token] ? momentFormattingRegexes[token] : token
)
.join(``)
).join(`|`)
}).join(`|`)

// calculate all lengths of the formats, if a string is longer or smaller it can't be valid
const ISO_8601_FORMAT_LENGTHS = [
...new Set(
ISO_8601_FORMAT.reduce((acc, val) => {
ISO_8601_FORMAT.reduce((acc: number[], val: string) => {
if (!val.endsWith(`Z`)) {
return acc.concat(val.length)
}
Expand Down Expand Up @@ -154,7 +179,7 @@ const looksLikeDateEndRegex = /(\d|Z)$/
* @param {*} value
* @return {boolean}
*/
function looksLikeADate(value) {
export function looksLikeADate(value?: string): boolean {
// quick check if value does not look like a date
if (
!value ||
Expand All @@ -178,7 +203,7 @@ function looksLikeADate(value) {
* @param {*} value
* @return {boolean}
*/
function isDate(value) {
export function isDate(value: MomentInput): boolean {
const momentDate = moment.utc(value, ISO_8601_FORMAT, true)
return typeof value !== `number` && momentDate.isValid()
}
Expand All @@ -189,7 +214,7 @@ const formatDate = ({
difference,
formatString,
locale = `en`,
}) => {
}: IFormatDateArgs): string | number => {
const normalizedDate = JSON.parse(JSON.stringify(date))
if (formatString) {
return moment
Expand All @@ -210,7 +235,10 @@ const formatDate = ({
return normalizedDate
}

const getDateResolver = (options = {}, fieldConfig) => {
export const getDateResolver = (
options: IDateResolverOption = {},
fieldConfig: DateResolverFieldConfig
): { args: Record<string, any>; resolve: DateResolver } => {
const { locale, formatString, fromNow, difference } = options
return {
args: {
Expand Down Expand Up @@ -246,7 +274,7 @@ const getDateResolver = (options = {}, fieldConfig) => {
defaultValue: locale,
},
},
async resolve(source, args, context, info) {
async resolve(source, args, context, info): ReturnType<DateResolver> {
const resolver = fieldConfig.resolve || context.defaultFieldResolver
const date = await resolver(source, args, context, {
...info,
Expand All @@ -261,5 +289,3 @@ const getDateResolver = (options = {}, fieldConfig) => {
},
}
}

module.exports = { GraphQLDate, getDateResolver, isDate, looksLikeADate }
2 changes: 1 addition & 1 deletion packages/gatsby/src/schema/types/filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const {
const { addDerivedType } = require(`./derived-types`)
const { InputTypeComposer } = require(`graphql-compose`)
const { GraphQLJSON } = require(`graphql-compose`)
const { GraphQLDate } = require(`./date`)
import { GraphQLDate } from "./date"

const SEARCHABLE_ENUM = {
SEARCHABLE: `SEARCHABLE`,
Expand Down

0 comments on commit f1b3a66

Please sign in to comment.