npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

business-engine

v1.0.1

Published

`business-engine` helps you enforce business rules on your domain. Easily testable and standalone, you will now have freedom over your code base.

Downloads

31

Readme

Business Engine

npm version Build Status GitHub issues Dependencies Dev Dependencies Peer Dependencies Coverage Status Known Vulnerabilities npm downloads GitHub license GitHub version code style: prettier

Empower your software!

Business Engine is a Node.js module allowing you to easily implement your business rules against your domain. Testable, standalone, opinionated and framework agnostic, you now have the power to make your code base shiny again.

It can be used on its own, or altogether with some other tools, such as Mongoose.

Installation

npm install business-engine --save

or

yarn add business-engine --exact --latest

Usage

Because Business Engine is totally DOM free and UI Independent, you can basically do whatever you want with it. An example would be to check whether a given entity is valid according to predefined business rules. We could ask the engine to check said entity in a dedicated service, upon creation or update.

Let's do it. We will show how to validate a simple user representation against a few business rules.

Here is what our User domain looks like:

export class User {
    public email: string;
    public lastName: string;
    public firstName: string;
}

Let's review which business rules we would like to apply on this User class.

1 - First name property is mandatory 2 - Email property should match a given email pattern (anything that ends in @gmail.com), but only when we create it 2 - Email property should be unique in our database

The first and second rules are quite easy to implement. Actually, there are even rules shipped with Business Engine that will do the work for us. We will use the StringPropertyRequiredRule and StringFormatRule rules, respectively.

The latter is a bit more complicated. As Business Engine is database agnostic, this kind of rules cannot be pre-implemented for us. We have to do it ourselves. For brevity, we won't show the database logic. Let's implement the UniqueUserEmailRule rule.

import { isNil } from "lodash";
import { User } from "../domain/User";
import { BusinessRule, BusinessRuleError } from "business-engine";

// IMPORTANT NOTE
// The entire business engine logic is built around optionals.
import Optional from "typescript-optional";

export class UniqueUserEmailRule<User> extends BusinessRule<User> {

    // This method allows you to implement some kind of routing logic.
    // If the rule applies to your entity, then return true.
    // If not, return false.
    // For example, this can be useful if you only want to target a specific mode
    // no matter what. Or if the rule must only target entities containing specific properties,
    // and so on.
    public isApplicable(user: User): boolean {
        return true;
    }

    protected checkForCreation(user: User): Optional<BusinessRuleError<User>> {
        // ... database logic to check if user's email address is already taken

        if (/* email address already in use */) {
            // When the entity being check is not compliant
            // the engine expects an error to be returned.
            return Optional.ofNonNull(this.buildError(user));
        }

        // When the entity being checked is valid, no error should be risen.
        // Therefore an error-free optional.
        return Optional.empty();
    }

    // In our case, the UPDATE logic is just the same as the CREATE logic
    protected checkForUpdate(user: User): Optional<BusinessRuleError<User>> {
        return this.checkForCreation(user);
    }

    private buildError(user: User): BusinessRuleError<User> {
        return new BusinessRuleError<User>("my-project.errors.email.already.used", "email must be unique")
            .set("EMAIL", user.email);
    }
}

Let's say we have a UserService which role is to handle all user interactions, between our resource layer and our repository layer. It has the duty to make sure our User conforms to our rules before making it to the next layer.

import { List } from "immutable";
import { User } from "../domain/User";
import { UniqueUserEmailRule } from "../rules/UniqueUserEmailRule";
import { BusinessRuleService, IBusinessRule, BusinessRuleMode, StringPropertyRequiredRule, StringFormatRule } from "business-engine";

export class UserService extends BusinessRuleService {
    // The rules will be applied one after the other, stopping at the first error.
    protected readonly businessRules: List<IBusinessRule<User>> = List(
        // Creating a rule that can be applied in CREATE and UPDATE mode on the firstName property
        new StringPropertyRequiredRule<User>(BusinessRuleMode.ANY, "firstName"),
        
        // Again, CREATE mode only, on email property, with the pattern validator
        new StringFormatRule<User>(BusinessRuleMode.CREATE, "email", /.*@gmail\.com$/i),
        
        // Finally our custom rule
        new UniqueUserEmailRule(BusinessRuleMode.ANY)
    );
    
    public createUser(user: User): User {
        // Will throw an error if user does not comply with our rules
        this.checkForCreation(user);
        
        // ... your logic here
    }
    
    public updateUser(user: User): User {
        // Will throw an error if user does not comply with our rules
        this.checkForUpdate(user);
        
        // ... your logic here
    }
}

Embedded rules

By design, Business Engine is shipped with a few handful of useful basic rules.

Here is the list:

  • StringFormatRule Checks if a given entity's property comply to a given pattern

  • StringPropertyRequiredRule Checks if a given entity's string property if present (e.g. not null, not undefined and not empty)

  • ObjectPropertyRequiredRule Checks if a given entity's property if present (e.g. not null and not undefined)

Contributing

Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests to us.

Setup

Everything should be available without you installing anything globally. Just run this command and you are good to go:

yarn

Running the tests

Business Engine uses Mocha and Chai under the hood. Shipped with 100% test coverage. If you intend to improve the code, or add business rules, your PR is expected to keep the 100% test coverage ratio.

To run the tests, just do:

npm test

or

yarn test

Versioning

We use SemVer for versioning. For the versions available, see the tags on this repository.

Authors

  • Raphaël MARQUES - Initial work - Adrael

See also the list of contributors who participated in this project.

License

This project is licensed under the MIT License - see the LICENSE.md file for details.