Miss any of our Open RFC calls?Watch the recordings here! »

@alcadica/contract

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

Install

npm i @alcadica/contract

DownloadsWeekly Downloads

2

Version

1.0.1

License

MIT

Unpacked Size

24.1 kB

Total Files

5

Last publish

Collaborators

  • avatar
  • avatar