ti2 1.0.12 → 1.0.15

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/README.md CHANGED
@@ -4,6 +4,12 @@ Ti2 (Tourism Information Interchange) is an open source integration framework, b
4
4
 
5
5
  Core functions of Ti2 are currently focused on content, rates, and bookings.
6
6
 
7
+ ### Why use it ?
8
+
9
+ Ti2 gives a free, open source solution to building integrations across our industry. In addition, tools can be built on top of Ti2, that add additional value to these integrations - whether for the good of our industry or for profit.
10
+
11
+ **Become part of the community, start building on Ti2 today!**
12
+
7
13
  ## About this Project
8
14
 
9
15
  ### How it Works
@@ -16,57 +22,15 @@ App Plugins are value added tools that only speak to Ti2 and other plugins. For
16
22
 
17
23
  Ti2 can be deployed on your own servers, or you can connect to a Ti2 instance that another company is hosting.
18
24
 
19
- ### Why use Ti2 ?
20
-
21
- Ti2 gives a free, open source solution to building integrations across our industry. In addition, tools can be built on top of Ti2, that add additional value to these integrations - whether for the good of our industry or for profit.
22
-
23
- **Become part of the community, start building on Ti2 today!**
24
-
25
25
  ## Getting Started
26
26
 
27
- ### Requirements
27
+ You can write your [own plugin]{@tutorial plugin-development} that hooks up to a Ti2 instance or you can run a server that that hosts your [own **Ti2** instance]{@tutorial setup-your-instance} with any plugins (your own or from the plugin library).
28
28
 
29
- Some environment variables are required for ti2 to start
30
-
31
- - DB_URL (mysql connection in url format)
32
- - dbCryptoKey (integration details encription key, should be a 32 chars random string base64 encoded)
33
- - adminKey (a key for admin related requests)
34
- - jwtKey (a key to encrypt user sessions request)
35
- - frontendKey (an additional optional key to validate the origin of the requests)
36
- - PORT (an optional port to run the http server, in case a port is not specified as a parameter)
37
-
38
- ### Starting your server
39
-
40
- You can start your own instance by instlling ti2 and any aplugin syou may want to use on your own nodejs project root folter:
41
-
42
- ```bash
43
- $ npm i ti2 ti2-travelgate ti2-ventrata ti2-tourconnect
44
- ```
45
-
46
- To start the server with default values use the following:
47
-
48
- ```javascript
49
- const ti2 = require('ti2')({
50
- plugins: {
51
- travelgate: require('ti2-travelgate'),
52
- ventrata: require('ti2-ventrata'),
53
- tourconnect: require('ti2-tourconnect'),
54
- },
55
- });
56
- ```
57
29
 
58
30
  ## Plugins
59
31
 
60
32
  Plugins are the connectores to other systems and/or features you intent to use; by default the server will start an API service on port 10010 and the swagger documentation on the path //api-docs, (you can disable wither by passing the startServer param as False or the apiDocs as False.
61
33
 
62
- Plugin environment keys are passed down to the instance while is being created, this is the preferred way of accesing environmen keys from the plugins, such values are not design to hold client / user's API keys or specific data, they are to be stored on the database itself via the AppKey collection.
63
-
64
- Plugin ENV variable name convention: ti2_pluginName_environmenVariableName, for example:
65
-
66
- ```env
67
- ti2_tourconnect_apiUrl=http://backend:8080
68
- ```
69
-
70
34
  ### Plugin Library
71
35
 
