Skip to main content

latest

Veelit Validator is a lightweight JavaScript library for validating data against a defined schema. It is a wrapper around the fastest-validator library

Works with
This package works with Bun
It is unknown whether this package works with Cloudflare Workers
This package works with Node.js
This package works with Deno
It is unknown whether this package works with Browsers
JSR Score
70%
Published
2 weeks ago

Veelit Validator

Introduction

Veelit Validator is a lightweight JavaScript library for validating data against a defined schema. It is a wrapper around the fastest-validator library with the enhanced ability to easily define custom validation rules and more.

Installation

with npm:

npm install @veelit/validator

with Bun:

Bun add @veelit/validator

with yarn:

yarn add @veelit/validator

import the Validator class from the package:

import { VeelitValidator } from '@veelit/validator'

Features

  • Extends Fastest-Validator`: Veelit Validator extends the fastest-validator library, providing all its API features.

  • Custom Validators:Contains an easy to understand method to add custom validation rules.

      validator.addValidators(
        /* custom validator config goes here */
        [
          {
            type: 'notEqual',
            validatorFn: (validatorProps: CustomValidatorProps) => {
              const { schema, data, field, value, errors } = validatorProps
    
              // notEqual Rule: compare the value of the field being validated to the value of another field
              if (value === data?.[schema.to]) {
                errors.push({
                  type: 'notEqualField',
                  message: `The '${field}' field value cannot not be equal to the '${schema.to}' field value`,
                  field,
                })
              }
    
              // min Rule: check if the value of the field being validated is at least the specified length
              if (value?.length < schema.min) {
                errors.push({
                  type: 'minField',
                  message: `The ${field} field value must be at least ${schema.min} characters long`,
                  field,
                  expected: schema.min,
                  actual: value?.length,
                })
              }
    
              return value
            },
          },
        ]
      )
    
  • Contains inbuilt validations that are not available in fastest-validator: e.g. notEqual validator for comparing two fields and ensuring they are not equal, with additional support for minimum length checks.

  • Rudimentary SQL Injection Protection: Confugurable protection against SQL injection attacks by default.

    Note: The SQL Injection protection feature is rudimentary and may not cover all possible attack vectors. It adds an extra security layer to escape SQL-sensitive characters that may reduce the risk of SQL injection. It is not recommended as a primary defense and should be used in conjunction with a more robust solution like prepared statements.

      if (this.sqlProtection) {
        input = input
          .replace(/\\/g, '\\\\') // Escape backslashes
          .replace(/\'/g, "\\'") // Escape single quotes
          .replace(/\"/g, '\\"') // Escape double quotes
          .replace(/\n/g, '\\n') // Escape newlines
          .replace(/\r/g, '\\r') // Escape carriage returns
          .replace(/\x00/g, '\\0') // Escape null bytes
          .replace(/\x1a/g, '\\Z') // Escape Ctrl+Z (EOF)
          .replace(/--/g, '') // Remove SQL comments
          .replace(/;/g, '') // Remove SQL terminators
      }
    
  • Cross-Site Scripting (XSS) Protection: Configurable protection against XSS attacks by default.

      if (this.xssProtection) {
        // Apply XSS filtering to cleanse the input of harmful HTML/Javascript content
        input = xssFilters.inHTMLData(input)
    
        // Strip all HTML content, since no HTML is allowed
        input = sanitizeHtml(input, {
          allowedTags: [],
          allowedAttributes: {},
        })
      }
    
  • MoleculerJs, Backend and Frontend Integration: Configurable for use with Moleculerjs, NodeJs, Bun and frontend applications that utilise javascript. Usage in MoleculerJs:

    import Moleculer, { ServiceBroker, type BrokerOptions } from 'moleculer'
    import { VeelitValidator } from '@veelit/validator'
    
    const config = {
      validator:  new VeelitValidator({ 
        target: 'moleculer',
        // other validator config goes here...
    
      })
      // other moleculer config goes here...
    }
    
    const broker = new ServiceBroker(config)
    
    

Usage

1. Initialization

Instantiate the VeelitValidator with optional custom validators and security features enabled/disabled. Here's an example of how to initialize the validator with custom validators and security features disabled:

const config = {
  sqlProtection: false, // default true
  xssProtection: false, // default true
  customValidators: [
    {
      type: 'notEqual',
      validatorFn: (validatorProps) => {
        // Custom validation logic
      },
    },
  ],
}

const validator = new VeelitValidator(config)

2. Adding Validators

You can add validators dynamically using the addValidators method:

validator.addValidators([
  {
    type: 'newValidatorType',
    validatorFn: (validatorProps) => {
      // Validation logic here
    },
  },
])

3. Schema Definition

Define the schema with the necessary validation rules for each field. Since it is based on fastest validator, the schema defintiions are the same. Here's an example schema:

const schema = {
  firstName: 'string|min:3',
  lastName: 'string|min:3',
  email: 'email',
  dateOfBirth: 'string',
  idNumber: 'string|numeric',
  limits: {
    type: 'object',
    props: {
      daily: {
        type: 'number',
        min: 5,
        max: 500000,
      },
      perTransaction: {
        type: 'number',
        min: 5,
        max: 150000,
      },
    },
  },
  oneTimePassword: 'string|numeric|min:4',
  newPassword: 'notEqual|to:oneTimePassword|min:4',
  confirmPassword: 'equal|field:newPassword',
}

4. Data Object

Create the data object that should conform to the defined schema:

const data = {
  firstName: 'john',
  lastName: 'Doe',
  email: 'john.doe@gmail.com',
  dateOfBirth: '1990-01-01',
  idNumber: '1234567890',
  limits: {
    daily: 500000,
    perTransaction: 150000,
  },
  oneTimePassword: '1234',
  newPassword: '1234',
  confirmPassword: '1234',
}

5. Validation Execution

Instantiate the validator and validate the data:

import { VeelitValidator } from '@veelit/validator'

const schema = {
  name: 'string|min:3',
  age: 'number|min:18',
}

const data = {
  name: 'John Doe',
  age: 22,
}

try {
  const validator = new VeelitValidator()
  const isValid = validator.compile(schema)(data)
  
  console.log('Validation Passed:', isValid)
} catch (error) {
  console.error('Validation Failed:', error.message)
}

Custom Validators

Below is a table that describes each property provided to the custom validator functions. These properties are crucial for the dynamic validation of data based on predefined schemas.

Property Type Description Example
schema ValidatorSchema The schema object for the field being validated, detailing the validation rules. Defined as:
`newPassword: 'notEqual
data Object The object containing all the fields that are being validated. { oneTimePassword: '5678', newPassword: '1234' }
field String The key in the data object that is currently being validated, matching a key in the schema object. 'newPassword'
value Any The current value of the field being validated, used for conditions such as min length. '1234'
errors Array of ValidatorError An array that will be populated with details about the failures if the validation fails. [ { type: 'notEqualField', message: "The 'newPassword' field value cannot be equal to the 'oneTimePassword' field value", field: 'newPassword' } ]

Notes

  • The schema object defines what validation rules apply to each field. For example, the newPassword field must not equal the value of oneTimePassword and must be at least 4 characters long.
  • The data object includes all data being processed, important for validations that compare fields or check the overall structure.
  • The field directly corresponds to the individual data element being checked.
  • The value represents the data contained in the field being validated.
  • The errors array collects any and all issues found during validation, each described by a ValidatorError object that includes the type of error, a descriptive message, and the field associated with the error.

Example:

notEqual custom validator

It ensures that the a validated field is not equal to another field. If the fields are equal, an error is added to the errors array.

Implementation of the notEqual custom validator:

const customValidators = [
  {
    type: 'notEqual',
    validatorFn: (validatorProps: CustomValidatorProps) => {
      const { schema, data, field, value, errors } = validatorProps

      // notEqual Rule: compare the value of the field being validated to the value of another field
      if (value === data?.[schema.to]) {
        errors.push({
          type: 'notEqualField',
          message: `The '${field}' field value cannot not be equal to the '${schema.to}' field value`,
          field,
        })
      }

      // min Rule: check if the value of the field being validated is at least the specified length
      if (value?.length < schema.min) {
        errors.push({
          type: 'minField',
          message: `The ${field} field value must be at least ${schema.min} characters long`,
          field,
          expected: schema.min,
          actual: value?.length,
        })
      }

      return value
    },
  },
]

Example schema and data for the notEqual validation:

// usage
const schema = {
  newPassword: {
    type: 'notEqual',
    to: 'oneTimePassword',
    min: 4,
  },
}

// or
const schema = {
  newPassword: 'notEqual|to:oneTimePassword|min:4',
}

const data = {
  oneTimePassword: '5678',
  newPassword: '1234',
}

try {
  const isValid = validator.compile(schema)(data)
  console.log('Validation Passed:', isValid)
} catch (error) {
  console.error('Validation Failed:', error.message)
}

Add Package

deno add @veelit/validator

Import symbol

import * as mod from "@veelit/validator";

Add Package

npx jsr add @veelit/validator

Import symbol

import * as mod from "@veelit/validator";

Add Package

yarn dlx jsr add @veelit/validator

Import symbol

import * as mod from "@veelit/validator";

Add Package

pnpm dlx jsr add @veelit/validator

Import symbol

import * as mod from "@veelit/validator";

Add Package

bunx jsr add @veelit/validator

Import symbol

import * as mod from "@veelit/validator";