ti2 1.0.48 → 1.0.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/api.yml CHANGED
@@ -208,6 +208,13 @@ components:
208
208
  type: string
209
209
  name:
210
210
  type: string
211
+ pickuppoint:
212
+ type: object
213
+ properties:
214
+ id:
215
+ type: string
216
+ name:
217
+ type: string
211
218
  bookingSearchQuery:
212
219
  type: object
213
220
  additionalProperties: true
@@ -1170,6 +1177,81 @@ paths:
1170
1177
  type: array
1171
1178
  items:
1172
1179
  $ref: '#/components/schemas/agent'
1180
+ /{appKey}/{userId}/pickup-points:
1181
+ get:
1182
+ security:
1183
+ - bearerAuth: ['admin', 'user']
1184
+ tags:
1185
+ - bookings
1186
+ summary: Gets all pickup points for this supplier
1187
+ operationId: getPickupPoints
1188
+ parameters:
1189
+ - name: appKey
1190
+ in: path
1191
+ description: name of the app to get the pickup points from (defaults to first token found)
1192
+ required: true
1193
+ example: 'fareharbor'
1194
+ schema:
1195
+ type: string
1196
+ - name: userId
1197
+ in: path
1198
+ description: the user/company that the appKey belongs to
1199
+ required: true
1200
+ schema:
1201
+ type: string
1202
+ responses:
1203
+ '200':
1204
+ description: pickup points
1205
+ content:
1206
+ application/json:
1207
+ schema:
1208
+ type: object
1209
+ properties:
1210
+ pickupPoints:
1211
+ type: array
1212
+ items:
1213
+ $ref: '#/components/schemas/pickuppoint'
1214
+ /{appKey}/{userId}/{hint}/pickup-points:
1215
+ get:
1216
+ security:
1217
+ - bearerAuth: ['admin', 'user']
1218
+ tags:
1219
+ - bookings
1220
+ summary: Gets all pickup points for this supplier
1221
+ operationId: getPickupPoints
1222
+ parameters:
1223
+ - name: appKey
1224
+ in: path
1225
+ description: name of the app to get the pickup points from (defaults to first token found) using the hint
1226
+ required: true
1227
+ example: 'fareharbor'
1228
+ schema:
1229
+ type: string
1230
+ - name: userId
1231
+ in: path
1232
+ description: the user/company that the appKey belongs to
1233
+ required: true
1234
+ schema:
1235
+ type: string
1236
+ - name: hint
1237
+ in: path
1238
+ description: a specific token hint to be used
1239
+ required: true
1240
+ example: 'fareharbor-helloworld'
1241
+ schema:
1242
+ type: string
1243
+ responses:
1244
+ '200':
1245
+ description: pickup points
1246
+ content:
1247
+ application/json:
1248
+ schema:
1249
+ type: object
1250
+ properties:
1251
+ pickupPoints:
1252
+ type: array
1253
+ items:
1254
+ $ref: '#/components/schemas/pickuppoint'
1173
1255
  /bookings/{appKey}/{userId}/search:
1174
1256
  post:
1175
1257
  security:
@@ -27,6 +27,7 @@ const queryAllotment = plugins => async (req, res, next) => {
27
27
  const results = await app.queryAllotment({
28
28
  token,
29
29
  payload: query,
30
+ requestId: req.requestId,
30
31
  });
31
32
  return res.json(results);
32
33
  } catch (err) {
@@ -190,6 +190,7 @@ const validateAppToken = plugins => async (req, res, next) => {
190
190
  assert(app.validateToken, `could not find the validateToken method for ${appKey}`);
191
191
  const valid = await app.validateToken({
192
192
  token,
193
+ requestId: req.requestId,
193
194
  });
194
195
  return res.json({ valid });
195
196
  } catch (err) {
@@ -5,6 +5,7 @@ const { typeDefs: productTypeDefs, query: productQuery } = require('./graphql-sc
5
5
  const { typeDefs: availTypeDefs, query: availQuery } = require('./graphql-schemas/availability');
6
6
  const { typeDefs: bookingTypeDefs, query: bookingQuery } = require('./graphql-schemas/booking');
7
7
  const { typeDefs: rateTypeDefs, query: rateQuery } = require('./graphql-schemas/rate');
8
+ const { typeDefs: pickupTypeDefs, query: pickupQuery } = require('./graphql-schemas/pickup-point');
8
9
 
9
10
  const typeDefsAndQueries = {
10
11
  productTypeDefs,
@@ -15,6 +16,8 @@ const typeDefsAndQueries = {
15
16
  bookingQuery,
16
17
  rateTypeDefs,
17
18
  rateQuery,
19
+ pickupTypeDefs,
20
+ pickupQuery,
18
21
  };
19
22
 
20
23
  const bookingsSearch = plugins => async (req, res, next) => {
@@ -38,6 +41,7 @@ const bookingsSearch = plugins => async (req, res, next) => {
38
41
  token,
39
42
  payload: body,
40
43
  typeDefsAndQueries,
44
+ requestId: req.requestId,
41
45
  });
42
46
  return res.json(results);
43
47
  } catch (err) {
@@ -66,6 +70,7 @@ const bookingsCancel = plugins => async (req, res, next) => {
66
70
  token,
67
71
  payload: body,
68
72
  typeDefsAndQueries,
73
+ requestId: req.requestId,
69
74
  });
70
75
  return res.json(results);
71
76
  } catch (err) {
@@ -78,6 +83,7 @@ const $bookingsProductSearch = plugins => async ({
78
83
  userId,
79
84
  hint,
80
85
  payload,
86
+ requestId,
81
87
  }) => {
82
88
  const app = plugins.find(({ name }) => name === appKey);
83
89
  // const app = load(appKey);
@@ -94,6 +100,7 @@ const $bookingsProductSearch = plugins => async ({
94
100
  token,
95
101
  payload,
96
102
  typeDefsAndQueries,
103
+ requestId,
97
104
  });
98
105
  return results;
99
106
  };
@@ -102,9 +109,10 @@ const bookingsProductSearch = plugins => async (req, res, next) => {
102
109
  const {
103
110
  params,
104
111
  body: payload,
112
+ requestId,
105
113
  } = req;
106
114
  try {
107
- return res.json(await $bookingsProductSearch(plugins)({ ...params, payload }));
115
+ return res.json(await $bookingsProductSearch(plugins)({ ...params, payload, requestId }));
108
116
  } catch (err) {
109
117
  return next(err);
110
118
  }
@@ -131,6 +139,7 @@ const bookingsAvailabilitySearch = plugins => async (req, res, next) => {
131
139
  token,
132
140
  payload,
133
141
  typeDefsAndQueries,
142
+ requestId: req.requestId,
134
143
  });
135
144
  return res.json(results);
136
145
  } catch (err) {
@@ -143,6 +152,7 @@ const $bookingsAvailabilityCalendar = plugins => async ({
143
152
  userId,
144
153
  hint,
145
154
  payload,
155
+ requestId,
146
156
  }) => {
147
157
  const app = plugins.find(({ name }) => name === appKey);
148
158
  // const app = load(appKey);
@@ -159,6 +169,7 @@ const $bookingsAvailabilityCalendar = plugins => async ({
159
169
  token,
160
170
  payload,
161
171
  typeDefsAndQueries,
172
+ requestId,
162
173
  });
163
174
  };
164
175
 
@@ -166,9 +177,14 @@ const bookingsAvailabilityCalendar = plugins => async (req, res, next) => {
166
177
  const {
167
178
  params,
168
179
  body: payload,
180
+ requestId,
169
181
  } = req;
170
182
  try {
171
- return res.json(await $bookingsAvailabilityCalendar(plugins)({ ...params, payload }));
183
+ return res.json(await $bookingsAvailabilityCalendar(plugins)({
184
+ ...params,
185
+ payload,
186
+ requestId,
187
+ }));
172
188
  } catch (err) {
173
189
  return next(err);
174
190
  }
@@ -196,6 +212,7 @@ const searchQuote = plugins => async (req, res, next) => {
196
212
  token,
197
213
  payload,
198
214
  typeDefsAndQueries,
215
+ requestId: req.requestId,
199
216
  });
200
217
  return res.json(results);
201
218
  } catch (err) {
@@ -225,6 +242,7 @@ const createBooking = plugins => async (req, res, next) => {
225
242
  token,
226
243
  payload,
227
244
  typeDefsAndQueries,
245
+ requestId: req.requestId,
228
246
  });
229
247
  return res.json(results);
230
248
  } catch (err) {
@@ -253,6 +271,7 @@ const getAffiliateAgents = plugins => async (req, res, next) => {
253
271
  const results = await app.getAffiliateAgents({
254
272
  token,
255
273
  payload,
274
+ requestId: req.requestId,
256
275
  });
257
276
  return res.json(results);
258
277
  } catch (err) {
@@ -281,6 +300,36 @@ const getAffiliateDesks = plugins => async (req, res, next) => {
281
300
  const results = await app.getAffiliateDesks({
282
301
  token,
283
302
  payload,
303
+ requestId: req.requestId,
304
+ });
305
+ return res.json(results);
306
+ } catch (err) {
307
+ return next(err);
308
+ }
309
+ };
310
+
311
+ const getPickupPoints = plugins => async (req, res, next) => {
312
+ const {
313
+ params: { appKey, userId, hint },
314
+ body: payload,
315
+ } = req;
316
+ try {
317
+ const app = plugins.find(({ name }) => name === appKey);
318
+ // const app = load(appKey);
319
+ const userAppKeys = (await UserAppKey.findOne({
320
+ where: {
321
+ userId,
322
+ integrationId: appKey,
323
+ ...(hint ? { hint } : {}),
324
+ },
325
+ }));
326
+ assert(userAppKeys, 'could not find the app key');
327
+ const token = await userAppKeys.token;
328
+ assert(app.getPickupPoints, `getPickupPoints is not available for ${appKey}`);
329
+ const results = await app.getPickupPoints({
330
+ token,
331
+ payload,
332
+ typeDefsAndQueries,
284
333
  });
285
334
  return res.json(results);
286
335
  } catch (err) {
@@ -300,4 +349,5 @@ module.exports = plugins => ({
300
349
  createBooking: createBooking(plugins),
301
350
  getAffiliateAgents: getAffiliateAgents(plugins),
302
351
  getAffiliateDesks: getAffiliateDesks(plugins),
352
+ getPickupPoints: getPickupPoints(plugins),
303
353
  });
@@ -0,0 +1,16 @@
1
+ const typeDefs = `
2
+ type Query {
3
+ id: ID
4
+ name: String
5
+ }
6
+ `;
7
+
8
+ const query = `{
9
+ id
10
+ name
11
+ }`;
12
+
13
+ module.exports = {
14
+ typeDefs,
15
+ query,
16
+ };
package/index.js CHANGED
@@ -9,6 +9,10 @@ const bb = require('bluebird');
9
9
  const { Op } = require('sequelize');
10
10
  const R = require('ramda');
11
11
  const { v4: uuidv4 } = require('uuid');
12
+ const EventEmitter = require('eventemitter2');
13
+
14
+ const ti2Events = new EventEmitter({ captureRejections: true, wildcard: true });
15
+ ti2Events.on('event error', console.error);
12
16
 
13
17
  const schema = yaml.load(fs.readFileSync(`${__dirname}/api.yml`));
14
18
 
@@ -49,7 +53,7 @@ module.exports = async ({
49
53
  const nuName = attr.replace(/_/g, '-').replace(`ti2-${pluginName}-`, '');
50
54
  params[nuName] = value;
51
55
  });
52
- const pluginInstance = await new Plugin({ name: pluginName, ...params });
56
+ const pluginInstance = await new Plugin({ name: pluginName, events: ti2Events, ...params });
53
57
  return pluginInstance;
54
58
  });
55
59
  if (worker) {
@@ -128,55 +132,42 @@ module.exports = async ({
128
132
  notFound: (req, res) => res.sendStatus(404),
129
133
  notImplemented: (req, res) => res.sendStatus(501),
130
134
  });
131
- const onRequestStartPlugins = plugins.filter(currentPlugin => (api.getAllFuncs(currentPlugin).indexOf('onRequestStart') > -1));
132
- const onRequestEndPlugins = plugins.filter(currentPlugin => (api.getAllFuncs(currentPlugin).indexOf('onRequestEnd') > -1));
135
+ const eventHandlerPlugins = plugins.filter(currentPlugin => (api.getAllFuncs(currentPlugin).indexOf('eventHandler') > -1));
136
+ eventHandlerPlugins.forEach(plugin => {
137
+ plugin.eventHandler(ti2Events);
138
+ });
133
139
 
134
- if (onRequestStartPlugins.length > 0) {
135
- app.use((req, res, next) => {
136
- const startHrTime = process.hrtime();
137
- const requestId = uuidv4();
138
- const body = {
139
- requestId,
140
- date: Math.floor(Date.now() / 1e3),
141
- url: req.url,
142
- // body: req.body,
143
- params: req.pathParams,
144
- query: req.query,
145
- appRecord: req.appRecord,
146
- method: req.method,
147
- operationId: R.path(['openapi', 'operation', 'operationId'], req),
148
- client: req.headers['x-forwarded-for'] || req.connection.remoteAddress,
149
- };
150
- bb.each(onRequestStartPlugins, async startPlugin => {
151
- try {
152
- await startPlugin.onRequestStart(body);
153
- } catch (err) {
154
- console.log(`unable to log to ${startPlugin.name}`, err);
155
- }
156
- }).then();
157
- if (onRequestEndPlugins.length > 0) {
158
- res.on('finish', () => {
159
- const elapsedHrTime = process.hrtime(startHrTime);
160
- const responseTimeInMs = parseInt(
161
- elapsedHrTime[0] * 1e3 + elapsedHrTime[1] / 1e6,
162
- 10,
163
- );
164
- bb.each(onRequestEndPlugins, async endPlugin => {
165
- try {
166
- await endPlugin.onRequestEnd({
167
- ...body,
168
- responseTimeInMs,
169
- responseStatusCode: res.statusCode,
170
- });
171
- } catch (err) {
172
- console.log(`unable to log to ${endPlugin.name}`, err);
173
- }
174
- }).then();
175
- });
176
- }
177
- next();
140
+ app.use((req, res, next) => {
141
+ const startHrTime = process.hrtime();
142
+ const requestId = uuidv4();
143
+ const body = {
144
+ requestId,
145
+ date: Math.floor(Date.now() / 1e3),
146
+ url: req.url,
147
+ body: req.body,
148
+ params: req.pathParams,
149
+ query: req.query,
150
+ appRecord: req.appRecord,
151
+ method: req.method,
152
+ operationId: R.path(['openapi', 'operation', 'operationId'], req),
153
+ client: req.headers['x-forwarded-for'] || req.connection.remoteAddress,
154
+ };
155
+ ti2Events.emit('request.start', body);
156
+ req.requestId = requestId;
157
+ res.on('finish', () => {
158
+ const elapsedHrTime = process.hrtime(startHrTime);
159
+ const responseTimeInMs = parseInt(
160
+ elapsedHrTime[0] * 1e3 + elapsedHrTime[1] / 1e6,
161
+ 10,
162
+ );
163
+ ti2Events.emit('request.end', {
164
+ ...body,
165
+ responseTimeInMs,
166
+ responseStatusCode: res.statusCode,
167
+ });
178
168
  });
179
- }
169
+ next();
170
+ });
180
171
 
181
172
  connect(app);
182
173
  app.use(middleware.mock());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ti2",
3
- "version": "1.0.48",
3
+ "version": "1.0.50",
4
4
  "description": "Tourist Industry Exchange (TI2)",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -28,6 +28,7 @@
28
28
  "bluebird": "^3.7.2",
29
29
  "bull": "^4.8.2",
30
30
  "commander": "^9.2.0",
31
+ "eventemitter2": "^6.4.9",
31
32
  "express": "^4.17.2",
32
33
  "ioredis": "^5.0.4",
33
34
  "js-yaml": "^4.1.0",