Skip to content
Snippets Groups Projects
Unverified Commit 02ec4b11 authored by Ajay Nishad's avatar Ajay Nishad Committed by GitHub
Browse files

Merge pull request #10 from beckn/feat/ajay/create_arch

Add new arch
parents 625bd652 cabf05e0
No related branches found
No related tags found
No related merge requests found
Showing
with 295 additions and 170 deletions
{
"context": {
"path": "context"
},
"message.catalog.descriptor.name": {
"path": "title"
}
}
import { IRequestContextStructure_ver_1_1_0 } from "../common/context";
import axios from "axios";
export class ProtocolServer {
bap_client_URL = process.env.BAP_CLIENT_URI as string;
context: IRequestContextStructure_ver_1_1_0;
message: any;
constructor(payload: {
context: IRequestContextStructure_ver_1_1_0;
message: any;
}) {
this.context = payload.context;
this.message = payload.message;
}
async call() {
const payload = {
context: this.context,
message: this.message
};
return axios.post(`${this.bap_client_URL}/${this.context.action}`, payload);
}
}
import _ from "lodash";
export interface IDescriptorOutput {
name?: string;
code?: string;
short_desc?: string;
long_desc?: string;
additional_desc?: {
url?: string;
content_type?: "text/plain" | "text/html" | "application/json";
};
media?: {
mimetype?: string;
url?: string;
signature?: string;
dsa?: string;
}[];
images?: {
url?: string;
size_type?: "xs" | "sm" | "md" | "lg" | "xl" | "custom";
width?: string;
height?: string;
}[];
}
interface DescriptorGeneratorInput {
descriptionName?: string;
descriptionCode?: string;
shortDesc?: string;
longDesc?: string;
media?: any[];
images?: any[];
descriptionUrl?: string;
descriptionUrlContentType?: string;
}
export const descriptorGenerator = (
input: DescriptorGeneratorInput
): IDescriptorOutput => {
let obj: any = {
...(input?.descriptionName && { name: input?.descriptionName }),
...(input?.descriptionCode && { code: input?.descriptionCode }),
...(input?.shortDesc && { short_desc: input?.shortDesc }),
...(input?.longDesc && { long_desc: input?.longDesc }),
...(() => {
if (input?.media?.length) {
return {
media: input?.media?.map((medi: any) => ({
mimetype: medi?.mimetype,
url: medi?.url,
signature: medi?.signature,
dsa: medi?.dsa
}))
};
}
})(),
...(() => {
if (input?.images?.length) {
return {
images: input?.images?.map((image: any) => ({
url: image?.url,
size_type: image?.sizeType,
width: image?.width,
height: image?.height
}))
};
}
})(),
...(() => {
if (input?.descriptionUrl)
return {
additional_desc: {
url: input?.descriptionUrl,
content_type: input?.descriptionUrlContentType
}
};
})()
};
return obj;
};
import Joi from "joi";
import { Request, Response, NextFunction } from "express";
export interface IRequestContext {
domain: string;
bppId?: string;
bppUri?: string;
transactionId: string;
messageId: string;
bapId?: string;
bapUri?: string;
key?: string;
}
export const requestContextSchema = Joi.object({
domain: Joi.string().required(),
bppId: Joi.string().optional(),
bppUri: Joi.string().optional(),
transactionId: Joi.string().optional(),
messageId: Joi.string().optional(),
key: Joi.string().optional()
});
export const requestSchema = Joi.object({
context: requestContextSchema.required()
});
export const validateRequest = (
req: Request,
res: Response,
next: NextFunction
) => {
const { error } = requestSchema.validate(req.body, { allowUnknown: true });
if (error) {
return res.status(400).send({
message: "Invalid Request",
data: error.message,
success: false
});
}
return next();
};
export function removeEmptyObjectKeys(obj: any) {
for (const key in obj) {
if (typeof obj[key] === 'object' && obj[key] !== null) {
removeEmptyObjectKeys(obj[key]);
if (Object.keys(obj[key]).length === 0) {
delete obj[key];
}
}
}
return obj;
}
import { injectable } from 'inversify';
import 'reflect-metadata';
import * as dotenv from 'dotenv';
@injectable()
export class ConfigService {
private readonly apiKey: string;
private readonly appName;
private readonly appEnv;
private readonly appKey;
private readonly appDebug;
private readonly appPort;
private readonly appUrl;
private readonly psBaseUri;
private readonly psBapId;
private readonly psBapUri;
private readonly psCityName;
private readonly psCityCode;
private readonly psCountryName;
private readonly psCountryCode;
constructor() {
// Load environment variables from .env file
dotenv.config();
// Retrieve the API_KEY from environment variables
this.apiKey = process.env.APP_KEY || '';
this.appName = process.env.APP_NAME || '';
this.appEnv = process.env.APP_ENV || '';
this.appKey = process.env.APP_KEY || '';
this.appDebug = process.env.APP_DEBUG || '';
this.appPort = process.env.APP_PORT || '';
this.appUrl = process.env.APP_URL || '';
this.psBaseUri = process.env.PS_BASE_URI || '';
this.psBapId = process.env.PS_BAP_ID || '';
this.psBapUri = process.env.PS_BAP_URI || '';
this.psCityName = process.env.PS_CITY_NAME || '';
this.psCityCode = process.env.PS_CITY_CODE || '';
this.psCountryName = process.env.PS_COUNTRY_NAME || '';
this.psCountryCode = process.env.PS_COUNTRY_CODE || '';
}
getApiKey(): string {
return this.apiKey;
}
getAppName(): string {
return this.appName;
};
getAppEnv(): string {
return this.appEnv;
};
getAppKey(): string {
return this.appKey;
};
getAppDebug(): string {
return this.appDebug;
};
getAppPort(): string {
return this.appPort;
};
getAppUrl(): string {
return this.appUrl;
};
getPsBaseUri(): string {
return this.psBaseUri;
};
getPsBapId(): string {
return this.psBapId;
};
getPsBapUri(): string {
return this.psBapUri;
};
getPsCityName(): string {
return this.psCityName;
};
getPsCityCode(): string {
return this.psCityCode;
};
getPsCountryName(): string {
return this.psCountryName;
};
getPsCountryCode(): string {
return this.psCountryCode;
};
}
import { inject } from "inversify";
import { controller, httpPost, requestBody } from "inversify-express-utils";
import { GCLService } from "./gcl.service";
@controller('/')
export class GCLController {
constructor(@inject(GCLService) private service: GCLService) { }
@httpPost('search')
public async search(@requestBody() body: any): Promise<any> {
const searchResult = await this.service.search(body);
return searchResult;
}
@httpPost('select')
public async select(@requestBody() body: any): Promise<any> {
const selectResult = await this.service.select(body);
return selectResult;
}
@httpPost('init')
public async init(@requestBody() body: any): Promise<any> {
const initResult = await this.service.init(body);
return initResult;
}
@httpPost('confirm')
public async confirm(@requestBody() body: any): Promise<any> {
const confirmResult = await this.service.confirm(body);
return confirmResult;
}
@httpPost('status')
public async status(@requestBody() body: any): Promise<any> {
const statusResult = await this.service.status(body);
return statusResult;
}
}
import { inject, injectable } from "inversify";
import { TLService } from "../tl/tl.service";
import { PSClientService } from "../psclient/psclient.service";
@injectable()
export class GCLService {
constructor(
@inject(TLService) private tlService: TLService,
@inject(PSClientService) private psClientService: PSClientService
) { }
async search(body: any) {
const payload = await this.tlService.transform(body, "search");
const psResponse = await this.psClientService.post(payload);
const response = await this.tlService.transform(psResponse, "on_search");
return response;
}
async select(body: any) {
const payload = await this.tlService.transform(body, "select");
const psResponse = await this.psClientService.postMany(payload);
const response = await this.tlService.transform(psResponse, "on_select");
return response;
}
async init(body: any) {
const payload = await this.tlService.transform(body, "init");
const psResponse = await this.psClientService.postMany(payload);
const response = await this.tlService.transform(psResponse, "on_init");
return response;
}
async confirm(body: any) {
// const payload = await this.tlService.transform(body, "select");
// const psResponse = await this.psClientService.postMany(payload);
// const response = await this.tlService.transform(psResponse, "on_select");
// return response;
return "In Progress";
}
async status(body: any) {
// const payload = await this.tlService.transform(body, "select");
// const psResponse = await this.psClientService.postMany(payload);
// const response = await this.tlService.transform(psResponse, "on_select");
// return response;
return "In Progress";
}
}
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
import { inject, injectable } from 'inversify';
import { AppLogger } from '../app/app.logger';
@injectable()
class HttpClient {
private readonly client: AxiosInstance;
constructor(@inject(AppLogger) private logger: AppLogger) {
this.client = axios.create({
headers: {
'Content-Type': 'application/json',
},
});
// Add request interceptor
this.client.interceptors.request.use((config: InternalAxiosRequestConfig) => {
// Modify the request config if needed
logger.info("Making network request: \n%s %s\nHEADERS %s \nDATA %o", config.method?.toUpperCase(), config.url, JSON.stringify(config.headers), JSON.stringify(config.data));
return config;
}, (error: any) => {
// Handle request error
logger.error("Request error: \n%o", error.data);
return Promise.reject(error);
});
// Add response interceptor
this.client.interceptors.response.use((response: AxiosResponse) => {
// Modify the response data if needed
logger.info("Response received: %o\n", JSON.stringify(response.data));
return response;
}, (error: any) => {
// Handle response error
logger.error("Response error: %o", error.message);
return Promise.reject(error);
});
}
async get<T>(url: string, config?: AxiosRequestConfig): Promise<T> {
const response: AxiosResponse<T> = await this.client.get(url, config);
return response.data;
}
async post<T>(url: string, data: any, config?: AxiosRequestConfig): Promise<T> {
const response: AxiosResponse<T> = await this.client.post(url, data, config);
return response.data;
}
async put<T>(url: string, data: any, config?: AxiosRequestConfig): Promise<T> {
const response: AxiosResponse<T> = await this.client.put(url, data, config);
return response.data;
}
async delete<T>(url: string, config?: AxiosRequestConfig): Promise<T> {
const response: AxiosResponse<T> = await this.client.delete(url, config);
return response.data;
}
}
export default HttpClient;
import express, { Express } from "express";
import { startServer } from "./app/server";
import dotenv from "dotenv";
const app: Express = express();
dotenv.config();
startServer(app);
import { Container } from 'inversify';
import "reflect-metadata";
import { ConfigService } from '../config/config.service';
import { GCLService } from '../gcl/gcl.service';
import { TLService } from '../tl/tl.service';
import { InversifyExpressServer } from 'inversify-express-utils';
import { PSClientService } from '../psclient/psclient.service';
import { AppLogger } from '../app/app.logger';
import HttpClient from '../httpclient/http.service';
import { ErrorHandlerMiddleware } from '../middleware/errorhandler.middleware';
const container = new Container();
const server = new InversifyExpressServer(container);
container.bind<ConfigService>(ConfigService).to(ConfigService);
container.bind<GCLService>(GCLService).to(GCLService);
container.bind<TLService>(TLService).to(TLService);
container.bind<PSClientService>(PSClientService).to(PSClientService);
container.bind<AppLogger>(AppLogger).to(AppLogger);
container.bind<HttpClient>(HttpClient).to(HttpClient);
container.bind<ErrorHandlerMiddleware>(ErrorHandlerMiddleware).toSelf();
export { server, container };
import { inject, injectable } from 'inversify';
import { Request, Response, NextFunction } from 'express';
import { AppLogger } from '../app/app.logger';
@injectable()
export class ErrorHandlerMiddleware {
constructor(@inject(AppLogger) private logger: AppLogger) { }
public handleError(error: Error, req: Request, res: Response, next: NextFunction): void {
this.logger.error("%s", error.stack);
const statusCode = res.statusCode === 200 ? 500 : res.statusCode;
res.status(statusCode).json({
error: {
message: error.message
},
});
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment