@fl45h97/eazy
TypeScript icon, indicating that this package has built-in type declarations

3.0.1 • Public • Published

Eazy package

Eazy package is supposed to be used easily. It provides some frames to do tasks in server side, for example: api endpoint input validation, Email service, Logsystem, Database connector, Html generator with ejs, custom routing, property validator


Logger

This class is used to create logs to the console, furthermore it can be set up to send email on error.

Example:

Logger.error( 'Error message!', 'Err_code', true); // last parameter is optional. if it set to true, empty lines will appear before and after the message. default=false
Logger.warning("Warning message!",true);
Logger.info('Info message!');
Logger.trace("Trace message!");      
Logger.success("Task successfully completed!");

Logging to console can be disabled via

Logger.writeconsole = false;

Sending email message on error can be enabled by

Logger.sendmail = true;

A callback can be attached in case of error. So if you want to implement a different email system or send an http request you can do so.

Logger.errorCallbackFunction = myFunction;

Log level can be set via

Logger.level=Loglevel.trace;

...

export enum LogLevel {
  none = 0,
  error = 1,
  warning = 2,
  info = 3,
  trace = 4,
}

How to use the api endpoint input validation feature?

First of all, you should create fields which implement the IField interface e.g.:

export class DateField implements IField{

   public type: FieldType = FieldType.date;
   public min: Date;
   public max: Date;
   public validators: Validator[] = [];

   constructor(public name: string, public optional : boolean = false) {
      this.min = new Date('1900/01/01');
      this.max = new Date('2100/01/01');
      this.validators = [DefaultValidators.basicDateFormat];
   }
}

- Tip: It is a good practice to let the name property to be changed dinamically, because you might want to use 2 DateField as input in 1 endpoint - Tip: It is a good practice to let the optional property to be changed dinamically, because you might want to reuse the DateField in different models

After that you should define a model which describes an endpoint. eg.:

export class EndpointModel implements IModel {

    fromDate : IField = new DateField('from');
    toDate : IField = new DateField('to');

    groups: IField[][] = [];
    public interfaceHelpMessage = () : string => {
        return 'Test interface : 2 field is required. to and from Date field.';
    }

    constructor(){
        this.groups= [
            [this.fromDate,this.toDate],
        ]
    }
}

As you can see, Models should implements IModel interface! interfaceHelpMessage() should be described correctly, because it is useful when debugging is enabled. !!! groups should be assigned!

In the example above, fromDate and toDate always have to be present when you request this endpoint! If you want to make fromDate optional you should set the optional flag:

export class EndpointModel implements IModel {

    fromDate : IField = new DateField('from', true);
    // ...
}

In the groups you always declare what is a valid request made of!

Now you have the fields and an endpoint model now it's time connect it with a Controller e.g.:

export class TestController extends Controller {
    
    constructor(){
        super();
        this.registerRequestValidator({get: new EndpointModel()}, true);
    }

    async get(req: Request, res: Response): Promise<void> {
      throw new Error("Method not implemented.");
   }

   async post(req: Request, res: Response): Promise<void> {
      throw new Error("Method not implemented.");
   }

   async patch(req: Request, res: Response): Promise<void> {
      throw new Error("Method not implemented.");
   }

   async put(req: Request, res: Response): Promise<void> {
      throw new Error("Method not implemented.");
   }

   async delete(req: Request, res: Response): Promise<void> {
      throw new Error("Method not implemented.");
   }
}

Your controller should extends Controller class, in this way you can use your Models in the controller.

this.registerRequestValidator({get: new EndpointModel()}, true);

This function register your Model to the Controller. registerRequestValidator(...) requires 1 parameter (and 1 optional): The first parameter should be an object of IValidators interface which looks like this:

export interface IValidators {
  get?: IModel;
  patch?: IModel;
  post?: IModel;
  put?: IModel;
  delete?: IModel;
}

The optional paramęter helpMessage should be used only in development phase. It returns an http site with useful, detailed information, if model validation fails. In this way, you can debug your endpoint easily.

As you can see, you can either use one IModel with different groups for all method or you can declare different IModel for different method. It's up to you.


Guard

Another great security feature to use. For example, you can create a Guard for your protected endpoint, in this way you check permissions, rights, users, whatever you want... Guards have to extend the Guard baseclass. e.g.:

export class MyGuard extends Guard{
    protected checkGet(req: Request, res: Response): boolean {
        res.status(HttpCodes.forbidden).send();
        return false;
    }
    protected checkPost(req: Request, res: Response): boolean {
        return true;
    }
    protected checkPatch(req: Request, res: Response): boolean {
        return true;
    }
    protected checkDelete(req: Request, res: Response): boolean {
        return true;
    }
    protected checkPut(req: Request, res: Response): boolean {
        return true;
    }
}

You can use the HttpCodes enum to get the proper http status code.

- Please note: If your check functions return true, then the Guard baseclass will call then next() function. If it returns false or does not return, then nothing happens. If your customGuard returns false, then you should send a response also.


Routing

Router handler is also available in order to register Guards and Model validation correctly. You should first create a Routes.ts file. e.g.:

export class Routes {
    public static all : IRoute[] =
    [
        {path: '/test', guard: new MyGuard(), controller: new TestController()}
    ]
}

guard is an optional paramter.

After your routes are up, you should register them into the express app. e.g.:

const app : Application = express();
app.use('/api',RoutesHandler.register(Routes.all));

- Tip: You can use the Logger.errorCallbackFunction(...) which is called at the end of Logger.error(...). In this way you can declare what should happen on error. E.g.:

You could send a custom email (via EmailService.sendMail(...)) generated by HtmlGenerator

You could save error message to a custom file

You can terminate the process

You can make an http call to a custom website


Validator

Validator(please don't confuse with IValidators) Is used in IField interface, in order to create custom validators. E.g.: phone,mail,only letter and so on.

You can create a Validator like

new Validator(/^[A-Za-z]+$/, 'It must contains letters only.');

In the DefaultValidators class there are some validators provided already. I will add more in future.

export class DefaultValidators {
  public static readonly containsNumber: Validator = new Validator(/\d+/, 'It must contains a digit.');
  public static readonly containsAlphabet: Validator = new Validator(/[a-zA-Z]/, 'It must contains an english letter.');

  public static readonly onlyLetters: Validator = new Validator(/^[A-Za-z]+$/, 'It must contains letters only.');
  public static readonly onlyNumbers: Validator = new Validator(/^[0-9]+$/, 'It must contains numbers only.');
  public static readonly onlyMixOfAlphaNumeric: Validator = new Validator(
    /^([a-zA-Z0-9])+$/,
    'It must be a mixture of english letters and digits!',
  );
  public static readonly basicDateFormat: Validator = new Validator(
    /^([0-9]){4}([-/]){1}[0-9]{2}([-/])[0-9]{2}/,
    'It must be a date formatted like YYYY-MM-DD or YYYY/MM/DD',
  );
}

Package Sidebar

Install

npm i @fl45h97/eazy

Weekly Downloads

2

Version

3.0.1

License

ISC

Unpacked Size

222 kB

Total Files

287

Last publish

Collaborators

  • fl45h97