codeceptjs 4.0.0-beta.2 → 4.0.0-beta.21

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 (209) hide show
  1. package/README.md +133 -120
  2. package/bin/codecept.js +107 -96
  3. package/bin/test-server.js +64 -0
  4. package/docs/webapi/clearCookie.mustache +1 -1
  5. package/docs/webapi/click.mustache +5 -1
  6. package/lib/actor.js +73 -103
  7. package/lib/ai.js +159 -188
  8. package/lib/assert/empty.js +22 -24
  9. package/lib/assert/equal.js +30 -37
  10. package/lib/assert/error.js +14 -14
  11. package/lib/assert/include.js +43 -48
  12. package/lib/assert/throws.js +11 -11
  13. package/lib/assert/truth.js +22 -22
  14. package/lib/assert.js +20 -18
  15. package/lib/codecept.js +262 -162
  16. package/lib/colorUtils.js +50 -52
  17. package/lib/command/check.js +206 -0
  18. package/lib/command/configMigrate.js +56 -51
  19. package/lib/command/definitions.js +96 -109
  20. package/lib/command/dryRun.js +77 -79
  21. package/lib/command/generate.js +234 -194
  22. package/lib/command/gherkin/init.js +42 -33
  23. package/lib/command/gherkin/snippets.js +76 -74
  24. package/lib/command/gherkin/steps.js +20 -17
  25. package/lib/command/info.js +74 -38
  26. package/lib/command/init.js +301 -290
  27. package/lib/command/interactive.js +41 -32
  28. package/lib/command/list.js +28 -27
  29. package/lib/command/run-multiple/chunk.js +51 -48
  30. package/lib/command/run-multiple/collection.js +5 -5
  31. package/lib/command/run-multiple/run.js +5 -1
  32. package/lib/command/run-multiple.js +97 -97
  33. package/lib/command/run-rerun.js +19 -25
  34. package/lib/command/run-workers.js +68 -92
  35. package/lib/command/run.js +39 -27
  36. package/lib/command/utils.js +80 -64
  37. package/lib/command/workers/runTests.js +388 -226
  38. package/lib/config.js +109 -50
  39. package/lib/container.js +765 -261
  40. package/lib/data/context.js +60 -61
  41. package/lib/data/dataScenarioConfig.js +47 -47
  42. package/lib/data/dataTableArgument.js +32 -32
  43. package/lib/data/table.js +22 -22
  44. package/lib/effects.js +307 -0
  45. package/lib/element/WebElement.js +327 -0
  46. package/lib/els.js +160 -0
  47. package/lib/event.js +173 -163
  48. package/lib/globals.js +141 -0
  49. package/lib/heal.js +89 -85
  50. package/lib/helper/AI.js +131 -41
  51. package/lib/helper/ApiDataFactory.js +107 -75
  52. package/lib/helper/Appium.js +542 -404
  53. package/lib/helper/FileSystem.js +100 -79
  54. package/lib/helper/GraphQL.js +44 -43
  55. package/lib/helper/GraphQLDataFactory.js +52 -52
  56. package/lib/helper/JSONResponse.js +126 -88
  57. package/lib/helper/Mochawesome.js +54 -29
  58. package/lib/helper/Playwright.js +2547 -1316
  59. package/lib/helper/Puppeteer.js +1578 -1181
  60. package/lib/helper/REST.js +209 -68
  61. package/lib/helper/WebDriver.js +1482 -1342
  62. package/lib/helper/errors/ConnectionRefused.js +6 -6
  63. package/lib/helper/errors/ElementAssertion.js +11 -16
  64. package/lib/helper/errors/ElementNotFound.js +5 -9
  65. package/lib/helper/errors/RemoteBrowserConnectionRefused.js +5 -5
  66. package/lib/helper/extras/Console.js +11 -11
  67. package/lib/helper/extras/PlaywrightLocator.js +110 -0
  68. package/lib/helper/extras/PlaywrightPropEngine.js +18 -18
  69. package/lib/helper/extras/PlaywrightReactVueLocator.js +17 -8
  70. package/lib/helper/extras/PlaywrightRestartOpts.js +25 -11
  71. package/lib/helper/extras/Popup.js +22 -22
  72. package/lib/helper/extras/React.js +27 -28
  73. package/lib/helper/network/actions.js +36 -42
  74. package/lib/helper/network/utils.js +78 -84
  75. package/lib/helper/scripts/blurElement.js +5 -5
  76. package/lib/helper/scripts/focusElement.js +5 -5
  77. package/lib/helper/scripts/highlightElement.js +8 -8
  78. package/lib/helper/scripts/isElementClickable.js +34 -34
  79. package/lib/helper.js +2 -3
  80. package/lib/history.js +23 -19
  81. package/lib/hooks.js +8 -8
  82. package/lib/html.js +94 -104
  83. package/lib/index.js +38 -27
  84. package/lib/listener/config.js +30 -23
  85. package/lib/listener/emptyRun.js +54 -0
  86. package/lib/listener/enhancedGlobalRetry.js +110 -0
  87. package/lib/listener/exit.js +16 -18
  88. package/lib/listener/globalRetry.js +70 -0
  89. package/lib/listener/globalTimeout.js +181 -0
  90. package/lib/listener/helpers.js +76 -51
  91. package/lib/listener/mocha.js +10 -11
  92. package/lib/listener/result.js +11 -0
  93. package/lib/listener/retryEnhancer.js +85 -0
  94. package/lib/listener/steps.js +71 -59
  95. package/lib/listener/store.js +20 -0
  96. package/lib/locator.js +214 -197
  97. package/lib/mocha/asyncWrapper.js +274 -0
  98. package/lib/mocha/bdd.js +167 -0
  99. package/lib/mocha/cli.js +341 -0
  100. package/lib/mocha/factory.js +163 -0
  101. package/lib/mocha/featureConfig.js +89 -0
  102. package/lib/mocha/gherkin.js +231 -0
  103. package/lib/mocha/hooks.js +121 -0
  104. package/lib/mocha/index.js +21 -0
  105. package/lib/mocha/inject.js +46 -0
  106. package/lib/{interfaces → mocha}/scenarioConfig.js +58 -34
  107. package/lib/mocha/suite.js +89 -0
  108. package/lib/mocha/test.js +184 -0
  109. package/lib/mocha/types.d.ts +42 -0
  110. package/lib/mocha/ui.js +242 -0
  111. package/lib/output.js +141 -71
  112. package/lib/parser.js +54 -44
  113. package/lib/pause.js +173 -145
  114. package/lib/plugin/analyze.js +403 -0
  115. package/lib/plugin/{autoLogin.js → auth.js} +178 -79
  116. package/lib/plugin/autoDelay.js +36 -40
  117. package/lib/plugin/coverage.js +131 -78
  118. package/lib/plugin/customLocator.js +22 -21
  119. package/lib/plugin/customReporter.js +53 -0
  120. package/lib/plugin/enhancedRetryFailedStep.js +99 -0
  121. package/lib/plugin/heal.js +101 -110
  122. package/lib/plugin/htmlReporter.js +3648 -0
  123. package/lib/plugin/pageInfo.js +140 -0
  124. package/lib/plugin/pauseOnFail.js +12 -11
  125. package/lib/plugin/retryFailedStep.js +82 -47
  126. package/lib/plugin/screenshotOnFail.js +111 -92
  127. package/lib/plugin/stepByStepReport.js +159 -101
  128. package/lib/plugin/stepTimeout.js +20 -25
  129. package/lib/plugin/subtitles.js +38 -38
  130. package/lib/recorder.js +193 -130
  131. package/lib/rerun.js +94 -49
  132. package/lib/result.js +238 -0
  133. package/lib/retryCoordinator.js +207 -0
  134. package/lib/secret.js +20 -18
  135. package/lib/session.js +95 -89
  136. package/lib/step/base.js +239 -0
  137. package/lib/step/comment.js +10 -0
  138. package/lib/step/config.js +50 -0
  139. package/lib/step/func.js +46 -0
  140. package/lib/step/helper.js +50 -0
  141. package/lib/step/meta.js +99 -0
  142. package/lib/step/record.js +74 -0
  143. package/lib/step/retry.js +11 -0
  144. package/lib/step/section.js +55 -0
  145. package/lib/step.js +18 -329
  146. package/lib/steps.js +54 -0
  147. package/lib/store.js +38 -7
  148. package/lib/template/heal.js +3 -12
  149. package/lib/template/prompts/generatePageObject.js +31 -0
  150. package/lib/template/prompts/healStep.js +13 -0
  151. package/lib/template/prompts/writeStep.js +9 -0
  152. package/lib/test-server.js +334 -0
  153. package/lib/timeout.js +60 -0
  154. package/lib/transform.js +8 -8
  155. package/lib/translation.js +34 -21
  156. package/lib/utils/loaderCheck.js +124 -0
  157. package/lib/utils/mask_data.js +47 -0
  158. package/lib/utils/typescript.js +237 -0
  159. package/lib/utils.js +411 -228
  160. package/lib/workerStorage.js +37 -34
  161. package/lib/workers.js +532 -296
  162. package/package.json +124 -95
  163. package/translations/de-DE.js +5 -3
  164. package/translations/fr-FR.js +5 -4
  165. package/translations/index.js +22 -12
  166. package/translations/it-IT.js +4 -3
  167. package/translations/ja-JP.js +4 -3
  168. package/translations/nl-NL.js +76 -0
  169. package/translations/pl-PL.js +4 -3
  170. package/translations/pt-BR.js +4 -3
  171. package/translations/ru-RU.js +4 -3
  172. package/translations/utils.js +10 -0
  173. package/translations/zh-CN.js +4 -3
  174. package/translations/zh-TW.js +4 -3
  175. package/typings/index.d.ts +546 -185
  176. package/typings/promiseBasedTypes.d.ts +150 -875
  177. package/typings/types.d.ts +547 -992
  178. package/lib/cli.js +0 -249
  179. package/lib/dirname.js +0 -5
  180. package/lib/helper/Expect.js +0 -425
  181. package/lib/helper/ExpectHelper.js +0 -399
  182. package/lib/helper/MockServer.js +0 -223
  183. package/lib/helper/Nightmare.js +0 -1411
  184. package/lib/helper/Protractor.js +0 -1835
  185. package/lib/helper/SoftExpectHelper.js +0 -381
  186. package/lib/helper/TestCafe.js +0 -1410
  187. package/lib/helper/clientscripts/nightmare.js +0 -213
  188. package/lib/helper/testcafe/testControllerHolder.js +0 -42
  189. package/lib/helper/testcafe/testcafe-utils.js +0 -63
  190. package/lib/interfaces/bdd.js +0 -98
  191. package/lib/interfaces/featureConfig.js +0 -69
  192. package/lib/interfaces/gherkin.js +0 -195
  193. package/lib/listener/artifacts.js +0 -19
  194. package/lib/listener/retry.js +0 -68
  195. package/lib/listener/timeout.js +0 -109
  196. package/lib/mochaFactory.js +0 -110
  197. package/lib/plugin/allure.js +0 -15
  198. package/lib/plugin/commentStep.js +0 -136
  199. package/lib/plugin/debugErrors.js +0 -67
  200. package/lib/plugin/eachElement.js +0 -127
  201. package/lib/plugin/fakerTransform.js +0 -49
  202. package/lib/plugin/retryTo.js +0 -121
  203. package/lib/plugin/selenoid.js +0 -371
  204. package/lib/plugin/standardActingHelpers.js +0 -9
  205. package/lib/plugin/tryTo.js +0 -105
  206. package/lib/plugin/wdio.js +0 -246
  207. package/lib/scenario.js +0 -222
  208. package/lib/ui.js +0 -238
  209. package/lib/within.js +0 -70
@@ -1,8 +1,8 @@
1
- import { default as axios } from 'axios';
2
- import Helper from '@codeceptjs/helper';
3
- import Secret from '../secret.js';
4
- import { beautify } from '../utils.js';
5
- import { output } from '../output.js';
1
+ import axios from 'axios'
2
+ import Helper from '@codeceptjs/helper'
3
+ import { Agent } from 'https'
4
+ import Secret from '../secret.js'
5
+ import { beautify } from '../utils.js'
6
6
 
7
7
  /**
8
8
  * ## Configuration
@@ -10,14 +10,16 @@ import { output } from '../output.js';
10
10
  * @typedef RESTConfig
11
11
  * @type {object}
12
12
  * @prop {string} [endpoint] - API base URL
13
- * @prop {boolean} [prettyPrintJson=false] - pretty print json for response/request on console logs
14
- * @prop {number} [timeout=1000] - timeout for requests in milliseconds. 10000ms by default
15
- * @prop {object} [defaultHeaders] - a list of default headers
16
- * @prop {function} [onRequest] - a async function which can update request object.
17
- * @prop {function} [onResponse] - a async function which can update response object.
13
+ * @prop {boolean} [prettyPrintJson=false] - pretty print json for response/request on console logs.
14
+ * @prop {boolean} [printCurl=false] - print cURL request on console logs. False by default.
15
+ * @prop {number} [timeout=1000] - timeout for requests in milliseconds. 10000ms by default.
16
+ * @prop {object} [defaultHeaders] - a list of default headers.
17
+ * @prop {object} [httpAgent] - create an agent with SSL certificate
18
+ * @prop {function} [onRequest] - an async function which can update request object.
19
+ * @prop {function} [onResponse] - an async function which can update response object.
18
20
  * @prop {number} [maxUploadFileSize] - set the max content file size in MB when performing api calls.
19
21
  */
