ti2 1.0.19 → 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 +62 -0
- package/cli.js +2 -0
- package/closeAll.js +2 -0
- package/controllers/bookings.js +53 -34
- package/index.js +34 -3
- package/package.json +2 -1
- package/worker/index.js +1 -1
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/cli.js
CHANGED
|
@@ -21,6 +21,7 @@ program.command('dbapp')
|
|
|
21
21
|
)
|
|
22
22
|
.action(async (integration, action) => {
|
|
23
23
|
await migrateApp({ integrationId: integration, action });
|
|
24
|
+
process.exit(0);
|
|
24
25
|
});
|
|
25
26
|
|
|
26
27
|
program.command('db')
|
|
@@ -31,6 +32,7 @@ program.command('db')
|
|
|
31
32
|
)
|
|
32
33
|
.action(async action => {
|
|
33
34
|
await migrate({ action });
|
|
35
|
+
process.exit(0);
|
|
34
36
|
});
|
|
35
37
|
|
|
36
38
|
program.parse();
|
package/closeAll.js
CHANGED
package/controllers/bookings.js
CHANGED
|
@@ -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
|
|
85
|
+
params,
|
|
62
86
|
body: payload,
|
|
63
87
|
} = req;
|
|
64
88
|
try {
|
|
65
|
-
|
|
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
|
|
147
|
+
params,
|
|
116
148
|
body: payload,
|
|
117
149
|
} = req;
|
|
118
150
|
try {
|
|
119
|
-
|
|
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
|
-
|
|
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(
|
|
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,
|
|
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.
|
|
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",
|
package/worker/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
const throng = require('throng');
|
|
2
2
|
require('util').inspect.defaultOptions.depth = null;
|
|
3
|
-
const fakePlugin = require('../test/plugin');
|
|
4
3
|
|
|
5
4
|
const { queue, saveResult } = require('./queue');
|
|
6
5
|
|
|
@@ -35,6 +34,7 @@ const worker = ({ plugins: pluginsParam }) => (id, disconnect) => {
|
|
|
35
34
|
console.log(`job ${jobId} > running ${pluginName}:${method} for ${userId}`);
|
|
36
35
|
const plugins = await (async () => {
|
|
37
36
|
if (inTesting) {
|
|
37
|
+
const fakePlugin = require('../test/plugin');
|
|
38
38
|
return [...pluginsParam, await new fakePlugin({ name: pluginName })];
|
|
39
39
|
}
|
|
40
40
|
return pluginsParam;
|