1.0.22 • Published 11 days ago

helocore v1.0.22

Weekly downloads
-
License
MIT
Repository
github
Last release
11 days ago

helocore

NPM
version NPM
downloads

A lightweight Node.js and TypeScript dependency injection framework powered tsyringe. for building APIs and microservices. You can use only with fastify.

Table of Contents

Installation

npm install --save helocore

Modify your tsconfig.json to include the following settings

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

Quick Start

// Redis.ts
import { singleton } from "helocore";

@singleton()
export default class Redis {
  // ...
}
// ResponseModel.ts
export default class ResponseModel<T> {
  public data?: T
  public status_code: number = 200
  public trace_id: string = ""
}
// application.ts
import { Modules, PermissionModule, HandleErrorResponse, DataSource, dataSourceList, EventsModules, coreSettings } from "helocore";
import TestController from './TestController'
import PermissionControl from './PermissionControl'
import Redis from './Redis'
import ResponseModel from './ResponseModel'
import EventsTest from './Events'

// default true
coreSettings.logger = false

// Controller layer defining
Modules([
  TestController
])

// Event layer defining
EventsModules([
  EventsTest
])

// Permission Control Layer
PermissionModule(PermissionControl)

// --> Datasource layer. You can take connection container defined key.
// example
// dataSourceList.redis => giving containered Redis
DataSource({
  redis: Redis
})

// --> Controller Handle Error
// error => error
// traceId => generated request unique key
// step => <controller | service>
// lang => req.headers['accept-language']
HandleErrorResponse<ResponseModel<any>>(async (error: any, traceId: string, step: string, lang: string) => {
  const response = new ResponseModel()
  response.status_code = 400
  response.trace_id = traceId
  return response
})
// index.ts
import "reflect-metadata";
import "./application";
import { fetchRoutes } from "helocore";

const fastify = Fastify()

fastify.register((app, _, done) => {
  fetchRoutes(app)
  done()
}, { prefix: '/api/v1' })

fastify.listen({ port: 3000 }, () => console.log('API is Running'))

coreSettings

  • logger: helocore logger with trace_id to command prompt. it can reachable from req.trace_id

Decorators

Controller()

This decorator is determine your prefix routes and at the same time your controller layer

Usage

import { Controller, injectable } from "helocore";

@Controller('/prefix')
@injectable()
export default class TestController {
  // ...
}

Get(), Post(), Put(), Delete(), Head(), Patch(), Options()

These decorators are determine your routes endpoints

Usage

// TestService.ts
import { Service, injectable } from "helocore";

@Service // not must. only for logs now
@injectable()
export default class TestService {
  Get(lang) {
    return {
      name: 'helocore'
    }
  }
}
import { Controller, Get, injectable } from "helocore";
import TestService from "./TestService";

@Controller('/prefix')
@injectable()
export default class TestController {
  
  constructor(
    private readonly testService: TestService
  ) { }

  @Get('/get') // endpoint => /api/v1/prefix/get -- Method => GET
  async Get() {
    const testData = await this.testService.Get()
    // ...
  }
}

Request(), Body(), Params(), Query(), Headers(), Reply()

Usage

import { Controller, Post, Body, injectable } from "helocore";

@Controller('/prefix')
@injectable()
export default class TestController {
  
  @Post('/save')
  Save(@Body() body: TBody) {
    // ...
  }
}

Middleware() and defineMiddleware

This decorator is determine middleware layer on your routes. this layer run before run from controller layer. We have two selection middleware type

Usage

// testvalidation.ts
import { defineMiddleware, Body, singleton } from "helocore";

@defineMiddleware
@singleton()
export default class TestValidation {
  
  Validation(@Body body: TBody) {
    // ...
  }
}
Prefix
// testcontroller.ts
import { Controller, Body, injectable, Post } from "helocore";
import TestValidation from "./testvalidation";

@Controller('/prefix', [ // prefix middleware
  {
    funcs: ['Validation'],
    class: TestValidation
  }
])
@injectable()
export default class TestController {
  
  @Post('/save')
  Save(@Body body: TBody) {
    // ...
  }
}
Endpoint
// testcontroller.ts
import { Controller, Body, Middleware, injectable, Post } from "helocore";
import TestValidation from "./testvalidation";

@Controller('/prefix')
@injectable()
export default class TestController {
  
  @Post('/save')
  @Middleware([
    {
      funcs: ['Validation'],
      class: TestValidation
    }
  ])
  Save(@Body body: TBody) {
    // ...
  }
}

Permissions()

This decorator is determine permission middleware layer.

Usage

// PermissionControl.ts
import { singleton, definePermission, Request, Body, IDefinePermission } from "helocore";

