🚀 DAY 5 OF LAUNCH WEEK: Introducing Socket Firewall Enterprise.Learn more →
Socket
Book a DemoInstallSign in
Socket

@activix/spec-pattern

Package Overview
Dependencies
Maintainers
4
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@activix/spec-pattern

Specification Pattern in TypeScript

latest
Source
npmnpm
Version
1.1.2
Version published
Maintainers
4
Created
Source

spec-pattern

Implementation of the Specification Pattern for JavaScript and TypeScript.

Useful for building complex filters or rules in a easy way.

No external dependencies. Fully tested. Adopts semantic versioning. Forks are welcome!

Build Status

Install

$ npm install spec-pattern --save

Examples

A simple Between rule

import { Between } from 'spec-pattern';

let rules = new Between( 1, 3 );

console.log( rules.isSatisfiedBy( 2 ) ); // true

A little more complex Between rule

import { Between } from 'spec-pattern';

let rules = new Between( 1, 3 )
   .or( new Between( 6, 9 ) );

console.log( rules.isSatisfiedBy( 2 ) ); // true
console.log( rules.isSatisfiedBy( 7 ) ); // true
console.log( rules.isSatisfiedBy( 5 ) ); // false

Composing rules

import { Between, In, GreaterThan } from 'spec-pattern';

let rules = new Between( 1, 3 )
   .or( new Between( 6, 9 ) )
   .or( new In( [ 11, 25, 31 ] )
   .or( new GreaterThan( 50 ) );

console.log( rules.isSatisfiedBy( 2 ) ); // true
console.log( rules.isSatisfiedBy( 7 ) ); // true
console.log( rules.isSatisfiedBy( 5 ) ); // false
console.log( rules.isSatisfiedBy( 11 ) ); // true
console.log( rules.isSatisfiedBy( 50 ) ); // false
console.log( rules.isSatisfiedBy( 51 ) ); // true

Not only numbers

import { StartsWith, Contains } from 'spec-pattern';

let rules = new StartsWith( 'Hello' )
    .andNot( new Contains( 'world' ) );

console.log( rules.isSatisfiedBy( 'Hello Bob' ) ); // true
console.log( rules.isSatisfiedBy( 'Hello world' ) ); // false
import { LengthBetween, EqualTo } from 'spec-pattern';

let rules = new LengthBetween( 2, 5 )
    .andNot( new EqualTo( 'Hello' ) );

console.log( rules.isSatisfiedBy( '' ) ); // false
console.log( rules.isSatisfiedBy( 'Hi' ) ); // true
console.log( rules.isSatisfiedBy( 'Hello' ) ); // false
console.log( rules.isSatisfiedBy( 'Howdy' ) ); // true
console.log( rules.isSatisfiedBy( 'Hello world' ) ); // false

Available classes

  • EqualTo( value: any )
  • GreaterThan( value: any )
  • GreaterThanOrEqualTo( value: any )
  • LessThan( value: any )
  • LessThanOrEqualTo( value: any )
  • Between( min: any, max: any )
  • In( values: array )
  • StartsWith( value: string, ignoreCase: boolean = false )
  • EndsWith( value: string, ignoreCase: boolean = false )
  • Contains( value: string, ignoreCase: boolean = false )
  • LengthBetween( min: any, max: any )
  • Matches( regex: RegExp )

All these classes extend the abstract class Composite, which in turn implements the interface Spec:

interface Spec< T > {

    isSatisfiedBy( candidate: T ): boolean;

    and( other: Spec< T > ): Spec< T >;

    andNot( other: Spec< T > ): Spec< T >;

    or( other: Spec< T > ): Spec< T >;

    orNot( other: Spec< T > ): Spec< T >;

    not(): Spec< T >;
}

Creating your own class

Creating your own class is very easy. Just extends abstract class Composite_, like in the following example. Of course, you can also extend one of the aforementioned classes or implement the interface Spec_ (but why reinventing the wheel, right?).

Let's create a class DifferentFrom_ ...

...in TypeScript:

import { Composite } from 'spec-pattern';

export class DifferentFrom< T > extends Composite< T > {

    constructor( private _value: T ) {
        super();
    }

    isSatisfiedBy( candidate: T ): boolean {
        return this._value != candidate;
    }

    toString(): string {
        return 'different from ' + this._value;
    }
}

...or in JavaScript 6+:

import { Composite } from 'spec-pattern';

class DifferentFrom extends Composite {

    constructor( value ) {
        this._value = value;
    }

    isSatisfiedBy( candidate ) {
        return this._value != candidate;
    }

    toString() {
        return 'different from ' + this._value;
    }
}

...or in JavaScript 5+:

var Composite  = require( 'spec-pattern' ).Composite;

function DifferentFrom( value ) {

    Composite.call( this ); // super()

    this._value = value;

    this.isSatisfiedBy = function ( candidate ) {
        return this._value != candidate;
    };

    this.toString = function() {
        return 'different from ' + this._value;
    };
}

DifferentFrom.prototype = Object.create( Composite.prototype );
DifferentFrom.prototype.constructor = DifferentFrom;

That's it! Just three methods: constructor, isSatisfiedBy, and toString().

License

MIT © Thiago Delgado Pinto

Keywords

design-pattern

FAQs

Package last updated on 19 Jul 2018

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