A collection of scalar types not included in base GraphQL.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Custom scalar creation utilities for advanced use cases. These utilities allow developers to create custom GraphQL scalar types with regex-based validation for domain-specific requirements.
Base class for creating custom GraphQL scalar types with regular expression validation.
/**
* Base class for creating custom GraphQL scalar types with regex validation
* Extends GraphQLScalarType with regex-based validation logic
*/
class RegularExpression extends GraphQLScalarType {
constructor(name: string, regex: RegExp, options?: RegularExpressionOptions);
}Parameters:
name: The name of the custom scalar typeregex: Regular expression pattern for validationoptions: Optional configuration objectConfiguration interface for customizing RegularExpression behavior.
interface RegularExpressionOptions {
/** Custom error message function */
errorMessage?: RegularExpressionErrorMessageFn;
/** Description for the scalar type */
description?: string;
/** Whether to only accept string values */
stringOnly?: boolean;
}Function type for generating custom error messages.
/**
* Function type for generating custom validation error messages
* @param r - The regular expression that failed validation
* @param v - The value that failed validation
* @returns Custom error message string
*/
type RegularExpressionErrorMessageFn = (r: RegExp, v: any) => string;import { RegularExpression } from "graphql-scalars";
// Create a custom scalar for product codes
const GraphQLProductCode = new RegularExpression(
"ProductCode",
/^[A-Z]{2}-[0-9]{4}-[A-Z]{2}$/,
{
description: "Product code in format XX-0000-XX",
errorMessage: (regex, value) =>
`Product code must match format XX-0000-XX, got: ${value}`,
stringOnly: true
}
);
// Create a custom scalar for license plates
const GraphQLLicensePlate = new RegularExpression(
"LicensePlate",
/^[A-Z0-9]{1,8}$/,
{
description: "Vehicle license plate (1-8 alphanumeric characters)",
stringOnly: true
}
);
// Create a custom scalar for hex colors (alternative to built-in)
const GraphQLCustomHexColor = new RegularExpression(
"CustomHexColor",
/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/,
{
description: "Hexadecimal color code (#RGB or #RRGGBB)",
errorMessage: (regex, value) =>
`Invalid hex color format: ${value}. Expected #RGB or #RRGGBB`,
stringOnly: true
}
);import { GraphQLObjectType, GraphQLString, GraphQLSchema } from "graphql";
// Define schema using custom scalars
const ProductType = new GraphQLObjectType({
name: "Product",
fields: {
id: { type: GraphQLProductCode },
name: { type: GraphQLString },
color: { type: GraphQLCustomHexColor },
},
});
const VehicleType = new GraphQLObjectType({
name: "Vehicle",
fields: {
licensePlate: { type: GraphQLLicensePlate },
make: { type: GraphQLString },
model: { type: GraphQLString },
},
});
// Schema with type definitions
const typeDefs = `
scalar ProductCode
scalar LicensePlate
scalar CustomHexColor
type Product {
id: ProductCode!
name: String!
color: CustomHexColor
}
type Vehicle {
licensePlate: LicensePlate!
make: String!
model: String!
}
`;
// Resolvers map
const resolvers = {
ProductCode: GraphQLProductCode,
LicensePlate: GraphQLLicensePlate,
CustomHexColor: GraphQLCustomHexColor,
};// Social Security Number (US format)
const GraphQLSSN = new RegularExpression(
"SSN",
/^\d{3}-\d{2}-\d{4}$/,
{
description: "US Social Security Number (XXX-XX-XXXX)",
errorMessage: (regex, value) =>
`SSN must be in format XXX-XX-XXXX, got: ${value}`,
stringOnly: true
}
);
// Credit Card Number (basic format validation)
const GraphQLCreditCard = new RegularExpression(
"CreditCard",
/^\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}$/,
{
description: "Credit card number (16 digits with optional spaces or dashes)",
errorMessage: (regex, value) =>
`Invalid credit card format: ${value}`,
stringOnly: true
}
);
// Stock Symbol
const GraphQLStockSymbol = new RegularExpression(
"StockSymbol",
/^[A-Z]{1,5}$/,
{
description: "Stock trading symbol (1-5 uppercase letters)",
errorMessage: (regex, value) =>
`Stock symbol must be 1-5 uppercase letters, got: ${value}`,
stringOnly: true
}
);
// Semantic Version (custom implementation)
const GraphQLCustomSemVer = new RegularExpression(
"CustomSemVer",
/^(\d+)\.(\d+)\.(\d+)(?:-([a-zA-Z0-9\-\.]+))?(?:\+([a-zA-Z0-9\-\.]+))?$/,
{
description: "Semantic version (MAJOR.MINOR.PATCH)",
errorMessage: (regex, value) =>
`Invalid semantic version format: ${value}. Expected MAJOR.MINOR.PATCH`,
stringOnly: true
}
);When stringOnly: true, the scalar will only accept string literals in GraphQL queries:
// With stringOnly: true
const GraphQLStrictCode = new RegularExpression(
"StrictCode",
/^[A-Z]{3}$/,
{ stringOnly: true }
);
// Valid GraphQL usage:
// mutation { createItem(code: "ABC") }
// Invalid GraphQL usage (will throw error):
// mutation { createItem(code: 123) }Provide meaningful error messages for better developer experience:
const GraphQLCustomFormat = new RegularExpression(
"CustomFormat",
/^[A-Z]{2}-\d{4}$/,
{
errorMessage: (regex, value) => {
if (typeof value !== 'string') {
return `Expected string value, got ${typeof value}: ${value}`;
}
if (value.length !== 7) {
return `Expected 7 characters (XX-0000), got ${value.length}: ${value}`;
}
return `Invalid format. Expected XX-0000 pattern, got: ${value}`;
}
}
);# Query using custom scalars
query GetProduct($productId: ProductCode!) {
product(id: $productId) {
id
name
color
}
}
# Mutation with validation
mutation CreateVehicle($input: VehicleInput!) {
createVehicle(input: $input) {
licensePlate
make
model
}
}Variables:
{
"productId": "AB-1234-CD",
"input": {
"licensePlate": "ABC123",
"make": "Toyota",
"model": "Camry"
}
}// Valid values for custom scalars
const validData = {
productCode: "AB-1234-CD", // Matches XX-0000-XX pattern
licensePlate: "ABC123", // 1-8 alphanumeric characters
hexColor: "#FF5733", // Valid hex color
ssn: "123-45-6789", // Valid SSN format
stockSymbol: "AAPL" // 1-5 uppercase letters
};
// Invalid values (will fail validation)
const invalidData = {
productCode: "AB-12345-CD", // Too many digits
licensePlate: "ABC@123", // Special character not allowed
hexColor: "#GG5733", // Invalid hex characters
ssn: "123456789", // Missing dashes
stockSymbol: "apple" // Lowercase not allowed
};RegularExpression is ideal for:
Consider using specific built-in scalars when available, as they often provide better validation and error messages than custom regex-based solutions.