2.0.2 • Published 1 year ago

@graphql-directive/validator v2.0.2

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

Validator.js Directives

A validator.js wrapper for GraphQL validation directive

Node.js CI Coverage Status

Validation directive Example: @validate(method: METHOD[, OPTIONS]) is used to validate input values of GraphQL fields against specific rules defined in the directive.

import val from "@graphql-directive/validator"
import { makeExecutableSchema } from "@graphql-tools/schema"
import { ApolloServer } from "@apollo/server";
import { startStandaloneServer } from "@apollo/server/standalone"

const typeDefs = `
    input UserInput {
        name: String!       @validate(method: LENGTH, max: 150)
        email: String!      @validate(method: EMAIL)
        dateOfBirth: Date!  @validate(method: BEFORE)
    }
    type Mutation { 
        addUser(user:UserInput!): Boolean!
    }
`

const schema = val.transform(makeExecutableSchema({
    typeDefs: [val.typeDefs, typeDefs],
    resolvers: { /* resolvers */ }
}))

const server = new ApolloServer({ schema })
const { url } = await startStandaloneServer(server)
console.log(`Server running at ${url}`)

Validation Result

For each failed validation, server will throw GraphQLError with message USER_INPUT_ERROR. The detail error message can be seen in extension.error property like below.

{
  "data": {},
  "errors": [
    {
      "message": "USER_INPUT_ERROR",
      "extensions": {
        "error": [
          {
            "message": "Must have a length within the specified range",
            "path": "addUser.user.name"
          },
          {
            "message": "Must be a valid email address",
            "path": "addUser.user.email"
          }
        ],
        "code": "INTERNAL_SERVER_ERROR",
        "stacktrace": [ ]
      }
    }
  ]
}

Custom Error Message

Currently its possible to create your own error message by providing the message on message parameter like example below.

@validate(method: EMAIL, message: "Please provide a valid email address")

Validation Methods

The validation directive supports all of the validation functions in Validator.js. Below is a list of the supported methods and their respective parameters.

