@sap/async-xsjs 1.0.3 → 1.0.5

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/CHANGELOG.md CHANGED
@@ -5,6 +5,20 @@ This project adheres to [Semantic Versioning](http://semver.org/).
5
5
 
6
6
  The format is based on [Keep a Changelog](http://keepachangelog.com/).
7
7
 
8
+ <a name="1.0.5"></a>
9
+ ## 1.0.5 - 2023-06-08
10
+
11
+ ### Fixed
12
+ - Replace deprecated _request_ with _axios_ v1.3.5
13
+
14
+
15
+ <a name="1.0.4"></a>
16
+ ## 1.0.4 - 2023-03-28
17
+
18
+ ### Updated
19
+ - Updated hana-client to v2.16.21
20
+ - Updated hdbext to v7.7.3
21
+
8
22
  <a name="1.0.3"></a>
9
23
  ## 1.0.3 - 2023-02-07
10
24
 
package/README.md CHANGED
@@ -49,10 +49,15 @@ var options = xsenv.getServices({
49
49
  secureStore: 'secureStore',
50
50
  auditLog: 'audit-log'
51
51
  });
52
- var xsjs_server = await async_xsjs(options);
53
- await xsjs_server.listen(port);
54
-
55
- console.log('Node XS server listening on port %d', port);
52
+ async_xsjs(options).then((async_xsjs_server)=>{
53
+ async_xsjs_server.listen(port, (err)=>{
54
+ if(!err) {
55
+ console.log('Node XS server listening on port %d', port);
56
+ }else{
57
+ console.log('Node XS server failed to start on port %d', port);
58
+ }
59
+ });
60
+ });
56
61
  ```
57
62
 
58
63
  The starting function takes an object that contains service credentials and application options.
@@ -2,12 +2,15 @@
2
2
 
3
3
  var util = require('util');
4
4
  var qs = require('querystring');
5
- var requestLib = require('request');
5
+ var axios = require('axios');
6
6
  var _ = require('lodash');
7
7
  var SAPPassport = require('@sap/e2e-trace').Passport;
8
8
  var WebResponse = require('../../web/WebResponse');
9
+ var CRLF = require('../../constants').WEB.MESSAGES.LINE_BREAK;
9
10
  var MultipartResponseBuilder = require('../../web/utils/MultipartResponseBuilder');
10
11
  var contentTypeParser = require('content-type');
12
+ var stream = require('stream');
13
+ var URL = require('url').URL;
11
14
 
12
15
  var methodMapping = {
13
16
  // -1: 'INVALID',
@@ -65,15 +68,19 @@ Client.prototype.request = function (arg0, arg1, proxyOpt) {
65
68
  if (this._timeoutInMilliseconds) {
66
69
  options.timeout = this._timeoutInMilliseconds;
67
70
  }
68
- this._response = new Promise ((resolve, reject) => {
69
- requestLib(options, function(err, response) {
70
- if (err) {
71
- reject(err);
72
- return;
73
- }
74
- resolve(response);
75
- });
76
- });
71
+
72
+ options.validateStatus = function (status) {
73
+ // succesfully resolve the promise for all status codes,
74
+ // otherwise an error is thrown which is incompatible with the current WebResponse logic
75
+ return status > 0;
76
+ };
77
+ this._response = axios.request(options)
78
+ .then(response => {
79
+ return response;
80
+ })
81
+ .catch(error => {
82
+ throw error;
83
+ });
77
84
  return this;
78
85
  };
79
86
 
@@ -134,19 +141,46 @@ function handleEntities(options, webRequest) {
134
141
  }
135
142
 
136
143
  if (multiPartHeader.indexOf('related') > -1) {
137
- options.multipart = [];
138
- webRequest.entities.forEach(entity => {
139
- options.multipart.push({
140
- 'content-type': entity.contentType,
141
- body: entity.body._content
142
- });
143
- });
144
+
145
+ options.data = buildMultipartRelatedData(webRequest, boundary);
144
146
  } else {
145
147
  throw new Error('Multipart/form-data and Multi-part/mixed are not supported!');
146
148
  }
147
149
  }
148
150
  }
149
151
 
152
+ function buildMultipartRelatedData(webRequest, boundary) {
153
+ const finale = `--${boundary}--`;
154
+ const dataStream = new stream.PassThrough();
155
+ let isStream = false;
156
+ webRequest.entities.forEach(entity => {
157
+ const preamble = `--${boundary}${CRLF}`;
158
+ dataStream.push(preamble);
159
+ if (entity.contentType) {
160
+ dataStream.push(`content-type: ${entity.contentType}${CRLF}`);
161
+ }
162
+ dataStream.push(CRLF);
163
+ let body = entity.body._content;
164
+ if (body instanceof stream.Stream) {
165
+ isStream = true;
166
+ body.pipe(dataStream, {end: false});
167
+ body.on('end', () => {
168
+ dataStream.push(CRLF);
169
+ dataStream.push(finale);
170
+ dataStream.push(null);
171
+ });
172
+ } else {
173
+ dataStream.push(body);
174
+ dataStream.push(CRLF);
175
+ }
176
+ });
177
+ if (!isStream) {
178
+ dataStream.push(finale);
179
+ dataStream.push(null);
180
+ }
181
+ return dataStream;
182
+ }
183
+
150
184
  function addPath(options, webRequest) {
151
185
  if (webRequest.path) {
152
186
  if (options.url.charAt(options.url.length - 1) !== '/' && webRequest.path.charAt(0) !== '/') {
@@ -181,14 +215,15 @@ function addCookies(options, webRequest) {
181
215
 
182
216
  function addBody(options, webRequest) {
183
217
  if (options.method === 'POST' || options.method === 'PUT' || options.method === 'PATCH') {
184
- options.body = webRequest.body._content;
185
- options.json = false;
218
+ options.data = options.data || webRequest.body._content;
219
+ options.responseType = 'text';
186
220
  }
187
221
  }
188
222
 
223
+
189
224
  function setProxy(options, proxyOpt) {
190
225
  if (proxyOpt) {
191
- options.proxy = proxyOpt;
226
+ options.proxy = new URL(proxyOpt);
192
227
  }
193
228
  }
194
229
 
@@ -203,7 +238,7 @@ function addPathPrefix(options, destination) {
203
238
 
204
239
  function setProxyFromDestination(options, destination) {
205
240
  if (destination.useProxy === true) {
206
- return options.proxy = 'http://' + destination.proxyHost + ':' + destination.proxyPort;
241
+ return options.proxy = new URL('http://' + destination.proxyHost + ':' + destination.proxyPort);
207
242
  }
208
243
  // explicitly disable proxy
209
244
  if (destination.useProxy === false) {
@@ -213,7 +248,7 @@ function setProxyFromDestination(options, destination) {
213
248
 
214
249
  function setBasicAuthFromDestination(options, destination) {
215
250
  if (destination.authType === 'basic') {
216
- options.auth = { user: destination.username, pass: destination.password };
251
+ options.auth = { username: destination.username, password: destination.password };
217
252
  }
218
253
  }
219
254
 
@@ -19,7 +19,6 @@ module.exports = WebResponse;
19
19
 
20
20
  function WebResponse(res, followUpContext) {
21
21
  WebEntityResponse.call(this, res);
22
-
23
22
  if (!res) {
24
23
  this.cookies = new CookiesTupelList();
25
24
  this.status = 200;
@@ -28,9 +27,12 @@ function WebResponse(res, followUpContext) {
28
27
  setBodyOrEntities(this, res);
29
28
  this.cookies = new CookiesTupelList();
30
29
  this.cookies._addData(extractCookies(res));
31
- this.status = res.statusCode;
32
- this.statusMessage = status[res.statusCode];
33
- this._httpVersion = 'HTTP/' + res.httpVersion;
30
+ var statusCode = res.statusCode || res.status;
31
+ this.status = statusCode;
32
+ this.statusMessage = status[statusCode];
33
+ var httpVersion = (res.req && res.req.httpVersion) || (res.request &&
34
+ ((res.request.res && res.request.res.httpVersion) || (res.request.response && res.request.response.httpVersion)));
35
+ this._httpVersion = 'HTTP/' + httpVersion;
34
36
  }
35
37
 
36
38
  if (followUpContext) {
@@ -75,10 +77,10 @@ function normalizeResponseHeaders(webResponse) {
75
77
  function setBodyOrEntities(webResponse, internalResponse) {
76
78
  var boundary = extractBoundaryOfMultipartResponse(webResponse);
77
79
  if (boundary) {
78
- MultipartParser.parseFromBuffer(internalResponse.body, boundary, webResponse, MESSAGE_TYPE.RESPONSE);
80
+ MultipartParser.parseFromBuffer(internalResponse.data, boundary, webResponse, MESSAGE_TYPE.RESPONSE);
79
81
  webResponse.body = undefined;
80
82
  } else {
81
- internalResponse.body && webResponse.setBody(internalResponse.body);
83
+ internalResponse.data && webResponse.setBody(internalResponse.data);
82
84
  }
83
85
  }
84
86