@definePermission
@singleton()
export default class PermissionControl implements IDefinePermission {
  
  async CheckPermission(permissions: Array<string>, @Request req: FastifyRequest, @Body body: TBody): Promise<boolean> {
    // ...
    // permissions => ['test.create', 'test.list']
    return true
  }
}
// testcontroller.ts
import { Controller, Body, Middleware, injectable, Post, Permissions } from "helocore";

@Controller('/prefix')
@injectable()
export default class TestController {
  
  @Post('/save')
  @Permissions('test.create', 'test.list')
  Save(@Body body: TBody) {
    // ...
  }
}

RateLimit()

This decorator is determine request limit on your route. You can look here ratelimit doc

Usage

// index.ts
import "reflect-metadata";
import "./application";
import Fastify from 'fastify';
import RateLimit from '@fastify/rate-limit';
import { fetchRoutes } from "helocore";

const fastify = Fastify()

fastify.register(RateLimit, {
  errorResponseBuilder: function (request, context) {
    return {
      code: 429,
      error: 'Too Many Requests',
      message: `Rate limit exceeded, retry in ${context.after}. Try again soon.`,
      expiresIn: Math.ceil(context.ttl / 1000)// seconds
    }
  }
})

fastify.register((app, _, done) => {
  fetchRoutes(app)
  done()
}, { prefix: '/api/v1' })

fastify.listen({ port: 3000 }, () => console.log('API is Running'))
// testcontroller.ts
import { Controller, Body, RateLimit, injectable, Post } from "helocore";

@Controller('/prefix')
@injectable()
export default class TestController {
  
  @Post('/save')
  @RateLimit({
    max: 3,
    timeWindow: 10000
  })
  Save(@Body body: TBody) {
    // ...
  }
}

CustomParamDecorator

You can define custom param decorator

Usage

// customdecorators.ts
import { FastifyRequest } from 'fastify';
import { createParamDecorator } from "helocore";

export const Lang = createParamDecorator((req: FastifyRequest) => {
  return req.headers['accept-language']
})
// testcontroller.ts
import { Controller, injectable, Post } from "helocore";
import { Lang } from "./customdecorators";

@Controller('/prefix')
@injectable()
export default class TestController {
  
  @Post('/save')
  Save(@Lang lang: string ) {
    console.log(lang)
    // ...
  }
}

Service

You can determine service for logs

Usage

// TestService.ts
import { Service, injectable } from "helocore";

@Service // not must. only for logs now
@injectable()
export default class TestService {
  Save(lang) {
    console.log(lang)
    // ...
  }
}
// testcontroller.ts
import { Controller, injectable, Post } from "helocore";
import TestService from "./TestService";

@Controller('/prefix')
@injectable()
export default class TestController {
  constructor(
    private readonly testService: TestService
  ) { }
  
  @Post('/save')
  Save() {
    this.testService.Save(lang)
    // ...
  }
}

Events

You can determine events

Usage

// events.ts
import { OnEvent, injectable } from 'helocore'

@injectable()
export default class EventTest {
  @OnEvent('test')
  create(data: object) {
    console.log(data)
  }
}
// application.ts
import { EventsModule } from 'helocore'
import EventTest from "./EventTest"

// ..
EventsModule([
  EventTest
])
// ..
// eventcontroller.ts
import { Controller, Events, Get, injectable } from 'helocore'

@Controller('/event')
@injectable()
export default class EventController {
  constructor(
    private readonly events: Events
  ) { }

  @Get('/')
  async EventTest() {
    this.events.emit('test', { message: 'test_message' })
    // ...
  }
}

EndpointOptions

it can use fastify route options

Usage

// controller.ts
import { Controller, EndpointOptions, Post, injectable } from 'helocore'

@Controller('/')
@injectable()
export default class TestController {
  @Post('/')
  @EndpointOptions({ // fastify route options
    bodyLimit: 10485760 // json body 11MB
  })
  async Test() {
    // ...
  }
}

Contributing

This project welcomes contributions and suggestions. If you see missing or want to improve on this project, you can create issue and open pull request.

1.0.22

11 days ago

1.0.21

11 days ago

1.0.20

11 days ago

1.0.19

2 months ago

1.0.18

2 months ago

1.0.17

4 months ago

1.0.16

4 months ago

1.0.14

4 months ago

1.0.11

4 months ago

1.0.12

4 months ago

1.0.9

6 months ago

1.0.8

6 months ago

1.0.7

6 months ago

1.0.6

6 months ago

1.0.10

6 months ago

1.0.5

8 months ago

1.0.4

9 months ago

1.0.3

9 months ago

1.0.2

9 months ago

1.0.1

9 months ago

1.0.0

9 months ago