/graphql-scalars

📐 A library of custom GraphQL scalar types for creating precise type-safe GraphQL schemas, with validation powered by Yup.

Primary LanguageTypeScriptMIT LicenseMIT

📐 GraphQL Scalars

npmtraviscodecov

A library of custom GraphQL scalar types for creating precise type-safe GraphQL schemas, with validation powered by Yup.


📦 Installation

npm install --save graphql @saeris/graphql-scalars
# or
yarn add graphql @saeris/graphql-scalars

🔧 Usage

To use these scalars you'll need to add them in two places, your schema and your resolvers map. Here is an example of how to use them with Apollo Server:

import { ApolloServer } from "apollo-server"
import { makeExecutableSchema } from "graphql-tools"
import CustomScalars, { RegularExpressionFactory } from "@saeris/graphql-scalars"
// Alternatively, import individual scalars and resolvers:
// import { DateTimeScalar, DateTime } from "@saeris/graphql-scalars"

const { scalar: MyRegexScalar, resolver: MyRegex } = RegularExpressionFactory(`MyRegex`, /^abc$/)

const server = new ApolloServer({
  schema: makeExecutableSchema({
    typeDefs: [
      ...CustomScalars.keys(),
      // DateTimeScalar,
      MyRegexScalar
    ],
    resolvers: {
      ...CustomScalars.values(),
      // DateTime,
      MyRegex
    }
  })
})

server.listen().then(({ url }) => {
  console.log(`🚀 Server ready at ${url}`)
})

Now you can use them in your schema just like you would any other Type/Scalar:

type Person {
  birthDate: DateTime
  ageInYears: PositiveInt

  heightInInches: PositiveFloat

  minimumHourlyRate: UnsignedFloat

  currentlyActiveProjects: UnsignedInt

  email: EmailAddress
  homePage: URL

  phoneNumber: PhoneNumber
  homePostalCode: PostalCode
}

🏖️ Example

