@sap-ux/axios-extension 1.16.6 → 1.17.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/README.adoc CHANGED
@@ -117,3 +117,14 @@ const metadata = await service.metadata();
117
117
 
118
118
  ```
119
119
  See more examples in link:./test/factory.test.ts[/test/factory.test.ts]
120
+
121
+ ## Proxy Support
122
+
123
+ To enable a patched version of `https-proxy-agent`, to support `tls.connect` connections, update your environment variable with the following `TOOLSUITE_FEATURES` environment variable;
124
+
125
+ ```bash
126
+ export TOOLSUITE_FEATURES=sap.ux.enablePatchProxy
127
+ export HTTPS_PROXY=<YOUR-PROXY:PORT>
128
+ ```
129
+
130
+
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import type { Service } from '../base/service-provider';
3
2
  import type { AxiosResponse } from 'axios';
4
3
  import { Axios } from 'axios';
@@ -117,9 +116,10 @@ export declare class LayeredRepositoryService extends Axios implements Service {
117
116
  * Merge a given app descriptor variant with the stord app descriptor.
118
117
  *
119
118
  * @param appDescriptorVariant zip file containing an app descriptor variant
119
+ * @param workspacePath value for workspacePath URL parameter
120
120
  * @returns a promise with an object containing merged app descriptors with their id as keys.
121
121
  */
122
- mergeAppDescriptorVariant(appDescriptorVariant: Buffer): Promise<{
122
+ mergeAppDescriptorVariant(appDescriptorVariant: Buffer, workspacePath?: string): Promise<{
123
123
  [key: string]: MergedAppDescriptor;
124
124
  }>;
125
125
  /**
@@ -62,11 +62,19 @@ class LayeredRepositoryService extends axios_1.Axios {
62
62
  * Merge a given app descriptor variant with the stord app descriptor.
63
63
  *
64
64
  * @param appDescriptorVariant zip file containing an app descriptor variant
65
+ * @param workspacePath value for workspacePath URL parameter
65
66
  * @returns a promise with an object containing merged app descriptors with their id as keys.
66
67
  */
67
- async mergeAppDescriptorVariant(appDescriptorVariant) {
68
+ async mergeAppDescriptorVariant(appDescriptorVariant, workspacePath) {
69
+ const path = '/appdescr_variant_preview/';
70
+ const params = new URLSearchParams(this.defaults?.params);
71
+ if (workspacePath) {
72
+ params.append('workspacePath', workspacePath);
73
+ }
68
74
  try {
69
- const response = await this.put('/appdescr_variant_preview/', appDescriptorVariant, {
75
+ const response = await this.put(path, appDescriptorVariant, {
76
+ paramsSerializer: (params) => decodeURIComponent(params.toString()),
77
+ params,
70
78
  headers: {
71
79
  'Content-Type': 'application/zip'
72
80
  }
@@ -1,6 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getErrorMessageFromString = exports.logError = exports.prettyPrintTimeInMs = exports.prettyPrintError = exports.prettyPrintMessage = void 0;
3
+ exports.prettyPrintTimeInMs = void 0;
4
+ exports.prettyPrintMessage = prettyPrintMessage;
5
+ exports.prettyPrintError = prettyPrintError;
6
+ exports.logError = logError;
7
+ exports.getErrorMessageFromString = getErrorMessageFromString;
4
8
  const url_1 = require("url");
5
9
  const axios_1 = require("axios");
6
10
  /**
@@ -52,7 +56,6 @@ function prettyPrintMessage({ msg, log, host, isDest = false }) {
52
56
  log.debug(msg);
53
57
  }
54
58
  }
55
- exports.prettyPrintMessage = prettyPrintMessage;
56
59
  /**
57
60
  * @param root0 root0
58
61
  * @param root0.host hostname
@@ -101,7 +104,6 @@ function prettyPrintError({ error, log, host, isDest }, showAllMessages = true)
101
104
  }
102
105
  }
103
106
  }
104
- exports.prettyPrintError = prettyPrintError;
105
107
  /**
106
108
  * Print a user friendly time string.
107
109
  *
@@ -142,7 +144,6 @@ function logError({ error, host, log, isDest }) {
142
144
  }
143
145
  }
144
146
  }
145
- exports.logError = logError;
146
147
  /**
147
148
  * Get ErrorMessage object from response contain an error as a string.
148
149
  *
@@ -164,5 +165,4 @@ function getErrorMessageFromString(data) {
164
165
  }
165
166
  return error;
166
167
  }
167
- exports.getErrorMessageFromString = getErrorMessageFromString;
168
168
  //# sourceMappingURL=message.js.map
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import { type AxiosResponse, type AxiosRequestConfig } from 'axios';
3
2
  import { ODataService } from '../base/odata-service';
4
3
  /**
@@ -3,7 +3,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.attachConnectionHandler = exports.Cookies = exports.defaultTimeout = exports.CSRF = void 0;
6
+ exports.Cookies = exports.defaultTimeout = exports.CSRF = void 0;
7
+ exports.attachConnectionHandler = attachConnectionHandler;
7
8
  const axios_1 = require("axios");
8
9
  const detect_content_type_1 = __importDefault(require("detect-content-type"));
9
10
  var CSRF;
@@ -181,5 +182,4 @@ function attachConnectionHandler(provider) {
181
182
  return response;
182
183
  });
183
184
  }
184
- exports.attachConnectionHandler = attachConnectionHandler;
185
185
  //# sourceMappingURL=connection.js.map
@@ -14,7 +14,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.getReentranceTicketAuthInterceptor = exports.attachReentranceTicketAuthInterceptor = exports.attachUaaAuthInterceptor = exports.attachBasicAuthInterceptor = exports.Uaa = void 0;
17
+ exports.Uaa = void 0;
18
+ exports.attachBasicAuthInterceptor = attachBasicAuthInterceptor;
19
+ exports.attachUaaAuthInterceptor = attachUaaAuthInterceptor;
20
+ exports.attachReentranceTicketAuthInterceptor = attachReentranceTicketAuthInterceptor;
21
+ exports.getReentranceTicketAuthInterceptor = getReentranceTicketAuthInterceptor;
18
22
  const axios_1 = require("axios");
19
23
  const reentrance_ticket_1 = require("./reentrance-ticket");
20
24
  const uaa_1 = require("./uaa");
@@ -31,7 +35,6 @@ function attachBasicAuthInterceptor(provider) {
31
35
  return response;
32
36
  });
33
37
  }
34
- exports.attachBasicAuthInterceptor = attachBasicAuthInterceptor;
35
38
  /**
36
39
  * @param provider Abap Service Provider
37
40
  * @param service Service Information
@@ -59,7 +62,6 @@ function attachUaaAuthInterceptor(provider, service, refreshToken, refreshTokenU
59
62
  return request;
60
63
  });
61
64
  }
62
- exports.attachUaaAuthInterceptor = attachUaaAuthInterceptor;
63
65
  /**
64
66
  * Get the reentrace ticket from the backend and add it to the header.
65
67
  *
@@ -73,7 +75,6 @@ function attachReentranceTicketAuthInterceptor({ provider }) {
73
75
  const ejectCallback = () => provider.interceptors.request.eject(oneTimeInterceptorId);
74
76
  oneTimeInterceptorId = provider.interceptors.request.use(getReentranceTicketAuthInterceptor({ provider, ejectCallback }));
75
77
  }
76
- exports.attachReentranceTicketAuthInterceptor = attachReentranceTicketAuthInterceptor;
77
78
  /**
78
79
  * Get the interceptor that fetches and uses reentrance tickets from the backend.
79
80
  *
@@ -101,5 +102,4 @@ function getReentranceTicketAuthInterceptor({ provider, ejectCallback }) {
101
102
  return request;
102
103
  };
103
104
  }
104
- exports.getReentranceTicketAuthInterceptor = getReentranceTicketAuthInterceptor;
105
105
  //# sourceMappingURL=index.js.map
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getReentranceTicket = void 0;
3
+ exports.getReentranceTicket = getReentranceTicket;
4
4
  const open = require("open");
5
5
  const connection_1 = require("../connection");
6
6
  const abap_system_1 = require("./abap-system");
@@ -31,5 +31,4 @@ async function getReentranceTicket({ backendUrl, logger, timeout = connection_1.
31
31
  open(url)?.catch((error) => logger.error(error));
32
32
  });
33
33
  }
34
- exports.getReentranceTicket = getReentranceTicket;
35
34
  //# sourceMappingURL=index.js.map
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import type { Logger } from '@sap-ux/logger';
3
2
  import http from 'http';
4
3
  import type { ABAPSystem } from './abap-system';
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.setupRedirectHandling = void 0;
6
+ exports.setupRedirectHandling = setupRedirectHandling;
7
7
  const http_1 = __importDefault(require("http"));
8
8
  const error_1 = require("../error");
9
9
  const message_1 = require("../../abap/message");
@@ -56,5 +56,4 @@ function setupRedirectHandling({ resolve, reject, timeout, backend, logger }) {
56
56
  redirectUrl: (port) => `http://localhost:${port}${REDIRECT_PATH}`
