UNPKG

9.94 kBPlain TextView Raw
1import * as bodyParser from 'body-parser';
2import * as express from 'express';
3import {response, IResponse} from './tools';
4
5export interface ICheckRequiredParams {
6 req: any;
7 context: string;
8 required: Array<string>;
9}
10
11export interface IApi {
12 route?: string;
13 method?: string;
14 instance?: any;
15 get?: any; // return object from instance like "get('player') from instance.dependencies.player"
16 execute?: any;
17 executeFirst?: any;
18 dependencies?: any; // {playCard: playCard, user: user}
19 context: string;
20 send?: any;
21 res?: any;
22 req?: any;
23 allowCors?: boolean;
24 required?: Array<string>;
25 swaggerFilePath?: string;
26}
27
28export const checkRequiredParams = (r: ICheckRequiredParams): IResponse => {
29 try {
30 if (r.required && r.required.length) {
31 const _body = Object.keys(r.req.body),
32 _params = Object.keys(r.req.params);
33
34 if(_body.length && _params.length) {
35 for (let i = 0; i < r.required.length; i++) {
36 if (_body.indexOf(r.required[i]) < 0) {
37 if (_params.indexOf(r.required[i]) > -1) {
38 continue;
39 }
40 return response(false, `${r.context} '${r.required[i]}' is required`);
41 }
42 }
43 return response(true, null, true);
44 } else {
45 const p = _body.length ? _body : (_params.length ? _params : null);
46 if (p && p.length) {
47 // indexOf required
48 for (let i = 0; i < r.required.length; i++) {
49 if (p.indexOf(r.required[i]) < 0) {
50 return response(false, `${r.context} '${r.required[i]}' is required`);
51 }
52 }
53 return response(true, null, true);
54 }
55 }
56
57 return response(false, 'Required parameters do not match requirements!', null);
58 }
59 }catch (error) {
60 console.log(65, error)
61 }
62}
63
64export class Api {
65 app: any;
66 dependencies: any; // any object/class like Player, Status, Play, Game
67
68 constructor(dependencies: any) {
69 if (dependencies) {
70 this.dependencies = dependencies;
71 }
72
73 const app = express();
74 process.setMaxListeners(Infinity);
75
76 app.use(bodyParser.json({strict: false}));
77
78 app.use(function (req, res, next) {
79 res
80 .set('Access-Control-Allow-Origin', '*')
81 .set('Access-Control-Allow-Methods', 'GET, POST, DELETE, PUT')
82 .set('Access-Control-Allow-Credentials', true)
83 .set('Access-Control-Allow-Headers', 'Origin, Accept, Content-Type, X-Requested-With, X-Merchant-Id');
84
85 process.on('unhandledRejection', (reason, p) => {
86 console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
87 // application specific logging, throwing an error, or other logic here
88 });
89 next();
90 });
91 app.disable('x-powered-by');
92
93 this.app = app;
94 }
95
96 get(dependencyName: string) {
97 if (this.dependencies[dependencyName]) {
98 return this.dependencies[dependencyName];
99 }
100 return null;
101 }
102
103 routes(params: Array<IApi>) {
104 for (let i = 0; i < params.length; i++) {
105 let route = params[i].route.toString().trim(), method,
106 swaggerFilePath = params[i].swaggerFilePath || '../../swagger';
107
108 if (route.indexOf(' ') > -1) {
109 [method, route] = params[i].route.split(' ');
110 } else {
111 route = params[i].route;
112 method = (params[i].method === undefined) ? 'get' : params[i].method.toString();
113 }
114 method = method.toLowerCase();
115
116 const _params = params[i], that = this;
117
118 this.app[method](route, function(req, res) {
119 if (_params.allowCors === undefined) {
120 _params.allowCors = true;
121 }
122
123 // if (_params.allowCors) {
124 res
125 .set('Access-Control-Allow-Origin', '*')
126 .set('Access-Control-Allow-Methods', 'GET, POST, DELETE, PUT')
127 .set('Access-Control-Allow-Credentials', true)
128 .set('Access-Control-Allow-Headers', 'Origin, Accept, Content-Type, X-Requested-With, X-Merchant-Id');
129 // }
130
131 if (route.indexOf('_swagger') > -1) {
132 return res.json(require(swaggerFilePath));
133 } else {
134 if (_params.required && _params.required.length) {
135 const __response = checkRequiredParams({req, required: _params.required, context: _params.context});
136
137 if (!__response.success) {
138 return res.status(400).json(__response);
139 }
140 }
141
142 const p = {
143 res,
144 req,
145 method,
146 instance: that,
147 context: _params.context,
148 execute: _params['execute'],
149 allowCors: _params.allowCors
150 };
151
152 that.app.res = res;
153 that.app.req = req;
154
155 if (_params.executeFirst) {
156 p['executeFirst'] = _params['executeFirst'];
157 }
158
159 that.executeRoute(p);
160 }
161 });
162 }
163 }
164
165 /**
166 * Get the Client IP address.
167 */
168 async getSourceIp(): Promise<IResponse>{
169 try{
170
171 if(!this.app || !this.app.req ){
172 return response(false, 'Not SourceIp Address found.');
173 }
174
175 const sourceIp = (this.app.req.headers['x-forwarded-for'] ||
176 this.app.req.connection.remoteAddress ||
177 this.app.req.socket.remoteAddress ||
178 this.app.req.connection.socket.remoteAddress).split(",")[0] || '';
179
180 if(sourceIp){
181 return response(true, null, {sourceIp: sourceIp});
182 }else{
183 return response(false, 'Not SourceIp Address found.');
184 }
185
186 }catch (error) {
187 console.log(78, error);
188 return response(false, error);
189 }
190 }
191
192 async executeRoute(params: IApi): Promise<IResponse> {
193
194 const execute = params.execute,
195 executeFirst = params.executeFirst,
196 instance = params.instance;
197 let res = params.res, req = params.req;
198
199 try {
200 // executeFirst needs to be executed first
201 if (executeFirst) {
202 const [obj, meth] = params['executeFirst'].split('.');
203 const awResult = await instance['dependencies'][obj][meth](
204 params.method === 'get' ? params.req.params : params.req.body,
205 params.method !== 'get' ? params.req.params : instance,
206 params.method !== 'get' ? instance : null);
207
208 if(awResult) {
209
210 if (awResult.success) {
211 const [obj, meth] = params['execute'].split('.');
212 const _response = await instance['dependencies'][obj][meth](
213 params.method === 'get' ? params.req.params : params.req.body,
214 params.method !== 'get' ? params.req.params : instance,
215 params.method !== 'get' ? instance : null);
216 if (_response) {
217 if (_response.success && _response.data) {
218 if (Array.isArray(_response.data.Items)) {
219 return res.status(_response.data.Items.length? 200: 404).json(response(true, false, _response.data.Items.length > 1? _response.data.Items : _response.data.Items[0]));
220 } else {
221 res.status(200);
222 }
223 } else {
224 res.status(400);
225 }
226 } else {
227 res.status(500);
228 }
229 } else {
230 res.status(400);
231 }
232 } else {
233 res.status(500);
234 }
235 res.json(awResult);
236 } else {
237 const [obj, meth] = params['execute'].split('.');
238
239 const _response = await instance['dependencies'][obj][meth](
240 params.method === 'get' ? params.req.params : params.req.body,
241 params.method !== 'get' ? params.req.params : instance,
242 params.method !== 'get' ? instance : null);
243 if (_response) {
244 if (_response.success && _response.data) {
245 if (Array.isArray(_response.data.Items)) {
246 return res.status(_response.data.Items.length? 200: 404).json(response(true, false, _response.data.Items.length > 1? _response.data.Items : _response.data.Items[0]));
247 } else {
248 res.status(200);
249 }
250 } else {
251 res.status(400);
252 }
253 } else {
254 res.status(500);
255 }
256 res.json(_response);
257 }
258 } catch (error) {
259 console.log('[api()] error:', error);
260 return res.status(500).json(response(false, error.message));
261 }
262 }
263}