MethodDescriptionParameters / Example Usage
AFTERChecks if a date is after a specified date.Example: @validate(method: AFTER)
ALPHAChecks if a string contains only alphabetical characters.locale (optional): The locale to use for alphabet validation (defaults to en-US). Example: @validate(method: ALPHA, locale: "id-ID")
ALPHANUMERICChecks if a string contains only alphanumeric characters.locale (optional): The locale to use for alphabet validation (defaults to en-US). Example: @validate(method: ALPHANUMERIC, locale: "id-ID")
ASCIIChecks if a string contains only ASCII characters.Example: @validate(method: ASCII)
BASE64Checks if a string is a valid base64-encoded string.Example: @validate(method: BASE64)
BEFOREChecks if a date is before a specified date.Example: @validate(method: BEFORE)
BOOLEANChecks if a value is a boolean (true or false).Example: @validate(method: BOOLEAN)
CREDIT_CARDChecks if a string is a valid credit card number.Example: @validate(method: CREDIT_CARD)
CURRENCYChecks if a string is a valid currency amount.symbol: The currency symbol to use (defaults to $). decimal: The decimal separator to use (defaults to .). symbol_position: The position of the currency symbol (defaults to left). negative_sign_before: Whether to put the negative sign before or after the currency symbol (defaults to false). thousands_separator: The thousands separator to use (defaults to ,). allow_negative: Whether to allow negative currency amounts (defaults to false). Example: @validate(method: CURRENCY, allow_negative: true)
DATA_URIChecks if a string is a valid data URI.Example: @validate(method: DATA_URI)
DECIMALChecks if a string is a valid decimal number.Example: @validate(method: DECIMAL)
DIVISIBLE_BYChecks if a number is divisible by another number.number (required): The number to divide value by. Example: @validate(method: DIVISIBLE_BY, number: 3)
EMAILChecks if a string is a valid email address.allow_display_name: Whether to allow the use of display names (defaults to false). require_display_name: Whether to require the use of display names (defaults to false). allow_utf8_local_part: Whether to allow non-ASCII characters in the local part of the email address (defaults to false). require_tld: Whether to require a top-level domain (defaults to true). ignore_max_length: Whether to ignore the maximum length of the email address (defaults to false). Example: @validate(method: EMAIL, ignore_max_length: true)
ETHEREUM_ADDRESSChecks if a string is a valid Ethereum address.Example: @validate(method: ETHEREUM_ADDRESS)
FQDNChecks if a string is a fully qualified domain name (FQDN).require_tld: Whether to require a top-level domain (defaults to true). allow_underscores: Whether to allow underscores in domain names (defaults to false). allow_trailing_dot: Whether to allow a trailing dot in domain names (defaults to false). Example: @validate(method: FQDN)
FLOATChecks if a string is a valid float.min: The minimum value the float can be (defaults to Number.MIN_VALUE). max: The maximum value the float can be (defaults to Number.MAX_VALUE). gt: The value the float must be greater than. lt: The value the float must be less than. locale: The locale to use for validation (defaults to en-US). Example: @validate(method: FLOAT)
FULL_WIDTHChecks if a string contains any full-width characters.Example: @validate(method: FULL_WIDTH)
HALF_WIDTHChecks if a string contains any half-width characters.Example: @validate(method: HALF_WIDTH)
HEX_COLORChecks if a string is a valid hexadecimal color code.Example: @validate(method: HEX_COLOR)
HEXADECIMALChecks if a string is a valid hexadecimal number.Example: @validate(method: HEXADECIMAL)
IPChecks if a string is a valid IP address (version 4 or 6).version (optional): The IP version to validate against (4 or 6, defaults to 4). Example: @validate(method: IP)
IP_RANGEChecks if a string is a valid IP range.Example: @validate(method: IP_RANGE)
ISBNChecks if a string is a valid International Standard Book Number (ISBN).version (optional): The ISBN version to validate against (10 or 13, defaults to 13). Example: @validate(method: ISBN)
ISINChecks if a string is a valid International Securities Identification Number (ISIN).Example: @validate(method: ISIN)
ISO8601Checks if a string is a valid ISO 8601 date.Example: @validate(method: ISO8601)
ISO31661_ALPHA2Checks if a string is a valid ISO 3166-1 alpha-2 country code.Example: @validate(method: ISO31661_ALPHA2)
ISO31661_ALPHA3Checks if a string is a valid ISO 3166-1 alpha-3 country code.Example: @validate(method: ISO31661_ALPHA3)
ISRCChecks if a string is a valid International Standard Recording Code (ISRC).Example: @validate(method: ISRC)
ISSNChecks if a string is a valid International Standard Serial Number (ISSN).Example: @validate(method: ISSN)
JSONChecks if a string is valid JSON.Example: @validate(method: JSON)
JWTChecks if a string is a valid JSON Web Token (JWT).Example: @validate(method: JWT)
LAT_LONGChecks if a string is a valid latitude-longitude coordinate pair.Example: @validate(method: LAT_LONG)
LENGTHChecks if a string's length is within a specified range.min (optional): The minimum length of the string. max (optional): The maximum length of the string. Example: @validate(method: LENGTH)
LOWERCASEChecks if a string is all lowercase.Example: @validate(method: LOWERCASE)
MAC_ADDRESSChecks if a string is a valid Media Access Control (MAC) address.Example: @validate(method: MAC_ADDRESS)
MIME_TYPEChecks if a string is a valid MIME type.Example: @validate(method: MIME_TYPE)
MONGO_IDChecks if a string is a valid MongoDB ObjectId.Example: @validate(method: MONGO_ID)
MULTIBYTEChecks if a string contains any multibyte characters.Example: @validate(method: MULTIBYTE)
NOT_EMPTYChecks if a string is not an empty string.Example: @validate(method: NOT_EMPTY)
NUMERICChecks if a string is a valid number.no_symbols (optional): If true, disallows symbols in the number (such as a leading plus or minus sign). Defaults to false. locale (optional): The locale to use when validating the number. Can be a string (such as "en-US") or an array of strings (such as "en-US", "de-DE"). Example: @validate(method: NUMERIC)
PORTChecks if a string is a valid port number.Example: @validate(method: PORT)
POSTAL_CODEChecks if a string is a valid postal (ZIP) code for a given locale.locale (required): The locale to use when validating the postal code. Example: @validate(method: POSTAL_CODE, locale: "any")
REGEXChecks if a string matches a pattern.pattern (required): The pattern to match against. modifier: (Optional) The regex modifier. Example: @validate(method: REGEX, pattern: "^[a-zA-Z]", modifier: "i")
SLUGChecks if a string is a valid slug.Example: @validate(method: SLUG)
STRONG_PASSWORDChecks if a string is a strong password.minLength (optional): The minimum length of the password. Defaults to 8. minLowercase (optional): The minimum number of lowercase letters. Defaults to 1. minUppercase (optional): The minimum number of uppercase letters. Defaults to 1. minNumbers (optional): The minimum number of digits. Defaults to 1. minSymbols (optional): The minimum number of symbols. Defaults to 1. Example: @validate(method: STRONG_PASSWORD)
SURROGATE_PAIRChecks if a string contains any surrogate pairs characters.Example: @validate(method: SURROGATE_PAIR)
UPPERCASEChecks if a string is all uppercase.Example: @validate(method: UPPERCASE)
URLChecks if a string is a valid URL.protocols (optional): An array of valid protocols (such as http or https). Defaults to ['http', 'https', 'ftp']. require_tld (optional): If true, requires a top-level domain (such as .com). Defaults to true. require_protocol (optional): If true, requires a protocol (such as http). Defaults to false. Example: @validate(method: URL)
UUIDChecks if a string is a valid UUID.version (optional): The UUID version to validate against (such as 3, 4, or 5). Defaults to all versions. Example: @validate(method: UUID)
VARIABLE_WIDTHChecks if a string contains any full-width characters.Example: @validate(method: VARIABLE_WIDTH)
WHITELISTEDChecks if a string contains only whitelisted characters.chars (required): A string containing all allowed characters. Example: @validate(method: WHITELISTED, chars: "abcdefghijklkmopqrstuvwxyz")

Custom Valdiation

You can define your own custom validation logic by registering it on the transform function. First create your own custom validation logic with plugin

const customValidators: Plugins = {
    phone: (val) => /^(\()?\d{3}(\))?(-|\s)?\d{3}(-|\s)\d{4}$/.test(val) || "Invalid phone number"
}

Keep in mind that the name (phone) will be used to identify the plugin. Next step, register the plugin into the transformer.

const schema = val.transform(/* executable schema*/, { customValidators })

The final process, apply it on the @validate directive like below

input UserInput {
    phone: String!  @validate(method: CUSTOM, validator: "phone")
}