ti2 1.0.21 → 1.0.22

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/cache.js ADDED
@@ -0,0 +1,62 @@
1
+ const Redis = require('ioredis');
2
+ const hash = require('object-hash');
3
+
4
+ const REDIS_URL = process.env.REDIS_URL || 'redis://redis:6379';
5
+ const cache = new Redis(`${REDIS_URL}/2`);
6
+
7
+ const defaultTTL = 60 * 60; // 1 hour
8
+
9
+ const save = async ({
10
+ pluginName,
11
+ key: keyParam,
12
+ value,
13
+ ttl = defaultTTL,
14
+ }) => {
15
+ const key = `${pluginName}:${keyParam}`;
16
+ const keyType = typeof value === 'string';
17
+ await cache.set(key, JSON.stringify({
18
+ keyType,
19
+ value: keyType === 'string' ? value : JSON.stringify(value),
20
+ }));
21
+ await cache.expire(key, ttl);
22
+ };
23
+
24
+ const get = async ({
25
+ pluginName,
26
+ key: keyParam,
27
+ }) => {
28
+ const key = `${pluginName}:${keyParam}`;
29
+ const storeVal = await cache.get(key);
30
+ if (!storeVal) return storeVal;
31
+ const { keyType, value } = JSON.parse(storeVal);
32
+ if (keyType === 'string') {
33
+ return value;
34
+ }
35
+ return JSON.parse(value);
36
+ };
37
+
38
+ const getOrExec = async ({
39
+ pluginName,
40
+ key: keyParam,
41
+ ttl,
42
+ fn,
43
+ fnParams,
44
+ }) => {
45
+ const key = keyParam || hash({ fn, fnParams });
46
+ let value = await get({ pluginName, key });
47
+ if (value !== null) return value;
48
+ value = await fn(...fnParams);
49
+ await save({
50
+ pluginName,
51
+ key,
52
+ value,
53
+ ttl,
54
+ });
55
+ return value;
56
+ };
57
+
58
+ module.exports = {
59
+ cache,
60
+ save,
61
+ getOrExec,
62
+ };
package/closeAll.js CHANGED
@@ -1,6 +1,8 @@
1
1
  const { redisResults, queue } = require('./worker/queue');
2
+ const { cache } = require('./cache');
2
3
 
3
4
  module.exports = async () => {
4
5
  await queue.close();
5
6
  await redisResults.quit();
7
+ await cache.quit();
6
8
  };
@@ -56,28 +56,37 @@ const bookingsCancel = plugins => async (req, res, next) => {
56
56
  }
57
57
  };
58
58
 
59
+ const $bookingsProductSearch = plugins => async ({
60
+ appKey,
61
+ userId,
62
+ hint,
63
+ payload,
64
+ }) => {
65
+ const app = plugins.find(({ name }) => name === appKey);
66
+ // const app = load(appKey);
67
+ const userAppKeys = (await UserAppKey.findOne({
68
+ where: {
69
+ userId,
70
+ integrationId: appKey,
71
+ ...(hint ? { hint } : {}),
72
+ },
73
+ }));
74
+ assert(userAppKeys, 'could not find the app key');
75
+ const token = userAppKeys.appKey;
76
+ const results = await app.searchProducts({
77
+ token,
78
+ payload,
79
+ });
80
+ return results;
81
+ };
82
+
59
83
  const bookingsProductSearch = plugins => async (req, res, next) => {
60
84
  const {
61
- params: { appKey, userId, hint },
85
+ params,
62
86
  body: payload,
63
87
  } = req;
64
88
  try {
65
- const app = plugins.find(({ name }) => name === appKey);
66
- // const app = load(appKey);
67
- const userAppKeys = (await UserAppKey.findOne({
68
- where: {
69
- userId,
70
- integrationId: appKey,
71
- ...(hint ? { hint } : {}),
72
- },
73
- }));
74
- assert(userAppKeys, 'could not find the app key');
75
- const token = userAppKeys.appKey;
76
- const results = await app.searchProducts({
77
- token,
78
- payload,
79
- });
80
- return res.json(results);
89
+ return res.json(await $bookingsProductSearch(plugins)({ ...params, payload }));
81
90
  } catch (err) {
82
91
  return next(err);
83
92
  }
@@ -110,28 +119,36 @@ const bookingsAvailabilitySearch = plugins => async (req, res, next) => {
110
119
  }
111
120
  };
112
121
 
122
+ const $bookingsAvailabilityCalendar = plugins => async ({
123
+ appKey,
124
+ userId,
125
+ hint,
126
+ payload,
127
+ }) => {
128
+ const app = plugins.find(({ name }) => name === appKey);
129
+ // const app = load(appKey);
130
+ const userAppKeys = (await UserAppKey.findOne({
131
+ where: {
132
+ userId,
133
+ integrationId: appKey,
134
+ ...(hint ? { hint } : {}),
135
+ },
136
+ }));
137
+ assert(userAppKeys, 'could not find the app key');
138
+ const token = userAppKeys.appKey;
139
+ return app.availabilityCalendar({
140
+ token,
141
+ payload,
142
+ });
143
+ };
144
+
113
145
  const bookingsAvailabilityCalendar = plugins => async (req, res, next) => {
114
146
  const {
115
- params: { appKey, userId, hint },
147
+ params,
116
148
  body: payload,
117
149
  } = req;
118
150
  try {
119
- const app = plugins.find(({ name }) => name === appKey);
120
- // const app = load(appKey);
121
- const userAppKeys = (await UserAppKey.findOne({
122
- where: {
123
- userId,
124
- integrationId: appKey,
125
- ...(hint ? { hint } : {}),
126
- },
127
- }));
128
- assert(userAppKeys, 'could not find the app key');
129
- const token = userAppKeys.appKey;
130
- const results = await app.availabilityCalendar({
131
- token,
132
- payload,
133
- });
134
- return res.json(results);
151
+ return res.json(await $bookingsAvailabilityCalendar(plugins)({ ...params, payload }));
135
152
  } catch (err) {
136
153
  return next(err);
137
154
  }
@@ -196,8 +213,10 @@ const createBooking = plugins => async (req, res, next) => {
196
213
  module.exports = plugins => ({
197
214
  bookingsSearch: bookingsSearch(plugins),
198
215
  bookingsCancel: bookingsCancel(plugins),
216
+ $bookingsProductSearch,
199
217
  bookingsProductSearch: bookingsProductSearch(plugins),
200
218
  bookingsAvailabilitySearch: bookingsAvailabilitySearch(plugins),
219
+ $bookingsAvailabilityCalendar,
201
220
  bookingsAvailabilityCalendar: bookingsAvailabilityCalendar(plugins),
202
221
  searchQuote: searchQuote(plugins),
203
222
  createBooking: createBooking(plugins),
package/index.js CHANGED
@@ -18,6 +18,11 @@ const appController = require('./controllers/app');
18
18
  const userController = require('./controllers/user');
19
19
  const bookingsController = require('./controllers/bookings');
20
20
  const { Integration } = require('./models');
21
+ const cache = require('./cache');
22
+
23
+ // src : https://github.com/ramda/ramda/issues/3137#issuecomment-1016012904
24
+ const rebuild = fn => obj =>
25
+ Object.fromEntries(Object.entries(obj).flatMap(([k, v]) => fn(k, v)));
21
26
 
22
27
  module.exports = async ({
23
28
  apiDocs = true,
@@ -76,11 +81,37 @@ module.exports = async ({
76
81
  ...appController,
77
82
  ...userController(plugins),
78
83
  ...bookingsController(plugins),
84
+ cache: R.omit(['cache'], cache),
79
85
  }; // mehthods that should map to the yaml api spec
80
86
  app.plugins = plugins;
81
- createMiddleware(schema, app, (_err, middleware) => {
87
+ // add the plugin schema to the schema
88
+ const appControllers = {};
89
+ const allSchema = plugins.filter(e => e.schema).reduce((prev, { schema: currSchema, name }) => {
90
+ appControllers[name] = R.uniq(R.pluck(['operationId'])(R.flatten(Object.values(currSchema.paths || {}).map(Object.values))));
91
+ const newSchema = R.modifyPath(
92
+ ['paths'],
93
+ rebuild(
94
+ (attr, val) => {
95
+ const newVal = {};
96
+ Object.entries(val).forEach(([pathAttr, pathValue]) => {
97
+ newVal[pathAttr] = R.modifyPath(['operationId'], operationName => `${name}_${operationName}`, pathValue);
98
+ });
99
+ return [[`/apps/${name}${attr}`, newVal]];
100
+ },
101
+ ),
102
+ currSchema,
103
+ );
104
+ return R.mergeDeepLeft(prev, newSchema);
105
+ }, schema);
106
+ Object.entries(appControllers).forEach(([name, actions]) => {
107
+ actions.forEach(action => {
108
+ const thePlugin = plugins.find(({ name: pluginName }) => pluginName === name);
109
+ api[`${name}_${action}`] = thePlugin[action]({ plugins, api });
110
+ });
111
+ });
112
+ createMiddleware(allSchema, app, (_err, middleware) => {
82
113
  if (apiDocs) {
83
- app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(schema));
114
+ app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(allSchema));
84
115
  }
85
116
  app.use(
86
117
  middleware.metadata(),
@@ -88,7 +119,7 @@ module.exports = async ({
88
119
  middleware.parseRequest(),
89
120
  // middleware.validateRequest(),
90
121
  );
91
- const connect = connector(api, schema, {
122
+ const connect = connector(api, allSchema, {
92
123
  security: auth,
93
124
  });
94
125
  if (elasticLogsClient) { // API request logs are saved on elastic
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ti2",
3
- "version": "1.0.21",
3
+ "version": "1.0.22",
4
4
  "description": "Tourist Industry Exchange (TI2)",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -34,6 +34,7 @@
34
34
  "jsonwebtoken": "^8.5.1",
35
35
  "jwt-promise": "^1.0.0",
36
36
  "mysql2": "^2.3.3",
37
+ "object-hash": "^3.0.0",
37
38
  "ramda": "^0.28.0",
38
39
  "seque": "^1.2.1",
39
40
  "sequelize": "^6.13.0",