20
- const config = {};
22
+ const config = {}
21
23
 
22
24
  /**
23
25
  * REST helper allows to send additional requests to the REST API during acceptance tests.
@@ -41,6 +43,41 @@ const config = {};
41
43
  *}
42
44
  * ```
43
45
  *
46
+ * With httpAgent
47
+ *
48
+ * ```js
49
+ * {
50
+ * helpers: {
51
+ * REST: {
52
+ * endpoint: 'http://site.com/api',
53
+ * prettyPrintJson: true,
54
+ * httpAgent: {
55
+ * key: fs.readFileSync(__dirname + '/path/to/keyfile.key'),
56
+ * cert: fs.readFileSync(__dirname + '/path/to/certfile.cert'),
57
+ * rejectUnauthorized: false,
58
+ * keepAlive: true
59
+ * }
60
+ * }
61
+ * }
62
+ * }
63
+ * ```
64
+ *
65
+ * ```js
66
+ * {
67
+ * helpers: {
68
+ * REST: {
69
+ * endpoint: 'http://site.com/api',
70
+ * prettyPrintJson: true,
71
+ * httpAgent: {
72
+ * ca: fs.readFileSync(__dirname + '/path/to/ca.pem'),
73
+ * rejectUnauthorized: false,
74
+ * keepAlive: true
75
+ * }
76
+ * }
77
+ * }
78
+ * }
79
+ * ```
80
+ *
44
81
  * ## Access From Helpers
45
82
  *
46
83
  * Send REST requests by accessing `_executeRequest` method:
@@ -56,7 +93,7 @@ const config = {};
56
93
  */
