npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

easy-ts-api

v2.0.1-v5

Published

Api Server with open api interface

Downloads

20

Readme

EASY API SERVER

EASY API SERVER is an ts module that have for goal to create MVC pattern with express or fastify and auto configure swagger interface to manipulate the api

Installing

npm install --save easy-ts-api 

After that you create config file inside config/app.ts

    import { ServerOption } from "easy-ts-api";
    import path from "path";
    export const serverOption: ServerOption = {
        controllers: [path.join(__dirname, '..', '/controllers/**/*Controller')],
        middlewares: [path.join(__dirname, '..', '/middlewares/**/*Middleware')],
        models: [path.join(__dirname, '..', '/models/**/*Model.ts')]
    }

After that you can create server via express or fastify

Fastify server

import "reflect-metadata";
import { FastifyApplication, AppFactory, App } from 'easy-ts-api';
import {serverOption} from './config/app.ts'
// Fasify instance
async function bootstrap() {
    const app: App = await AppFactory.create<FastifyApplication>(FastifyApplication, serverOption);
    await app.serve(3000, 'localhost', 50, (_e, host) => {
        console.log(`Instance of fastify server running on  ${host}`)
    });
}
// boot app
bootstrap()
  

Express server

import "reflect-metadata";
import { ExpressApplication, AppFactory, App } from 'easy-ts-api';
import {serverOption} from './config/app.ts'

// Express inntance
async function bootstrap() {
    const app: App = await AppFactory.create<ExpressApplication>(ExpressApplication, serverOption); 
    await app.serve(3000, (port) => {
        console.log(`Instance of express server running on port ${port}`)
    });
}
// boot app
bootstrap()
 

Controller

There is an exemple of controller with openapi

import { All, Get,Use , OpenApi } from "easy-ts-api"
import { AppRequest, CookieType, AppResponse } from "easy-ts-api"
import { Params, Req, Res, Query, Headers, Ip, Session, Cookies } from "easy-ts-api";
import { Controller } from "easy-ts-api";



@Controller({ prefix: '/api' })
export default class ExempleController {

    @OpenApi({
        responses: {
            '200': {
                '$ref': '',
                'description': 'Response',
            }
        },
        parameters: [
            {
                name: 'authorization',
                in: 'header'
            }
        ]
    })
    @Get('/login/:id')
    public async login(@Params('id') id: number,@Headers('authorization') authorization) {
        return {
            name: 'login', 
            params: id,
            authorization: authorization
        }
    }

    @OpenApi({
        responses: {
            '200': {
                '$ref': '',
                'description': 'Response',
            }
        }
    })
    @Use(InjectMiddleWare) // can inject middleware for only some method
    @All('/register')
    public async register(@Req() req: AppRequest, @Res() res: AppResponse, @Query() query: any, @Headers() headers: any, @Ip() ip: string, @Session() session: any, @Cookies() cookies: CookieType) {
        cookies.set('name', 'cookies test') // setting cookie 
        cookies.set('key', 'cookies test') // setting cookie 
        return {
            name: 'register',
            query: query,
            headers: headers,
            ip: ip,
            session: session,
            cookies: cookies
        }
    }
}

Middleware

Middleware is based on express middleware but it can work perfectly with fastify

import { NextFunction,Request,Response } from 'express';
import { AppMiddleWare,Middleware } from 'easy-ts-api';

@Middleware()
export default class ExempleMiddleWare implements AppMiddleWare {

    public use(req: Request, res: Response, next: NextFunction){
        console.log('Called middleware')
        next();
    }
}

If you want to create InjectMiddleware, you dont need to use decorator @Middleware() to create it. Inject middleware can be injected by decorate class or decorate method. @Middleware() tell server that this middleware will be used globaly.

import { NextFunction,Request,Response } from 'express';
import { AppMiddleWare,Middleware } from 'easy-ts-api';

export default class InjectMiddleWare implements AppMiddleware {

    public use(req: Request, res: Response, next: NextFunction){
        console.log('Called inject middleware')
        next();
    }
}

For database create .env file and specify some parameters

NODE_ENV=development
DRIVER=mysql/postgres/sqlite/mongo
DATABASE=database
USER=root
PASSWORD=password
EXTENSION=.ts // .js for production

And model is base on sequilize-typescritpt You can also define you custom config for database by crete file inside config/database.ts and put you own value.

export const databaseConfig : DatabaseConfig = {
    database: ENV.Get('DATABASE'),
    host: ENV.Get('HOST'),
    port: ENV.Get('PORT') || 3306,
    dialect:  ENV.Get('DRIVER'),
    username: ENV.Get('USER'),
    password: ENV.Get('PASSWORD'),
    logging: console.log
}
import { AutoIncrement, Column, Model, PrimaryKey, Table } from "sequelize-typescript";
import { prop, Schema } from 'easy-ts-api';

@Table({
    timestamps: true,
})
@Schema()
export default class User extends Model {

    @AutoIncrement
    @PrimaryKey
    @Column
    @prop()
    id: number;

    @Column
    @prop()
    nickname: string;
}

You can transform Model or any class to body schema

import { prop, Schema } from 'easy-ts-api';

@Schema()
export class RegisterInput {
    @maxlength(20) //validator
    @prop()
    name: string

    @isemail() // validator
    @prop()
    email: string

    @hash() // hash password on set sha256 crypto-js
    @minlength(8) // validator
    @prop()
    password: string
}

if you want to use socket io with , enable it in serveroption

export const serverOption: ServerOption = {
    controllers: [path.join(__dirname, '..', '/controllers/**/*Controller')],
    middlewares: [path.join(__dirname, '..', '/middlewares/**/*Middleware')],
    models: [path.join(__dirname, '..', '/models/**/*Model.ts')],
    sockets: [path.join(__dirname, '..', '/sockets/**/*SocketController')], // socket controller
    cors: true,
    enableSocketIo: true,
    views: path.join(__dirname,'..', 'views'), // view path 
    viewEngine: 'twig' // twig or edge ( default twig)
}

and Create socket controller


import { ConnectedSocket, MessageBody, OnConnect, SocketController } from "easy-ts-api";
import { OnEvent,EmitOnSuccess,EmitOnFail,UseOnSocket } from 'easy-ts-api';
import TestMethodSocketMiddleware from './TestMethodSocketMiddleware'
import TestSocketMiddleware from "./TestSocketMiddleware";

@UseOnSocket(TestSocketMiddleware)
@SocketController()
export default class TestSocketController {

    @OnConnect()
    public async connection(@ConnectedSocket() socket) {
        console.log('user connected')
        console.log(socket.id)
    }

    @UseOnSocket(TestMethodSocketMiddleware)
    @EmitOnFail('error')
    @EmitOnSuccess('message')
    @OnEvent('message')
    public async message(@ConnectedSocket() socket, @MessageBody() data: any) {
        console.log('Message get from zvznr message : ', data, socket)
        return data;
    }
}

And socket middleware must be like

import { AppSocketMiddleware, SocketMiddleware } from 'easy-ts-api';

@SocketMiddleware()
export default class TestMethodSocketMiddleware implements AppSocketMiddleware {
    use(socket: any, next: ((err?: any) => any)) {
        console.log("do something, for example get authorization token and check authorization");
        next();
    }

}

You must use decorator middleware with @SocketMiddleware() to know that it is a socket decorator and not any class. It will be ignore without this decorator. After all, you can able to SocketIO from controller method parameter


...
    @OpenApi({
        responses: {
            '200': {
                '$ref': '',
                'description': 'Response',
            }
        }
    })
    @Middleware(InjectMiddleWare) 
    @Post('/register')
    public async register(@SocketIO() socket: any, @Body() body: RegisterInput) {
        /**
         *  // checking body if validates and will return ,
         * {
         *      isvalid: boolean,
         *      messages: {}
         * }
        */
        const validators = Validator.validate(body)
        
        console.log(body.password, validators)
        return {
            name: 'register',
        }
    }

...

Render file or render template

Render template work only with express


...
    @Render('users.index')
    @Get('/users')
    public async index(@View() twig: TwingEnvironment){
        return {title: 'Index'}
    }

    @RenderFile('storage')
    @Get('/file')
    public async file(){
        return 'images/b1.jpg'
    }

...

Other config

You can config openapi and database with

...
app.configOpenAPi({
    url: '/api/docs', // url to access the api docs
    options: { // swagger infos option
        version: '1.0',
    }
} as OpenAPiParams)
...

app.configDatabaseOption({
    force: true, // sequelize options
    alter: true
})

// use this if you use custom database config
app.initDatabase(databaseConfig);

...

Tsiresy Milà

[email protected]