You can quickly take this library for a spin by running the example either locally under the example directory (just run yarn && yarn start and open your browser to http://localhost:4000) or live inside of CodeSandbox here.

📐 Scalars

DateTime

import { DateTimeScalar, DateTime } from "@saeris/graphql-scalars"

Use real JavaScript Dates for GraphQL fields. Currently you can use a String or an Int (e.g., a timestamp in milliseconds) to represent a date/time. This scalar makes it easy to be explicit about the type and have a real JavaScript Date returned that the client can use without doing the inevitable parsing or conversion themselves.

EmailAddress

import { EmailAddressScalar, EmailAddress } from "@saeris/graphql-scalars"

A field whose value conforms to the standard internet email address format as specified in RFC822.

GUID

import { GUIDScalar, GUID } from "@saeris/graphql-scalars"

A field whose value is a generic Globally Unique Identifier.

Hexadecimal

import { HexadecimalScalar, Hexadecimal } from "@saeris/graphql-scalars"

A field whose value is a hexadecimal.

HexColorCode

import { HexColorCodeScalar, HexColorCode } from "@saeris/graphql-scalars"

A field whose value is a hex color code.

HSL

import { HSLScalar, HSL } from "@saeris/graphql-scalars"

A field whose value is a CSS HSL color.

HSLA

import { HSLAScalar, HSLA } from "@saeris/graphql-scalars"

A field whose value is a CSS HSLA color.

IPv4

import { IPv4Scalar, IPv4 } from "@saeris/graphql-scalars"

A field whose value is a IPv4 address.

IPv6

import { IPv6Scalar, IPv6 } from "@saeris/graphql-scalars"

A field whose value is a IPv6 address.

ISBN

import { ISBNScalar, ISBN } from "@saeris/graphql-scalars"

A field whose value is a ISBN-10 or ISBN-13 number.

MAC

import { MACScalar, MAC } from "@saeris/graphql-scalars"

A field whose value is a IEEE 802 48-bit MAC address.

NegativeFloat

import { NegativeFloatScalar, NegativeFloat } from "@saeris/graphql-scalars"

Floats that will have a value less than 0. Uses parseFloat().

NegativeInt

import { NegativeIntScalar, NegativeInt } from "@saeris/graphql-scalars"

Integers that will have a value less than 0. Uses parseInt().

NonPositiveFloat

import { NonPositiveFloatScalar, NonPositiveFloat } from "@saeris/graphql-scalars"

Floats that will have a value of 0 or less. Uses parseFloat().

NonPositiveInt

import { NonPositiveIntScalar, NonPositiveInt } from "@saeris/graphql-scalars"

Integers that will have a value of 0 or less. Uses parseInt().

PhoneNumber

import { PhoneNumberScalar, PhoneNumber } from "@saeris/graphql-scalars"

A field whose value conforms to the standard E.164 format as specified in E.164 specification. Basically this is +17895551234. The very powerful libphonenumber library is available to take that format, parse and display it in whatever display format you want. It can also be used to parse user input and get the E.164 format to pass into a schema.

Port

import { PortScalar, Port } from "@saeris/graphql-scalars"

A field whose value is a valid TCP port within the range of 0 to 65535.

PositiveFloat

import { PositiveFloatScalar, PositiveFloat } from "@saeris/graphql-scalars"

Floats that will have a value greater than 0. Uses parseFloat().

PositiveInt

import { PositiveIntScalar, PositiveInt } from "@saeris/graphql-scalars"

Integers that will have a value greater than 0. Uses parseInt().

PostalCode

import { PostalCodeScalar, PostalCode } from "@saeris/graphql-scalars"

A field whose value conforms to the standard Portal Code format of any of the following countries:

  • US - United States
  • GB - United Kingdom
  • DE - Germany
  • CA - Canada
  • FR - France
  • IT - Italy
  • AU - Australia
  • NL - Netherlands
  • ES - Spain
  • DK - Denmark
  • SE - Sweden
  • BE - Belgium
  • IN - India

Uses joi-postalcode for validation, which uses postal-codes-js under the hood.

RGB

import { RGBScalar, RGB } from "@saeris/graphql-scalars"

A field whose value is a CSS RGB color.

RGBA

import { RGBAScalar, RGBA } from "@saeris/graphql-scalars"

A field whose value is a CSS RGBA color.

UnsignedFloat

import { UnsignedFloatScalar, UnsignedFloat } from "@saeris/graphql-scalars"

Floats that will have a value of 0 or more. Uses parseFloat().

UnsignedInt

import { UnsignedIntScalar, UnsignedInt } from "@saeris/graphql-scalars"

Integers that will have a value of 0 or more. Uses parseInt().

URL

import { URLScalar, URL } from "@saeris/graphql-scalars"

A field whose value conforms to the standard URL format as specified in RFC3986.

🏭 Factories

rangeFactory

import { rangeFactory } from "@saeris/graphql-scalars"

A GraphQLScalarType factory that takes the following config:

  • name - The name of your custom scalar
  • start - Minimum value this scalar will accept
  • end - Maximum value this scalar will accept
  • float - Set to true to accept Floats, false to accept Integers (Optional, default: false)

The following will create a scalar that accepts any Float between 1 and 1000 as a valid value

const { scalar: RangeScalar, resolver: Range } = new RegularExpressionFactory({
  name: 'Range',
  start: 1,
  end: 1000,
  float: true
});

regularExpressionFactory

import { regularExpressionFactory } from "@saeris/graphql-scalars"

A GraphQLScalarType factory that takes the following config:

  • name - The name of your custom scalar
  • regex - The regex to be used to check against any values for fields with this new type

The following will create a scalar that accepts only Strings that match ABC as a valid value

const { scalar: RegexScalar, resolver: Regex } = new RegularExpressionFactory({
  name: 'Regex',
  regex: /^ABC$/
});

📣 Acknowledgements

This library was forked from @okgrow/graphql-scalars and uses Yup for validation.

🥂 License

Released under the MIT license.