Foreword
ivo is a user story focused utility that helps you build factory methods to manage entities and their values in your domain.
In short, it is an event-driven schema validator which provides an interface for you to clearly define the behaviour of your entities at creation and during updates.
Installation
$ npm i ivo
Importing
// Using Nodejs `require`
const { Schema } = require('ivo');
// Using ES6 imports
import { Schema } from 'ivo';
Defining a schema
import { Schema, type Summary } from 'ivo';
type UserRole = 'admin' | 'user';
type Input = {
firstName: string;
lastName: string;
password: string;
role?: UserRole;
};
type Output = {
createdAt: Date;
firstName: string;
fullName: string;
id: number;
lastName: string;
password: string;
role: UserRole;
updatedAt: Date;
};
type ISummary = Summary<Input, Output>;
const userSchema = new Schema<Input, Output>(
{
firstName: {
required: true,
validator: validateString('invalid first name')
},
fullName: {
default: '',
dependent: true,
dependsOn: ['firstName', 'lastName'],
resolver: getFullName
},
id: { constant: true, value: generateUserId },
lastName: {
required: true,
validator: validateString('invalid last name')
},
password: { required: true, validator: validatePassword },
role: { default: 'user', shouldInit: false, validator: validateRole }
},
{ timestamps: true }
);
// resolvers
function getFullName({ context: { firstName, lastName } }: ISummary) {
return `${firstName} ${lastName}`;
}
// get the model
const UserModel = userSchema.getModel();
Creating an entity
import userDb from 'db-of-choice'; // use any db that supports the information you are modelling
const { data, error } = await UserModel.create({
firstName: 'John',
fullName: 'Mr. James',
id: 1,
lastName: 'Doe',
lastSeen: new Date(),
name: 'John Doe',
password: 'au_34ibUv^T-adjInFjj',
role: 'admin'
});
if (error) return handleError(error);
console.log(data);
// {
// createdAt: new Date(),
// firstName: "John",
// fullName: "John Doe",
// id: 18927934748659724,
// lastName: "Doe",
// password: "**************",
// role: "user",
// updatedAt: new Date(),
// };
await userDb.insert(data);
Updating an entity
const user = await userDb.findById(18927934748659724);
if (!user) return handleError({ message: 'User not found' });
const { data, error } = await UserModel.update(user, {
firstName: 'Peter',
id: 2,
age: 34,
fullName: 'Tony Stark'
});
if (error) return handleError(error);
// age is ignored because it is not a valid property
// fullName is ignored because it is dependent
// id is ignored because it is a constant
console.log(data); // { firstName: "Peter", fullName: "Peter Doe", updatedAt: new Date() }
await userDb.updateById(user.id, data);