![Oracle Drags Its Feet in the JavaScript Trademark Dispute](https://cdn.sanity.io/images/cgdhsj6q/production/919c3b22c24f93884c548d60cbb338e819ff2435-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
indicative
Advanced tools
Indicative is an expressive Javascript validator for humans. Improve your workflow by removing all unnecessary curly braces and nested declarations. Under the hood indicative has following.
if
validationsInstalling indicative requires node 4.0 or greater with npm installed.
npm i --save indicative
Indicative is an expressive schema/raw validator for NodeJs and offers clean syntax over snake of curly braces.To validate an object of data, you need to define a schema where each field can have multiple rules.
You start by requiring indicative and then make use of multiple methods to validate a data object with schema definition.
const indicative = require('indicative')
Validate method will run the validation cycle, which gets terminated on the first error.
const rules = {
username: 'required'
}
const data = {
username: null
}
indicative
.validate(data, rules)
.then(function () {
// validation passed
})
.catch(function (errors) {
// validation failed
})
Validate all will validate all fields even after errors are thrown and return an array of error messages.
indicative.validateAll(data, rules)
Indicative helps you in defining rules as a string, which makes it more readable and remove unnecessary curly braces from your schema definition.
A rule is a combination of certain logical expression that are parsed by a parser before starting validation.
A basic rule may look like this, where we define multiple rules by separating them with a pipe symbol.
{
email_address: 'required|email'
}
A complex rule can have values defined next to rule definition, which later will be used to run validations.
{
age: 'required|above:18'
}
Define age is separated by the colon on above
rule. Also, some rules can accept multiple values next to a given rule.
{
age: 'required|range:18,40'
}
Schema definition is an object containing multiple rules for multiple fields and is used by validation methods.
const rules = {
username : 'required|alpha_numeric',
email : 'required|email',
password : 'required|min:6|max:30'
}
Schema object is a set of different rules defined for different fields and in order to validate an object of data you need to pass rules
and data
together to validate
method.
const rules = {
username : 'required|alpha_numeric',
email : 'required|email',
password : 'required|min:6|max:30'
}
const data = {
username : 'doe22',
email : 'doe@example.org',
password : 'doe123456'
}
indicative
.validate(data, rules)
.then(function () {
// validation passed
})
.catch(function (errors) {
// validation failed
})
In order to validate nested data you need to make use of dot-notation
to target nested fields inside data object.
const rules = {
'profile.username' : 'required',
'profile.password' : 'required|min:6|max:30'
}
const data = {
profile:{
username : 'doe22',
password : 'doe123456'
}
}
Here dot-notation
will help you in removing the use of unnecessary curly braces and can target nested data to any given number of levels.
Indicative self-constructs error messages when validation for a given rule fails, which may not be helpful when trying to keep error messages descriptive and personalised.
Global messages are defined on rules, and the same message will be used whenever a rule will fail.
const messages = {
required: 'This field is required to complete the registration process.'
}
indicative
.validate(data, rules, messages)
.then(function () {
// validation passed
})
.catch(function (errors) {
// validation failed
})
Whenever a required
rule fails, it will return your custom message instead of a self-constructed message.
field
specific messages are even more personalised as they are defined for a given rule and field.
const messages = {
'username.required' : 'Username is required to continue',
'email.required' : 'Email is required for further communication'
}
indicative
.validate(data, rules, messages)
.then(function () {
// validation passed
})
.catch(function (errors) {
// validation failed
})
Also, you can make use of dot-notation
while defining messages.
const messages = {
'profile.username.required': 'Username is required to setup profile'
}
instead of defining a string as a message, you can also define a function to return message
const messages = {
'username.required': function (field, validation, args) {
return `${field} is required`
}
}
All custom messages support templating, which means you can define special placeholders that will be replaced with actual values while constructing messages.
field
is the name of the field under validation
const messages = {
required: '{{field}} is required to complete registeration process'
}
Name of the validation rule.
const messages = {
email: '{{validation}} validation failed on {{field}}.'
}
const data = {
email: 'abc'
}
arguments
are values defined on rules inside schema, and they can be accessed using their array index.
const messages = {
above: '{{field}} must be over {{argument.0}} years'
}
const rules = {
age: 'above:18'
}
const data = {
age: 10
}
Above message will yield age must be over 18 years
.
Validating arrays asynchronously is never fun. Indicative makes it so simple to validating one level deep nested arrays using array expressions
.
const rules = {
'users.*.username': 'required|alpha',
'users.*.email': 'required|email'
}
const data = {
users: [
{
username: 'validUsername',
email: 'bar.sneark@gmail.com'
},
{
username: '123Invalid',
email: 'bar.com'
}
]
}
indicative
.validate(data, rules)
.then(function () {
// validation passed
})
.catch(function (errors) {
// validation failed
})
Also you can validate flat arrays using the same expression syntax.
const rules = {
'emails': 'array|min:2',
'emails.*': 'email'
}
const data = {
emails: ['foo@bar.com', 'invalid.com']
}
indicative
.validate(data, rules)
.then(function () {
// validation passed
})
.catch(function (errors) {
// validation failed
})
First rule of developing applications is to keep your datastores clean. Indicative sanitizor will help you in normalizing data by using set of specific rules.
Like validations you can use a schema object to sanitize our data object.
const indicative = require('indicative')
const data = {
email: 'bar.sneaky+foo@googlemail.com',
age: '22',
aboutme: 'i am dev @<a href="http://nowhere.com">nowhere</a>'
}
const sanitizationRules = {
email: 'normalize_email',
age: 'to_int',
aboutme: 'strip_links'
}
const sanitizedData = indicative.sanitize(data, sanitizationRules)
console.log(sanitizedData)
/**
{
email: 'barsneaky@gmail.com',
age: 22,
aboutme: 'i am dev @nowhere'
}
*/
For quick sanitizations you can make use of raw filters
const indicative = require('indicative')
indicative.sanitizor.toInt('22') // 22
indicative.sanitizor.slug('hello world') // hello-world
indicative.sanitizor.toDate('22-1-2016') // javascript date object
Below is the list of filters available to be used for raw and schema sanitizations.
removes values inside blacklist from the actual string. Passed values are used inside a regex, so make sure to escape values properly. \\[\\]
instead of \
.
// raw sanitization
indicative.sanitizor.blacklist('hello world', 'ord')
// with schema
{
description: 'blacklist:ord'
}
Escapes html characters with html entities
// raw sanitization
indicative.sanitizor.escape('<div> hello world </div>')
// with schema
{
description: 'escape'
}
Normalizes email and accepts options to avoid certains transformations.
!lc - Do not convert email to lowercase, hence domain name will be converted to lowercase. FOO@GMAIL.COM
will become FOO@gmail.com
!rd - Stop sanitizor from removing dots.
!re - Do not remove everything after +
symbol. bar.sneaky+foo@gmail.com
will become barsneaky+foo@gmail.com
// raw sanitization
indicative.sanitizor.normalizeEmail('bar.sneaky+foo@gmail.com', ['!rd', '!re', '!lc'])
// with schema
{
email: 'normalize_email:!rd,!re,!lc'
}
Converts value to a boolean, 0, false, null, undefined, ''
will return false
and everything else will return true
.
// raw sanitization
indicative.sanitizor.toBoolean('false')
// with schema
{
isAdmin: 'to_boolean'
}
Converts value to float and returns NaN
if unable to convert.
// raw sanitization
indicative.sanitizor.toFloat('32.55')
// with schema
{
marks: 'to_float'
}
Converts value to integer and returns NaN
if unable to convert.
// raw sanitization
indicative.sanitizor.toInt('32')
// with schema
{
age: 'to_int'
}
Converts value to date object and returns null
if unable to convert.
// raw sanitization
indicative.sanitizor.toDate('2010-22-10')
// with schema
{
birthday: 'to_date'
}
Strips <a></a>
tags from a given string. If input is not a string, actual value will be returned.
// raw sanitization
indicative.sanitizor.stripLinks('<a href="http://adonisjs.com"> Adonisjs </a>')
// with schema
{
bio: 'strip_links'
}
Strips html tags from a given string. If input is not a string, actual value will be returned.
// raw sanitization
indicative.sanitizor.stripTags('<p> Hello </p>')
// with schema
{
tweet: 'strip_tags'
}
Converts a given value to plural. Which means person
will be converted to people
.
// raw sanitization
indicative.sanitizor.plural('child')
// with schema
{
november14: 'plural'
}
Converts a given value to singular. Which means people
will be converted to person
.
// raw sanitization
indicative.sanitizor.plural('children')
// with schema
{
november14: 'singular'
}
Converts a given to camel-case.
// raw sanitization
indicative.sanitizor.camelCase('users-controller')
// with schema
{
fileName: 'camel_case'
}
capitalize
a given string.
// raw sanitization
indicative.sanitizor.capitalize('doe')
// with schema
{
fullName: 'capitalize'
}
decapitalize
a given string.
// raw sanitization
indicative.sanitizor.decapitalize('Bar')
// with schema
{
username: 'decapitalize'
}
converts a value to title case
// raw sanitization
indicative.sanitizor.title('hello-world')
// with schema
{
title: 'title'
}
Converts a value to url friendly slug.
// raw sanitization
indicative.sanitizor.slug('learn node in 30 minutes')
// with schema
{
title: 'slug'
}
Indicative ships with a handful of validation rules, which may or may not be enough for your application that's why it is so easy to extend schema or raw validator to register your custom rules.
Extending Schema validator will register your custom rule to validations store and should follow defined convention, where all rules are registered as camelCase
and consumed as snake_case
.
For example, indicative's alpha_numeric
rule is defined as alphaNumeric
inside validation store.
Validation method supports async
execution and should return a promise. Async
execution makes is easier for you to write database driven rules. For example unique
rule to check if the username already exists or not.
const unique = function (data, field, message, args, get) {
return new Promise(function (resolve, reject) {
// get value of field under validation
const fieldValue = get(data, field)
// resolve if value does not exists, value existence
// should be taken care by required rule.
if(!fieldValue) {
return resolve('validation skipped')
}
// checking for username inside database
User
.where('username', fieldValue)
.then(function (result) {
if(result){
reject(message)
}else{
resolve('username does not exists')
}
})
.catch(resolve)
})
}
Above we defined a method to check for a unique username inside the database, validation method can keep any logic to validate data but you should know about method parameters to make valid decisions.
validate
method.min:4
will have args array as [4]
.get
method takes care of it.Once you have defined your validation method, you can add it to validations store by calling extend
method.
indicative.extend('unique', unique, 'Field should be unique')
Extend method takes 3 required parameters to register validation to validations store.
camelCase
which is consumed as snake_case
.Once your custom validation rule has been stored, you can consume it inside your schema.
const rules = {
username: 'required|unique'
}
Extending raw validator is fairly simple as raw validations are quick validations. An example of raw validation can be
indicative.is.email('your@youremail.com')
And to extend raw validator you need to define a validation method that can accept n
number of arguments based on validation expectations. A good example of raw validation can be a password strength checker
const strongPassword = function (password) {
const strongRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#\$%\^&\*])(?=.{8,})/
return strongRegex.test(password)
}
Above we created a function to check whether a password is strong enough or not, and now we can register it is a raw validator.
indicative.is.extend('strongPassword', strongPassword)
is.extend
accepts two parameters where the first one is the method name and second is validation method to execute. Finally, you can use this method as follows.
indicative.is.strongPassword('lowerUPP@123')
// returns true
You can also extend sanitizor to add more filters to it. All extended methods will get the value to sanitize, with an array of options.
const uppercase = function (value, options: Array) {
return value.toUpperCase()
}
Above we created a simple method to return Uppercase
version of a string. Now we will added to the list of sanitizor filters, so that we can use it later.
indicative.sanitizor.extend('uppercase', uppercase)
Now finally you can use it.
// raw sanitizor
indicative.sanitizor.uppercase('hello world')
// with schema
{
userStatus: 'uppercase'
}
Below is the list of methods supported by the raw validator, also you can extend raw validator to add your rules.
Types based validations will check for a certain type
indicative.is.array({age:22})
=> false
indicative.is.array('hello world')
=> false
indicative.is.array([20,22])
=> true
indicative.is.array([])
=> true
indicative.is.boolean('true')
=> false
indicative.is.boolean('hello')
=> false
indicative.is.boolean(0)
=> true
indicative.is.boolean(1)
=> true
indicative.is.boolean(true)
=> true
indicative.is.boolean(false)
=> true
strict true
will only return true when a date object is passed.
indicative.is.date('2011-10-20')
=> true
indicative.is.date('2011-10-20', true)
=> false
indicative.is.date(new Date('2011-10-20'))
=> true
indicative.is.date(new Date('2011-10-20'), true)
=> true
indicative.is.function(function () {})
=> true
indicative.is.function('function () {}')
=> false
indicative.is.null(null)
=> true
indicative.is.null('null')
=> false
indicative.is.number(22)
=> true
indicative.is.number('22')
=> false
indicative.is.object({name:'doe'})
=> true
indicative.is.object(['doe'])
=> false
indicative.is.object('doe')
=> false
indicative.is.object({})
=> true
indicative.is.json(JSON.stringify({name:'doe'}))
=> true
indicative.is.json(JSON.stringify([10,20]))
=> true
indicative.is.json({name:'doe'})
=> false
indicative.is.string(JSON.stringify({name:'doe'}))
=> true
indicative.is.string('hello world')
=> true
indicative.is.string(22)
=> false
indicative.is.sameType(22,10)
=> true
indicative.is.sameType('hello', 'world')
=> true
indicative.is.sameType(22, '10')
=> false
indicative.is.existy('')
=> false
indicative.is.existy(null)
=> false
indicative.is.existy(undefined)
=> false
indicative.is.existy('hello')
=> true
indicative.is.existy(22)
=> true
indicative.is.truthy(false)
=> false
indicative.is.truthy(0)
=> false
indicative.is.truthy(true)
=> true
indicative.is.truthy('hello')
=> true
indicative.is.falsy(false)
=> true
indicative.is.falsy(0)
=> true
indicative.is.falsy(true)
=> false
indicative.is.falsy('hello')
=> false
indicative.is.empty(null)
=> true
indicative.is.empty(undefined)
=> true
indicative.is.empty({})
=> true
indicative.is.empty([])
=> true
indicative.is.empty('')
=> true
indicative.is.empty('hello')
=> false
indicative.is.empty(0)
=> false
indicative.is.url('http://adonisjs.com')
=> true
indicative.is.url('https://adonisjs.com')
=> true
indicative.is.url('adonisjs.com')
=> false
indicative.is.url('adonisjs')
=> false
indicative.is.email('email@example.org')
=> true
indicative.is.url('email.org')
=> false
indicative.is.phone('1235554567')
=> true
indicative.is.phone('444-555-1234')
=> true
indicative.is.phone('246.555.8888')
=> true
indicative.is.phone('19929')
=> false
supports Visa,MasterCard,American Express,Diners Club,Discover,JCB
indicative.is.creditCard('4444-4444-4444-4444')
=> true
indicative.is.creditCard('4444444444444444')
=> true
indicative.is.creditCard('3685-1600-4490-1023')
=> false
indicative.is.alpha('virk')
=> true
indicative.is.alpha('VIrk')
=> true
indicative.is.alpha('virk123')
=> false
indicative.is.alphaNumeric('virk')
=> true
indicative.is.alphaNumeric('virk123')
=> true
indicative.is.alphaNumeric('virk@123')
=> false
indicative.is.ip('127.0.0.1')
=> true
indicative.is.ip('192.168.0.1')
=> true
indicative.is.ip('1:2:3:4:5:6:7:8')
=> true
indicative.is.ip('localhost')
=> false
indicative.is.ipv4('127.0.0.1')
=> true
indicative.is.ipv4('192.168.0.1')
=> true
indicative.is.ipv4('1:2:3:4:5:6:7:8')
=> false
indicative.is.ipv6('985.12.3.4')
=> true
indicative.is.ipv6('1:2:3:4:5:6:7:8')
=> true
indicative.is.ipv6('1.2.3')
=> false
run your own custom regex
indicative.is.regex(/[a-z]+/,'virk')
=> true
indicative.is.regex(/[a-z]+/,'virk123')
=> false
indicative.is.same(10,5+5)
=> true
indicative.is.same('hello','hello')
=> true
indicative.is.same('10',10)
=> false
indicative.is.even(10)
=> true
indicative.is.even(5)
=> false
indicative.is.odd(10)
=> false
indicative.is.odd(5)
=> true
indicative.is.positive(10)
=> true
indicative.is.positive(-10)
=> false
indicative.is.negative(10)
=> false
indicative.is.negative(-10)
=> true
indicative.is.above(10, 20)
=> false
indicative.is.above(30,20)
=> true
indicative.is.under(30, 20)
=> false
indicative.is.under(10,20)
=> true
indicative.is.between(20,10,30)
=> true
indicative.is.between(5,10,30)
=> false
indicative.is.inArray(10,[10,20,40])
=> true
indicative.is.inArray(5,[10,20,40])
=> false
indicative.is.sorted([10,20,40,50])
=> true
indicative.is.sorted([10,15,5,20])
=> false
indicative.is.intersectAny([10,20],[30,10,40])
=> true
indicative.is.intersectAny([10,20],[30,50,40])
=> false
indicative.is.intersectAll([10,20],[20,10,50,40])
=> true
indicative.is.intersectAll([10,20],[10,50,40])
=> false
indicative.is.today(new Date())
=> true
// if today date is 2015-11-30
indicative.is.today("2015-11-30")
=> true
const yesterday = new Date(new Date().setDate(new Date().getDate() - 1))
indicative.is.today(yesterday)
=> false
indicative.is.yesterday(new Date())
=> false
// if yesterday date was 2015-11-29
indicative.is.yesterday("2015-11-29")
=> true
const yesterday = new Date(new Date().setDate(new Date().getDate() - 1))
indicative.is.yesterday(yesterday)
=> true
indicative.is.tomorrow(new Date())
=> false
// if tomorrow date will be 2015-12-01
indicative.is.tomorrow("2015-12-01")
=> true
const tomorrow = new Date(new Date().setDate(new Date().getDate() + 1))
indicative.is.tomorrow(tomorrow)
=> true
indicative.is.past("2001-01-10")
=> true
const tomorrow = new Date(new Date().setDate(new Date().getDate() + 1))
indicative.is.past(tomorrow)
=> false
indicative.is.future("2001-01-10")
=> false
const tomorrow = new Date(new Date().setDate(new Date().getDate() + 1))
indicative.is.future(tomorrow)
=> true
indicative.is.after("2015-10-01", "2015-10-03")
=> false
indicative.is.after("2015-10-01", "2015-09-10")
=> true
indicative.is.before("2015-10-01", "2015-10-03")
=> true
indicative.is.before("2015-10-01", "2015-09-10")
=> false
indicative.is.dateFormat("2015-10-01", ['YYYY-MM-DD'])
=> true
indicative.is.dateFormat("2015/10/01", ['YYYY-MM-DD'])
=> false
indicative.is.dateFormat("2015/10/01", ['YYYY-MM-DD', 'YYYY/MM/DD'])
=> true
indicative.is.inDateRange("2015-10-01", "2015-09-01", "2015-12-01")
=> true
indicative.is.inDateRange("2015-10-01", "2015-11-01", "2015-12-01")
=> false
Schema rules can/may be different from raw validation rules. In order make use of schema validation rules you need to pass a schema object to indicative validate
or validateAll
method.
const indicative = require('indicative')
const rules = {
username : 'required|alpha_numeric|min:6|max:20',
email : 'required|email'
}
indicative
.validate(data, rules)
.then (function () {
// validation passed
})
.catch(function () {
// validation failed
})
above accepted after after_offset_of alpha alpha_numeric array before before_offset_of boolean date date_format different email ends_with equals in includes integer ip ipv4 ipv6 json max min not_equals not_in object range regex required required_if required_when required_with_all required_with_any required_without_all required_without_any same starts_with string under url
the field under validation should be above defined value
{
age : 'above:18'
}
field should have been accepted with truthy value for ex - yes,1,true
{
toc: 'accepted'
}
the value of field should be after define date
{
newyear_party: 'after:2015-12-24'
}
the value of field should be after defined offset from today's date
{
expires: 'after_offset_of:12,months'
}
the value of field should contain letters only
{
name: 'alpha'
}
the value of field should contain letters and numbers only
{
username: 'alpha_numeric'
}
the value should be an array
{
permissions : 'array'
}
the value of field should be before define date
{
file_tax: 'before:2015-03-31'
}
the value of field should be before defined offset from today's date
{
enrollment: 'before_offset_of:1,year'
}
value of field should contain a boolean value, true,false,0,1,'0','1' will yield true
{
is_admin: 'boolean'
}
the value of field should be a valid date, MM/DD/YYYY, MM-DD-YYYY, YYYY-MM-DD, YYYY/MM/DD formats are allowed
{
published_on: 'date'
}
the value of field should be a valid date according to given format
{
published_on: 'date_format:YYYY-MM-DD'
}
the value of 2 fields should be different
{
alternate_email: 'different:email'
}
should be a valid email address
{
email_address: 'email'
}
the string should end with given letters
{
domain: 'ends_with:.com'
}
the value of field under validation should equal the defined value
{
age: 'equals:26'
}
the value of field should fall within defined values
{
gender: 'in:Male,Female,Other'
}
the value of field should include define letters
{
sub_domain: 'includes:adonisjs'
}
the value of field under validation should be an integer
{
age: 'integer'
}
the value of field under validation should be a valid ip address
{
ip_address: 'ip'
}
the value of field under validation should be a valid ipv4 address
{
ip_address: 'ipv4'
}
the value of field under validation should be a valid ipv6 address
{
ip_address: 'ipv6'
}
value of field is safe for JSON.parse
{
meta_data: 'json'
}
The length of a given field should not be more than defined length. Numbers and strings are evaluated same way.
{
password: 'max:20'
}
The length of a given field should not be less than defined length. Numbers and strings are evaluated same way
{
password: 'min:6'
}
the value of field under should be different from defined value
{
username: 'not_equals:admin'
}
the value of field under should not be one of the defined values.
{
username: 'not_in:admin,super,root'
}
the value of field should be a valid javascript object
{
profile: 'object'
}
value of field should be inside defined range, shorthand for min and max
{
password: 'range:6,20'
}
the value of field under validation should satisfy regex pattern.
Note : Always define rules as array when making use of regex rule
{
username: ['regex:^[a-zA-z]+$']
}
the field should exist and contain some value
{
username: 'required'
}
the field is required when defined field exists
{
password_confirmation: 'required_if:password'
}
the field is required when value of defined field is same as defined value
{
state: 'required_when:country,US'
}
the field is required when all other fields are present
{
social_geek: 'required_with_all:twitter,facebook,tumblr'
}
the field is required when any of the other fields are present
{
social_login: 'required_with_any:facebook_token,twitter_token'
}
the field is required when all of the other fields does not exist
{
rent: 'required_without_all:onwer,buyer'
}
the field is required when any of the other fields does not exist
{
sell: 'required_without_any:onwer,buyer'
}
the value of field should be same as the value of define field
{
password_confirm: 'same:password'
}
the value of field should start with defined letters
{
accepted: 'starts_with:y'
}
the value of field under validation should be a string
{
username: 'string'
}
the value of field should be under defined value
{
age: 'under:60'
}
the value of field should be a valid url
{
blog: 'url'
}
FAQs
Concise data validation library for Node.js and browsers
The npm package indicative receives a total of 14,239 weekly downloads. As such, indicative popularity was classified as popular.
We found that indicative demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.