@constructor-io/constructorio-node 4.0.0 → 4.2.0
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/package.json +3 -2
- package/src/constructorio.js +3 -0
- package/src/modules/autocomplete.js +2 -0
- package/src/modules/browse.js +10 -6
- package/src/modules/quizzes.js +240 -0
- package/src/modules/recommendations.js +4 -0
- package/src/modules/search.js +2 -0
- package/src/modules/tasks.js +12 -2
- package/src/modules/tracker.js +2 -0
- package/src/utils/helpers.js +11 -2
package/package.json
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@constructor-io/constructorio-node",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.0",
|
|
4
4
|
"description": "Constructor.io Node.js client",
|
|
5
5
|
"main": "src/constructorio.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"version": "chmod +x ./scripts/verify-node-version.sh && ./scripts/verify-node-version.sh && npm run docs && git add ./docs/*",
|
|
8
8
|
"check-lisc": "license-checker --production --onlyAllow 'Apache-2.0;BSD-3-Clause;MIT'",
|
|
9
9
|
"lint": "eslint 'src/**/*.js' 'spec/**/*.js'",
|
|
10
|
+
"test:parallel": "mkdir -p test && cp -rf src/* test && mocha --parallel ./spec/*",
|
|
10
11
|
"test": "mkdir -p test && cp -rf src/* test && mocha ./spec/*",
|
|
11
12
|
"precoverage": "rm -rf ./coverage && rm -rf ./.nyc_output",
|
|
12
|
-
"coverage": "nyc --all --reporter=html npm run test",
|
|
13
|
+
"coverage": "nyc --all --reporter=html npm run test:parallel",
|
|
13
14
|
"postcoverage": "open coverage/index.html && rm -rf test",
|
|
14
15
|
"docs": "jsdoc --configure ./.jsdoc.json ./README.md --recurse ./src --destination ./docs",
|
|
15
16
|
"prepare": "husky install"
|
package/src/constructorio.js
CHANGED
|
@@ -8,6 +8,7 @@ const Recommendations = require('./modules/recommendations');
|
|
|
8
8
|
const Tracker = require('./modules/tracker');
|
|
9
9
|
const Catalog = require('./modules/catalog');
|
|
10
10
|
const Tasks = require('./modules/tasks');
|
|
11
|
+
const Quizzes = require('./modules/quizzes');
|
|
11
12
|
const { version: packageVersion } = require('../package.json');
|
|
12
13
|
|
|
13
14
|
/**
|
|
@@ -30,6 +31,7 @@ class ConstructorIO {
|
|
|
30
31
|
* @property {object} tracker - Interface to {@link module:tracker}
|
|
31
32
|
* @property {object} catalog - Interface to {@link module:catalog}
|
|
32
33
|
* @property {object} tasks - Interface to {@link module:tasks}
|
|
34
|
+
* @property {object} quizzes - Interface to {@link module:quizzes}
|
|
33
35
|
* @returns {class}
|
|
34
36
|
*/
|
|
35
37
|
constructor(options = {}) {
|
|
@@ -65,6 +67,7 @@ class ConstructorIO {
|
|
|
65
67
|
this.tracker = new Tracker(this.options);
|
|
66
68
|
this.catalog = new Catalog(this.options);
|
|
67
69
|
this.tasks = new Tasks(this.options);
|
|
70
|
+
this.quizzes = new Quizzes(this.options);
|
|
68
71
|
}
|
|
69
72
|
}
|
|
70
73
|
|
|
@@ -153,6 +153,8 @@ class Autocomplete {
|
|
|
153
153
|
return Promise.reject(e);
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
+
Object.assign(headers, helpers.combineCustomHeaders(this.options, networkParameters));
|
|
157
|
+
|
|
156
158
|
// Append security token as 'x-cnstrc-token' if available
|
|
157
159
|
if (this.options.securityToken && typeof this.options.securityToken === 'string') {
|
|
158
160
|
headers['x-cnstrc-token'] = this.options.securityToken;
|
package/src/modules/browse.js
CHANGED
|
@@ -193,9 +193,11 @@ function createBrowseUrlForFacetOptions(facetName, parameters, userParameters, o
|
|
|
193
193
|
}
|
|
194
194
|
|
|
195
195
|
// Create request headers using supplied options and user parameters
|
|
196
|
-
function createHeaders(options, userParameters) {
|
|
196
|
+
function createHeaders(options, userParameters, networkParameters = {}) {
|
|
197
197
|
const headers = {};
|
|
198
198
|
|
|
199
|
+
Object.assign(headers, helpers.combineCustomHeaders(options, networkParameters));
|
|
200
|
+
|
|
199
201
|
// Append security token as 'x-cnstrc-token' if available
|
|
200
202
|
if (options.securityToken && typeof options.securityToken === 'string') {
|
|
201
203
|
headers['x-cnstrc-token'] = options.securityToken;
|
|
@@ -273,7 +275,7 @@ class Browse {
|
|
|
273
275
|
const fetch = (this.options && this.options.fetch) || nodeFetch;
|
|
274
276
|
const controller = new AbortController();
|
|
275
277
|
const { signal } = controller;
|
|
276
|
-
const headers = createHeaders(this.options, userParameters);
|
|
278
|
+
const headers = createHeaders(this.options, userParameters, networkParameters);
|
|
277
279
|
|
|
278
280
|
try {
|
|
279
281
|
requestUrl = createBrowseUrlFromFilter(filterName, filterValue, parameters, userParameters, this.options);
|
|
@@ -357,7 +359,7 @@ class Browse {
|
|
|
357
359
|
const fetch = (this.options && this.options.fetch) || nodeFetch;
|
|
358
360
|
const controller = new AbortController();
|
|
359
361
|
const { signal } = controller;
|
|
360
|
-
const headers = createHeaders(this.options, userParameters);
|
|
362
|
+
const headers = createHeaders(this.options, userParameters, networkParameters);
|
|
361
363
|
|
|
362
364
|
try {
|
|
363
365
|
requestUrl = createBrowseUrlFromIDs(itemIds, parameters, userParameters, this.options);
|
|
@@ -428,7 +430,7 @@ class Browse {
|
|
|
428
430
|
const fetch = (this.options && this.options.fetch) || nodeFetch;
|
|
429
431
|
const controller = new AbortController();
|
|
430
432
|
const { signal } = controller;
|
|
431
|
-
const headers = createHeaders(this.options, userParameters);
|
|
433
|
+
const headers = createHeaders(this.options, userParameters, networkParameters);
|
|
432
434
|
const { serviceUrl } = this.options;
|
|
433
435
|
const queryParams = createQueryParams(parameters, userParameters, this.options);
|
|
434
436
|
|
|
@@ -488,6 +490,7 @@ class Browse {
|
|
|
488
490
|
const fetch = (this.options && this.options.fetch) || nodeFetch;
|
|
489
491
|
const controller = new AbortController();
|
|
490
492
|
const { signal } = controller;
|
|
493
|
+
const headers = createHeaders(this.options, userParameters, networkParameters);
|
|
491
494
|
|
|
492
495
|
try {
|
|
493
496
|
requestUrl = createBrowseUrlForFacets(parameters, userParameters, this.options);
|
|
@@ -499,7 +502,7 @@ class Browse {
|
|
|
499
502
|
helpers.applyNetworkTimeout(this.options, networkParameters, controller);
|
|
500
503
|
|
|
501
504
|
return fetch(requestUrl, {
|
|
502
|
-
headers: helpers.createAuthHeader(this.options),
|
|
505
|
+
headers: { ...headers, ...helpers.createAuthHeader(this.options) },
|
|
503
506
|
signal,
|
|
504
507
|
}).then((response) => {
|
|
505
508
|
if (response.ok) {
|
|
@@ -542,6 +545,7 @@ class Browse {
|
|
|
542
545
|
const fetch = (this.options && this.options.fetch) || nodeFetch;
|
|
543
546
|
const controller = new AbortController();
|
|
544
547
|
const { signal } = controller;
|
|
548
|
+
const headers = createHeaders(this.options, userParameters, networkParameters);
|
|
545
549
|
|
|
546
550
|
try {
|
|
547
551
|
requestUrl = createBrowseUrlForFacetOptions(facetName, parameters, userParameters, this.options);
|
|
@@ -553,7 +557,7 @@ class Browse {
|
|
|
553
557
|
helpers.applyNetworkTimeout(this.options, networkParameters, controller);
|
|
554
558
|
|
|
555
559
|
return fetch(requestUrl, {
|
|
556
|
-
headers: helpers.createAuthHeader(this.options),
|
|
560
|
+
headers: { ...headers, ...helpers.createAuthHeader(this.options) },
|
|
557
561
|
signal,
|
|
558
562
|
}).then((response) => {
|
|
559
563
|
if (response.ok) {
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/* eslint-disable object-curly-newline, no-underscore-dangle */
|
|
2
|
+
const qs = require('qs');
|
|
3
|
+
const nodeFetch = require('node-fetch').default;
|
|
4
|
+
const helpers = require('../utils/helpers');
|
|
5
|
+
|
|
6
|
+
// Create URL from supplied quizId and parameters
|
|
7
|
+
// eslint-disable-next-line max-params
|
|
8
|
+
function createQuizUrl(quizId, parameters, userParameters, options, path) {
|
|
9
|
+
const {
|
|
10
|
+
apiKey,
|
|
11
|
+
version,
|
|
12
|
+
} = options;
|
|
13
|
+
const {
|
|
14
|
+
sessionId,
|
|
15
|
+
clientId,
|
|
16
|
+
userId,
|
|
17
|
+
segments,
|
|
18
|
+
} = userParameters;
|
|
19
|
+
const serviceUrl = 'https://quizzes.cnstrc.com';
|
|
20
|
+
let queryParams = { c: version };
|
|
21
|
+
let answersParamString = '';
|
|
22
|
+
|
|
23
|
+
queryParams.key = apiKey;
|
|
24
|
+
queryParams.i = clientId;
|
|
25
|
+
queryParams.s = sessionId;
|
|
26
|
+
|
|
27
|
+
// Pull user segments from options
|
|
28
|
+
if (segments && segments.length) {
|
|
29
|
+
queryParams.us = segments;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Pull user id from options
|
|
33
|
+
if (userId) {
|
|
34
|
+
queryParams.ui = userId;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Validate quiz id is provided
|
|
38
|
+
if (!quizId || typeof quizId !== 'string') {
|
|
39
|
+
throw new Error('quizId is a required parameter of type string');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (path === 'finalize' && (typeof parameters.answers !== 'object' || !Array.isArray(parameters.answers) || parameters.answers.length === 0)) {
|
|
43
|
+
throw new Error('answers is a required parameter of type array');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (parameters) {
|
|
47
|
+
const { section, answers, versionId } = parameters;
|
|
48
|
+
|
|
49
|
+
// Pull section from parameters
|
|
50
|
+
if (section) {
|
|
51
|
+
queryParams.section = section;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Pull version_id from parameters
|
|
55
|
+
if (versionId) {
|
|
56
|
+
queryParams.version_id = versionId;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Pull answers from parameters and transform
|
|
60
|
+
if (answers) {
|
|
61
|
+
answers.forEach((ans) => {
|
|
62
|
+
answersParamString += `&${qs.stringify({ a: ans }, { arrayFormat: 'comma' })}`;
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
queryParams._dt = Date.now();
|
|
68
|
+
queryParams = helpers.cleanParams(queryParams);
|
|
69
|
+
|
|
70
|
+
const queryString = qs.stringify(queryParams, { indices: false });
|
|
71
|
+
|
|
72
|
+
return `${serviceUrl}/v1/quizzes/${encodeURIComponent(quizId)}/${encodeURIComponent(path)}/?${queryString}${answersParamString}`;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Interface to quiz related API calls
|
|
77
|
+
*
|
|
78
|
+
* @module quizzes
|
|
79
|
+
* @inner
|
|
80
|
+
* @returns {object}
|
|
81
|
+
*/
|
|
82
|
+
class Quizzes {
|
|
83
|
+
constructor(options) {
|
|
84
|
+
this.options = options || {};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Retrieve quiz question from API
|
|
89
|
+
*
|
|
90
|
+
* @function getQuizNextQuestion
|
|
91
|
+
* @description Retrieve quiz question from Constructor.io API
|
|
92
|
+
* @param {string} id - The identifier of the quiz
|
|
93
|
+
* @param {string} [parameters] - Additional parameters to refine result set
|
|
94
|
+
* @param {string} [parameters.section] - Product catalog section
|
|
95
|
+
* @param {array} [parameters.answers] - An array for answers in the format [[1,2],[1]]
|
|
96
|
+
* @param {string} [parameters.versionId] - Version identifier for the quiz.
|
|
97
|
+
* @param {object} [userParameters] - Parameters relevant to the user request
|
|
98
|
+
* @param {number} [userParameters.sessionId] - Session ID, utilized to personalize results
|
|
99
|
+
* @param {number} [userParameters.clientId] - Client ID, utilized to personalize results
|
|
100
|
+
* @param {string} [userParameters.userId] - User ID, utilized to personalize results
|
|
101
|
+
* @param {string} [userParameters.segments] - User segments
|
|
102
|
+
* @param {string} [userParameters.userIp] - Origin user IP, from client
|
|
103
|
+
* @param {string} [userParameters.userAgent] - Origin user agent, from client
|
|
104
|
+
* @param {object} [networkParameters] - Parameters relevant to the network request
|
|
105
|
+
* @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
|
|
106
|
+
* @returns {Promise}
|
|
107
|
+
* @see https://docs.constructor.io/rest_api/quiz/using_quizzes/#answering-a-quiz
|
|
108
|
+
* @example
|
|
109
|
+
* constructorio.quizzes.getQuizNextQuestion('quizId', {
|
|
110
|
+
* answers: [[1,2],[1]],
|
|
111
|
+
* section: '123',
|
|
112
|
+
* versionId: '123'
|
|
113
|
+
* });
|
|
114
|
+
*/
|
|
115
|
+
getQuizNextQuestion(quizId, parameters, userParameters = {}, networkParameters = {}) {
|
|
116
|
+
const headers = {};
|
|
117
|
+
let requestUrl;
|
|
118
|
+
const fetch = (this.options && this.options.fetch) || nodeFetch;
|
|
119
|
+
const controller = new AbortController();
|
|
120
|
+
const { signal } = controller;
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
requestUrl = createQuizUrl(quizId, parameters, userParameters, this.options, 'next');
|
|
124
|
+
} catch (e) {
|
|
125
|
+
return Promise.reject(e);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Append security token as 'x-cnstrc-token' if available
|
|
129
|
+
if (this.options.securityToken && typeof this.options.securityToken === 'string') {
|
|
130
|
+
headers['x-cnstrc-token'] = this.options.securityToken;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Append user IP as 'X-Forwarded-For' if available
|
|
134
|
+
if (userParameters.userIp && typeof userParameters.userIp === 'string') {
|
|
135
|
+
headers['X-Forwarded-For'] = userParameters.userIp;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Append user agent as 'User-Agent' if available
|
|
139
|
+
if (userParameters.userAgent && typeof userParameters.userAgent === 'string') {
|
|
140
|
+
headers['User-Agent'] = userParameters.userAgent;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Handle network timeout if specified
|
|
144
|
+
helpers.applyNetworkTimeout(this.options, networkParameters, controller);
|
|
145
|
+
|
|
146
|
+
return fetch(requestUrl, { headers, signal })
|
|
147
|
+
.then((response) => {
|
|
148
|
+
if (response.ok) {
|
|
149
|
+
return response.json();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return helpers.throwHttpErrorFromResponse(new Error(), response);
|
|
153
|
+
})
|
|
154
|
+
.then((json) => {
|
|
155
|
+
if (json.version_id) {
|
|
156
|
+
return json;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
throw new Error('getQuizNextQuestion response data is malformed');
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Retrieves filter expression and recommendation URL from given answers
|
|
165
|
+
*
|
|
166
|
+
* @function getQuizResults
|
|
167
|
+
* @description Retrieve quiz recommendation and filter expression from Constructor.io API
|
|
168
|
+
* @param {string} id - The identifier of the quiz
|
|
169
|
+
* @param {string} [parameters] - Additional parameters to refine result set
|
|
170
|
+
* @param {string} [parameters.section] - Product catalog section
|
|
171
|
+
* @param {array} [parameters.answers] - An array of answers in the format [[1,2],[1]]
|
|
172
|
+
* @param {string} [parameters.versionId] - Specific version identifier for the quiz
|
|
173
|
+
* @param {object} [userParameters] - Parameters relevant to the user request
|
|
174
|
+
* @param {number} [userParameters.sessionId] - Session ID, utilized to personalize results
|
|
175
|
+
* @param {number} [userParameters.clientId] - Client ID, utilized to personalize results
|
|
176
|
+
* @param {string} [userParameters.userId] - User ID, utilized to personalize results
|
|
177
|
+
* @param {string} [userParameters.segments] - User segments
|
|
178
|
+
* @param {string} [userParameters.userIp] - Origin user IP, from client
|
|
179
|
+
* @param {string} [userParameters.userAgent] - Origin user agent, from client
|
|
180
|
+
* @param {object} [networkParameters] - Parameters relevant to the network request
|
|
181
|
+
* @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
|
|
182
|
+
* @returns {Promise}
|
|
183
|
+
* @see https://docs.constructor.io/rest_api/quiz/using_quizzes/#completing-the-quiz
|
|
184
|
+
* @example
|
|
185
|
+
* constructorio.quizzes.getQuizResults('quizId', {
|
|
186
|
+
* answers: [[1,2],[1]],
|
|
187
|
+
* section: '123',
|
|
188
|
+
* versionId: '123'
|
|
189
|
+
* });
|
|
190
|
+
*/
|
|
191
|
+
getQuizResults(quizId, parameters, userParameters = {}, networkParameters = {}) {
|
|
192
|
+
let requestUrl;
|
|
193
|
+
const headers = {};
|
|
194
|
+
const fetch = (this.options && this.options.fetch) || nodeFetch;
|
|
195
|
+
const controller = new AbortController();
|
|
196
|
+
const { signal } = controller;
|
|
197
|
+
|
|
198
|
+
try {
|
|
199
|
+
requestUrl = createQuizUrl(quizId, parameters, userParameters, this.options, 'finalize');
|
|
200
|
+
} catch (e) {
|
|
201
|
+
return Promise.reject(e);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Append security token as 'x-cnstrc-token' if available
|
|
205
|
+
if (this.options.securityToken && typeof this.options.securityToken === 'string') {
|
|
206
|
+
headers['x-cnstrc-token'] = this.options.securityToken;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Append user IP as 'X-Forwarded-For' if available
|
|
210
|
+
if (userParameters.userIp && typeof userParameters.userIp === 'string') {
|
|
211
|
+
headers['X-Forwarded-For'] = userParameters.userIp;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Append user agent as 'User-Agent' if available
|
|
215
|
+
if (userParameters.userAgent && typeof userParameters.userAgent === 'string') {
|
|
216
|
+
headers['User-Agent'] = userParameters.userAgent;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Handle network timeout if specified
|
|
220
|
+
helpers.applyNetworkTimeout(this.options, networkParameters, controller);
|
|
221
|
+
|
|
222
|
+
return fetch(requestUrl, { headers, signal })
|
|
223
|
+
.then((response) => {
|
|
224
|
+
if (response.ok) {
|
|
225
|
+
return response.json();
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return helpers.throwHttpErrorFromResponse(new Error(), response);
|
|
229
|
+
})
|
|
230
|
+
.then((json) => {
|
|
231
|
+
if (json.version_id) {
|
|
232
|
+
return json;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
throw new Error('getQuizResults response data is malformed');
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
module.exports = Quizzes;
|
|
@@ -142,6 +142,8 @@ class Recommendations {
|
|
|
142
142
|
return Promise.reject(e);
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
+
Object.assign(headers, helpers.combineCustomHeaders(this.options, networkParameters));
|
|
146
|
+
|
|
145
147
|
// Append security token as 'x-cnstrc-token' if available
|
|
146
148
|
if (this.options.securityToken && typeof this.options.securityToken === 'string') {
|
|
147
149
|
headers['x-cnstrc-token'] = this.options.securityToken;
|
|
@@ -209,6 +211,8 @@ class Recommendations {
|
|
|
209
211
|
const headers = {};
|
|
210
212
|
const requestUrl = `${serviceUrl}/v1/recommendation_pods?key=${apiKey}`;
|
|
211
213
|
|
|
214
|
+
Object.assign(headers, helpers.combineCustomHeaders(this.options, networkParameters));
|
|
215
|
+
|
|
212
216
|
// Append security token as 'x-cnstrc-token' if available
|
|
213
217
|
if (this.options.securityToken && typeof this.options.securityToken === 'string') {
|
|
214
218
|
headers['x-cnstrc-token'] = this.options.securityToken;
|
package/src/modules/search.js
CHANGED
|
@@ -202,6 +202,8 @@ class Search {
|
|
|
202
202
|
return Promise.reject(e);
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
+
Object.assign(headers, helpers.combineCustomHeaders(this.options, networkParameters));
|
|
206
|
+
|
|
205
207
|
// Append security token as 'x-cnstrc-token' if available
|
|
206
208
|
if (this.options.securityToken && typeof this.options.securityToken === 'string') {
|
|
207
209
|
headers['x-cnstrc-token'] = this.options.securityToken;
|
package/src/modules/tasks.js
CHANGED
|
@@ -61,6 +61,9 @@ class Tasks {
|
|
|
61
61
|
const fetch = (this.options && this.options.fetch) || nodeFetch;
|
|
62
62
|
const controller = new AbortController();
|
|
63
63
|
const { signal } = controller;
|
|
64
|
+
const headers = {
|
|
65
|
+
'Content-Type': 'application/json',
|
|
66
|
+
};
|
|
64
67
|
|
|
65
68
|
if (parameters) {
|
|
66
69
|
const { num_results_per_page: numResultsPerPageOld, numResultsPerPage, page, startDate, endDate, status, type } = parameters;
|
|
@@ -98,12 +101,14 @@ class Tasks {
|
|
|
98
101
|
return Promise.reject(e);
|
|
99
102
|
}
|
|
100
103
|
|
|
104
|
+
Object.assign(headers, helpers.combineCustomHeaders(this.options, networkParameters));
|
|
105
|
+
|
|
101
106
|
helpers.applyNetworkTimeout(this.options, networkParameters, controller);
|
|
102
107
|
|
|
103
108
|
return fetch(requestUrl, {
|
|
104
109
|
method: 'GET',
|
|
105
110
|
headers: {
|
|
106
|
-
|
|
111
|
+
...headers,
|
|
107
112
|
...helpers.createAuthHeader(this.options),
|
|
108
113
|
},
|
|
109
114
|
signal,
|
|
@@ -132,6 +137,9 @@ class Tasks {
|
|
|
132
137
|
const fetch = (this.options && this.options.fetch) || nodeFetch;
|
|
133
138
|
const controller = new AbortController();
|
|
134
139
|
const { signal } = controller;
|
|
140
|
+
const headers = {
|
|
141
|
+
'Content-Type': 'application/json',
|
|
142
|
+
};
|
|
135
143
|
|
|
136
144
|
try {
|
|
137
145
|
requestUrl = createTaskUrl(`tasks/${parameters.id}`, this.options);
|
|
@@ -139,12 +147,14 @@ class Tasks {
|
|
|
139
147
|
return Promise.reject(e);
|
|
140
148
|
}
|
|
141
149
|
|
|
150
|
+
Object.assign(headers, helpers.combineCustomHeaders(this.options, networkParameters));
|
|
151
|
+
|
|
142
152
|
helpers.applyNetworkTimeout(this.options, networkParameters, controller);
|
|
143
153
|
|
|
144
154
|
return fetch(requestUrl, {
|
|
145
155
|
method: 'GET',
|
|
146
156
|
headers: {
|
|
147
|
-
|
|
157
|
+
...headers,
|
|
148
158
|
...helpers.createAuthHeader(this.options),
|
|
149
159
|
},
|
|
150
160
|
signal,
|
package/src/modules/tracker.js
CHANGED
|
@@ -84,6 +84,8 @@ function send(url, userParameters, networkParameters, method = 'GET', body = {})
|
|
|
84
84
|
const { signal } = controller;
|
|
85
85
|
const headers = {};
|
|
86
86
|
|
|
87
|
+
Object.assign(headers, helpers.combineCustomHeaders(this.options, networkParameters));
|
|
88
|
+
|
|
87
89
|
// Append security token as 'x-cnstrc-token' if available
|
|
88
90
|
if (this.options.securityToken && typeof this.options.securityToken === 'string') {
|
|
89
91
|
headers['x-cnstrc-token'] = this.options.securityToken;
|
package/src/utils/helpers.js
CHANGED
|
@@ -43,16 +43,25 @@ const utils = {
|
|
|
43
43
|
},
|
|
44
44
|
|
|
45
45
|
// Abort network request based on supplied timeout interval (in milliseconds)
|
|
46
|
-
// -
|
|
46
|
+
// - Method call parameter takes precedence over global options parameter
|
|
47
47
|
applyNetworkTimeout: (options = {}, networkParameters = {}, controller = undefined) => {
|
|
48
48
|
const optionsTimeout = options && options.networkParameters && options.networkParameters.timeout;
|
|
49
49
|
const networkParametersTimeout = networkParameters && networkParameters.timeout;
|
|
50
|
-
const timeout =
|
|
50
|
+
const timeout = networkParametersTimeout || optionsTimeout;
|
|
51
51
|
|
|
52
52
|
if (typeof timeout === 'number') {
|
|
53
53
|
setTimeout(() => controller.abort(), timeout);
|
|
54
54
|
}
|
|
55
55
|
},
|
|
56
|
+
|
|
57
|
+
// Combine headers from options and networkParameters
|
|
58
|
+
// - Method call parameter takes precedence over global options parameter
|
|
59
|
+
combineCustomHeaders: (options = {}, networkParameters = {}) => {
|
|
60
|
+
const optionsHeaders = options && options.networkParameters && options.networkParameters.headers;
|
|
61
|
+
const networkParametersHeaders = networkParameters && networkParameters.headers;
|
|
62
|
+
|
|
63
|
+
return { ...optionsHeaders, ...networkParametersHeaders };
|
|
64
|
+
},
|
|
56
65
|
};
|
|
57
66
|
|
|
58
67
|
module.exports = utils;
|