57
94
  class REST extends Helper {
58
95
  constructor(config) {
59
- super(config);
96
+ super(config)
60
97
  this.options = {
61
98
  timeout: 10000,
62
99
  defaultHeaders: {},
@@ -64,39 +101,57 @@ class REST extends Helper {
64
101
  prettyPrintJson: false,
65
102
  onRequest: null,
66
103
  onResponse: null,
67
- };
104
+ }
68
105
 
69
106
  if (this.options.maxContentLength) {
70
- const maxContentLength = this.options.maxUploadFileSize * 1024 * 1024;
71
- this.options.maxContentLength = maxContentLength;
72
- this.options.maxBodyLength = maxContentLength;
107
+ const maxContentLength = this.options.maxUploadFileSize * 1024 * 1024
108
+ this.options.maxContentLength = maxContentLength
109
+ this.options.maxBodyLength = maxContentLength
73
110
  }
74
111
 
75
112
  // override defaults with config
76
- this._setConfig(config);
113
+ this._setConfig(config)
114
+
115
+ this.headers = { ...this.options.defaultHeaders }
116
+
117
+ // Create an agent with SSL certificate
118
+ if (this.options.httpAgent) {
119
+ // if one of those keys is there, all good to go
120
+ if (this.options.httpAgent.ca || this.options.httpAgent.key || this.options.httpAgent.cert) {
121
+ this.httpsAgent = new Agent(this.options.httpAgent)
122
+ } else {
123
+ // otherwise, throws an error of httpAgent config
124
+ throw Error('Please recheck your httpAgent config!')
125
+ }
126
+ }
77
127
 
78
- this.headers = { ...this.options.defaultHeaders };
79
- this.axios = axios.create();
128
+ this.axios = this.httpsAgent ? axios.create({ httpsAgent: this.httpsAgent }) : axios.create()
80
129
  // @ts-ignore
81
- this.axios.defaults.headers = this.options.defaultHeaders;
130
+ this.axios.defaults.headers = this.options.defaultHeaders
82
131
  }
83
132
 
84
133
  static _config() {
85
134
  return [
86
- { name: 'endpoint', message: 'Endpoint of API you are going to test', default: 'http://localhost:3000/api' },
87
- ];
135
+ {
136
+ name: 'endpoint',
137
+ message: 'Endpoint of API you are going to test',
138
+ default: 'http://localhost:3000/api',
139
+ },
140
+ ]
88
141
  }
