@serenity-js/rest 3.19.0 → 3.20.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.
Files changed (50) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/lib/index.d.ts +1 -0
  3. package/lib/index.d.ts.map +1 -1
  4. package/lib/index.js +1 -0
  5. package/lib/index.js.map +1 -1
  6. package/lib/io/AxiosRequestConfigDefaults.d.ts +14 -0
  7. package/lib/io/AxiosRequestConfigDefaults.d.ts.map +1 -0
  8. package/lib/io/AxiosRequestConfigDefaults.js +3 -0
  9. package/lib/io/AxiosRequestConfigDefaults.js.map +1 -0
  10. package/lib/io/ProxyAgent.d.ts +55 -0
  11. package/lib/io/ProxyAgent.d.ts.map +1 -0
  12. package/lib/io/ProxyAgent.js +111 -0
  13. package/lib/io/ProxyAgent.js.map +1 -0
  14. package/lib/io/axiosProxyOverridesFor.d.ts +12 -0
  15. package/lib/io/axiosProxyOverridesFor.d.ts.map +1 -0
  16. package/lib/io/axiosProxyOverridesFor.js +35 -0
  17. package/lib/io/axiosProxyOverridesFor.js.map +1 -0
  18. package/lib/io/createAxios.d.ts +9 -0
  19. package/lib/io/createAxios.d.ts.map +1 -0
  20. package/lib/io/createAxios.js +67 -0
  21. package/lib/io/createAxios.js.map +1 -0
  22. package/lib/io/createUrl.d.ts +10 -0
  23. package/lib/io/createUrl.d.ts.map +1 -0
  24. package/lib/io/createUrl.js +30 -0
  25. package/lib/io/createUrl.js.map +1 -0
  26. package/lib/io/index.d.ts +3 -0
  27. package/lib/io/index.d.ts.map +1 -0
  28. package/lib/io/index.js +19 -0
  29. package/lib/io/index.js.map +1 -0
  30. package/lib/screenplay/abilities/CallAnApi.d.ts +7 -9
  31. package/lib/screenplay/abilities/CallAnApi.d.ts.map +1 -1
  32. package/lib/screenplay/abilities/CallAnApi.js +8 -64
  33. package/lib/screenplay/abilities/CallAnApi.js.map +1 -1
  34. package/lib/screenplay/abilities/index.d.ts +0 -1
  35. package/lib/screenplay/abilities/index.d.ts.map +1 -1
  36. package/lib/screenplay/abilities/index.js +0 -1
  37. package/lib/screenplay/abilities/index.js.map +1 -1
  38. package/lib/screenplay/interactions/ChangeApiConfig.d.ts +2 -2
  39. package/lib/screenplay/interactions/ChangeApiConfig.js +2 -2
  40. package/package.json +4 -4
  41. package/src/index.ts +1 -0
  42. package/src/io/AxiosRequestConfigDefaults.ts +15 -0
  43. package/src/io/ProxyAgent.ts +129 -0
  44. package/src/io/axiosProxyOverridesFor.ts +39 -0
  45. package/src/io/createAxios.ts +50 -0
  46. package/src/io/createUrl.ts +39 -0
  47. package/src/io/index.ts +2 -0
  48. package/src/screenplay/abilities/CallAnApi.ts +11 -55
  49. package/src/screenplay/abilities/index.ts +0 -1
  50. package/src/screenplay/interactions/ChangeApiConfig.ts +2 -2
