@aks007/node-base
Version:
577 lines (539 loc) • 20.5 kB
TypeScript
import winston, { Logger } from 'winston';
import express, { Request as Request$1, Application, Response, NextFunction, Router } from 'express';
import mongoose, { Document, SaveOptions, FilterQuery, Mongoose, Model, ClientSession } from 'mongoose';
import _ from 'lodash';
import Agenda, { DefineOptions, Job } from 'agenda';
import { AxiosError } from 'axios';
import { Kafka, Producer, logLevel, Consumer } from 'kafkajs';
import moment from 'moment-timezone';
import { S3Client } from '@aws-sdk/client-s3';
type LogLevel = 'info' | 'warn' | 'error' | 'debug';
declare const createLogger: (opts: {
dir?: string | undefined;
filePrefix?: string | undefined;
enableConsoleLog: boolean;
enableFileLog: boolean;
logLevel: LogLevel;
timestampFormat?: string;
}) => winston.Logger;
interface MongooseOptionInterface {
returnObject: boolean;
new: boolean;
many?: boolean;
}
/**
* Default ABSTRACT class: CrudService
* this class will be used as base class
* to create all the crud service around the project
*
* Note: We're using keyword object in this file as this required as abstract class
*/
declare abstract class CrudService<T, U> {
abstract groupDBFields: unknown;
/**
* Projections Mapping Only
* This will be used in MongoDB Query
*/
abstract projections: string[];
protected idFieldPrefix: string;
protected primaryKey: string;
protected primaryValueLength: number;
protected primaryValueSeparator: string;
/**
* This is Actually Array of strings
* This will be just a reference to mapping
*
* This will be used in filtering the projection fields/columns
*/
protected defaultProjections: never[];
protected _count: number;
private _itemsPerPage;
get itemsPerPage(): number;
/**
* This function must be static
* neither it won't work
*
* @param doc
* @param ret
* @param options
*/
static modifyMongooseDoc: (doc: Document, ret: Record<string, unknown>, options: Record<string, unknown>) => Record<string, unknown>;
getProjections: () => string[];
prepareCrudListAsObject<T>(list: Document[]): T[];
/**
* Well, usually mongoose handles this conversion
* i.e. this string to ObjectId conversion
* but in case of pipelines in aggregation it doesn't
* in that case, we have to convert it manually
*
* so, this function exists
* please use this to convert the string id to ObjectId
*
* @param id
*/
createMongooseObjectId(id: string): mongoose.Types.ObjectId;
/**
* Prepare projection
* for Dates
*
* @param dateField
* @param returnTime
*/
dateStringProject(dateField: string, returnTime?: boolean): Record<string, unknown>;
findRandomEntry<T>(filters?: Record<string, unknown>): Promise<T>;
initiateIndex(): Promise<void>;
/**
* Use the following functions as information merger in a object
* in a way that can be used in MongoDB to search the query
*
* @param filters
* @param wildCardSearch
* @param dateFrom
* @param dateTo
*/
abstract prepareFilters(filters: Record<string, unknown>, wildCardSearch: string, dateFrom: Date | string, //moment.Moment,
dateTo: Date | string): void;
abstract prepareAggregation<T = unknown>(req: Request$1, filters: Record<string, unknown>, wildCardSearch: string, dateFrom: Date, dateTo: Date, projections?: Record<string, unknown>, virtualConditional?: Partial<U>): void;
abstract count(req: Request$1, filters: Record<string, unknown>, wildCardSearch: string, dateFrom: Date, //moment.Moment,
dateTo: Date, //moment.Moment
virtualConditional?: Partial<U>): any;
abstract sum(req: Request$1, filters: Record<string, unknown>, wildCardSearch: string, dateFrom: Date, dateTo: Date, baseKey: string, sumKey: string): any;
abstract find(req: Request$1, filters: Record<string, unknown>, wildCardSearch: string, dateFrom: Date | string, //moment.Moment,
dateTo: Date | string, //moment.Moment,
page: number, itemsPerPage: number, project: string[], saveOptions: SaveOptions, virtualConditional: Partial<U>, isStreaming: boolean): any;
abstract findAndCount(req: Request$1, filters: FilterQuery<T>, wildCardSearch: string, dateFrom: Date, dateTo: Date, page: number, itemsPerPage: number, projections: string[], virtualConditional?: Partial<U>): Promise<{
totalData: T[];
totalCount: number;
}>;
abstract getRandomEntry(): any;
abstract findOne(req: Request$1, filters: Record<string, unknown>, project: string[], saveOptions: SaveOptions): any;
abstract findOneAndUpdate(req: Request$1, filters: Record<string, unknown>, inputs: Record<string, unknown>, saveOptions: SaveOptions): any;
abstract update(req: Request$1, filters: Record<string, unknown>, inputs: Record<string, unknown>, mongooseOption: MongooseOptionInterface, ...args: Record<string, unknown>[]): any;
abstract create(req: Request$1, inputs: Record<string, unknown>, saveOptions: SaveOptions, ...args: Record<string, unknown>[]): any;
abstract createMultiple(req: Request$1, inputs: Record<string, unknown>[], saveOptions: SaveOptions, ...args: Record<string, unknown>[]): any;
abstract delete(req: Request$1, filters: Record<string, unknown>, saveOptions: SaveOptions): any;
protected abstract getMongoose(): Mongoose;
protected abstract getDefaultProjections(): string[];
protected abstract getLogger(): Logger;
protected abstract getModel(): Model<Document>;
/**
* Prepare projection
* @param projections
*/
protected prepareProjections: (projections?: string[]) => _.Dictionary<unknown>;
protected prepareFilterIds(filter: Record<string, unknown>, keys: string[]): void;
protected filterObjectKeys: <T_1>(inputObj: Record<string, unknown>, keys?: string[], keepId?: boolean) => T_1;
protected prepareDateFilterAggregation(dateFrom: Date, dateTo: Date): Record<string, unknown>;
/**
* Initiates a mongoose session with mongoose library
* and start the transaction we well
* Here, we don't need to call startTransaction method,
* but only we have to call commit or abort transaction
*
* @param saveOptions
* @protected
*/
protected startSessionTransaction(saveOptions?: SaveOptions): Promise<ClientSession>;
/**
* End the transaction conditionally
* And the condition is that saveOption or saveOption's session
* must be empty in order to mark the session ended
* it is because we have to mark only those sessions which has been initiated by function itself
*
* @param session
* @param saveOptions
* @protected
*/
protected endSessionTransaction(session: ClientSession, saveOptions?: SaveOptions): Promise<void>;
protected commitSessionTransaction(session: ClientSession, saveOptions?: SaveOptions): Promise<void>;
protected abortSessionTransaction(session: ClientSession, saveOptions: mongoose.SaveOptions | undefined, error: Error): Promise<void>;
/**
* Please use this method after passing the session object
* in other functions
*
* @param session
* @protected
*/
protected assertSessionInTransaction(session: ClientSession): void;
protected abstract primaryKeyPrefix(): string;
protected addPagination(aggregations: Record<string, unknown>[], itemsPerPage: number, page?: number, sort?: boolean): Record<string, unknown>[];
}
declare class LogBuilder {
private _log;
constructor(title: string, titleValue?: string | undefined);
static create(title: string): LogBuilder;
addNewLine(prefix?: string | undefined): LogBuilder;
addSection(key: string | undefined, value?: string | undefined): LogBuilder;
addErrorSection(message: string | undefined): LogBuilder;
addWarningSection(message: string | undefined): LogBuilder;
build(skipNewLine?: boolean): string;
}
interface JobOptionInterface {
cron?: string;
timeStartAt?: string;
timeRepeatAt?: string;
timeRepeatEvery?: string;
startDate?: Date;
endDate?: Date;
data?: unknown;
deleteIfExists?: boolean;
logBuilder: LogBuilder;
}
declare abstract class JobService<T> {
protected _title: string | undefined;
get title(): string;
register: ({ agenda, options, }: {
agenda: Agenda;
options?: DefineOptions | undefined;
}) => void;
onHandle: (job: Job) => Promise<void>;
remove(): Promise<void>;
scheduleIfNot(inputs: T, opts?: JobOptionInterface): Promise<void>;
schedule(inputs: T, opts: JobOptionInterface): Promise<void>;
protected abstract getLogger(): Logger;
protected abstract getMongoose(): Mongoose;
protected abstract getAgenda(): Agenda;
protected abstract onRun(job: Job, data: T, opts: JobOptionInterface): Promise<void>;
}
declare class ExceptionMonitorService {
private readonly _id;
private _logger;
private queueService;
constructor({ kafkaConnection, kafkaTopic, kafkaGroupId, kafkaClientId, id, logger, }: {
kafkaConnection: string;
kafkaTopic: string;
kafkaGroupId: string;
kafkaClientId: string;
id: string;
logger?: winston.Logger;
});
send(error: Error): Promise<void> | undefined;
listen(): void;
private handleListenCallback;
}
interface opts {
port: number;
logger: winston.Logger;
logRoutes: boolean;
enableCluster: boolean;
exceptionMonitor?: ExceptionMonitorService;
before: (server: Application) => Promise<void>;
after?: (server: Application) => Promise<void>;
}
declare function startApplication(opts: opts): Promise<void>;
declare class ApiResponse<T> {
private static ERR_KEY_DEFAULT;
private result;
private success;
private code;
private httpCode;
private message;
private errors;
private page;
private itemsCount;
private allItemsCount;
constructor();
addError(err: string | string[] | Error | AxiosError<ApiResponse<T>>): this;
setErrors(errors: string[] | Error[] | AxiosError<ApiResponse<T>>[]): this;
getErrors(): {
[key: string]: string[];
};
setAppCode(code: number): this;
getAppCode(): number;
setHttpCode(code: number): this;
getHttpCode(): number;
setMessage(message: string): this;
getMessage(): string;
setResult(result: T): this;
getResult(): T;
setItemsCount(count: number): this;
getItemsCount(): number;
setPage(page: number): this;
getPage(): number;
setSuccess(success?: boolean): this;
getSuccess(): boolean;
setAllItemsCount(totalItems: number): this;
getAllItemsCount(): number;
markSuccess(): this;
createResponse(): ApiResponse<T>;
}
type Callback1Void<Input> = (input: Input) => void;
declare abstract class BaseKafkaService<Child> {
protected _logger: Logger | undefined;
protected _host: string | undefined;
protected _pollTimeInterval: number | undefined;
protected _pollTimeout: number | undefined;
protected _numConsumers: number | undefined;
protected _topic: string | undefined;
protected _group: string | undefined;
protected _clientId: string | undefined;
protected kafka: Kafka;
protected producer: Producer | undefined;
protected onNewMessageReceived: ((message: Record<string, string[]>) => void) | undefined;
private consumers;
protected constructor(host: string, clientId: string);
setLogger(value: Logger): Child;
setPollTimeInterval(value: number | undefined): Child;
clientId(value: string | undefined): Child;
setPollTimeout(value: number | undefined): Child;
setNumConsumers(value: number | undefined): Child;
setTopic(value: string | undefined): Child;
setGroup(value: string | undefined): Child;
disconnect(): void;
toWinstonLogLevel: (level: logLevel) => "info" | "warn" | "error" | "debug";
init(): Promise<void>;
setUp(): void;
protected abstract getThis(): Child;
protected initSender(): Promise<void>;
protected startPolling(): void;
protected _poll(consumer: Consumer): Promise<void>;
protected setOnMessageReceived(handler: Callback1Void<Record<string, string[]>>): Promise<void>;
protected initConsumer(): Promise<void>;
}
interface QueueInterface<Entry> {
send(key: string, message: Entry | Entry[]): void;
init(): void;
deInit(): void;
}
declare class KafkaQueueService<Entry> extends BaseKafkaService<KafkaQueueService<Entry>> implements QueueInterface<Entry> {
constructor(host: string, clientId: string);
send(key: string, message: Entry | Entry[]): Promise<void>;
deInit(): void;
onReceive(handler: Callback1Void<Record<string, Entry[]>>): Promise<KafkaQueueService<Entry>>;
protected getThis(): KafkaQueueService<Entry>;
}
declare class DateHelper {
monthsName: string[];
toH2HDateString(date: Date): string;
toFrontendString(date: Date): string;
getLastMonthsNames(num: number): string[];
getMonthName(num: number): string;
parseToDate(dateStr: string): Date | undefined;
/**
* To parse the given date string
* with the given timezone in string format
* and return the moment object for the same
*
* This return UTC formatted moment object
*
* @param dateStr
* @param timezone
*/
parseByTimeZone(dateStr: string, timezone: string): moment.Moment;
/**
* Converts the given date object to given timezone
* and return the UTC formatted timezone
*
* @param date
* @param timezone
*/
convertToTimezone(date: Date, timezone: string): moment.Moment;
/**
* Returns number of days in the current month
*/
daysInThisMonth(): number;
/**
* Check if two dates fall in the same week
* @returns boolean
*/
doesWeekMatch(dateA: Date, dateB: Date): boolean;
/**
* Check if the month of two dates fall in same year
* @returns boolean
*/
sameMonthYear(dateA: Date, dateB: Date): boolean;
/**
* Convert dateFrom
* @returns date
*/
dateFrom(date: string): Date;
/**
* Convert dateTo
* @returns date
*/
dateTo(date: string): Date;
}
declare class ObjectHelper {
removeNullAndEmptyValues(obj: Record<string, unknown>): void;
/**
* Matches and search by using regex expression
* in the given string
*
* @param object
* @param pattern
* @param exactMatch
*/
doObjectContainKeyPattern(object: Record<string, unknown>, pattern: string, exactMatch?: boolean): boolean;
/**
* Matches and search by using regex expression
* in the given string
*
* @param object
* @param pattern
*/
removeObjectKeyByPattern(object: Record<string, unknown>, pattern: string): Record<string, unknown>;
/**
* Filter out the object by matching the given string pattern
* by using the regex expression object
*
* @param obj
* @param pattern
*/
filterObjectByKeys(obj: Record<string, unknown>, pattern: string): {
[p: string]: unknown;
};
}
/**
* Attach user to req.currentUser
* @param hashedToken string
*/
declare const internalAuth: (hashedToken: string) => (req: Request$1, res: Response, next: NextFunction) => Promise<void>;
interface Request extends express.Request {
id: string;
}
/**
* Logger Interceptor
* To Intercept all the request and response
*/
declare const logRequestResponse: () => (request: Request, response: Response, next: NextFunction | undefined) => Promise<void>;
declare const _default: {
query: string;
headers: string;
body: string;
params: string;
};
declare class StringUtils {
static get REGEX_EMAIL(): RegExp;
static get REGEX_MOBILE(): RegExp;
static isValidEmail(str: string, regex: RegExp): boolean;
static isValidMobile(str: string, regex: RegExp): boolean;
ucfirst(str: string): string;
/**
* To Generate a Random Alphabetical String
* for the given number of digits
*
* @param digits Number of digits to be generated
*/
generateRandomString(digits: number): string;
/**
* This function basically create a new string
* with the help of given string
*
* @param str The String for which a new string has to be created
*/
generateShaSum(str: string): Promise<string>;
}
declare class RequestUtils {
static getTokenFromHeader: (req: Request$1) => string | undefined;
}
declare class ProcessUtils {
static sleep(ms: number): Promise<void>;
}
declare class PathUtils {
static addSlashPrefix(input: string): string;
static prepare(...args: (string | undefined)[]): string;
}
declare function setUpSwagger({ app, title, version, description, baseURL, dirToScan, routePath, routePrefix, tags, contact, }: {
app: express.Application;
title: string;
version?: string;
description?: string;
baseURL: string;
dirToScan?: string[];
routePath?: string;
routePrefix?: string;
tags?: {
name: string;
description?: string;
}[];
contact?: {
name?: 'Castler';
url?: 'https://www.castler.com';
};
}): void;
declare class AppEnvUtils {
init(): void;
}
declare class AwsEnvUtils {
private client;
private secretId;
constructor({ region, secretId }: {
region: string;
secretId: string;
});
init(): Promise<number>;
protected apply(envs: Record<string, never>): number;
}
interface DocumentInterface {
name: string;
ext: string;
mimeType: string;
}
interface FileService {
save(doc: DocumentInterface): void;
find(): DocumentInterface[];
findOne(): DocumentInterface | undefined;
download(): void;
}
declare class LocalStorageService implements FileService {
download(): void;
find(): DocumentInterface[];
findOne(): DocumentInterface | undefined;
save(doc: DocumentInterface): void;
}
declare class S3StorageService implements FileService {
client: S3Client;
constructor(keyId: string, accessKey: string, region: string);
download(): void;
find(): DocumentInterface[];
findOne(): DocumentInterface | undefined;
save(doc: DocumentInterface): void;
}
/**
* @swagger
* /health:
* get:
* summary: Status check for project
* description: Check and tell if project is up or not
* tags:
* - Health Check Controller
* responses:
* 200:
* description: A Blank response.
*/
declare function setUpExpressBase({ server, exceptionMonitor, allowedOrigins, allowedHeaders, useCORS, routePrefix, createRoutes, }: {
server: Application;
exceptionMonitor?: ExceptionMonitorService;
useCORS?: boolean;
allowedOrigins?: string[];
allowedHeaders?: string[];
routePrefix: string;
createRoutes: () => Router;
}): void;
declare abstract class LogUtils {
protected readonly _logger: Logger;
protected constructor(_logger: Logger);
error: (message: string, ...meta: unknown[]) => void;
info: (message: string, ...meta: unknown[]) => void;
warn: (message: string, ...meta: unknown[]) => void;
silly: (message: string, ...meta: unknown[]) => void;
alert: (message: string, ...meta: unknown[]) => void;
}
declare abstract class BaseError extends Error {
error: {
[key: string]: string[];
} | undefined;
protected constructor(message: string, error?: {
[key: string]: string[];
} | undefined);
toString(): string;
}
declare class RequestValidationError extends BaseError {
constructor(error: {
[key: string]: string[];
} | undefined);
}
declare class UnauthorizedError extends BaseError {
constructor();
}
export { ApiResponse, AppEnvUtils, AwsEnvUtils, BaseError, BaseKafkaService, CrudService, DateHelper, ExceptionMonitorService, type FileService, type JobOptionInterface, JobService, KafkaQueueService, LocalStorageService, LogBuilder, type LogLevel, LogUtils, type MongooseOptionInterface, ObjectHelper, PathUtils, ProcessUtils, type QueueInterface, type Request, RequestUtils, RequestValidationError, S3StorageService, StringUtils, UnauthorizedError, createLogger, internalAuth, logRequestResponse, _default as requestFields, setUpExpressBase, setUpSwagger, startApplication };