89
142
 
90
143
  static _checkRequirements() {
91
144
  try {
92
- require('axios');
145
+ // In ESM, axios is already imported at the top, so no need to check
146
+ // The import will fail at module load time if axios is missing
147
+ return null
93
148
  } catch (e) {
94
- return ['axios'];
149
+ return ['axios']
95
150
  }
96
151
  }
97
152
 
98
153
  _before() {
99
- this.headers = { ...this.options.defaultHeaders };
154
+ this.headers = { ...this.options.defaultHeaders }
100
155
  }
101
156
 
102
157
  /**
@@ -105,7 +160,7 @@ class REST extends Helper {
105
160
  * @param {object} headers headers list
106
161
  */
107
162
  haveRequestHeaders(headers) {
108
- this.headers = { ...this.headers, ...headers };
163
+ this.headers = { ...this.headers, ...headers }
109
164
  }
110
165
 
111
166
  /**
@@ -119,7 +174,7 @@ class REST extends Helper {
119
174
  * @param {string | CodeceptJS.Secret} accessToken Bearer access token
120
175
  */
121
176
  amBearerAuthenticated(accessToken) {
122
- this.haveRequestHeaders({ Authorization: `Bearer ${accessToken}` });
177
+ this.haveRequestHeaders({ Authorization: `Bearer ${accessToken}` })
123
178
  }
124
179
 
125
180
  /**
@@ -131,54 +186,74 @@ class REST extends Helper {
131
186
  */