72
36
  | Methods | [Ventrata](https://github.com/TourConnect/ti2-ventrata) | [TravelGateX](https://github.com/TourConnect/ti2-travelgate) | [Didgigo](https://github.com/TourConnect/ti2-didgigo) | [TourConnect](https://github.com/TourConnect/ti2-tourconnect)
@@ -93,27 +57,6 @@ ti2_tourconnect_apiUrl=http://backend:8080
93
57
  |createBooking|✓|✓|
94
58
  |cancelBooking|✓|✓|
95
59
 
96
- ## API logging
97
-
98
- Currently logging is supported via elastic search, an elasticLogClient value can ben passed down, example:
99
-
100
- ```javascript
101
- const { Client } = require('@elastic/elasticsearch');
102
- const elasticLogsClient = (() => {
103
- if (!elasticLogs) return null;
104
- return new Client({ node: elasticLogs });
105
- })();
106
-
107
- const ti2 = require('ti2')({
108
- elasticLogsClient,
109
- plugins: {
110
- ventrata: require('ti2-ventrata'),
111
- travelgate: require('ti2-travelgate'),
112
- tourconnect: require('ti2-tourconnect'),
113
- },
114
- });
115
- ```
116
-
117
60
  ## Contributing
118
61
 
119
62
  Contributions are welcome and ecouraged.
package/api.yml CHANGED
@@ -816,6 +816,97 @@ paths:
816
816
  application/json:
817
817
  schema:
818
818
  $ref: '#/components/schemas/bookingsProductSearchReturn'
819
+ /bookings/{appKey}/{userId}/availabilitycalendar:
820
+ post:
821
+ security:
822
+ - bearerAuth: ['admin', 'user']
823
+ tags:
824
+ - bookings
825
+ summary: Availability Search
826
+ operationId: bookingsAvailabilityCalendar
827
+ parameters:
828
+ - name: appKey
829
+ in: path
830
+ description: app to search availability for, defaults to first token
831
+ required: true
832
+ example: 'travelgate-hotelx'
833
+ schema:
834
+ type: string
835
+ - name: userId
836
+ in: path
837
+ description: the user/company that the appKey belongs to
838
+ required: true
839
+ schema:
840
+ type: string
841
+ requestBody:
842
+ description: both app details
843
+ required: true
844
+ content:
845
+ application/json:
846
+ schema:
847
+ $ref: '#/components/schemas/AnyValue'
848
+ responses:
849
+ '200':
850
+ description: search results
851
+ content:
852
+ application/json:
853
+ schema:
854
+ type: object
855
+ properties:
856
+ availability:
857
+ type: array
858
+ required: true
859
+ items:
860
+ $ref: '#/components/schemas/availabilityItem'
861
+ /bookings/{appKey}/{userId}/{hint}/availabilitycalendar:
862
+ post:
863
+ security:
864
+ - bearerAuth: ['admin', 'user']
865
+ tags:
866
+ - bookings
867
+ summary: Availability Search for an specific hint
868
+ operationId: bookingsAvailabilityCalendar
869
+ parameters:
870
+ - name: appKey
871
+ in: path
872
+ description: app to search availability for, defaults to first token
873
+ required: true
874
+ example: 'travelgate-hotelx'
875
+ schema:
876
+ type: string
877
+ - name: userId
878
+ in: path
879
+ description: the user/company that the appKey belongs to
880
+ required: true
881
+ schema:
882
+ type: string
883
+ - name: hint
884
+ in: path
885
+ description: a specific token hint to be used
886
+ required: true
887
+ example: 'travelgate-australia'
888
+ schema:
889
+ type: string
890
+ requestBody:
891
+ description: both app details
892
+ required: true
893
+ content:
894
+ application/json:
895
+ schema:
896
+ $ref: '#/components/schemas/AnyValue'
897
+ responses:
898
+ '200':
899
+ description: search results
900
+ content:
901
+ application/json:
902
+ schema:
903
+ type: object
904
+ properties:
905
+ availability:
906
+ type: array
907
+ required: true
908
+ items:
909
+ $ref: '#/components/schemas/availabilityItem'
819
910
  /bookings/{appKey}/{userId}/availability:
820
911
  post:
821
912
  security:
@@ -110,6 +110,33 @@ const bookingsAvailabilitySearch = plugins => async (req, res, next) => {
110
110
  }
111
111
  };
112
112
 
