@alcadica/contract
v1.0.1
Published
Data contracts for data validation
Downloads
4
Readme
@alcadica/contract
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>
)
}
}