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

helocore

v1.1.0

Published

A lightweight Node.js and TypeScript dependency injection framework

Downloads

146

Readme

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.