113
+ const bookingsAvailabilityCalendar = plugins => async (req, res, next) => {
114
+ const {
115
+ params: { appKey, userId, hint },
116
+ body: payload,
117
+ } = req;
118
+ 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);
135
+ } catch (err) {
136
+ return next(err);
137
+ }
138
+ };
139
+
113
140
  const searchQuote = plugins => async (req, res, next) => {
114
141
  const {
115
142
  params: { appKey, userId, hint },
@@ -171,6 +198,7 @@ module.exports = plugins => ({
171
198
  bookingsCancel: bookingsCancel(plugins),
172
199
  bookingsProductSearch: bookingsProductSearch(plugins),
173
200
  bookingsAvailabilitySearch: bookingsAvailabilitySearch(plugins),
201
+ bookingsAvailabilityCalendar: bookingsAvailabilityCalendar(plugins),
174
202
  searchQuote: searchQuote(plugins),
175
203
  createBooking: createBooking(plugins),
176
204
  });
package/jsdoc.conf.json CHANGED
@@ -13,7 +13,10 @@
13
13
  ],
14
14
  "templates": {
15
15
  "cleverLinks": true,
16
- "monospaceLinks": true
16
+ "monospaceLinks": true,
17
+ "default": {
18
+ "includeDate": false
19
+ }
17
20
  },
18
21
  "opts": {
19
22
  "destination": "docs",
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "ti2",
3
- "version": "1.0.12",
3
+ "version": "1.0.15",
4
4
  "description": "Tourist Industry Exchange (TI2)",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
7
  "test": "jest",
8
8
  "sequelize": "sequelize-cli",
9
- "doc": "jsdoc -c jsdoc.conf.json"
9
+ "doc": "jsdoc -c jsdoc.conf.json -u tutorials"
10
10
  },
11
11
  "repository": {
12
12
  "type": "git",
package/test/plugin.js CHANGED
@@ -3,24 +3,9 @@ const chance = require('chance').Chance();
3
3
 
4
4
  class Plugin {
5
5
  /**
6
- * **General** Methods:
7
- * * [validateToken](#validateToken).
6
+ * For a comprehensive list of methods visit the
7
+ * [Plugin Development]{@tutorial plugin-development} page.
8
8
  *
9
- * **Content Methods**:
10
- * * [getProfile](#getProfile)
11
- * * [updateProfile](#updateProfile)
12
- * * [createLocation](#createLocation)
13
- * * [updateLocation](#updateLocation)
14
- * * [getProducts](#getProducts)
15
- * * [createProduct](#createProduct)
16
- * * [updateProduct](#updateProduct)
17
- *
18
- * **Booking Methods**:
19
- * * [searchBooking](#searchBooking)
20
- * * [searchProducts](#searchProducts)
21
- * * [searchAvailability](#searchAvailability)
22
- * * [searchQuote](#searchQuote)
23
- * * [createBooking](#createBooking)
24
9
  * ---
25
10
  *
26
11
  * @param {Object} args - New / Overwriting attributes for the Plugin.
@@ -61,11 +46,11 @@ class Plugin {
61
46
  }
62
47
 
63
48
  /**
64
- * Check the vailidity of an integration token. *part of **General** Methods*
49
+ * Check the validity of an integration token.
65
50
  * @async
66
51
  * @param {Object} args - Availability search arguments.
67
52
  * @param {Object} args.token - A token definition, it's content varies between integrations.
68
- * @returns {Boolean} - The token vailidity True/False
53
+ * @returns {Boolean} - The token validity True/False
69
54
  */
70
55
  validateToken() {
71
56
  return Boolean(this);
@@ -321,7 +306,7 @@ class Plugin {
321
306
  * @param {string} args.payload.travelDateEnd - Date of travel end.
322
307
  * @param {Holder} args.payload.holder - Search for a particular holder.
323
308
  * @returns {object} retVal - the return object.
324
- * @returns {Booking[]} retVal.bookings - Array of Bookings matchin the criteria.
309
+ * @returns {Booking[]} retVal.bookings - Array of Bookings matching the criteria.
325
310
  */
326
311
  searchBooking() {
327
312
  }
@@ -378,7 +363,22 @@ class Plugin {
378
363
  searchAvailability() {
379
364
  // return (args);
380
365
  }
381
-
366
+ /**
367
+ * Retrieve an availability calendar over a date range
368
+ * @async
369
+ * @param {Object} args - Availability search arguments.
370
+ * @param {Object} args.token - A token definition, it's content varies between integrations.
371
+ * @param {Object} args.payload - Search spect object.
372
+ * @param {string} args.payload.dateFormat - Date format sent, using [momentjs formatting](https://momentjs.com/docs/#/parsing/string-format/).
373
+ * @param {string} args.payload.travelDateStart - Date of travel start.
374
+ * @param {string} args.payload.travelDateEnd - Date of travel end.
375
+ * @param {Occupancy[]} args.payload.occupancies - Occupancy detail.
376
+ * @returns {object} retVal - the return object
377
+ * @returns {Availability[]} retVal.availability - Array of availability objects
378
+ */
379
+ availabilityCalndar() {
380
+ // return (args);
381
+ }
382
382
  /**
383
383
  * A quote return spec
384
384
  * @typedef {Object} Quote
@@ -0,0 +1,8 @@
1
+ {
2
+ "setup-your-instance": {
3
+ "title": "Running your own Ti2"
4
+ },
5
+ "plugin-development": {
6
+ "title": "Plugin Development"
7
+ }
8
+ }
@@ -0,0 +1,230 @@
1
+ ## Getting Started
2
+
3
+ Plugins can extend the functionality of Ti2 and/or provide access to other platforms; you should use one of the following methods to provide a stadandarized way to access other systems; if you want to implement new functionality that is not encompassed on the available methods you are more than welcome to add new methods and contribute to the Ti2 codebase.
4
+
5
+ ## Available Methods
6
+
7
+ We are using a set of standardized methods to maintain compatibility; the following methods are available, more can be supported but should be a added to the TI2 spec first to maximize it's compatibility.
8
+
9
+ **General Methods** (should always be included):
10
+ * [validateToken]{@link Plugin#validateToken}
11
+
12
+ **Content Methods** (marketing information for (company)profile, locations and/or products):
13
+ * [getProfile]{@link Plugin#getProfile}
14
+ * [updateProfile]{@link Plugin#updateProfile}
15
+ * [createLocation]{@link Plugin#createLocation}
16
+ * [updateLocation]{@link Plugin#updateLocation}
17
+ * [getProducts]{@link Plugin#getProducts}
18
+ * [createProduct]{@link Plugin#createProduct}
19
+ * [updateProduct]{@link Plugin#updateProduct}
20
+
21
+ **Booking Methods** (bookings and operations):
22
+ * [searchBooking]{@link Plugin#searchBooking}
23
+ * [searchProducts]{@link Plugin#searchProducts}
24
+ * [searchAvailability]{@link Plugin#searchAvailability}
25
+ * [searchQuote]{@link Plugin#searchQuote}
26
+ * [createBooking]{@link Plugin#createBooking}
27
+
28
+ ---
29
+
30
+ ## Environment variables
31
+
32
+ Plugin environment keys are passed down from the hosting ti2 instance when they are generated, this is the preferred way to access environment keys from the plugins, such values are not design to hold client / user's API keys or specific data, they are to be stored in the database via the AppKey collection.
33
+
34
+ Plugin ENV variable name convention: ti2_pluginName_environmenVariableName, for example:
35
+
36
+ ```env
37
+ ti2_tourconnect_apiUrl=http://backend:8080
38
+ ```
39
+
40
+
41
+ ## Codebase setup
42
+
43
+ You can review some of the plugins previously developed and use them as a guide, plugin methods are encourage to include tests and to return results with the same format; however, the returned values can include additional information, currently Ti2 is expected to run on node version 12.22.8; we suggest you use the same for your codebase.
44
+
45
+
46
+ After initializing your git environment for development; you can initialize your node project; we recommend naming your repo ti2-\<pluginname\> but it is not required.
47
+
48
+ ```bash
49
+ $ node init .
50
+ ```
51
+
52
+ ## Entry file / constructor
53
+
54
+ The plugin is expected to have an index.js file that exports a Plugin Class like so:
55
+
56
+ ```javascript
57
+ // index.js
58
+ class Plugin {
59
+ constructor(params = {}) { // we get the env variables from here
60
+ Object.entries(params).forEach(([attr, value]) => {
61
+ this[attr] = value;
62
+ });
63
+ }
64
+ }
65
+ module.exports = Plugin;
66
+ ```
67
+
68
+ The constructor of the plugins should extend the attributes with the received params, this allows the plugin to receive configurations or settings that are to be used by any user, for example, settings data that can be shared across accounts.
69
+
70
+ By default Ti2 will pass down all environment variables that match the plugin name to it's constructor; for example, if the following environment variables are defined:
71
+
72
+ ```
73
+ ti2_ventrata_acceptLanguage=en
74
+ ti2_travelgate_clientCode=tourconnect
75
+ ti2_tourconnect_apiUrl=http://backend:8080
76
+ ```
77
+
78
+ The plugin named ti2-ventrata would receive acceptLanguage variable and it's value, ti2-travelgate the clientCode variable and ti-touconnect the apiUrl value.
79
+
80
+ ## Method calling
81
+
82
+ On the previous example code we are declaring a validateToken method; we are normally expected to receive two parameters one is token and the second one payload.
83
+
84
+ ```javascript
85
+ // index.js
86
+ class Plugin {
87
+ constructor(params = {}) { // we get the env variables from here
88
+ Object.entries(params).forEach(([attr, value]) => {
89
+ this[attr] = value;
90
+ });
91
+ }
92
+ async validateToken({
93
+ token: {
94
+ apiKey = this.apiKey,
95
+ apiUrl = this.apiUrl,
96
+ },
97
+ }) {
98
+ // TODO: actually test the apiKey against the integration.
99
+ return assert(apiKey);
100
+ }
101
+ }
102
+ module.exports = Plugin;
103
+ ```
104
+
105
+ The token parameter should store all the settings for the current configured end user; on these example we are defaulting this settings to the ones configured to the pluging when it was instanced; so if the user settings do not include an apiUrl it will fall back to the environment variable on the running server.
106
+
107
+ ## Testing Suite
108
+
109
+ The plugin should contain a test file, for the following example assumes we will be using jest as the testing platform.
110
+
111
+ ```bash
112
+ $ npm i -D jest
113
+ ```
114
+
115
+ ```javascript
116
+ // index.test.js
117
+ const Plugin = require('./index');
118
+
119
+ const app = new Plugin({
120
+ jwtKey: process.env.ti2_ventrata_jwtKey,
121
+ });
122
+
123
+ describe('Base Tests', () => {
124
+ const token = { // a valid token to run tests
125
+ apiKey: process.env.ti2_ventrata_apiKey,
126
+ endpoint: process.env.ti2_ventrata_endpoint,
127
+ };
128
+ it('should not validate an invalid api key', async () => {
129
+ const isValid = await app.validateToken({
130
+ token: { apiKey: 'some Randomg Text' }
131
+ });
132
+ expect(isValid).toBeFalsy();
133
+ });
134
+ it('should not validate an invalid api key', async () => {
135
+ const isValid = await app.validateToken({
136
+ token,
137
+ });
138
+ expect(isValid).toBeTruthy();
139
+ });
140
+ });
141
+
142
+ ```
143
+
144
+ ```bash
145
+ $ npx jest
146
+ ```
147
+
148
+ ## Deploying
149
+
150
+ ### To your own Instance
151
+
152
+ After setting up a [Ti2 instance]{@tutorial setup-your-instance} you can add your development folder as a package on your instance's npm repo (not on the plugin's instance), like so:
153
+
154
+ ```json
155
+ "dependencies": {
156
+ "ti2-myplugin": "file:../ti2-myplugin"
157
+ }
158
+ ```
159
+
160
+ ### To our hosted instance
161
+
162
+ [Contact us](https://www.ti2.travel/contact-us) with the npm published package to begin the testing and deployment process.
163
+
164
+ ## Extending the base API
165
+
166
+ Ti2 uses the [Swagger API specification](https://swagger.io/specification/) standard to define it's own methods, you can review the basic methods [here](https://ti2-staging.tourconnect.com/api-docs/); these methods can be extended using the same format; this allows any plugin to extend the base API endpoints that are linked to any plugin method (part of the basic methods or new ones).
167
+
168
+ All the extender methods would be availble under the /\[plugin name] namespace, i.e.: /ti2-greatPlugin/ping.
169
+
170
+ For Ti2 to pickup the extender definition, one must create a new file on the root of the plugin named api.yml, such file would contain only the methods to be extended and it must comply with the current swagger version used on ti2.
171
+
172
+ ```yaml
173
+ # api.yml
174
+ openapi: '3.0.0'
175
+ info:
176
+ description: My amazing ti2-plugin
177
+ version: 0.0.1
178
+ title: Ti2's new plugin
179
+ components:
180
+ securitySchemes:
181
+ bearerAuth:
182
+ type: http
183
+ scheme: bearer
184
+ bearerFormat: JWT
185
+ schemas:
186
+ ServerInfo:
187
+ type: object
188
+ properties:
189
+ name:
190
+ type: string
191
+ description:
192
+ type: string
193
+ version:
194
+ type: string
195
+ uptime:
196
+ type: string
197
+ paths:
198
+ /ping:
199
+ get:
200
+ tags:
201
+ - public
202
+ summary: Should return basic system status
203
+ operationId: ping
204
+ responses:
205
+ '200':
206
+ description: success
207
+ content:
208
+ application/json:
209
+ schema:
210
+ $ref: '#/components/schemas/ServerInfo'
211
+ ```
212
+
213
+ ## Database Migrations (plugin's own database tables)
214
+
215
+ Ti2 uses [Sequelize v6.13](https://sequelize.org/v6) which is the database ORM we ecourage you to use, you can add your own tables via migrations that should be placed under a migrations folder on the root of the plugin folder.
216
+
217
+ Migrations should be run after the fact, from the root of ti2 instance like so:
218
+
219
+
220
+ ```
221
+ $ npm explore ti2<pluginName> -- npx sequelize db:migrate"
222
+ ```
223
+
224
+ We strongly encourage all the plugin's table names are prefixed with the plugin name (i.e. ti2-pluginName-cacheTable).
225
+
226
+ This should be executed after the ti2 project migrations have been executed.
227
+
228
+ ## Scheduled Task (to be released on v2)
229
+
230
+ TBD.
@@ -0,0 +1,98 @@
1
+ ## Why would I want to run my own instance?
2
+
3
+ * Scenario 1: You want to test your plugins before submitting it to our Ti2 instance, it is a good idea to spin up your own Ti2 test instance, you can test against all the Ti2 REST Apis (In the future, we will provide a Ti2 sandbox instance).
4
+
5
+ * Scenario 2: You want to host your own Ti2 server so you can have everything under your own control.
6
+
7
+ When you are runnning a Ti2 server you can access the documentation page on the url (http://[yourinstance]/api-docs/) that shows the available API methods, you can review the [swagger documentation page online](https://ti2-staging.tourconnect.com/api-docs/) .
8
+
9
+ ## Security
10
+
11
+ An admin api key is set trough an environment variable called adminKey; using this API key is possible to create Users and/or application authentications.
12
+
13
+ A new User/User Authentication can be created using the endpoint [createUserToken](https://ti2.tourconnect.dev/api-docs/#/admin/createUserToken); the return value consists of a JWT token for further user intraction with the App; the admin API key is required; no password is saved on the server side.
14
+
15
+ Apps/Integrations can be created using the admin API Key; this after the plugin had been added to the codebase; the app can be created using the endpoint [createApp](https://ti2.tourconnect.dev/api-docs/#/admin/createApp); such endpoint returns a key that can be used by the app to interact with user Ids; such interactions allow the app to push for changes related to user integrations, the app can list the users currently configured for it using the endpoint [listAppTokens](https://ti2.tourconnect.dev/api-docs/#/app/listAppTokens); the passwords for Apps are encripted onde the database using aes-256-cbc, more details can be found on the [``models/integrations.js``](https://github.com/ti2travel/ti2/blob/main/models/integration.js) file.
16
+
17
+ User + app integration credentials can be added after the app has been added to the system; these can be added by either the user, admin or the app itself using the endpoint [createAppToken](https://ti2.tourconnect.dev/api-docs/#/app/createAppToken). These keys are saved in JWT format on the database.
18
+
19
+ ## Get Started
20
+
21
+ ### Requirements and Evironment variables
22
+
23
+ A MySQl instance is required and the following environment variables are required:
24
+
25
+ - DB_URL (mysql connection in url format)
26
+ - dbCryptoKey (integration details encription key, should be a 32 chars base64 encoded random string)
27
+ - adminKey (a key for admin related requests)
28
+ - jwtKey (a key to encrypt user sessions request)
29
+ - frontendKey (an additional optional key to validate the origin of the requests)
30
+ - PORT (an optional port to run the http server, in case a port is not specified as a parameter)
31
+
32
+ ```
33
+ DB_URL=mysql://root:@mysqlserver/ti2development
34
+ dbCryptoKey=cG9VYmJyQ2tlSDVHeXQ4RUN4VlNieEJRejNYWDlZU0g=
35
+ jwtSecret=C8k0mrHVfWVTP7pIoZEHRrvFgTULhw3E4swDq1aoDH4P
36
+ frontendKey=IpOiLahrGQxsQimwoK7Z
37
+ adminKey=bCviyz7iKyuEBoOVlODn
38
+ ```
39
+
40
+ ### Initialize a new NodeJS project
41
+
42
+ We suggest creating a folder with your instance name+i2 (i.e acme-ti2); then initialize an node's npm package and install ti2 along with any plugins to be used.
43
+
44
+ ```bash
45
+ $ mkdir acme-ti2
46
+ $ cd acmme-ti2
47
+ $ npm init .
48
+ $ npm i ti2 ti2-tourconnect
49
+ ```
50
+
51
+
52
+ After installing the ti2 package you need to run the database migrations for ti2:
53
+
54
+ ```
55
+ $ npm explore ti2<pluginName> -- npx sequelize db:migrate"
56
+ ```
57
+
58
+ ### Entry File
59
+
60
+ then just create an entry file like this :
61
+
62
+ ```javascript
63
+ // index.js
64
+ const ti2 = require('ti2')({
65
+ plugins: {
66
+ travelgate: require('ti2-travelgate'),
67
+ ventrata: require('ti2-ventrata'),
68
+ tourconnect: require('ti2-tourconnect'),
69
+ },
70
+ });
71
+ ```
72
+
73
+ and stat the server using node:
74
+
75
+ ```
76
+ $ node index.js
77
+ ```
78
+
79
+ ## API logging
80
+
81
+ Currently logging is supported via elastic search, an elasticLogClient value can ben passed down, example:
82
+
83
+ ```javascript
84
+ const { Client } = require('@elastic/elasticsearch');
85
+ const elasticLogsClient = (() => {
86
+ if (!elasticLogs) return null;
87
+ return new Client({ node: elasticLogs });
88
+ })();
89
+
90
+ const ti2 = require('ti2')({
91
+ elasticLogsClient,
92
+ plugins: {
93
+ ventrata: require('ti2-ventrata'),
94
+ travelgate: require('ti2-travelgate'),
95
+ tourconnect: require('ti2-tourconnect'),
96
+ },
97
+ });
98
+ ```