57
57
  };
58
58
  }
59
- exports.setupRedirectHandling = setupRedirectHandling;
60
59
  //# sourceMappingURL=redirect.js.map
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ODataRequestError = exports.isAxiosError = void 0;
3
+ exports.ODataRequestError = void 0;
4
+ exports.isAxiosError = isAxiosError;
4
5
  /**
5
6
  * Type guard to narrow an unknown exception to the AxiosError type if it is compatible.
6
7
  *
@@ -10,7 +11,6 @@ exports.ODataRequestError = exports.isAxiosError = void 0;
10
11
  function isAxiosError(e) {
11
12
  return typeof e === 'object' && e !== null && 'isAxiosError' in e;
12
13
  }
13
- exports.isAxiosError = isAxiosError;
14
14
  /**
15
15
  * Error object that is to be thrown if an OData service responds with an error
16
16
  */
package/dist/factory.d.ts CHANGED
@@ -5,6 +5,28 @@ import type { ProviderConfiguration } from './base/service-provider';
5
5
  import { ServiceProvider } from './base/service-provider';
6
6
  import type { ODataService } from './base/odata-service';
7
7
  import { AbapServiceProvider } from './abap';
8
+ import { type HttpsProxyAgentOptions, HttpsProxyAgent } from 'https-proxy-agent';
9
+ /**
10
+ * PatchedHttpsProxyAgent is a custom implementation of HttpsProxyAgent that allows to pass additional options, currently not supported by the original implementation when calling tls.connect
11
+ */
12
+ export declare class PatchedHttpsProxyAgent<Uri extends string> extends HttpsProxyAgent<Uri> {
13
+ private readonly extraOptions;
14
+ /**
15
+ * Extension of the base constructor.
16
+ *
17
+ * @param proxy
18
+ * @param opts
19
+ */
20
+ constructor(proxy: Uri | URL, opts?: HttpsProxyAgentOptions<Uri>);
21
+ /**
22
+ * Performs transparent encryption of written data and all required TLS negotiation.
23
+ *
24
+ * @param req
25
+ * @param opts
26
+ * @returns {Promise<net.Socket>}
27
+ */
28
+ connect(req: any, opts: any): Promise<import("net").Socket>;
29
+ }
8
30
  /**
9
31
  * Create an instance of a basic service provider.
10
32
  *
package/dist/factory.js CHANGED
@@ -3,7 +3,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.createServiceForUrl = exports.createForDestination = exports.createForAbapOnCloud = exports.AbapCloudEnvironment = exports.createForAbap = exports.create = void 0;
6
+ exports.AbapCloudEnvironment = exports.PatchedHttpsProxyAgent = void 0;
7
+ exports.create = create;
8
+ exports.createForAbap = createForAbap;
9
+ exports.createForAbapOnCloud = createForAbapOnCloud;
10
+ exports.createForDestination = createForDestination;
11
+ exports.createServiceForUrl = createServiceForUrl;
7
12
  const cloneDeep_1 = __importDefault(require("lodash/cloneDeep"));
8
13
  const btp_utils_1 = require("@sap-ux/btp-utils");
9
14
  const https_1 = require("https");
@@ -12,6 +17,38 @@ const service_provider_1 = require("./base/service-provider");
12
17
  const abap_1 = require("./abap");
13
18
  const util_1 = require("util");
14
19
  const patchTls_1 = require("./base/patchTls");
20
+ const proxy_from_env_1 = require("proxy-from-env");
21
+ const https_proxy_agent_1 = require("https-proxy-agent");
22
+ const http_proxy_agent_1 = require("http-proxy-agent");
23
+ const feature_toggle_1 = require("@sap-ux/feature-toggle");
24
+ /**
25
+ * PatchedHttpsProxyAgent is a custom implementation of HttpsProxyAgent that allows to pass additional options, currently not supported by the original implementation when calling tls.connect
26
+ */
27
+ // eslint-disable-next-line jsdoc/require-jsdoc
28
+ class PatchedHttpsProxyAgent extends https_proxy_agent_1.HttpsProxyAgent {
29
+ extraOptions;
30
+ /**
31
+ * Extension of the base constructor.
32
+ *
33
+ * @param proxy
34
+ * @param opts
35
+ */
36
+ constructor(proxy, opts) {
37
+ super(proxy, opts);
38
+ this.extraOptions = opts;
39
+ }
40
+ /**
41
+ * Performs transparent encryption of written data and all required TLS negotiation.
42
+ *
43
+ * @param req
44
+ * @param opts
45
+ * @returns {Promise<net.Socket>}
46
+ */
47
+ async connect(req, opts) {
48
+ return super.connect(req, { ...this.extraOptions, ...opts });
49
+ }
50
+ }
51
+ exports.PatchedHttpsProxyAgent = PatchedHttpsProxyAgent;
15
52
  /**
16
53
  * Create a new instance of given type and set default configuration merged with the given config.
17
54
  *
@@ -21,9 +58,21 @@ const patchTls_1 = require("./base/patchTls");
21
58
  */
