zafiro
TypeScript icon, indicating that this package has built-in type declarations

1.0.0-alpha.14 • Public • Published

💎 Zafiro is a strongly typed and lightweight web framework for Node.js apps powered by TypeScript, InversifyJS, TypeORM and Express 🚀

Join the chat at https://gitter.im/inversify/InversifyJS npm version Build Status Dependencies img Known Vulnerabilities Twitter Follow

⚠️ 🚧 This library is under construction 🚧 ⚠️

The Basics

This step-by-step guide will guide your through the Zafiro basics.

Installation

You can install Zafiro using npm:

npm install zafiro reflect-metadata

Creating an application

Zafiro exposes a function named createApp that allows you to bootstrap an Express application in just a few minutes.

The application entry point look as follows:

import "reflect-metadata";
import { createApp } from "zafiro";
import { appBindings } from "./config/ioc_config";
import { expressConfig } from "./config/express_config";
import { CustomAccountRepository } from "./repositories/account_repository";
 
(async () => {
 
    try {
        const app = await createApp({
            database: "postgres",
            containerModules: [appBindings],
            expressConfig: expressConfig,
            AccountRepository: CustomAccountRepository
        });
 
        app.listen(
            3000,
            () => console.log(
                "Example app listening on port 3000!"
            )
        );
 
    } catch (e) {
        console.log(e.message);
    }
 
})();

You can learn more about all the available configuration options in the wiki page about configuration.

Required Environment Variables

A Zafiro application expects the following environment variables to be available:

  • The DATABASE_HOST variable should contain the network address of your database.
  • The DATABASE_PORT variable should contain the network port of your database.
  • The DATABASE_USER variable should contain the user name of your database.
  • The DATABASE_PASSWORD variable should contain the user password of your database.
  • The DATABASE_DBvariable should contain the name of your database.

Required Project Folders

A Zafiro application expects the following directory structure and convention:

  • /src/controllers/ You must add your controllers unders this folder. The controllers are powerd by inversify-express-utils.

  • /src/entities/ You must add your entities unders this folder. The entities are powerd by TypeORM.

⚠️ Please note that each entity and each controller in your application must be defined on its own file and be exported using a default ES6 export.

Defining an Entity

You can define an entity as follows:

import { Entity, Column, PrimaryGeneratedColumn } from "typeorm";
 
@Entity()
export default class DirectMessage {
 
    @PrimaryGeneratedColumn()
    id: number;
 
    @Column()
    senderId: number;
 
    @Column()
    recipientId: number;
 
    @Column()
    content: string;
 
    @CreateDateColumn()
    createdDate: Date;
}

The Entity API in Zafiro is powered by TypeORM API:

Declaring a Repository

A Repository<T> will be generated automatically at runtime. The repository API is powered by TypeORM.

You can access a Repository<T> by injection it into a Controller, BaseMiddleware, AuthProvider, etc. First you need to declare a type identifier for the repository that you wish to inject:

const TYPE = {
    DirectMessageRepository: Symbol.for("Repository<DirectMessage>")
};

Then you can inject it using the @inject annotation:

@inject(TYPE.DirectMessageRepository) private readonly _dmRepository: Repository<DirectMessage>;

The Dependency Injection API in Zafiro is powered by InversifyJS.

The Repository API in Zafiro is powered by TypeORM API:

Declaring a Controller

You can declare a controller as follows:

import { injectable, inject } from "inversify";
import { controller, httpGet, BaseHttpController } from "inversify-express-utils";
import { TYPE } from "./contants/types";
 
@controller("/direct_message")
class UserPreferencesController extends BaseHttpController {
 
    @inject(TYPE.DirectMessageRepository) private readonly _dmRepository: Repository<DirectMessage>;
 
    @httpGet("/")
    public async get() {
        if (!this.httpContext.user.isAuthenticated()) {
            this.httpContext.res.status(403).send("Forbidden");
        } else {
            return await this._dmRepository.find({
                recipientId: this.httpContext.details.id;
            });
        }
    }
 
}

The Controllers API in Zafiro is powered by inversify-express-utils.

Why Zafiro?

I created Zafiro because I love working with JavaScript and Node.js but I miss the boilerplate-automation and the type-safety productivity boost that I have experienced while working with other technologies in the past.

Thanks to InversifyJS and TypeORM, Zafiro is able to automate a lot of the boilerplate required to create an Express application. As a first step, Zafiro is able to create a database connection, auto-generate the data repositories and inject them into your controllers:

Zafiro has been designed with the goal of providing a great developer experience.

I plan to continue working hard to:

  • Make Zafiro very robust.
  • Reduce the amount of required boilerplate.
  • Improve the developer experience.

Example Application

An example application is available at zafiro-realworld-example.

Package Sidebar

Install

npm i zafiro

Weekly Downloads

0

Version

1.0.0-alpha.14

License

MIT

Unpacked Size

701 kB

Total Files

85

Last publish

Collaborators

  • remojansen