package/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [3.20.0](https://github.com/serenity-js/serenity-js/compare/v3.19.0...v3.20.0) (2024-03-02)
7
+
8
+
9
+ ### Features
10
+
11
+ * **rest:** createAxios function instantiates axios with HTTP proxy support ([c453678](https://github.com/serenity-js/serenity-js/commit/c4536784c0bd9e77826563b944904fb862c43c83))
12
+
13
+
14
+
15
+
16
+
6
17
  # [3.19.0](https://github.com/serenity-js/serenity-js/compare/v3.18.1...v3.19.0) (2024-03-01)
7
18
 
8
19
  **Note:** Version bump only for package @serenity-js/rest
package/lib/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
+ export * from './io';
1
2
  export * from './screenplay';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,MAAM,CAAC;AACrB,cAAc,cAAc,CAAC"}
package/lib/index.js CHANGED
@@ -14,5 +14,6 @@ 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
+ __exportStar(require("./io"), exports);
17
18
  __exportStar(require("./screenplay"), exports);
18
19
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,uCAAqB;AACrB,+CAA6B"}
@@ -0,0 +1,14 @@
1
+ import { type CreateAxiosDefaults } from 'axios';
2
+ export type AxiosRequestConfigProxyDefaults = {
3
+ host: string;
4
+ port?: number;
5
+ auth?: {
6
+ username: string;
7
+ password: string;
8
+ };
9
+ protocol?: string;
10
+ };
11
+ export type AxiosRequestConfigDefaults<Data = any> = Omit<CreateAxiosDefaults<Data>, 'proxy'> & {
12
+ proxy?: AxiosRequestConfigProxyDefaults | false;
13
+ };
14
+ //# sourceMappingURL=AxiosRequestConfigDefaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AxiosRequestConfigDefaults.d.ts","sourceRoot":"","sources":["../../src/io/AxiosRequestConfigDefaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAEjD,MAAM,MAAM,+BAA+B,GAAG;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE;QACH,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB,CAAA;AAED,MAAM,MAAM,0BAA0B,CAAC,IAAI,GAAG,GAAG,IAAI,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,GAAG;IAC5F,KAAK,CAAC,EAAE,+BAA+B,GAAG,KAAK,CAAC;CACnD,CAAA"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=AxiosRequestConfigDefaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AxiosRequestConfigDefaults.js","sourceRoot":"","sources":["../../src/io/AxiosRequestConfigDefaults.ts"],"names":[],"mappings":""}
@@ -0,0 +1,55 @@
1
+ /// <reference types="node" />
2
+ import type { AgentConnectOpts } from 'agent-base';
3
+ import { Agent } from 'agent-base';
4
+ import * as http from 'http';
5
+ import { type HttpProxyAgentOptions } from 'http-proxy-agent';
6
+ import { type HttpsProxyAgentOptions } from 'https-proxy-agent';
7
+ type GetProxyForUrlCallback = (url: string) => string;
8
+ export type ProxyAgentOptions = HttpProxyAgentOptions<''> & HttpsProxyAgentOptions<''> & {
9
+ /**
10
+ * Default `http.Agent` instance to use when no proxy is
11
+ * configured for a request. Defaults to a new `http.Agent()`
12
+ * instance with the proxy agent options passed in.
13
+ */
14
+ httpAgent?: http.Agent;
15
+ /**
16
+ * Default `http.Agent` instance to use when no proxy is
17
+ * configured for a request. Defaults to a new `https.Agent()`
18
+ * instance with the proxy agent options passed in.
19
+ */
20
+ httpsAgent?: http.Agent;
21
+ /**
22
+ * A callback for dynamic provision of proxy for url.
23
+ * Defaults to standard proxy environment variables,
24
+ * see https://www.npmjs.com/package/proxy-from-env for details
25
+ */
26
+ getProxyForUrl?: GetProxyForUrlCallback;
27
+ };
28
+ /**
29
+ * A simplified version of the original
30
+ * [`ProxyAgent`](https://github.com/TooTallNate/proxy-agents/blob/5923589c2e5206504772c250ac4f20fc31122d3b/packages/proxy-agent/src/index.ts)
31
+ * with fewer dependencies.
32
+ *
33
+ * Delegates requests to the appropriate `Agent` subclass based on the "proxy"
34
+ * environment variables, or the provided `agentOptions.getProxyForUrl` callback.
35
+ *
36
+ * Uses an LRU cache to prevent unnecessary creation of proxy `http.Agent` instances.
37
+ */
38
+ export declare class ProxyAgent extends Agent {
39
+ private readonly agentOptions;
40
+ private static proxyAgents;
41
+ /**
42
+ * Cache for `Agent` instances.
43
+ */
44
+ private readonly cache;
45
+ private readonly httpAgent;
46
+ private readonly httpsAgent;
47
+ private readonly getProxyForUrl;
48
+ constructor(agentOptions: ProxyAgentOptions);
49
+ connect(request: http.ClientRequest, options: AgentConnectOpts): Promise<http.Agent>;
50
+ private createAgent;
51
+ private isValidProtocol;
52
+ destroy(): void;
53
+ }
54
+ export {};
55
+ //# sourceMappingURL=ProxyAgent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProxyAgent.d.ts","sourceRoot":"","sources":["../../src/io/ProxyAgent.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAkB,KAAK,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAE9E,OAAO,EAAmB,KAAK,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAYjF,KAAK,sBAAsB,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;AAEtD,MAAM,MAAM,iBAAiB,GACzB,qBAAqB,CAAC,EAAE,CAAC,GACzB,sBAAsB,CAAC,EAAE,CAAC,GAAG;IACzB;;;;OAIG;IACH,SAAS,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC;IACvB;;;;OAIG;IACH,UAAU,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC;IACxB;;;;OAIG;IACH,cAAc,CAAC,EAAE,sBAAsB,CAAC;CAC3C,CAAC;AAEN;;;;;;;;;GASG;AACH,qBAAa,UAAW,SAAQ,KAAK;IAmBrB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAjBzC,OAAO,CAAC,MAAM,CAAC,WAAW,CAGxB;IAEF;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,KAAK,CAGnB;IAEH,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAa;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAyB;gBAE3B,YAAY,EAAE,iBAAiB;IAO7C,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;IA4BnG,OAAO,CAAC,WAAW;IAanB,OAAO,CAAC,eAAe;IAId,OAAO,IAAI,IAAI;CAI3B"}
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.ProxyAgent = void 0;
27
+ const core_1 = require("@serenity-js/core");
28
+ const agent_base_1 = require("agent-base");
29
+ const http = __importStar(require("http"));
30
+ const http_proxy_agent_1 = require("http-proxy-agent");
31
+ const https = __importStar(require("https"));
32
+ const https_proxy_agent_1 = require("https-proxy-agent");
33
+ const lru_cache_1 = require("lru-cache");
34
+ const proxy_from_env_1 = require("proxy-from-env");
35
+ const protocols = [
36
+ ...http_proxy_agent_1.HttpProxyAgent.protocols,
37
+ ];
38
+ /**
39
+ * A simplified version of the original
40
+ * [`ProxyAgent`](https://github.com/TooTallNate/proxy-agents/blob/5923589c2e5206504772c250ac4f20fc31122d3b/packages/proxy-agent/src/index.ts)
41
+ * with fewer dependencies.
42
+ *
43
+ * Delegates requests to the appropriate `Agent` subclass based on the "proxy"
44
+ * environment variables, or the provided `agentOptions.getProxyForUrl` callback.
45
+ *
46
+ * Uses an LRU cache to prevent unnecessary creation of proxy `http.Agent` instances.
47
+ */
48
+ class ProxyAgent extends agent_base_1.Agent {
49
+ agentOptions;
50
+ static proxyAgents = {
51
+ http: [http_proxy_agent_1.HttpProxyAgent, https_proxy_agent_1.HttpsProxyAgent],
52
+ https: [http_proxy_agent_1.HttpProxyAgent, https_proxy_agent_1.HttpsProxyAgent],
53
+ };
54
+ /**
55
+ * Cache for `Agent` instances.
56
+ */
57
+ cache = new lru_cache_1.LRUCache({
58
+ max: 20,
59
+ dispose: (value, key) => value.destroy(),
60
+ });
61
+ httpAgent;
62
+ httpsAgent;
63
+ getProxyForUrl;
64
+ constructor(agentOptions) {
65
+ super(agentOptions);
66
+ this.agentOptions = agentOptions;
67
+ this.httpAgent = agentOptions?.httpAgent || new http.Agent(agentOptions);
68
+ this.httpsAgent = agentOptions?.httpsAgent || new https.Agent(agentOptions);
69
+ this.getProxyForUrl = agentOptions?.getProxyForUrl || proxy_from_env_1.getProxyForUrl;
70
+ }
71
+ async connect(request, options) {
72
+ const { secureEndpoint } = options;
73
+ const isWebSocket = request.getHeader('upgrade') === 'websocket';
74
+ const protocol = secureEndpoint
75
+ ? (isWebSocket ? 'wss:' : 'https:')
76
+ : (isWebSocket ? 'ws:' : 'http:');
77
+ const host = request.getHeader('host');
78
+ const url = new URL(request.path, `${protocol}//${host}`).href;
79
+ const proxy = this.getProxyForUrl(url);
80
+ if (!proxy) {
81
+ return secureEndpoint
82
+ ? this.httpsAgent
83
+ : this.httpAgent;
84
+ }
85
+ // attempt to get a cached `http.Agent` instance first
86
+ const cacheKey = `${protocol}+${proxy}`;
87
+ let agent = this.cache.get(cacheKey);
88
+ if (!agent) {
89
+ agent = this.createAgent(new URL(proxy), secureEndpoint || isWebSocket);
90
+ this.cache.set(cacheKey, agent);
91
+ }
92
+ return agent;
93
+ }
94
+ createAgent(proxyUrl, requiresTls) {
95
+ const protocol = proxyUrl.protocol.replace(':', '');
96
+ if (!this.isValidProtocol(protocol)) {
97
+ throw new core_1.ConfigurationError(`Unsupported protocol for proxy URL: ${proxyUrl}`);
98
+ }
99
+ const ctor = ProxyAgent.proxyAgents[protocol][requiresTls ? 1 : 0];
100
+ return new ctor(proxyUrl, this.agentOptions);
101
+ }
102
+ isValidProtocol(v) {
103
+ return protocols.includes(v);
104
+ }
105
+ destroy() {
106
+ this.cache.clear();
107
+ super.destroy();
108
+ }
109
+ }
110
+ exports.ProxyAgent = ProxyAgent;
111
+ //# sourceMappingURL=ProxyAgent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProxyAgent.js","sourceRoot":"","sources":["../../src/io/ProxyAgent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /// <reference types="node" />
2
+ import type * as http from 'http';
3
+ import type { AxiosRequestConfigDefaults } from './AxiosRequestConfigDefaults';
4
+ /**
5
+ * @param options
6
+ */
7
+ export declare function axiosProxyOverridesFor<Data = any>(options: AxiosRequestConfigDefaults<Data>): {
8
+ proxy: false;
9
+ httpAgent: http.Agent;
10
+ httpsAgent: http.Agent;
11
+ };
12
+ //# sourceMappingURL=axiosProxyOverridesFor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"axiosProxyOverridesFor.d.ts","sourceRoot":"","sources":["../../src/io/axiosProxyOverridesFor.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,IAAI,MAAM,MAAM,CAAC;AAGlC,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAI/E;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,GAAG,GAAG,EAAE,OAAO,EAAE,0BAA0B,CAAC,IAAI,CAAC,GAAG;IAC3F,KAAK,EAAE,KAAK,CAAC;IAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC;IAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAA;CAC9D,CA0BA"}
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.axiosProxyOverridesFor = void 0;
4
+ const tiny_types_1 = require("tiny-types");
5
+ const createUrl_1 = require("./createUrl");
6
+ const ProxyAgent_1 = require("./ProxyAgent");
7
+ /**
8
+ * @param options
9
+ */
10
+ function axiosProxyOverridesFor(options) {
11
+ const envProxyOverride = options.proxy
12
+ && (0, createUrl_1.createUrl)({
13
+ username: options.proxy?.auth?.username,
14
+ password: options.proxy?.auth?.password,
15
+ protocol: options.proxy?.protocol,
16
+ hostname: (0, tiny_types_1.ensure)('proxy.host', options.proxy?.host, (0, tiny_types_1.isDefined)()),
17
+ port: options.proxy?.port
18
+ }).toString();
19
+ const agent = new ProxyAgent_1.ProxyAgent({
20
+ httpAgent: options.httpAgent,
21
+ httpsAgent: options.httpsAgent,
22
+ // if there's a specific proxy override configured, use it
23
+ // if not - detect proxy automatically based on env variables
24
+ getProxyForUrl: envProxyOverride
25
+ ? (url_) => envProxyOverride
26
+ : undefined,
27
+ });
28
+ return {
29
+ proxy: false,
30
+ httpAgent: agent,
31
+ httpsAgent: agent,
32
+ };
33
+ }
34
+ exports.axiosProxyOverridesFor = axiosProxyOverridesFor;
35
+ //# sourceMappingURL=axiosProxyOverridesFor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"axiosProxyOverridesFor.js","sourceRoot":"","sources":["../../src/io/axiosProxyOverridesFor.ts"],"names":[],"mappings":";;;AACA,2CAA+C;AAG/C,2CAAwC;AACxC,6CAA0C;AAE1C;;GAEG;AACH,SAAgB,sBAAsB,CAAa,OAAyC;IAGxF,MAAM,gBAAgB,GAAmB,OAAO,CAAC,KAAK;WAC/C,IAAA,qBAAS,EAAC;YACT,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ;YACvC,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ;YACvC,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,QAAQ;YACjC,QAAQ,EAAE,IAAA,mBAAM,EAAC,YAAY,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,IAAA,sBAAS,GAAE,CAAC;YAChE,IAAI,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI;SAC5B,CAAC,CAAC,QAAQ,EAAE,CAAC;IAElB,MAAM,KAAK,GAAG,IAAI,uBAAU,CAAC;QACzB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,UAAU,EAAE,OAAO,CAAC,UAAU;QAE9B,0DAA0D;QAC1D,6DAA6D;QAC7D,cAAc,EAAE,gBAAgB;YAC5B,CAAC,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,gBAAgB;YACpC,CAAC,CAAC,SAAS;KAClB,CAAC,CAAC;IAEH,OAAO;QACH,KAAK,EAAE,KAAK;QACZ,SAAS,EAAE,KAAK;QAChB,UAAU,EAAE,KAAK;KACpB,CAAC;AACN,CAAC;AA5BD,wDA4BC"}
@@ -0,0 +1,9 @@
1
+ import { type AxiosInstance } from 'axios';
2
+ import type { AxiosRequestConfigDefaults } from './AxiosRequestConfigDefaults';
3
+ /**
4
+ * Creates an Axios instance with desired configuration and proxy support.
5
+ *
6
+ * @param axiosInstanceOrConfig
7
+ */
8
+ export declare function createAxios(axiosInstanceOrConfig?: AxiosInstance | AxiosRequestConfigDefaults): AxiosInstance;
9
+ //# sourceMappingURL=createAxios.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createAxios.d.ts","sourceRoot":"","sources":["../../src/io/createAxios.ts"],"names":[],"mappings":"AACA,OAAc,EAAS,KAAK,aAAa,EAA2B,MAAM,OAAO,CAAC;AAGlF,OAAO,KAAK,EAAE,0BAA0B,EAAmC,MAAM,8BAA8B,CAAC;AAEhH;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,qBAAqB,GAAE,aAAa,GAAG,0BAA+B,GAAG,aAAa,CAoBjH"}
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.createAxios = void 0;
27
+ const core_1 = require("@serenity-js/core");
28
+ const axios_1 = __importStar(require("axios"));
29
+ const axiosProxyOverridesFor_1 = require("./axiosProxyOverridesFor");
30
+ /**
31
+ * Creates an Axios instance with desired configuration and proxy support.
32
+ *
33
+ * @param axiosInstanceOrConfig
34
+ */
35
+ function createAxios(axiosInstanceOrConfig = {}) {
36
+ const axiosInstanceGiven = isAxiosInstance(axiosInstanceOrConfig);
37
+ const axiosInstance = axiosInstanceGiven
38
+ ? axiosInstanceOrConfig
39
+ : axios_1.default.create({
40
+ timeout: core_1.Duration.ofSeconds(10).inMilliseconds(),
41
+ ...omit(axiosInstanceOrConfig, 'proxy'),
42
+ });
43
+ const proxyConfig = axiosInstanceGiven
44
+ ? axiosInstanceOrConfig.defaults.proxy
45
+ : axiosInstanceOrConfig.proxy;
46
+ const proxyOverrides = (0, axiosProxyOverridesFor_1.axiosProxyOverridesFor)({
47
+ ...axiosInstance.defaults,
48
+ proxy: proxyConfig || undefined,
49
+ });
50
+ return withOverrides(axiosInstance, proxyOverrides);
51
+ }
52
+ exports.createAxios = createAxios;
53
+ function isAxiosInstance(axiosInstanceOrConfig) {
54
+ return axiosInstanceOrConfig
55
+ && (axiosInstanceOrConfig instanceof axios_1.Axios || axiosInstanceOrConfig.defaults);
56
+ }
57
+ function withOverrides(axiosInstance, overrides) {
58
+ for (const [key, override] of Object.entries(overrides)) {
59
+ axiosInstance.defaults[key] = override;
60
+ }
61
+ return axiosInstance;
62
+ }
63
+ function omit(record, key) {
64
+ const { [key]: omitted_, ...rest } = record;
65
+ return rest;
66
+ }
67
+ //# sourceMappingURL=createAxios.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createAxios.js","sourceRoot":"","sources":["../../src/io/createAxios.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4CAA6C;AAC7C,+CAAkF;AAElF,qEAAkE;AAGlE;;;;GAIG;AACH,SAAgB,WAAW,CAAC,wBAAoE,EAAE;IAC9F,MAAM,kBAAkB,GAAG,eAAe,CAAC,qBAAqB,CAAC,CAAC;IAElE,MAAM,aAAa,GAAG,kBAAkB;QACpC,CAAC,CAAC,qBAAqB;QACvB,CAAC,CAAC,eAAK,CAAC,MAAM,CAAC;YACX,OAAO,EAAE,eAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,cAAc,EAAE;YAChD,GAAG,IAAI,CAAC,qBAAqB,EAAE,OAAO,CAAC;SAC1C,CAAC,CAAC;IAEP,MAAM,WAAW,GAAwD,kBAAkB;QACvF,CAAC,CAAC,qBAAqB,CAAC,QAAQ,CAAC,KAAK;QACtC,CAAC,CAAC,qBAAqB,CAAC,KAAK,CAAC;IAElC,MAAM,cAAc,GAAG,IAAA,+CAAsB,EAAC;QAC1C,GAAG,aAAa,CAAC,QAAQ;QACzB,KAAK,EAAE,WAAW,IAAI,SAAS;KAClC,CAAC,CAAC;IAEH,OAAO,aAAa,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;AACxD,CAAC;AApBD,kCAoBC;AAED,SAAS,eAAe,CAAC,qBAA0B;IAC/C,OAAO,qBAAqB;WACrB,CAAC,qBAAqB,YAAY,aAAK,IAAI,qBAAqB,CAAC,QAAQ,CAAC,CAAC;AACtF,CAAC;AAED,SAAS,aAAa,CAAa,aAA4B,EAAE,SAAmC;IAChG,KAAK,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;QACrD,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;KAC1C;IAED,OAAO,aAAa,CAAC;AACzB,CAAC;AAED,SAAS,IAAI,CAAsC,MAAS,EAAE,GAAM;IAChE,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC;IAC5C,OAAO,IAAI,CAAC;AAChB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /// <reference types="node" />
2
+ export interface CreateUrlOptions {
3
+ protocol?: string;
4
+ hostname: string;
5
+ port?: string | number;
6
+ username?: string;
7
+ password?: string;
8
+ }
9
+ export declare function createUrl(options: CreateUrlOptions): URL;
10
+ //# sourceMappingURL=createUrl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createUrl.d.ts","sourceRoot":"","sources":["../../src/io/createUrl.ts"],"names":[],"mappings":";AAEA,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,GAAG,CAYxD"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createUrl = void 0;
4
+ const tiny_types_1 = require("tiny-types");
5
+ function createUrl(options) {
6
+ const hostname = (0, tiny_types_1.ensure)('hostname', options?.hostname, (0, tiny_types_1.isString)(), (0, tiny_types_1.isNotBlank)()).trim();
7
+ const port = options?.port
8
+ ? ':' + options?.port
9
+ : (options?.protocol ? undefined : ':80');
10
+ return new URL([
11
+ options?.protocol && protocolFrom(options?.protocol),
12
+ (options?.username || options?.password) && credentialsFrom(options.username, options.password),
13
+ hostname,
14
+ port,
15
+ ].filter(Boolean).join(''));
16
+ }
17
+ exports.createUrl = createUrl;
18
+ function protocolFrom(protocol) {
19
+ const protocolName = protocol.match(/([A-Za-z]+)[/:]*/)[1];
20
+ (0, tiny_types_1.ensure)('hostname', protocolName, (0, tiny_types_1.isDefined)());
21
+ return protocolName + '://';
22
+ }
23
+ function credentialsFrom(username, password) {
24
+ return [
25
+ username && encodeURIComponent(username),
26
+ password && ':' + encodeURIComponent(password),
27
+ '@'
28
+ ].filter(Boolean).join('');
29
+ }
30
+ //# sourceMappingURL=createUrl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createUrl.js","sourceRoot":"","sources":["../../src/io/createUrl.ts"],"names":[],"mappings":";;;AAAA,2CAAqE;AAUrE,SAAgB,SAAS,CAAC,OAAyB;IAC/C,MAAM,QAAQ,GAAI,IAAA,mBAAM,EAAC,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAA,qBAAQ,GAAE,EAAE,IAAA,uBAAU,GAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACzF,MAAM,IAAI,GAAQ,OAAO,EAAE,IAAI;QAC3B,CAAC,CAAC,GAAG,GAAG,OAAO,EAAE,IAAI;QACrB,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAE9C,OAAO,IAAI,GAAG,CAAC;QACX,OAAO,EAAE,QAAQ,IAAI,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC;QACpD,CAAC,OAAO,EAAE,QAAQ,IAAI,OAAO,EAAE,QAAQ,CAAC,IAAI,eAAe,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC;QAC/F,QAAQ;QACR,IAAI;KACP,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;AAChC,CAAC;AAZD,8BAYC;AAED,SAAS,YAAY,CAAC,QAAiB;IACnC,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;IAE3D,IAAA,mBAAM,EAAC,UAAU,EAAE,YAAY,EAAE,IAAA,sBAAS,GAAE,CAAC,CAAC;IAE9C,OAAO,YAAY,GAAG,KAAK,CAAC;AAChC,CAAC;AAED,SAAS,eAAe,CAAC,QAAiB,EAAE,QAAiB;IACzD,OAAO;QACH,QAAQ,IAAI,kBAAkB,CAAC,QAAQ,CAAC;QACxC,QAAQ,IAAI,GAAG,GAAG,kBAAkB,CAAC,QAAQ,CAAC;QAC9C,GAAG;KACN,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './AxiosRequestConfigDefaults';
2
+ export * from './createAxios';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/io/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,eAAe,CAAC"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./AxiosRequestConfigDefaults"), exports);
18
+ __exportStar(require("./createAxios"), exports);
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/io/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+DAA6C;AAC7C,gDAA8B"}
@@ -1,7 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  import { Ability } from '@serenity-js/core';
3
3
  import { type AxiosDefaults, type AxiosInstance, type AxiosRequestConfig, type AxiosResponse } from 'axios';
4
- import type { AxiosRequestConfigDefaults } from './AxiosRequestConfigDefaults';
4
+ import type { AxiosRequestConfigDefaults } from '../../io';
5
5
  /**
6
6
  * An {@apilink Ability} that wraps [axios client](https://axios-http.com/docs/api_intro) and enables
7
7
  * the {@apilink Actor} to {@apilink Send} {@apilink HTTPRequest|HTTP requests} to HTTP APIs.
@@ -137,14 +137,13 @@ import type { AxiosRequestConfigDefaults } from './AxiosRequestConfigDefaults';
137
137
  *
138
138
  * ```ts
139
139
  * import { actorCalled } from '@serenity-js/core'
140
- * import { CallAnApi, GetRequest, LastResponse, Send } from '@serenity-js/rest'
140
+ * import { createAxios, CallAnApi, GetRequest, LastResponse, Send } from '@serenity-js/rest'
141
141
  * import { Ensure, equals } from '@serenity-js/assertions'
142
142
  *
143
- * import axios from 'axios'
144
143
  * import axiosRetry from 'axios-retry'
145
144
  *
146
- * const instance = axios.create({ baseURL 'https://api.example.org/' })
147
- * axiosRetry(axios, { retries: 3 })
145
+ * const instance = createAxios({ baseURL 'https://api.example.org/' })
146
+ * axiosRetry(instance, { retries: 3 })
148
147
  *
149
148
  * await actorCalled('Apisitt')
150
149
  * .whoCan(
@@ -167,11 +166,11 @@ import type { AxiosRequestConfigDefaults } from './AxiosRequestConfigDefaults';
167
166
  * import { CallAnApi, GetRequest, LastResponse, Send } from '@serenity-js/rest'
168
167
  * import { Ensure, equals } from '@serenity-js/assertions'
169
168
  *
170
- * import axios from 'axios'
169
+ * import { axiosCreate } from '@serenity-js/rest'
171
170
  * import axiosRetry from 'axios-retry'
172
171
  *
173
- * const instance = axios.create({ baseURL 'https://api.example.org/' })
174
- * axiosRetry(axios, { retries: 3 })
172
+ * const instance = axiosCreate({ baseURL 'https://api.example.org/' })
173
+ * axiosRetry(instance, { retries: 3 })
175
174
  *
176
175
  * await actorCalled('Apisitt')
177
176
  * .whoCan(
@@ -315,7 +314,6 @@ import type { AxiosRequestConfigDefaults } from './AxiosRequestConfigDefaults';
315
314
  export declare class CallAnApi extends Ability {
316
315
  private readonly axiosInstance;
317
316
  private lastResponse;
318
- private static readonly defaults;
319
317
  /**
320
318
  * Produces an {@apilink Ability|ability} to call a REST API at a specified `baseURL`;
321
319
  *
@@ -1 +1 @@
1
- {"version":3,"file":"CallAnApi.d.ts","sourceRoot":"","sources":["../../../src/screenplay/abilities/CallAnApi.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAkE,MAAM,mBAAmB,CAAC;AAC5G,OAAc,EAEV,KAAK,aAAa,EAElB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAErB,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,0BAA0B,EAAmC,MAAM,8BAA8B,CAAC;AAGhH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqTG;AACH,qBAAa,SAAU,SAAQ,OAAO;IAsEtB,OAAO,CAAC,QAAQ,CAAC,aAAa;IApE1C,OAAO,CAAC,YAAY,CAAgB;IAEpC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAE9B;IAEF;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,GAAG,MAAM,GAAG,SAAS;IAQ3C;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,aAAa,GAAG,0BAA0B,GAAG,SAAS;IAuB1F;;;;;;OAMG;gBAC0B,aAAa,EAAE,aAAa;IAIzD;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,IAAI;IAI7D;;;;;;;;;;;OAWG;IACG,OAAO,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC;IAgCjE;;;;;;;;OAQG;IACH,UAAU,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM;IAQ9C;;;;;;;;OAQG;IACH,eAAe,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,CAAC,GAAG,CAAC;CAOzE"}
1
+ {"version":3,"file":"CallAnApi.d.ts","sourceRoot":"","sources":["../../../src/screenplay/abilities/CallAnApi.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAwD,MAAM,mBAAmB,CAAC;AAClG,OAAO,EACH,KAAK,aAAa,EAElB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EACrB,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,0BAA0B,EAAC,MAAM,UAAU,CAAC;AAG1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoTG;AACH,qBAAa,SAAU,SAAQ,OAAO;IA+CtB,OAAO,CAAC,QAAQ,CAAC,aAAa;IA7C1C,OAAO,CAAC,YAAY,CAAgB;IAEpC;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,GAAG,MAAM,GAAG,SAAS;IAQ3C;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,aAAa,GAAG,0BAA0B,GAAG,SAAS;IAI1F;;;;;;OAMG;gBAC0B,aAAa,EAAE,aAAa;IAIzD;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,IAAI;IAI7D;;;;;;;;;;;OAWG;IACG,OAAO,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC;IAgCjE;;;;;;;;OAQG;IACH,UAAU,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM;IAQ9C;;;;;;;;OAQG;IACH,eAAe,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,CAAC,GAAG,CAAC;CAOzE"}
@@ -1,32 +1,8 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
2
  Object.defineProperty(exports, "__esModule", { value: true });
26
3
  exports.CallAnApi = void 0;
27
4
  const core_1 = require("@serenity-js/core");
28
- const axios_1 = __importStar(require("axios"));
29
- const proxy_1 = require("./proxy");
5
+ const io_1 = require("../../io");
30
6
  /**
31
7
  * An {@apilink Ability} that wraps [axios client](https://axios-http.com/docs/api_intro) and enables
32
8
  * the {@apilink Actor} to {@apilink Send} {@apilink HTTPRequest|HTTP requests} to HTTP APIs.
@@ -162,14 +138,13 @@ const proxy_1 = require("./proxy");
162
138
  *
163
139
  * ```ts
164
140
  * import { actorCalled } from '@serenity-js/core'
165
- * import { CallAnApi, GetRequest, LastResponse, Send } from '@serenity-js/rest'
141
+ * import { createAxios, CallAnApi, GetRequest, LastResponse, Send } from '@serenity-js/rest'
166
142
  * import { Ensure, equals } from '@serenity-js/assertions'
167
143
  *
168
- * import axios from 'axios'
169
144
  * import axiosRetry from 'axios-retry'
170
145
  *
171
- * const instance = axios.create({ baseURL 'https://api.example.org/' })
172
- * axiosRetry(axios, { retries: 3 })
146
+ * const instance = createAxios({ baseURL 'https://api.example.org/' })
147
+ * axiosRetry(instance, { retries: 3 })
173
148
  *
174
149
  * await actorCalled('Apisitt')
175
150
  * .whoCan(
@@ -192,11 +167,11 @@ const proxy_1 = require("./proxy");
192
167
  * import { CallAnApi, GetRequest, LastResponse, Send } from '@serenity-js/rest'
193
168
  * import { Ensure, equals } from '@serenity-js/assertions'
194
169
  *
195
- * import axios from 'axios'
170
+ * import { axiosCreate } from '@serenity-js/rest'
196
171
  * import axiosRetry from 'axios-retry'
197
172
  *
198
- * const instance = axios.create({ baseURL 'https://api.example.org/' })
199
- * axiosRetry(axios, { retries: 3 })
173
+ * const instance = axiosCreate({ baseURL 'https://api.example.org/' })
174
+ * axiosRetry(instance, { retries: 3 })
200
175
  *
201
176
  * await actorCalled('Apisitt')
202
177
  * .whoCan(
@@ -340,9 +315,6 @@ const proxy_1 = require("./proxy");
340
315
  class CallAnApi extends core_1.Ability {
341
316
  axiosInstance;
342
317
  lastResponse;
343
- static defaults = {
344
- timeout: core_1.Duration.ofSeconds(10).inMilliseconds(),
345
- };
346
318
  /**
347
319
  * Produces an {@apilink Ability|ability} to call a REST API at a specified `baseURL`;
348
320
  *
@@ -375,21 +347,7 @@ class CallAnApi extends core_1.Ability {
375
347
  * @param axiosInstanceOrConfig
376
348
  */
377
349
  static using(axiosInstanceOrConfig) {
378
- const axiosInstanceGiven = isAxiosInstance(axiosInstanceOrConfig);
379
- const axiosInstance = axiosInstanceGiven
380
- ? axiosInstanceOrConfig
381
- : axios_1.default.create({
382
- ...CallAnApi.defaults,
383
- ...omit(axiosInstanceOrConfig, 'proxy'),
384
- });
385
- const proxyConfig = axiosInstanceGiven
386
- ? axiosInstanceOrConfig.defaults.proxy
387
- : axiosInstanceOrConfig.proxy;
388
- const proxyOverrides = (0, proxy_1.axiosProxyOverridesFor)({
389
- ...axiosInstance.defaults,
390
- proxy: proxyConfig || undefined,
391
- });
392
- return new CallAnApi(withOverrides(axiosInstance, proxyOverrides));
350
+ return new CallAnApi((0, io_1.createAxios)(axiosInstanceOrConfig));
393
351
  }
394
352
  /**
395
353
  * #### Learn more
@@ -486,18 +444,4 @@ class CallAnApi extends core_1.Ability {
486
444
  }
487
445
  }
488
446
  exports.CallAnApi = CallAnApi;
489
- function isAxiosInstance(axiosInstanceOrConfig) {
490
- return axiosInstanceOrConfig
491
- && (axiosInstanceOrConfig instanceof axios_1.Axios || axiosInstanceOrConfig.defaults);
492
- }
493
- function withOverrides(axiosInstance, overrides) {
494
- for (const [key, override] of Object.entries(overrides)) {
495
- axiosInstance.defaults[key] = override;
496
- }
497
- return axiosInstance;
498
- }
499
- function omit(record, key) {
500
- const { [key]: omitted_, ...rest } = record;
501
- return rest;
502
- }
503
447
  //# sourceMappingURL=CallAnApi.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CallAnApi.js","sourceRoot":"","sources":["../../../src/screenplay/abilities/CallAnApi.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CallAnApi.js","sourceRoot":"","sources":["../../../src/screenplay/abilities/CallAnApi.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,2 @@
1
- export * from './AxiosRequestConfigDefaults';
2
1
  export * from './CallAnApi';
3
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/screenplay/abilities/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/screenplay/abilities/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
@@ -14,6 +14,5 @@ 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
- __exportStar(require("./AxiosRequestConfigDefaults"), exports);
18
17
  __exportStar(require("./CallAnApi"), exports);
19
18
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/screenplay/abilities/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+DAA6C;AAC7C,8CAA4B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/screenplay/abilities/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B"}
@@ -9,7 +9,7 @@ import { Interaction } from '@serenity-js/core';
9
9
  * ```ts
10
10
  * import { actorCalled } from '@serenity-js/core';
11
11
  * import { By Navigate, PageElement, Text } from '@serenity-js/web';
12
- * import { CallAnApi, ChangeApiConfig, GetRequest, LastResponse, Send } from '@serenity-js/rest'
12
+ * import { axiosCreate, CallAnApi, ChangeApiConfig, GetRequest, LastResponse, Send } from '@serenity-js/rest'
13
13
  * import { Ensure, equals } from '@serenity-js/assertions';
14
14
  *
15
15
  * import * as axios from 'axios';
@@ -25,7 +25,7 @@ import { Interaction } from '@serenity-js/core';
25
25
  * BrowseTheWeb.using(protractor.browser),
26
26
  *
27
27
  * // Note: no default base URL is given when the axios instance is created
28
- * CallAnApi.using(axios.create()),
28
+ * CallAnApi.using(axiosCreate()),
29
29
  * )
30
30
  * .attemptsTo(
31
31
  * Navigate.to('/profile'),
@@ -13,7 +13,7 @@ const abilities_1 = require("../abilities");
13
13
  * ```ts
14
14
  * import { actorCalled } from '@serenity-js/core';
15
15
  * import { By Navigate, PageElement, Text } from '@serenity-js/web';
16
- * import { CallAnApi, ChangeApiConfig, GetRequest, LastResponse, Send } from '@serenity-js/rest'
16
+ * import { axiosCreate, CallAnApi, ChangeApiConfig, GetRequest, LastResponse, Send } from '@serenity-js/rest'
17
17
  * import { Ensure, equals } from '@serenity-js/assertions';
18
18
  *
19
19
  * import * as axios from 'axios';
@@ -29,7 +29,7 @@ const abilities_1 = require("../abilities");
29
29
  * BrowseTheWeb.using(protractor.browser),
30
30
  *
31
31
  * // Note: no default base URL is given when the axios instance is created
32
- * CallAnApi.using(axios.create()),
32
+ * CallAnApi.using(axiosCreate()),
33
33
  * )
34
34
  * .attemptsTo(
35
35
  * Navigate.to('/profile'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serenity-js/rest",
3
- "version": "3.19.0",
3
+ "version": "3.20.0",
4
4
  "description": "Test REST APIs with Serenity/JS",
5
5
  "author": {
6
6
  "name": "Jan Molak",
@@ -46,7 +46,7 @@
46
46
  "node": "^16.13 || ^18.12 || ^20"
47
47
  },
48
48
  "dependencies": {
49
- "@serenity-js/core": "3.19.0",
49
+ "@serenity-js/core": "3.20.0",
50
50
  "agent-base": "7.1.0",
51
51
  "axios": "1.6.7",
52
52
  "http-proxy-agent": "7.0.2",
@@ -56,7 +56,7 @@
56
56
  },
57
57
  "devDependencies": {
58
58
  "@integration/testing-tools": "3.0.0",
59
- "@serenity-js/assertions": "3.19.0",
59
+ "@serenity-js/assertions": "3.20.0",
60
60
  "@types/chai": "4.3.12",
61
61
  "@types/mocha": "10.0.6",
62
62
  "axios-mock-adapter": "1.22.0",
@@ -66,5 +66,5 @@
66
66
  "ts-node": "10.9.2",
67
67
  "typescript": "5.2.2"
68
68
  },
69
- "gitHead": "6bc255b85d3e74d000b1584a64e460cc5adc1e23"
69
+ "gitHead": "2089afc60adb2751416fa6d800d4e7af95a99f25"
70
70
  }
package/src/index.ts CHANGED
@@ -1 +1,2 @@
1
+ export * from './io';
1
2
  export * from './screenplay';
@@ -0,0 +1,15 @@
1
+ import { type CreateAxiosDefaults } from 'axios';
2
+
3
+ export type AxiosRequestConfigProxyDefaults = {
4
+ host: string;
5
+ port?: number; // SOCKS proxies don't require port number
6
+ auth?: {
7
+ username: string;
8
+ password: string;
9
+ };
10
+ protocol?: string;
11
+ }
12
+
13
+ export type AxiosRequestConfigDefaults<Data = any> = Omit<CreateAxiosDefaults<Data>, 'proxy'> & {
14
+ proxy?: AxiosRequestConfigProxyDefaults | false;
15
+ }
@@ -0,0 +1,129 @@
1
+ import { ConfigurationError } from '@serenity-js/core';
2
+ import type { AgentConnectOpts } from 'agent-base';
3
+ import { Agent } from 'agent-base';
4
+ import * as http from 'http';
5
+ import { HttpProxyAgent, type HttpProxyAgentOptions } from 'http-proxy-agent';
6
+ import * as https from 'https';
7
+ import { HttpsProxyAgent, type HttpsProxyAgentOptions } from 'https-proxy-agent';
8
+ import { LRUCache } from 'lru-cache';
9
+ import { getProxyForUrl as envGetProxyForUrl } from 'proxy-from-env';
10
+
11
+ const protocols = [
12
+ ...HttpProxyAgent.protocols,
13
+ ] as const;
14
+
15
+ type AgentConstructor = new (proxy: URL | string, options?: ProxyAgentOptions) => Agent;
16
+
17
+ type ValidProtocol = (typeof protocols)[number];
18
+
19
+ type GetProxyForUrlCallback = (url: string) => string;
20
+
21
+ export type ProxyAgentOptions =
22
+ HttpProxyAgentOptions<''> &
23
+ HttpsProxyAgentOptions<''> & {
24
+ /**
25
+ * Default `http.Agent` instance to use when no proxy is
26
+ * configured for a request. Defaults to a new `http.Agent()`
27
+ * instance with the proxy agent options passed in.
28
+ */
29
+ httpAgent?: http.Agent;
30
+ /**
31
+ * Default `http.Agent` instance to use when no proxy is
32
+ * configured for a request. Defaults to a new `https.Agent()`
33
+ * instance with the proxy agent options passed in.
34
+ */
35
+ httpsAgent?: http.Agent;
36
+ /**
37
+ * A callback for dynamic provision of proxy for url.
38
+ * Defaults to standard proxy environment variables,
39
+ * see https://www.npmjs.com/package/proxy-from-env for details
40
+ */
41
+ getProxyForUrl?: GetProxyForUrlCallback;
42
+ };
43
+
44
+ /**
45
+ * A simplified version of the original
46
+ * [`ProxyAgent`](https://github.com/TooTallNate/proxy-agents/blob/5923589c2e5206504772c250ac4f20fc31122d3b/packages/proxy-agent/src/index.ts)
47
+ * with fewer dependencies.
48
+ *
49
+ * Delegates requests to the appropriate `Agent` subclass based on the "proxy"
50
+ * environment variables, or the provided `agentOptions.getProxyForUrl` callback.
51
+ *
52
+ * Uses an LRU cache to prevent unnecessary creation of proxy `http.Agent` instances.
53
+ */
54
+ export class ProxyAgent extends Agent {
55
+
56
+ private static proxyAgents: { [P in ValidProtocol]: [ AgentConstructor, AgentConstructor ] } = {
57
+ http: [ HttpProxyAgent, HttpsProxyAgent ],
58
+ https: [ HttpProxyAgent, HttpsProxyAgent ],
59
+ };
60
+
61
+ /**
62
+ * Cache for `Agent` instances.
63
+ */
64
+ private readonly cache = new LRUCache<string, Agent>({
65
+ max: 20,
66
+ dispose: (value: Agent, key: string) => value.destroy(),
67
+ });
68
+
69
+ private readonly httpAgent: http.Agent;
70
+ private readonly httpsAgent: http.Agent;
71
+ private readonly getProxyForUrl: GetProxyForUrlCallback;
72
+
73
+ constructor(private readonly agentOptions: ProxyAgentOptions) {
74
+ super(agentOptions);
75
+ this.httpAgent = agentOptions?.httpAgent || new http.Agent(agentOptions);
76
+ this.httpsAgent = agentOptions?.httpsAgent || new https.Agent(agentOptions as https.AgentOptions);
77
+ this.getProxyForUrl = agentOptions?.getProxyForUrl || envGetProxyForUrl;
78
+ }
79
+
80
+ override async connect(request: http.ClientRequest, options: AgentConnectOpts): Promise<http.Agent> {
81
+ const { secureEndpoint } = options;
82
+ const isWebSocket = request.getHeader('upgrade') === 'websocket';
83
+ const protocol = secureEndpoint
84
+ ? (isWebSocket ? 'wss:' : 'https:')
85
+ : (isWebSocket ? 'ws:' : 'http:');
86
+ const host = request.getHeader('host');
87
+ const url = new URL(request.path, `${protocol}//${host}`).href;
88
+ const proxy = this.getProxyForUrl(url);
89
+
90
+ if (! proxy) {
91
+ return secureEndpoint
92
+ ? this.httpsAgent
93
+ : this.httpAgent;
94
+ }
95
+
96
+ // attempt to get a cached `http.Agent` instance first
97
+ const cacheKey = `${ protocol }+${ proxy }`;
98
+ let agent = this.cache.get(cacheKey);
99
+ if (! agent) {
100
+ agent = this.createAgent(new URL(proxy), secureEndpoint || isWebSocket);
101
+
102
+ this.cache.set(cacheKey, agent);
103
+ }
104
+
105
+ return agent;
106
+ }
107
+
108
+ private createAgent(proxyUrl: URL, requiresTls: boolean): Agent {
109
+
110
+ const protocol = proxyUrl.protocol.replace(':', '');
111
+
112
+ if (! this.isValidProtocol(protocol)) {
113
+ throw new ConfigurationError(`Unsupported protocol for proxy URL: ${ proxyUrl }`);
114
+ }
115
+
116
+ const ctor = ProxyAgent.proxyAgents[protocol][requiresTls ? 1 : 0];
117
+
118
+ return new ctor(proxyUrl, this.agentOptions);
119
+ }
120
+
121
+ private isValidProtocol(v: string): v is ValidProtocol {
122
+ return (protocols as readonly string[]).includes(v);
123
+ }
124
+
125
+ override destroy(): void {
126
+ this.cache.clear();
127
+ super.destroy();
128
+ }
129
+ }
@@ -0,0 +1,39 @@
1
+ import type * as http from 'http';
2
+ import { ensure, isDefined } from 'tiny-types';
3
+
4
+ import type { AxiosRequestConfigDefaults } from './AxiosRequestConfigDefaults';
5
+ import { createUrl } from './createUrl';
6
+ import { ProxyAgent } from './ProxyAgent';
7
+
8
+ /**
9
+ * @param options
10
+ */
11
+ export function axiosProxyOverridesFor<Data = any>(options: AxiosRequestConfigDefaults<Data>): {
12
+ proxy: false, httpAgent: http.Agent, httpsAgent: http.Agent
13
+ } {
14
+ const envProxyOverride: string | false = options.proxy
15
+ && createUrl({
16
+ username: options.proxy?.auth?.username,
17
+ password: options.proxy?.auth?.password,
18
+ protocol: options.proxy?.protocol,
19
+ hostname: ensure('proxy.host', options.proxy?.host, isDefined()),
20
+ port: options.proxy?.port
21
+ }).toString();
22
+
23
+ const agent = new ProxyAgent({
24
+ httpAgent: options.httpAgent,
25
+ httpsAgent: options.httpsAgent,
26
+
27
+ // if there's a specific proxy override configured, use it
28
+ // if not - detect proxy automatically based on env variables
29
+ getProxyForUrl: envProxyOverride
30
+ ? (url_: string) => envProxyOverride
31
+ : undefined,
32
+ });
33
+
34
+ return {
35
+ proxy: false,
36
+ httpAgent: agent,
37
+ httpsAgent: agent,
38
+ };
39
+ }
@@ -0,0 +1,50 @@
1
+ import { Duration } from '@serenity-js/core';
2
+ import axios, { Axios, type AxiosInstance, type AxiosRequestConfig } from 'axios';
3
+
4
+ import { axiosProxyOverridesFor } from './axiosProxyOverridesFor';
5
+ import type { AxiosRequestConfigDefaults, AxiosRequestConfigProxyDefaults } from './AxiosRequestConfigDefaults';
6
+
7
+ /**
8
+ * Creates an Axios instance with desired configuration and proxy support.
9
+ *
10
+ * @param axiosInstanceOrConfig
11
+ */
12
+ export function createAxios(axiosInstanceOrConfig: AxiosInstance | AxiosRequestConfigDefaults = {}): AxiosInstance {
13
+ const axiosInstanceGiven = isAxiosInstance(axiosInstanceOrConfig);
14
+
15
+ const axiosInstance = axiosInstanceGiven
16
+ ? axiosInstanceOrConfig
17
+ : axios.create({
18
+ timeout: Duration.ofSeconds(10).inMilliseconds(),
19
+ ...omit(axiosInstanceOrConfig, 'proxy'),
20
+ });
21
+
22
+ const proxyConfig: AxiosRequestConfigProxyDefaults | false | undefined = axiosInstanceGiven
23
+ ? axiosInstanceOrConfig.defaults.proxy
24
+ : axiosInstanceOrConfig.proxy;
25
+
26
+ const proxyOverrides = axiosProxyOverridesFor({
27
+ ...axiosInstance.defaults,
28
+ proxy: proxyConfig || undefined,
29
+ });
30
+
31
+ return withOverrides(axiosInstance, proxyOverrides);
32
+ }
33
+
34
+ function isAxiosInstance(axiosInstanceOrConfig: any): axiosInstanceOrConfig is AxiosInstance {
35
+ return axiosInstanceOrConfig
36
+ && (axiosInstanceOrConfig instanceof Axios || axiosInstanceOrConfig.defaults);
37
+ }
38
+
39
+ function withOverrides<Data = any>(axiosInstance: AxiosInstance, overrides: AxiosRequestConfig<Data>): AxiosInstance {
40
+ for (const [key, override] of Object.entries(overrides)) {
41
+ axiosInstance.defaults[key] = override;
42
+ }
43
+
44
+ return axiosInstance;
45
+ }
46
+
47
+ function omit<T extends object, K extends keyof T>(record: T, key: K): Omit<T, K> {
48
+ const { [key]: omitted_, ...rest } = record;
49
+ return rest;
50
+ }
@@ -0,0 +1,39 @@
1
+ import { ensure, isDefined, isNotBlank, isString } from 'tiny-types';
2
+
3
+ export interface CreateUrlOptions {
4
+ protocol?: string;
5
+ hostname: string;
6
+ port?: string | number;
7
+ username?: string;
8
+ password?: string;
9
+ }
10
+
11
+ export function createUrl(options: CreateUrlOptions): URL {
12
+ const hostname = ensure('hostname', options?.hostname, isString(), isNotBlank()).trim();
13
+ const port = options?.port
14
+ ? ':' + options?.port
15
+ : (options?.protocol ? undefined : ':80');
16
+
17
+ return new URL([
18
+ options?.protocol && protocolFrom(options?.protocol),
19
+ (options?.username || options?.password) && credentialsFrom(options.username, options.password),
20
+ hostname,
21
+ port,
22
+ ].filter(Boolean).join(''));
23
+ }
24
+
25
+ function protocolFrom(protocol?: string): string {
26
+ const protocolName = protocol.match(/([A-Za-z]+)[/:]*/)[1];
27
+
28
+ ensure('hostname', protocolName, isDefined());
29
+
30
+ return protocolName + '://';
31
+ }
32
+
33
+ function credentialsFrom(username?: string, password?: string): string {
34
+ return [
35
+ username && encodeURIComponent(username),
36
+ password && ':' + encodeURIComponent(password),
37
+ '@'
38
+ ].filter(Boolean).join('');
39
+ }
@@ -0,0 +1,2 @@
1
+ export * from './AxiosRequestConfigDefaults';
2
+ export * from './createAxios';
@@ -1,16 +1,14 @@
1
- import { Ability, ConfigurationError, Duration, LogicError, TestCompromisedError } from '@serenity-js/core';
2
- import axios, {
3
- Axios,
1
+ import { Ability, ConfigurationError, LogicError, TestCompromisedError } from '@serenity-js/core';
2
+ import {
4
3
  type AxiosDefaults,
5
4
  type AxiosError,
6
5
  type AxiosInstance,
7
6
  type AxiosRequestConfig,
8
7
  type AxiosResponse,
9
- type CreateAxiosDefaults,
10
8
  } from 'axios';
11
9
 
12
- import type { AxiosRequestConfigDefaults, AxiosRequestConfigProxyDefaults } from './AxiosRequestConfigDefaults';
13
- import { axiosProxyOverridesFor } from './proxy';
10
+ import type { AxiosRequestConfigDefaults} from '../../io';
11
+ import { createAxios } from '../../io';
14
12
 
15
13
  /**
16
14
  * An {@apilink Ability} that wraps [axios client](https://axios-http.com/docs/api_intro) and enables
@@ -147,14 +145,13 @@ import { axiosProxyOverridesFor } from './proxy';
147
145
  *
148
146
  * ```ts
149
147
  * import { actorCalled } from '@serenity-js/core'
150
- * import { CallAnApi, GetRequest, LastResponse, Send } from '@serenity-js/rest'
148
+ * import { createAxios, CallAnApi, GetRequest, LastResponse, Send } from '@serenity-js/rest'
151
149
  * import { Ensure, equals } from '@serenity-js/assertions'
152
150
  *
153
- * import axios from 'axios'
154
151
  * import axiosRetry from 'axios-retry'
155
152
  *
156
- * const instance = axios.create({ baseURL 'https://api.example.org/' })
157
- * axiosRetry(axios, { retries: 3 })
153
+ * const instance = createAxios({ baseURL 'https://api.example.org/' })
154
+ * axiosRetry(instance, { retries: 3 })
158
155
  *
159
156
  * await actorCalled('Apisitt')
160
157
  * .whoCan(
@@ -177,11 +174,11 @@ import { axiosProxyOverridesFor } from './proxy';
177
174
  * import { CallAnApi, GetRequest, LastResponse, Send } from '@serenity-js/rest'
178
175
  * import { Ensure, equals } from '@serenity-js/assertions'
179
176
  *
180
- * import axios from 'axios'
177
+ * import { axiosCreate } from '@serenity-js/rest'
181
178
  * import axiosRetry from 'axios-retry'
182
179
  *
183
- * const instance = axios.create({ baseURL 'https://api.example.org/' })
184
- * axiosRetry(axios, { retries: 3 })
180
+ * const instance = axiosCreate({ baseURL 'https://api.example.org/' })
181
+ * axiosRetry(instance, { retries: 3 })
185
182
  *
186
183
  * await actorCalled('Apisitt')
187
184
  * .whoCan(
@@ -326,10 +323,6 @@ export class CallAnApi extends Ability {
326
323
 
327
324
  private lastResponse: AxiosResponse;
328
325
 
329
- private static readonly defaults: CreateAxiosDefaults<any> = {
330
- timeout: Duration.ofSeconds(10).inMilliseconds(),
331
- };
332
-
333
326
  /**
334
327
  * Produces an {@apilink Ability|ability} to call a REST API at a specified `baseURL`;
335
328
  *
@@ -363,26 +356,7 @@ export class CallAnApi extends Ability {
363
356
  * @param axiosInstanceOrConfig
364
357
  */
365
358
  static using(axiosInstanceOrConfig: AxiosInstance | AxiosRequestConfigDefaults): CallAnApi {
366
-
367
- const axiosInstanceGiven = isAxiosInstance(axiosInstanceOrConfig);
368
-
369
- const axiosInstance = axiosInstanceGiven
370
- ? axiosInstanceOrConfig
371
- : axios.create({
372
- ...CallAnApi.defaults,
373
- ...omit(axiosInstanceOrConfig, 'proxy'),
374
- });
375
-
376
- const proxyConfig: AxiosRequestConfigProxyDefaults | false | undefined = axiosInstanceGiven
377
- ? axiosInstanceOrConfig.defaults.proxy
378
- : axiosInstanceOrConfig.proxy;
379
-
380
- const proxyOverrides = axiosProxyOverridesFor({
381
- ...axiosInstance.defaults,
382
- proxy: proxyConfig || undefined,
383
- });
384
-
385
- return new CallAnApi(withOverrides(axiosInstance, proxyOverrides));
359
+ return new CallAnApi(createAxios(axiosInstanceOrConfig));
386
360
  }
387
361
 
388
362
  /**
@@ -488,21 +462,3 @@ export class CallAnApi extends Ability {
488
462
  return mappingFunction(this.lastResponse);
489
463
  }
490
464
  }
491
-
492
- function isAxiosInstance(axiosInstanceOrConfig: any): axiosInstanceOrConfig is AxiosInstance {
493
- return axiosInstanceOrConfig
494
- && (axiosInstanceOrConfig instanceof Axios || axiosInstanceOrConfig.defaults);
495
- }
496
-
497
- function withOverrides<Data = any>(axiosInstance: AxiosInstance, overrides: AxiosRequestConfig<Data>): AxiosInstance {
498
- for (const [key, override] of Object.entries(overrides)) {
499
- axiosInstance.defaults[key] = override;
500
- }
501
-
502
- return axiosInstance;
503
- }
504
-
505
- function omit<T extends object, K extends keyof T>(record: T, key: K): Omit<T, K> {
506
- const { [key]: omitted_, ...rest } = record;
507
- return rest;
508
- }
@@ -1,2 +1 @@
1
- export * from './AxiosRequestConfigDefaults';
2
1
  export * from './CallAnApi';
@@ -13,7 +13,7 @@ import { CallAnApi } from '../abilities';
13
13
  * ```ts
14
14
  * import { actorCalled } from '@serenity-js/core';
15
15
  * import { By Navigate, PageElement, Text } from '@serenity-js/web';
16
- * import { CallAnApi, ChangeApiConfig, GetRequest, LastResponse, Send } from '@serenity-js/rest'
16
+ * import { axiosCreate, CallAnApi, ChangeApiConfig, GetRequest, LastResponse, Send } from '@serenity-js/rest'
17
17
  * import { Ensure, equals } from '@serenity-js/assertions';
18
18
  *
19
19
  * import * as axios from 'axios';
@@ -29,7 +29,7 @@ import { CallAnApi } from '../abilities';
29
29
  * BrowseTheWeb.using(protractor.browser),
30
30
  *
31
31
  * // Note: no default base URL is given when the axios instance is created
32
- * CallAnApi.using(axios.create()),
32
+ * CallAnApi.using(axiosCreate()),
33
33
  * )
34
34
  * .attemptsTo(
35
35
  * Navigate.to('/profile'),