22
59
  function createInstance(ProviderType, config) {
23
60
  const providerConfig = (0, cloneDeep_1.default)(config);
24
- providerConfig.httpsAgent = new https_1.Agent({
61
+ const agentOptions = {
25
62
  rejectUnauthorized: !providerConfig.ignoreCertErrors
26
- });
63
+ };
64
+ const localProxy = (0, proxy_from_env_1.getProxyForUrl)(config.baseURL);
65
+ const isPatchProxyEnabled = (0, feature_toggle_1.isFeatureEnabled)('sap.ux.enablePatchProxy');
66
+ if (isPatchProxyEnabled && localProxy) {
67
+ // axios doesn't handle proxies correctly, instead use a custom agent with axios proxy disabled
68
+ providerConfig.httpsAgent = new PatchedHttpsProxyAgent(localProxy, agentOptions);
69
+ providerConfig.httpAgent = new http_proxy_agent_1.HttpProxyAgent(localProxy);
70
+ providerConfig.proxy = false;
71
+ }
72
+ // Default httpsAgent with optional parameters passed to the agent
73
+ if (!providerConfig.httpsAgent) {
74
+ providerConfig.httpsAgent = new https_1.Agent(agentOptions);
75
+ }
27
76
  delete providerConfig.ignoreCertErrors;
28
77
  providerConfig.withCredentials = providerConfig?.auth && Object.keys(providerConfig.auth).length > 0;
29
78
  /**
@@ -73,7 +122,6 @@ function create(config) {
73
122
  return createInstance(service_provider_1.ServiceProvider, config);
74
123
  }
75
124
  }
76
- exports.create = create;
77
125
  /**
78
126
  * Create an instance of an ABAP service provider.
79
127
  *
@@ -83,7 +131,6 @@ exports.create = create;
83
131
  function createForAbap(config) {
84
132
  return createInstance(abap_1.AbapServiceProvider, config);
85
133
  }
86
- exports.createForAbap = createForAbap;
87
134
  /** Supported ABAP environments on the cloud */
88
135
  var AbapCloudEnvironment;
89
136
  (function (AbapCloudEnvironment) {
@@ -129,7 +176,6 @@ function createForAbapOnCloud(options) {
129
176
  }
130
177
  return provider;
131
178
  }
132
- exports.createForAbapOnCloud = createForAbapOnCloud;
133
179
  /**
134
180
  * Create an instance of a service provider for the given destination.
135
181
  *
@@ -168,7 +214,6 @@ function createForDestination(options, destination, destinationServiceInstance)
168
214
  }
169
215
  return provider;
170
216
  }
171
- exports.createForDestination = createForDestination;
172
217
  /**
173
218
  * Create an instance of a basic service provider and then generate an extension for a service based on the given url.
174
219
  *
@@ -187,5 +232,4 @@ function createServiceForUrl(url, config = {}) {
187
232
  const provider = createInstance(service_provider_1.ServiceProvider, config);
188
233
  return provider.service(urlObject.pathname);
189
234
  }
190
- exports.createServiceForUrl = createServiceForUrl;
191
235
  //# sourceMappingURL=factory.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sap-ux/axios-extension",
3
- "version": "1.16.6",
3
+ "version": "1.17.0",
4
4
  "description": "Extension of the Axios module adding convenience methods to interact with SAP systems especially with OData services.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -22,14 +22,19 @@
22
22
  "qs": "6.11.0",
23
23
  "xpath": "0.0.33",
24
24
  "@xmldom/xmldom": "0.8.10",
25
+ "https-proxy-agent": "7.0.5",
26
+ "http-proxy-agent": "7.0.2",
27
+ "proxy-from-env": "1.1.0",
25
28
  "@sap-ux/btp-utils": "0.15.2",
26
- "@sap-ux/logger": "0.6.0"
29
+ "@sap-ux/logger": "0.6.0",
30
+ "@sap-ux/feature-toggle": "0.2.2"
27
31
  },
28
32
  "devDependencies": {
29
33
  "@types/lodash": "4.14.202",
30
34
  "nock": "13.4.0",
31
35
  "supertest": "6.3.3",
32
- "@sap-ux/project-access": "1.27.1"
36
+ "@types/proxy-from-env": "1.0.1",
37
+ "@sap-ux/project-access": "1.28.5"
33
38
  },
34
39
  "files": [
35
40
  "dist",