132
187
  async _executeRequest(request) {
133
188
  // Add custom headers. They can be set by amBearerAuthenticated() or haveRequestHeaders()
134
- request.headers = { ...this.headers, ...request.headers };
189
+ request.headers = { ...this.headers, ...request.headers }
135
190
 
136
- const _debugRequest = { ...request };
137
- this.axios.defaults.timeout = request.timeout || this.options.timeout;
191
+ const _debugRequest = { ...request }
192
+ this.axios.defaults.timeout = request.timeout || this.options.timeout
138
193
 
139
194
  if (this.headers && this.headers.auth) {
140
- request.auth = this.headers.auth;
195
+ request.auth = this.headers.auth
141
196
  }
142
197
 
143
198
  if (typeof request.data === 'object') {
144
- const returnedValue = {};
199
+ const returnedValue = {}
145
200
  for (const [key, value] of Object.entries(request.data)) {
146
- returnedValue[key] = value;
147
- if (value instanceof Secret) returnedValue[key] = value.getMasked();
201
+ returnedValue[key] = value
202
+ if (value instanceof Secret) returnedValue[key] = value.getMasked()
148
203
  }
149
- _debugRequest.data = returnedValue;
204
+ _debugRequest.data = returnedValue
150
205
  }
151
206
 
152
207
  if (request.data instanceof Secret) {
153
- _debugRequest.data = '*****';
154
- request.data = (typeof request.data === 'object' && !(request.data instanceof Secret)) ? { ...request.data.toString() } : request.data.toString();
208
+ _debugRequest.data = '*****'
209
+ request.data = typeof request.data === 'object' && !(request.data instanceof Secret) ? { ...request.data.toString() } : request.data.toString()
155
210
  }
156
211
 
157
- if ((typeof request.data) === 'string') {
212
+ if (typeof request.data === 'string') {
158
213
  if (!request.headers || !request.headers['Content-Type']) {
159
- request.headers = { ...request.headers, ...{ 'Content-Type': 'application/x-www-form-urlencoded' } };
214
+ request.headers = { ...request.headers, ...{ 'Content-Type': 'application/x-www-form-urlencoded' } }
160
215
  }
161
216
  }
162
217
 
163
218
  if (this.config.onRequest) {
164
- await this.config.onRequest(request);
219
+ await this.config.onRequest(request)
165
220
  }
166
221
 
167
- this.options.prettyPrintJson ? output.debugSection('Request', beautify(JSON.stringify(_debugRequest))) : output.debugSection('Request', JSON.stringify(_debugRequest));
222
+ try {
223
+ this.options.prettyPrintJson ? this.debugSection('Request', beautify(JSON.stringify(_debugRequest))) : this.debugSection('Request', JSON.stringify(_debugRequest))
224
+ } catch (e) {
225
+ console.log('[REST] Request:', JSON.stringify(_debugRequest))
226
+ }
168
227
 
169
- let response;
228
+ if (this.options.printCurl) {
229
+ try {
230
+ this.debugSection('CURL Request', curlize(request))
231
+ } catch (e) {
232
+ console.log('[REST] CURL Request:', curlize(request))
233
+ }
234
+ }
235
+
236
+ let response
170
237
  try {
171
- response = await this.axios(request);
238
+ response = await this.axios(request)
172
239
  } catch (err) {
173
- if (!err.response) throw err;
174
- output.debugSection('Response', `Response error. Status code: ${err.response.status}`);
175
- response = err.response;
240
+ if (!err.response) throw err
241
+ try {
242
+ this.debugSection('Response', `Response error. Status code: ${err.response.status}`)
243
+ } catch (e) {
244
+ console.log('[REST] Response error. Status code:', err.response.status)
245
+ }
246
+ response = err.response
176
247
  }
177
248
  if (this.config.onResponse) {
178
- await this.config.onResponse(response);
249
+ await this.config.onResponse(response)
179
250
  }
180
- this.options.prettyPrintJson ? output.debugSection('Response', beautify(JSON.stringify(response.data))) : output.debugSection('Response', JSON.stringify(response.data));
181
- return response;
251
+ try {
252
+ this.options.prettyPrintJson ? this.debugSection('Response', beautify(JSON.stringify(response.data))) : this.debugSection('Response', JSON.stringify(response.data))
253
+ } catch (e) {
254
+ console.log('[REST] Response:', JSON.stringify(response.data))
255
+ }
256
+ return response
182
257
  }
183
258
 
184
259
  /**
@@ -187,7 +262,7 @@ class REST extends Helper {
187
262
  * @param {*} url
188
263
  */
189
264
  _url(url) {
190
- return /^\w+\:\/\//.test(url) ? url : this.options.endpoint + url;
265
+ return /^\w+\:\/\//.test(url) ? url : this.options.endpoint + url
191
266
  }
192
267
 
193
268
  /**
@@ -200,7 +275,7 @@ class REST extends Helper {
200
275
  * @param {number} newTimeout - timeout in milliseconds
201
276
  */
202
277
  setRequestTimeout(newTimeout) {
203
- this.options.timeout = newTimeout;
278
+ this.options.timeout = newTimeout
204
279
  }
205
280
 
206
281
  /**
@@ -219,8 +294,29 @@ class REST extends Helper {
219
294
  const request = {
220
295
  baseURL: this._url(url),
221
296
  headers,
222
- };
223
- return this._executeRequest(request);
297
+ }
298
+ return this._executeRequest(request)
299
+ }
300
+
301
+ /**
302
+ * Send HEAD request to REST API
303
+ *
304
+ * ```js
305
+ * I.sendHeadRequest('/api/users.json');
306
+ * ```
307
+ *
308
+ * @param {*} url
309
+ * @param {object} [headers={}] - the headers object to be sent. By default, it is sent as an empty object
310
+ *
311
+ * @returns {Promise<*>} response
312
+ */
313
+ async sendHeadRequest(url, headers = {}) {
314
+ const request = {
315
+ baseURL: this._url(url),
316
+ method: 'HEAD',
317
+ headers,
318
+ }
319
+ return this._executeRequest(request)
224
320
  }
225
321
 
226
322
  /**
@@ -246,14 +342,14 @@ class REST extends Helper {
246
342
  method: 'POST',
247
343
  data: payload,
248
344
  headers,
249
- };
345
+ }
250
346
 
251
347
  if (this.options.maxContentLength) {
252
- request.maxContentLength = this.options.maxContentLength;
253
- request.maxBodyLength = this.options.maxContentLength;
348
+ request.maxContentLength = this.options.maxContentLength
349
+ request.maxBodyLength = this.options.maxContentLength
254
350
  }
255
351
 
256
- return this._executeRequest(request);
352
+ return this._executeRequest(request)
257
353
  }
258
354
 
259
355
  /**
@@ -279,14 +375,14 @@ class REST extends Helper {
279
375
  method: 'PATCH',
280
376
  data: payload,
281
377
  headers,
282
- };
378
+ }
283
379
 
284
380
  if (this.options.maxContentLength) {
285
- request.maxContentLength = this.options.maxContentLength;
286
- request.maxBodyLength = this.options.maxBodyLength;
381
+ request.maxContentLength = this.options.maxContentLength
382
+ request.maxBodyLength = this.options.maxBodyLength
287
383
  }
288
384
 
289
- return this._executeRequest(request);
385
+ return this._executeRequest(request)
290
386
  }
291
387
 
292
388
  /**
@@ -312,14 +408,14 @@ class REST extends Helper {
312
408
  method: 'PUT',
313
409
  data: payload,
314
410
  headers,
315
- };
411
+ }
316
412
 
317
413
  if (this.options.maxContentLength) {
318
- request.maxContentLength = this.options.maxContentLength;
319
- request.maxBodyLength = this.options.maxBodyLength;
414
+ request.maxContentLength = this.options.maxContentLength
415
+ request.maxBodyLength = this.options.maxBodyLength
320
416
  }
321
417
 
322
- return this._executeRequest(request);
418
+ return this._executeRequest(request)
323
419
  }
324
420
 
325
421
  /**
@@ -339,9 +435,54 @@ class REST extends Helper {
339
435
  baseURL: this._url(url),
340
436
  method: 'DELETE',
341
437
  headers,
342
- };
438
+ }
439
+
440
+ return this._executeRequest(request)
441
+ }
442
+
443
+ /**
444
+ * Sends DELETE request to API with payload.
445
+ *
446
+ * ```js
447
+ * I.sendDeleteRequestWithPayload('/api/users/1', { author: 'john' });
448
+ * ```
449
+ *
450
+ * @param {*} url
451
+ * @param {*} [payload={}] - the payload to be sent. By default it is sent as an empty object
452
+ * @param {object} [headers={}] - the headers object to be sent. By default, it is sent as an empty object
453
+ *
454
+ * @returns {Promise<*>} response
455
+ */
456
+ async sendDeleteRequestWithPayload(url, payload = {}, headers = {}) {
457
+ const request = {
458
+ baseURL: this._url(url),
459
+ method: 'DELETE',
460
+ data: payload,
461
+ headers,
462
+ }
463
+
464
+ return this._executeRequest(request)
465
+ }
466
+ }
467
+
468
+ export { REST as default }
469
+
470
+ function curlize(request) {
471
+ if (request.data?.constructor.name.toLowerCase() === 'formdata') return 'cURL is not printed as the request body is not a JSON'
472
+ let curl = `curl --location --request ${request.method ? request.method.toUpperCase() : 'GET'} ${request.baseURL} `.replace("'", '')
473
+
474
+ if (request.headers) {
475
+ Object.entries(request.headers).forEach(([key, value]) => {
476
+ curl += `-H "${key}: ${value}" `
477
+ })
478
+ }
479
+
480
+ if (!curl.toLowerCase().includes('content-type: application/json')) {
481
+ curl += '-H "Content-Type: application/json" '
482
+ }
343
483
 
344
- return this._executeRequest(request);
484
+ if (request.data) {
485
+ curl += `-d '${JSON.stringify(request.data)}'`
345
486
  }
487
+ return curl
346
488
  }
347
- export default REST;