From 13b93d37371cb22b3a15d11048113efbc4796537 Mon Sep 17 00:00:00 2001 From: Roman Date: Sun, 20 Oct 2024 17:16:42 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D1=80=D0=B3=D0=B0=D0=BD=D0=B8=D0=B7?= =?UTF-8?q?=D1=83=D0=B5=D1=82=20=D0=BB=D0=BE=D0=B3=D0=B8,=20=D0=BE=D0=BF?= =?UTF-8?q?=D0=B8=D1=88=D0=B5=D1=82=20=D1=81=D1=85=D0=B5=D0=BC=D1=83=20?= =?UTF-8?q?=D0=B8=20=D0=BA=D0=BE=D0=BD=D1=84=D0=B8=D0=B3,=20=D0=B4=D0=BE?= =?UTF-8?q?=D0=B1=D0=B0=D0=B2=D0=B8=D1=82=20=D0=B2=D0=BD=D0=B5=D0=B4=D1=80?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B7=D0=B0=D0=B2=D0=B8=D1=81=D0=B8?= =?UTF-8?q?=D0=BC=D0=BE=D1=81=D1=82=D0=B5=D0=B9.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + src/main.rest.ts | 19 +++++++++++++ src/rest/index.ts | 1 + src/rest/rest.application.ts | 18 +++++++++++++ src/shared/helpers/index.ts | 2 +- src/shared/libs/config/config.interface.ts | 3 +++ src/shared/libs/config/index.ts | 3 +++ src/shared/libs/config/rest.config.ts | 30 +++++++++++++++++++++ src/shared/libs/config/rest.schema.ts | 31 ++++++++++++++++++++++ src/shared/libs/logger/index.ts | 2 ++ src/shared/libs/logger/logger.interface.ts | 6 +++++ src/shared/libs/logger/pino.logger.ts | 28 +++++++++++++++++++ src/shared/types/component.enum.ts | 5 ++++ src/shared/types/index.ts | 1 + 14 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 src/main.rest.ts create mode 100644 src/rest/index.ts create mode 100644 src/rest/rest.application.ts create mode 100644 src/shared/libs/config/config.interface.ts create mode 100644 src/shared/libs/config/index.ts create mode 100644 src/shared/libs/config/rest.config.ts create mode 100644 src/shared/libs/config/rest.schema.ts create mode 100644 src/shared/libs/logger/index.ts create mode 100644 src/shared/libs/logger/logger.interface.ts create mode 100644 src/shared/libs/logger/pino.logger.ts create mode 100644 src/shared/types/component.enum.ts diff --git a/.gitignore b/.gitignore index 83c4c3e..1282217 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ .DS_Store coverage *.log +.env diff --git a/src/main.rest.ts b/src/main.rest.ts new file mode 100644 index 0000000..0318f50 --- /dev/null +++ b/src/main.rest.ts @@ -0,0 +1,19 @@ +import 'reflect-metadata'; +import { RestApplication } from './rest/index.js'; +import { Config, RestConfig, RestSchema } from './shared/libs/config/index.js'; +import { Logger, PinoLogger} from './shared/libs/logger/index.js'; +import { Container } from 'inversify'; +import { Component } from './shared/types/index.js'; + +async function bootstrap() { + const container = new Container(); + + container.bind(Component.RestApplication).to(RestApplication).inSingletonScope(); + container.bind(Component.Logger).to(PinoLogger).inSingletonScope(); + container.bind>(Component.Config).to(RestConfig).inSingletonScope(); + + const application = container.get(Component.RestApplication); + await application.init(); +} + +bootstrap(); diff --git a/src/rest/index.ts b/src/rest/index.ts new file mode 100644 index 0000000..5e51a1d --- /dev/null +++ b/src/rest/index.ts @@ -0,0 +1 @@ +export { RestApplication } from './rest.application.js'; diff --git a/src/rest/rest.application.ts b/src/rest/rest.application.ts new file mode 100644 index 0000000..860c4cd --- /dev/null +++ b/src/rest/rest.application.ts @@ -0,0 +1,18 @@ +import { inject, injectable } from 'inversify'; +import { Config, RestSchema } from '../shared/libs/config/index.js'; +import { Logger } from '../shared/libs/logger/index.js'; +import { Component } from '../shared/types/index.js'; + + +@injectable() +export class RestApplication { + constructor( + @inject(Component.Logger) private readonly logger: Logger, + @inject(Component.Config) private readonly config: Config + ) {} + + public async init() { + this.logger.info('Application initiazation'); + this.logger.info(`Get value from env $PORT: ${this.config.get('PORT')}`); + } +} diff --git a/src/shared/helpers/index.ts b/src/shared/helpers/index.ts index d67b765..2f8aee9 100644 --- a/src/shared/helpers/index.ts +++ b/src/shared/helpers/index.ts @@ -1 +1 @@ -export {getRandomElement, getRandomNumber, getRandomItems} from './functions.js'; +export { getRandomElement, getRandomNumber, getRandomItems } from './functions.js'; diff --git a/src/shared/libs/config/config.interface.ts b/src/shared/libs/config/config.interface.ts new file mode 100644 index 0000000..4310393 --- /dev/null +++ b/src/shared/libs/config/config.interface.ts @@ -0,0 +1,3 @@ +export interface Config { + get(key: T): U[T]; +} diff --git a/src/shared/libs/config/index.ts b/src/shared/libs/config/index.ts new file mode 100644 index 0000000..f099b0d --- /dev/null +++ b/src/shared/libs/config/index.ts @@ -0,0 +1,3 @@ +export { RestConfig } from './rest.config.js'; +export { Config } from './config.interface.js'; +export { RestSchema, configRestSchema } from './rest.schema.js'; diff --git a/src/shared/libs/config/rest.config.ts b/src/shared/libs/config/rest.config.ts new file mode 100644 index 0000000..a027bb5 --- /dev/null +++ b/src/shared/libs/config/rest.config.ts @@ -0,0 +1,30 @@ +import { config } from 'dotenv'; +import { Logger } from '../logger/index.js'; +import { Config, RestSchema, configRestSchema } from './index.js'; +import { inject, injectable } from 'inversify'; +import { Component } from '../../types/component.enum.js'; + + +@injectable() +export class RestConfig implements Config { + private readonly config: RestSchema; + + constructor( + @inject(Component.Logger)private readonly logger: Logger + ) { + const parsedOutput = config(); + + if (parsedOutput.error) { + throw new Error ('Can\'t read .env file. Perhaps the file does not exists.'); + } + configRestSchema.load({}); + configRestSchema.validate({ allowed: 'strict', output: this.logger.info }); + + this.config = configRestSchema.getProperties(); + this.logger.info('.env file found and successfully parsed!'); + } + + public get(key: T): RestSchema[T] { + return this.config[key]; + } +} diff --git a/src/shared/libs/config/rest.schema.ts b/src/shared/libs/config/rest.schema.ts new file mode 100644 index 0000000..64bb625 --- /dev/null +++ b/src/shared/libs/config/rest.schema.ts @@ -0,0 +1,31 @@ +import convict from 'convict'; +import validator from 'convict-format-with-validator'; + +convict.addFormats(validator); + +export type RestSchema = { + PORT: number, + SALT: string, + HOST_DB: string, +} + +export const configRestSchema = convict({ + PORT: { + doc: 'Port for incoming connections', + format: 'port', + env: 'PORT', + default: 4000 + }, + SALT: { + doc: 'Salt for password hash', + format: String, + env: 'SALT', + default: null + }, + HOST_DB: { + doc: 'IP address of the database server (MongoDB)', + format: 'ipaddress', + env: 'HOST_DB', + default: '127.0.0.1' + } +}); diff --git a/src/shared/libs/logger/index.ts b/src/shared/libs/logger/index.ts new file mode 100644 index 0000000..2382413 --- /dev/null +++ b/src/shared/libs/logger/index.ts @@ -0,0 +1,2 @@ +export { Logger} from './logger.interface.js'; +export { PinoLogger } from './pino.logger.js'; diff --git a/src/shared/libs/logger/logger.interface.ts b/src/shared/libs/logger/logger.interface.ts new file mode 100644 index 0000000..927837e --- /dev/null +++ b/src/shared/libs/logger/logger.interface.ts @@ -0,0 +1,6 @@ +export interface Logger { + info(message: string, ...args: unknown[]): void; + warn(message: string, ...args: unknown[]): void; + error(message: string, error: Error, ...args: unknown[]): void; + debug(message: string, ...args: unknown[]): void; +} diff --git a/src/shared/libs/logger/pino.logger.ts b/src/shared/libs/logger/pino.logger.ts new file mode 100644 index 0000000..7336d02 --- /dev/null +++ b/src/shared/libs/logger/pino.logger.ts @@ -0,0 +1,28 @@ +import { Logger as PinoInstance, pino} from 'pino'; +import { Logger } from './index.js'; +import { injectable } from 'inversify'; + +@injectable() +export class PinoLogger implements Logger { + private readonly logger: PinoInstance; + + constructor() { + this.logger = pino(); + } + + public info(message: string, ...args: unknown[]): void { + this.logger.info(message, ...args); + } + + public warn(message: string, ...args: unknown[]): void { + this.logger.warn(message, ...args); + } + + public error(message: string, error: Error, ...args: unknown[]): void { + this.logger.error(error, message, ...args); + } + + public debug(message: string, ...args: unknown[]): void { + this.logger.debug(message, ...args); + } +} diff --git a/src/shared/types/component.enum.ts b/src/shared/types/component.enum.ts new file mode 100644 index 0000000..91157c1 --- /dev/null +++ b/src/shared/types/component.enum.ts @@ -0,0 +1,5 @@ +export const Component = { + RestApplication: Symbol.for('RestApplication'), + Logger: Symbol.for('Logger'), + Config: Symbol.for('Config') +} as const; diff --git a/src/shared/types/index.ts b/src/shared/types/index.ts index ead490f..1247e3a 100644 --- a/src/shared/types/index.ts +++ b/src/shared/types/index.ts @@ -1,3 +1,4 @@ export { Offer } from './offer-type.js'; export { TypeUser, User } from './user-type.js'; export { MockServerData } from './mock-server-data.js'; +export { Component } from './component.enum.js';