Socket
Socket
Sign inDemoInstall

rule-filter-validator

Package Overview
Dependencies
1
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

rule-filter-validator


Version published
Maintainers
1
Created

Readme

Source

The idea

Given a specific scope what is the easiest way to write various rules that be tested against the scope for various reasons

Useful for testing & validation Business Logic stored as json.

Getting started

npm install rule-filter-validator

Usage

// Initial state/scope/payload
const SCOPE = {
    person: {
        id: 1,
        dob: "1998-02-18",
        age: 23,
        active: true,
        gender: 'F'
    }
}
// Validate and return errors
const rule: Filter = {
    "person": {
        "age": {
            "_gt": 18,
            "_lt": 25
        }
    }
}

let errors = validatePayload(rule, SCOPE);
return ! errors.length // true
// Simply validate
// Using field alter functions
isValidPayload({ person: { 'year(dob)': { _eq: 1998 } } }, SCOPE) // true


// Using $NOW
isValidPayload({ person: { 'dob': { _gt: '$NOW(-6 years)' } } }, SCOPE) // false

View all methods and functions

NOTE: Strictness

By default tests are case and type insensitive, meaning:

RuleFnScopeResult
1_eq'1'true
'ABC'_eq'abc'true
'zxc3'_contains3true
'zxc3'_contains'ZXC'true

Calling validatePayload(filter, payload, [strict = false]) with strict = true will make the validator to be case and type sensitive.

RuleFnScopeResult
1_eq'1'false
'ABC'_eq'abc'false
'zxc3'_contains3true
'zxc3'_contains'ZXC'false

_contains always compares as strings and is therefore not type sensitive


Advance Usage

Find a matching price rule
const prices = [
    {
        label: 'Child price'
        price: 100,
        logic: {
            "person": {
                "age": {
                    "_lt": 18
                }
            }
        }
    },
    {
        label: 'Adult price'
        price: 200,
        logic: {
            "person": {
                "age": {
                    "_gte": 18
                }
            }
        }
    }
]

const scope = getUserScope(); // You implement this.

const priceToPay = prices.find(({ price, logic }) => {
    let e = validatePayload(logic, scope)
    return ! e.length
})
Matching items in a list
const filter: Filter = {
    _or: [{
        permissions: {
            _$: {
                action: {
                    _eq: 'update',
                },
                collection: {
                    _eq: 'membership',
                },
                fields: {
                    _contains: 'status',
                },
            },
        },
    },
    {
        role: {
            _eq: 'admin',
        },
    }],
};

const scope = {
    role: 'author',
    permissions: [
        {
            action: 'create',
            collection: 'membership',
            fields: ['person', 'status'],
        },
        {
            action: 'read',
            collection: 'membership',
            fields: ['id', 'person', 'status'],
        },
        {action: 'update', collection: 'membership', fields: ['status']},
    ],
};

const canAccess = validatePayload(filter, scope, strict?).length === 0
Using functions and date adjustments
// passes
validatePayload(
    { person: {'year(dob)': {_eq: 2009}} },
    { person: { dob: '2009-02-18' } }
);

// passes (IF the year is currently 2021)
validatePayload(
    { person: {'year(dob)': {_eq: '$NOW(-12 years).year'}} },
    { person: { dob: '2009-02-19' } }
);



Methods

  • isValidPayload(Filter, Payload, strict?)

    This is a simple function that returns true if the payload is valid against the filter, and false otherwise.

  • validatePayload(Filter, Payload, strict?)

    This is the main function that validates the payload against the filter. It returns an array of errors, if any.

  • invertFilter(Filter)

    Inverts the filter, so that the filter will return the opposite of what it would have returned before.

  • extractFieldFromFilter(Filter, Field, Path?)

    This extracts the given field from the passed Filter and returns a new Filter object that only contains only the given field and its children, if any.

  • adjustDate(date, adjustment)

    The function applies adjustments to the Date using built-in methods such as setUTCMonth, setUTCHours, etc., based on the type of adjustment requested. If no supported adjustment type is supplied, it returns undefined.

    eg. -1 month will return the date 1 month before the given date.

    Supports years, months, days, hours, minutes, seconds, milliseconds, and weeks.


Dynamic values

Currently only supporting one dynamic value, which is $NOW.

Examples:

  • $NOW(-1 month) will test the payload with the date 1 month before the current date.
  • $NOW(-12 years).year will test the payload with the year 12 years before the current date.

Supports all field functions that can be applied to a date.


Operands

Special Operands

FnDescriptionAccepted Types
_andAll of the specified filters must be true for the expression to be truearray of filters
_orAt least one of the specified filters must be true for the expression to be truearray of filters
_$Used as an index for array of objects, whereby at least one item must pass the filter for the expression to be true.object

Field Functions

Used on fields to perform operations on them. eg. year(dob) will test with the year of the date of birth.

FnDescriptionAccepted Types
year()the year of the datedate, isoString
month()the month of the datedate, isoString
week()the week of the datedate, isoString
day()the day of the datedate, isoString
hour()the hour of the datedate, isoString
minute()the minute of the datedate, isoString
second()the second of the datedate, isoString
count()the number of items in the arrayarray

All Operands (Functions)

FnDescriptionAccepted Types
_eqequal tostring, number, boolean
_neqnot equal tostring, number, boolean
_containsstring/array containsstring, number
_ncontainsstring/array does not containstring, number
_starts_withstarts withstring, number
_nstarts_withdoes not start withstring, number
_ends_withends withstring, number
_nends_withdoes not end withstring, number
_ininstring, Array
_ninnot instring, Array
_betweenbetweenstring, number, Date
_nbetweennot betweenstring, number, Date
_gtgreater thanstring, number, Date
_gtegreater than or equal tostring, number, Date
_ltless thanstring, number, Date
_lteless than or equal tostring, number, Date
_nullnull =string, number, boolean, Date, Array
_nnullnot null =string, number, boolean, Date, Array
_emptyempty =string, Array
_nemptynot empty =string, Array
_submittedsubmitted =string, number, boolean, Date, Array
_regexmatching regexstring, number, boolean, Date

_$

Examples of using `_$`

Given the following data record:

const data = {
    colors: [{
        name: 'red',
        hex: '#ff0000',
    }, {
        name: 'green',
        hex: '#00ff00',
    }, {
        name: 'blue',
        hex: '#0000ff',
    }]
};

The following filter will pass:

{
    colors: {
        _$: {
            name: {
                _eq: 'red',
            },
        },
    },
}

And the following will fail:

{
    colors: {
        _$: {
            name: {
                _eq: 'yellow',
            },
        },
    },
}

You could also have multiple properties that have to match

// Will pass
{
    colors: {
        _$: {
            name: {
                _eq: 'red',
            },
            hex: {
                _eq: '#ff0000',
            },
        },
    },
}

// Will fail
{
    colors: {
        _$: {
            name: {
                _eq: 'red',
            },
            hex: {
                _eq: '#ff4444',
            },
        },
    },
};

Keywords

FAQs

Last updated on 18 Jun 2024

Did you know?

Socket

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.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc