@goast/typescript 0.3.8-beta1 → 0.3.9

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.
@@ -1,411 +1,411 @@
1
- // @ts-check
2
-
3
- import http from 'k6/http';
4
-
5
- /**
6
- * Defines the options for appending a parameter
7
- * @typedef {object} ParameterOptions
8
- * @property {string} [style]
9
- * @property {boolean} [explode]
10
- */
11
-
12
- /**
13
- * Base class for a parameter
14
- * @abstract
15
- * @property {string} name
16
- * @property {*} value
17
- * @property {ParameterOptions} options
18
- */
19
- class Parameter {
20
- /**
21
- * @param {string} name
22
- * @param {*} value
23
- * @param {ParameterOptions} options
24
- * @param {string} defaultStyle
25
- * @param {boolean} defaultExplode
26
- */
27
- constructor(name, value, options, defaultStyle, defaultExplode) {
28
- this.name = name;
29
- this.value = value;
30
- this.options = options || {};
31
- if (this.options.style === null || this.options.style === undefined) {
32
- this.options.style = defaultStyle;
33
- }
34
- if (this.options.explode === null || this.options.explode === undefined) {
35
- this.options.explode = defaultExplode;
36
- }
37
- }
38
-
39
- /**
40
- * @param {*} value
41
- * @param {string} separator
42
- * @returns {string}
43
- */
44
- serializeValue(value, separator = ',') {
45
- if (value === null || value === undefined) {
46
- return '';
47
- } else if (value instanceof Array) {
48
- return value
49
- .map((v) => this.serializeValue(v).split(separator).join(encodeURIComponent(separator)))
50
- .join(separator);
51
- } else if (typeof value === 'object') {
52
- /** @type {string[]} */
53
- const array = [];
54
- for (const key of Object.keys(value)) {
55
- let propVal = value[key];
56
- if (propVal !== null && propVal !== undefined) {
57
- propVal = this.serializeValue(propVal).split(separator).join(encodeURIComponent(separator));
58
- if (this.options.explode) {
59
- array.push(`${key}=${propVal}`);
60
- } else {
61
- array.push(key);
62
- array.push(propVal);
63
- }
64
- }
65
- }
66
- return array.join(separator);
67
- } else {
68
- return String(value);
69
- }
70
- }
71
- }
72
-
73
- /**
74
- * A parameter in the operation path
75
- * @param {string} name
76
- * @param {*} value
77
- * @param {ParameterOptions} options
78
- */
79
- class PathParameter extends Parameter {
80
- /**
81
- * @param {string} name
82
- * @param {*} value
83
- * @param {ParameterOptions} options
84
- */
85
- constructor(name, value, options) {
86
- super(name, value, options, 'simple', false);
87
- }
88
-
89
- /**
90
- * @param {string} path
91
- * @returns {string}
92
- */
93
- append(path) {
94
- let value = this.value;
95
- if (value === null || value === undefined) {
96
- value = '';
97
- }
98
- let prefix = this.options.style === 'label' ? '.' : '';
99
- const separator = this.options.explode ? (prefix === '' ? ',' : prefix) : ',';
100
- let alreadySerialized = false;
101
- if (this.options.style === 'matrix') {
102
- // The parameter name is just used as prefix, except in some cases...
103
- prefix = `;${this.name}=`;
104
- if (this.options.explode && typeof value === 'object') {
105
- prefix = ';';
106
- if (value instanceof Array) {
107
- // For arrays we have to repeat the name for each element
108
- value = value.map((v) => `${this.name}=${this.serializeValue(v, ';')}`);
109
- value = value.join(';');
110
- alreadySerialized = true;
111
- } else {
112
- // For objects we have to put each the key / value pairs
113
- value = this.serializeValue(value, ';');
114
- alreadySerialized = true;
115
- }
116
- }
117
- }
118
- value = prefix + (alreadySerialized ? value : this.serializeValue(value, separator));
119
- // Replace both the plain variable and the corresponding variant taking in the prefix and explode into account
120
- path = path.replace(`{${this.name}}`, value);
121
- path = path.replace(`{${prefix}${this.name}${this.options.explode ? '*' : ''}}`, value);
122
- return path;
123
- }
124
-
125
- /**
126
- * @param {*} value
127
- * @param {string} separator
128
- * @returns {string}
129
- */
130
- serializeValue(value, separator = ',') {
131
- let result = typeof value === 'string' ? encodeURIComponent(value) : super.serializeValue(value, separator);
132
- result = result.replace(/%3D/g, '=');
133
- result = result.replace(/%3B/g, ';');
134
- result = result.replace(/%2C/g, ',');
135
- return result;
136
- }
137
- }
138
-
139
- /**
140
- * A parameter in the query
141
- * @param {string} name
142
- * @param {*} value
143
- * @param {ParameterOptions} options
144
- */
145
- class QueryParameter extends Parameter {
146
- /**
147
- * @param {string} name
148
- * @param {*} value
149
- * @param {ParameterOptions} options
150
- */
151
- constructor(name, value, options) {
152
- super(name, value, options, 'form', true);
153
- }
154
-
155
- /**
156
- * @param {string} params
157
- * @returns {string}
158
- */
159
- append(params) {
160
- if (this.value instanceof Array) {
161
- // Array serialization
162
- if (this.options.explode) {
163
- for (const v of this.value) {
164
- params = `${params}${params ? '&' : '?'}${encodeURIComponent(this.name)}=${this.serializeValue(v)}`;
165
- }
166
- } else {
167
- const separator =
168
- this.options.style === 'spaceDelimited' ? ' ' : this.options.style === 'pipeDelimited' ? '|' : ',';
169
- return `${params}${params ? '&' : '?'}${encodeURIComponent(this.name)}=${this.serializeValue(this.value, separator)}`;
170
- }
171
- } else if (this.value !== null && typeof this.value === 'object') {
172
- // Object serialization
173
- if (this.options.style === 'deepObject') {
174
- // Append a parameter for each key, in the form `name[key]`
175
- for (const key of Object.keys(this.value)) {
176
- const propVal = this.value[key];
177
- if (propVal !== null && propVal !== undefined) {
178
- params = `${params}${params ? '&' : '?'}${encodeURIComponent(this.name)}[${encodeURIComponent(
179
- key,
180
- )}]=${this.serializeValue(propVal)}`;
181
- }
182
- }
183
- } else if (this.options.explode) {
184
- // Append a parameter for each key without using the parameter name
185
- for (const key of Object.keys(this.value)) {
186
- const propVal = this.value[key];
187
- if (propVal !== null && propVal !== undefined) {
188
- params = `${params}${params ? '&' : '?'}${encodeURIComponent(key)}=${this.serializeValue(propVal)}`;
189
- }
190
- }
191
- } else {
192
- // Append a single parameter whose values are a comma-separated list of key,value,key,value...
193
- const array = [];
194
- for (const key of Object.keys(this.value)) {
195
- const propVal = this.value[key];
196
- if (propVal !== null && propVal !== undefined) {
197
- array.push(key);
198
- array.push(propVal);
199
- }
200
- }
201
- params = `${params}${params ? '&' : '?'}${encodeURIComponent(this.name)}=${this.serializeValue(array)}`;
202
- }
203
- } else if (this.value !== null && this.value !== undefined) {
204
- // Plain value
205
- params = `${params}${params ? '&' : '?'}${encodeURIComponent(this.name)}=${this.serializeValue(this.value)}`;
206
- }
207
- return params;
208
- }
209
- }
210
-
211
- /**
212
- * A parameter in the HTTP request header
213
- */
214
- class HeaderParameter extends Parameter {
215
- /**
216
- * @param {string} name
217
- * @param {*} value
218
- * @param {ParameterOptions} options
219
- */
220
- constructor(name, value, options) {
221
- super(name, value, options, 'simple', false);
222
- }
223
-
224
- /**
225
- * @param {Object.<string, string>} headers
226
- * @returns {Object.<string, string>}
227
- */
228
- append(headers) {
229
- if (this.value !== null && this.value !== undefined) {
230
- if (this.value instanceof Array) {
231
- throw new Error('Array header values are not supported');
232
- } else {
233
- headers[this.name] = this.serializeValue(this.value);
234
- }
235
- }
236
- return headers;
237
- }
238
- }
239
-
240
- /**
241
- * Helper to build http requests from parameters
242
- * @property {string} rootUrl
243
- * @property {string} operationPath
244
- * @property {string} method
245
- */
246
- export class RequestBuilder {
247
- /**
248
- * @param {string} rootUrl
249
- * @param {string} operationPath
250
- * @param {string} method
251
- */
252
- constructor(rootUrl, operationPath, method) {
253
- this.rootUrl = rootUrl;
254
- this.operationPath = operationPath;
255
- this.method = method;
256
- this._path = new Map();
257
- this._query = new Map();
258
- this._header = new Map();
259
- this._bodyContent = null;
260
- this._bodyContentType = undefined;
261
- }
262
-
263
- /**
264
- * Sets a path parameter
265
- * @param {string} name
266
- * @param {*} value
267
- * @param {ParameterOptions} [options]
268
- */
269
- path(name, value, options) {
270
- this._path.set(name, new PathParameter(name, value, options || {}));
271
- }
272
-
273
- /**
274
- * Sets a query parameter
275
- * @param {string} name
276
- * @param {*} value
277
- * @param {ParameterOptions} [options]
278
- */
279
- query(name, value, options) {
280
- this._query.set(name, new QueryParameter(name, value, options || {}));
281
- }
282
-
283
- /**
284
- * Sets a header parameter
285
- * @param {string} name
286
- * @param {*} value
287
- * @param {ParameterOptions} [options]
288
- */
289
- header(name, value, options) {
290
- this._header.set(name, new HeaderParameter(name, value, options || {}));
291
- }
292
-
293
- /**
294
- * Sets the body content, along with the content type
295
- * @param {*} value
296
- * @param {string} [contentType]
297
- */
298
- body(value, contentType = 'application/json') {
299
- this._bodyContentType = contentType;
300
- if (this._bodyContentType === 'application/x-www-form-urlencoded' && value !== null && typeof value === 'object') {
301
- // Handle URL-encoded data
302
- /** @type {[string, string][]} */
303
- const pairs = [];
304
- for (const key of Object.keys(value)) {
305
- let val = value[key];
306
- if (!(val instanceof Array)) {
307
- val = [val];
308
- }
309
- for (const v of val) {
310
- const formValue = this.formDataValue(v);
311
- if (formValue !== null) {
312
- pairs.push([key, formValue]);
313
- }
314
- }
315
- }
316
- this._bodyContent = pairs.map((p) => `${encodeURIComponent(p[0])}=${encodeURIComponent(p[1])}`).join('&');
317
- } else if (this._bodyContentType.indexOf('json') !== -1 && value !== null && typeof value === 'object') {
318
- this._bodyContent = JSON.stringify(value);
319
- } else {
320
- // The body is the plain content
321
- this._bodyContent = value;
322
- }
323
- }
324
-
325
- /**
326
- * @private
327
- * @param {*} value
328
- * @returns {*}
329
- */
330
- formDataValue(value) {
331
- if (value === null || value === undefined) {
332
- return null;
333
- }
334
- if (typeof value === 'object') {
335
- return JSON.stringify(value);
336
- }
337
- return String(value);
338
- }
339
-
340
- /**
341
- * @typedef {object} BuildOptions
342
- * @property {string} [accept]
343
- * @property {import('k6/http').Params} [params]
344
- */
345
-
346
- /**
347
- * Builds the request with the current set parameters
348
- * @param {BuildOptions} [options]
349
- * @returns {import('k6/http').Response}
350
- */
351
- build(options) {
352
- // Perform the request
353
- return http.request(...this.buildRequestParams(options));
354
- }
355
-
356
- /**
357
- * Builds the request with the current set parameters
358
- * @param {BuildOptions} [options]
359
- * @returns {Promise<import('k6/http').Response>}
360
- */
361
- buildAsync(options) {
362
- // Perform the request
363
- return http.asyncRequest(...this.buildRequestParams(options));
364
- }
365
-
366
- /**
367
- * @private
368
- * @param {BuildOptions} [options]
369
- * @returns {Parameters<typeof import('k6/http').request>}
370
- */
371
- buildRequestParams(options) {
372
- options = options || {};
373
-
374
- // Path parameters
375
- let path = this.operationPath;
376
- for (const pathParam of this._path.values()) {
377
- path = pathParam.append(path);
378
- }
379
- const url = this.rootUrl + path;
380
-
381
- // Query parameters
382
- let httpParams = '';
383
- for (const queryParam of this._query.values()) {
384
- httpParams = queryParam.append(httpParams);
385
- }
386
-
387
- // Header parameters
388
- /** @type {Object.<string, string>} */
389
- let httpHeaders = {};
390
- if (options.accept) {
391
- httpHeaders['Accept'] = options.accept;
392
- }
393
- for (const headerParam of this._header.values()) {
394
- httpHeaders = headerParam.append(httpHeaders);
395
- }
396
-
397
- // Request content headers
398
- if (this._bodyContentType) {
399
- httpHeaders['Content-Type'] = this._bodyContentType;
400
- }
401
-
402
- return [
403
- this.method.toUpperCase(),
404
- url + httpParams,
405
- this._bodyContent,
406
- Object.assign({}, options.params, {
407
- headers: Object.assign({}, httpHeaders, options.params ? options.params.headers : {}),
408
- }),
409
- ];
410
- }
411
- }
1
+ // @ts-check
2
+
3
+ import http from 'k6/http';
4
+
5
+ /**
6
+ * Defines the options for appending a parameter
7
+ * @typedef {object} ParameterOptions
8
+ * @property {string} [style]
9
+ * @property {boolean} [explode]
10
+ */
11
+
12
+ /**
13
+ * Base class for a parameter
14
+ * @abstract
15
+ * @property {string} name
16
+ * @property {*} value
17
+ * @property {ParameterOptions} options
18
+ */
19
+ class Parameter {
20
+ /**
21
+ * @param {string} name
22
+ * @param {*} value
23
+ * @param {ParameterOptions} options
24
+ * @param {string} defaultStyle
25
+ * @param {boolean} defaultExplode
26
+ */
27
+ constructor(name, value, options, defaultStyle, defaultExplode) {
28
+ this.name = name;
29
+ this.value = value;
30
+ this.options = options || {};
31
+ if (this.options.style === null || this.options.style === undefined) {
32
+ this.options.style = defaultStyle;
33
+ }
34
+ if (this.options.explode === null || this.options.explode === undefined) {
35
+ this.options.explode = defaultExplode;
36
+ }
37
+ }
38
+
39
+ /**
40
+ * @param {*} value
41
+ * @param {string} separator
42
+ * @returns {string}
43
+ */
44
+ serializeValue(value, separator = ',') {
45
+ if (value === null || value === undefined) {
46
+ return '';
47
+ } else if (value instanceof Array) {
48
+ return value
49
+ .map((v) => this.serializeValue(v).split(separator).join(encodeURIComponent(separator)))
50
+ .join(separator);
51
+ } else if (typeof value === 'object') {
52
+ /** @type {string[]} */
53
+ const array = [];
54
+ for (const key of Object.keys(value)) {
55
+ let propVal = value[key];
56
+ if (propVal !== null && propVal !== undefined) {
57
+ propVal = this.serializeValue(propVal).split(separator).join(encodeURIComponent(separator));
58
+ if (this.options.explode) {
59
+ array.push(`${key}=${propVal}`);
60
+ } else {
61
+ array.push(key);
62
+ array.push(propVal);
63
+ }
64
+ }
65
+ }
66
+ return array.join(separator);
67
+ } else {
68
+ return String(value);
69
+ }
70
+ }
71
+ }
72
+
73
+ /**
74
+ * A parameter in the operation path
75
+ * @param {string} name
76
+ * @param {*} value
77
+ * @param {ParameterOptions} options
78
+ */
79
+ class PathParameter extends Parameter {
80
+ /**
81
+ * @param {string} name
82
+ * @param {*} value
83
+ * @param {ParameterOptions} options
84
+ */
85
+ constructor(name, value, options) {
86
+ super(name, value, options, 'simple', false);
87
+ }
88
+
89
+ /**
90
+ * @param {string} path
91
+ * @returns {string}
92
+ */
93
+ append(path) {
94
+ let value = this.value;
95
+ if (value === null || value === undefined) {
96
+ value = '';
97
+ }
98
+ let prefix = this.options.style === 'label' ? '.' : '';
99
+ const separator = this.options.explode ? (prefix === '' ? ',' : prefix) : ',';
100
+ let alreadySerialized = false;
101
+ if (this.options.style === 'matrix') {
102
+ // The parameter name is just used as prefix, except in some cases...
103
+ prefix = `;${this.name}=`;
104
+ if (this.options.explode && typeof value === 'object') {
105
+ prefix = ';';
106
+ if (value instanceof Array) {
107
+ // For arrays we have to repeat the name for each element
108
+ value = value.map((v) => `${this.name}=${this.serializeValue(v, ';')}`);
109
+ value = value.join(';');
110
+ alreadySerialized = true;
111
+ } else {
112
+ // For objects we have to put each the key / value pairs
113
+ value = this.serializeValue(value, ';');
114
+ alreadySerialized = true;
115
+ }
116
+ }
117
+ }
118
+ value = prefix + (alreadySerialized ? value : this.serializeValue(value, separator));
119
+ // Replace both the plain variable and the corresponding variant taking in the prefix and explode into account
120
+ path = path.replace(`{${this.name}}`, value);
121
+ path = path.replace(`{${prefix}${this.name}${this.options.explode ? '*' : ''}}`, value);
122
+ return path;
123
+ }
124
+
125
+ /**
126
+ * @param {*} value
127
+ * @param {string} separator
128
+ * @returns {string}
129
+ */
130
+ serializeValue(value, separator = ',') {
131
+ let result = typeof value === 'string' ? encodeURIComponent(value) : super.serializeValue(value, separator);
132
+ result = result.replace(/%3D/g, '=');
133
+ result = result.replace(/%3B/g, ';');
134
+ result = result.replace(/%2C/g, ',');
135
+ return result;
136
+ }
137
+ }
138
+
139
+ /**
140
+ * A parameter in the query
141
+ * @param {string} name
142
+ * @param {*} value
143
+ * @param {ParameterOptions} options
144
+ */
145
+ class QueryParameter extends Parameter {
146
+ /**
147
+ * @param {string} name
148
+ * @param {*} value
149
+ * @param {ParameterOptions} options
150
+ */
151
+ constructor(name, value, options) {
152
+ super(name, value, options, 'form', true);
153
+ }
154
+
155
+ /**
156
+ * @param {string} params
157
+ * @returns {string}
158
+ */
159
+ append(params) {
160
+ if (this.value instanceof Array) {
161
+ // Array serialization
162
+ if (this.options.explode) {
163
+ for (const v of this.value) {
164
+ params = `${params}${params ? '&' : '?'}${encodeURIComponent(this.name)}=${this.serializeValue(v)}`;
165
+ }
166
+ } else {
167
+ const separator =
168
+ this.options.style === 'spaceDelimited' ? ' ' : this.options.style === 'pipeDelimited' ? '|' : ',';
169
+ return `${params}${params ? '&' : '?'}${encodeURIComponent(this.name)}=${this.serializeValue(this.value, separator)}`;
170
+ }
171
+ } else if (this.value !== null && typeof this.value === 'object') {
172
+ // Object serialization
173
+ if (this.options.style === 'deepObject') {
174
+ // Append a parameter for each key, in the form `name[key]`
175
+ for (const key of Object.keys(this.value)) {
176
+ const propVal = this.value[key];
177
+ if (propVal !== null && propVal !== undefined) {
178
+ params = `${params}${params ? '&' : '?'}${encodeURIComponent(this.name)}[${encodeURIComponent(
179
+ key,
180
+ )}]=${this.serializeValue(propVal)}`;
181
+ }
182
+ }
183
+ } else if (this.options.explode) {
184
+ // Append a parameter for each key without using the parameter name
185
+ for (const key of Object.keys(this.value)) {
186
+ const propVal = this.value[key];
187
+ if (propVal !== null && propVal !== undefined) {
188
+ params = `${params}${params ? '&' : '?'}${encodeURIComponent(key)}=${this.serializeValue(propVal)}`;
189
+ }
190
+ }
191
+ } else {
192
+ // Append a single parameter whose values are a comma-separated list of key,value,key,value...
193
+ const array = [];
194
+ for (const key of Object.keys(this.value)) {
195
+ const propVal = this.value[key];
196
+ if (propVal !== null && propVal !== undefined) {
197
+ array.push(key);
198
+ array.push(propVal);
199
+ }
200
+ }
201
+ params = `${params}${params ? '&' : '?'}${encodeURIComponent(this.name)}=${this.serializeValue(array)}`;
202
+ }
203
+ } else if (this.value !== null && this.value !== undefined) {
204
+ // Plain value
205
+ params = `${params}${params ? '&' : '?'}${encodeURIComponent(this.name)}=${this.serializeValue(this.value)}`;
206
+ }
207
+ return params;
208
+ }
209
+ }
210
+
211
+ /**
212
+ * A parameter in the HTTP request header
213
+ */
214
+ class HeaderParameter extends Parameter {
215
+ /**
216
+ * @param {string} name
217
+ * @param {*} value
218
+ * @param {ParameterOptions} options
219
+ */
220
+ constructor(name, value, options) {
221
+ super(name, value, options, 'simple', false);
222
+ }
223
+
224
+ /**
225
+ * @param {Object.<string, string>} headers
226
+ * @returns {Object.<string, string>}
227
+ */
228
+ append(headers) {
229
+ if (this.value !== null && this.value !== undefined) {
230
+ if (this.value instanceof Array) {
231
+ throw new Error('Array header values are not supported');
232
+ } else {
233
+ headers[this.name] = this.serializeValue(this.value);
234
+ }
235
+ }
236
+ return headers;
237
+ }
238
+ }
239
+
240
+ /**
241
+ * Helper to build http requests from parameters
242
+ * @property {string} rootUrl
243
+ * @property {string} operationPath
244
+ * @property {string} method
245
+ */
246
+ export class RequestBuilder {
247
+ /**
248
+ * @param {string} rootUrl
249
+ * @param {string} operationPath
250
+ * @param {string} method
251
+ */
252
+ constructor(rootUrl, operationPath, method) {
253
+ this.rootUrl = rootUrl;
254
+ this.operationPath = operationPath;
255
+ this.method = method;
256
+ this._path = new Map();
257
+ this._query = new Map();
258
+ this._header = new Map();
259
+ this._bodyContent = null;
260
+ this._bodyContentType = undefined;
261
+ }
262
+
263
+ /**
264
+ * Sets a path parameter
265
+ * @param {string} name
266
+ * @param {*} value
267
+ * @param {ParameterOptions} [options]
268
+ */
269
+ path(name, value, options) {
270
+ this._path.set(name, new PathParameter(name, value, options || {}));
271
+ }
272
+
273
+ /**
274
+ * Sets a query parameter
275
+ * @param {string} name
276
+ * @param {*} value
277
+ * @param {ParameterOptions} [options]
278
+ */
279
+ query(name, value, options) {
280
+ this._query.set(name, new QueryParameter(name, value, options || {}));
281
+ }
282
+
283
+ /**
284
+ * Sets a header parameter
285
+ * @param {string} name
286
+ * @param {*} value
287
+ * @param {ParameterOptions} [options]
288
+ */
289
+ header(name, value, options) {
290
+ this._header.set(name, new HeaderParameter(name, value, options || {}));
291
+ }
292
+
293
+ /**
294
+ * Sets the body content, along with the content type
295
+ * @param {*} value
296
+ * @param {string} [contentType]
297
+ */
298
+ body(value, contentType = 'application/json') {
299
+ this._bodyContentType = contentType;
300
+ if (this._bodyContentType === 'application/x-www-form-urlencoded' && value !== null && typeof value === 'object') {
301
+ // Handle URL-encoded data
302
+ /** @type {[string, string][]} */
303
+ const pairs = [];
304
+ for (const key of Object.keys(value)) {
305
+ let val = value[key];
306
+ if (!(val instanceof Array)) {
307
+ val = [val];
308
+ }
309
+ for (const v of val) {
310
+ const formValue = this.formDataValue(v);
311
+ if (formValue !== null) {
312
+ pairs.push([key, formValue]);
313
+ }
314
+ }
315
+ }
316
+ this._bodyContent = pairs.map((p) => `${encodeURIComponent(p[0])}=${encodeURIComponent(p[1])}`).join('&');
317
+ } else if (this._bodyContentType.indexOf('json') !== -1 && value !== null && typeof value === 'object') {
318
+ this._bodyContent = JSON.stringify(value);
319
+ } else {
320
+ // The body is the plain content
321
+ this._bodyContent = value;
322
+ }
323
+ }
324
+
325
+ /**
326
+ * @private
327
+ * @param {*} value
328
+ * @returns {*}
329
+ */
330
+ formDataValue(value) {
331
+ if (value === null || value === undefined) {
332
+ return null;
333
+ }
334
+ if (typeof value === 'object') {
335
+ return JSON.stringify(value);
336
+ }
337
+ return String(value);
338
+ }
339
+
340
+ /**
341
+ * @typedef {object} BuildOptions
342
+ * @property {string} [accept]
343
+ * @property {import('k6/http').Params} [params]
344
+ */
345
+
346
+ /**
347
+ * Builds the request with the current set parameters
348
+ * @param {BuildOptions} [options]
349
+ * @returns {import('k6/http').Response}
350
+ */
351
+ build(options) {
352
+ // Perform the request
353
+ return http.request(...this.buildRequestParams(options));
354
+ }
355
+
356
+ /**
357
+ * Builds the request with the current set parameters
358
+ * @param {BuildOptions} [options]
359
+ * @returns {Promise<import('k6/http').Response>}
360
+ */
361
+ buildAsync(options) {
362
+ // Perform the request
363
+ return http.asyncRequest(...this.buildRequestParams(options));
364
+ }
365
+
366
+ /**
367
+ * @private
368
+ * @param {BuildOptions} [options]
369
+ * @returns {Parameters<typeof import('k6/http').request>}
370
+ */
371
+ buildRequestParams(options) {
372
+ options = options || {};
373
+
374
+ // Path parameters
375
+ let path = this.operationPath;
376
+ for (const pathParam of this._path.values()) {
377
+ path = pathParam.append(path);
378
+ }
379
+ const url = this.rootUrl + path;
380
+
381
+ // Query parameters
382
+ let httpParams = '';
383
+ for (const queryParam of this._query.values()) {
384
+ httpParams = queryParam.append(httpParams);
385
+ }
386
+
387
+ // Header parameters
388
+ /** @type {Object.<string, string>} */
389
+ let httpHeaders = {};
390
+ if (options.accept) {
391
+ httpHeaders['Accept'] = options.accept;
392
+ }
393
+ for (const headerParam of this._header.values()) {
394
+ httpHeaders = headerParam.append(httpHeaders);
395
+ }
396
+
397
+ // Request content headers
398
+ if (this._bodyContentType) {
399
+ httpHeaders['Content-Type'] = this._bodyContentType;
400
+ }
401
+
402
+ return [
403
+ this.method.toUpperCase(),
404
+ url + httpParams,
405
+ this._bodyContent,
406
+ Object.assign({}, options.params, {
407
+ headers: Object.assign({}, httpHeaders, options.params ? options.params.headers : {}),
408
+ }),
409
+ ];
410
+ }
411
+ }