@alcadica/contract
TypeScript icon, indicating that this package has built-in type declarations

1.0.1 • Public • Published

@alcadica/contract

Coverage Maintainability

Install

npm i --save @alcadica/contract

This package provides a simple but powerful way to estabilish a contract between a datasource and an entity. A contract is used to handle data channeling between a caller (application layer) and an owner (data layer, contract provider).

Examples

import contract from '@alcadica/contract';

class MyEntity {
  public foo: string = '';
}

let instance = new MyEntity();

let MyEntityContract = contract.createFromInstance(instance);

MyEntityContract.validators.foo.validate = entity => entity.foo.length > 0;

console.log(MyEntityContract.valid) // outputs false

instance.foo = '123';

console.log(MyEntityContract.valid) // outputs true

let newinstance = new MyEntity();

MyEntityContract.entity = newinstance;

console.log(MyEntityContract.valid) // outputs false

Creating a custom validator

import contract from '@alcadica/contract';

class Test {
  public constructor (
    public bar: string,
    public foo: number
  ) {};
}

const testContract = contract.createFromClass(Test, 'hello', 100);

testContract.entity.foo.validate = () => {
  return (value: string) => {
    return contract.createValidatorOutput(value.length > 5, 'foo length must be greater than 5');
  }
}

Using in express.js for input data validation

import Contract from '@alcadica/contract';
import * as express from 'express';

const route = express.Route();
const contract = Contract.create(['bar', 'foo']);

// we assume that the server will receive a json like this
// { "foo": "hello world", "bar": 123 }

contract.validators.bar.validator = (value: number) => value && value > 3 && value < 6;
contract.validators.foo.validator = (value: string) => value && value.length > 3;

route.post('/resource', (request, response) => {
  contract.entity = request.body;

  if (contract.valid) {
    response.status(200).json(contract);
  } else {
    response.status(400).json(contract);
  }
});

Using react form

import Contract from '@alcadica/contract';
import React from 'react';

interface IState {
  name: string;
  email: string;
}

const getInitialState: () => IState = () => ({
  name: '',
  email: '',
});

export default class MyForm extends React.Component<{}, IState> {
  public contract = Contract.createFromInstance(getInitialState());
  public state = getInitialState();

  public componentDidMount() {
    this.contract.validators.name.validator = (value: string) => value.length >= 3;
    this.contract.validators.name.validator = (email: string) => /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(value);
  }

  public createChangeListener(name: keyof IState) {
    return (event: React.ChangeEvent<HTMLInputElement>) => {
      this.contract.entity[name] = event.target.value;
      this.setState({ [name]: event.target.value });
    }
  }

  public render() {
    
    return (
      <form>
        <fieldset>
          <label>Name</label>
          <input onChange={ this.createChangeListener('name') } type="text" />
        </fieldset>
        <fieldset>  
          <label>Email</label>
          <input onChange={ this.createChangeListener('email') } type="text" />
        </fieldset>
        <div hidden={this.contract.valid}>
          Invalid fields are {this.contract.invalidKeys}
        </div>
      </form> 
    )
  }
}

Licence

MIT

Dependencies (0)

    Dev Dependencies (4)

    Package Sidebar

    Install

    npm i @alcadica/contract

    Weekly Downloads

    2

    Version

    1.0.1

    License

    MIT

    Unpacked Size

    24.1 kB

    Total Files

    5

    Last publish

    Collaborators

    • npm-alcadica
    • octod