@goast/typescript 0.5.1-k6.3 → 0.5.1

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 (104) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +52 -52
  3. package/assets/client/angular/angular-service.utils.ts +82 -82
  4. package/assets/client/angular/request-builder.ts +377 -377
  5. package/assets/client/fetch/fetch-client.utils.ts +52 -52
  6. package/assets/client/k6/request-builder.js +419 -419
  7. package/assets/client/k6/request-builder.ts +341 -341
  8. package/assets/stubs/easy-network-stub/easy-network-stub.utils.ts +259 -259
  9. package/esm/src/generators/models/models.d.ts +1 -1
  10. package/esm/src/generators/models/models.d.ts.map +1 -1
  11. package/esm/src/generators/services/angular-services/angular-service-generator.js +9 -9
  12. package/esm/src/generators/services/easy-network-stub/easy-network-stub-generator.js +9 -9
  13. package/esm/src/generators/services/fetch-clients/fetch-client-generator.js +2 -2
  14. package/esm/src/generators/services/k6-clients/k6-client-generator.js +11 -11
  15. package/package.json +1 -1
  16. package/script/src/generators/models/models.d.ts +1 -1
  17. package/script/src/generators/models/models.d.ts.map +1 -1
  18. package/script/src/generators/services/angular-services/angular-service-generator.js +9 -9
  19. package/script/src/generators/services/easy-network-stub/easy-network-stub-generator.js +9 -9
  20. package/script/src/generators/services/fetch-clients/fetch-client-generator.js +2 -2
  21. package/script/src/generators/services/k6-clients/k6-client-generator.js +11 -11
  22. package/src/mod.ts +7 -0
  23. package/src/src/assets.ts +9 -0
  24. package/src/src/ast/_index.ts +54 -0
  25. package/src/src/ast/common.ts +1 -0
  26. package/src/src/ast/index.ts +1 -0
  27. package/src/src/ast/node.ts +10 -0
  28. package/src/src/ast/nodes/argument.ts +40 -0
  29. package/src/src/ast/nodes/array-type.ts +49 -0
  30. package/src/src/ast/nodes/arrow-function.ts +91 -0
  31. package/src/src/ast/nodes/call.ts +55 -0
  32. package/src/src/ast/nodes/class.ts +133 -0
  33. package/src/src/ast/nodes/constructor-parameter.ts +70 -0
  34. package/src/src/ast/nodes/constructor.ts +77 -0
  35. package/src/src/ast/nodes/decorator.ts +76 -0
  36. package/src/src/ast/nodes/doc-tag.ts +291 -0
  37. package/src/src/ast/nodes/doc.ts +102 -0
  38. package/src/src/ast/nodes/enum-value.ts +72 -0
  39. package/src/src/ast/nodes/enum.ts +77 -0
  40. package/src/src/ast/nodes/export.ts +54 -0
  41. package/src/src/ast/nodes/function-type.ts +60 -0
  42. package/src/src/ast/nodes/function.ts +107 -0
  43. package/src/src/ast/nodes/generic-parameter.ts +71 -0
  44. package/src/src/ast/nodes/indexer.ts +60 -0
  45. package/src/src/ast/nodes/interface.ts +117 -0
  46. package/src/src/ast/nodes/intersection-type.ts +67 -0
  47. package/src/src/ast/nodes/lookup-type.ts +53 -0
  48. package/src/src/ast/nodes/method.ts +138 -0
  49. package/src/src/ast/nodes/object-type.ts +52 -0
  50. package/src/src/ast/nodes/object.ts +48 -0
  51. package/src/src/ast/nodes/parameter.ts +85 -0
  52. package/src/src/ast/nodes/property-accessor.ts +173 -0
  53. package/src/src/ast/nodes/property.ts +192 -0
  54. package/src/src/ast/nodes/reference.ts +194 -0
  55. package/src/src/ast/nodes/string.ts +49 -0
  56. package/src/src/ast/nodes/tuple.ts +53 -0
  57. package/src/src/ast/nodes/type-alias.ts +75 -0
  58. package/src/src/ast/nodes/typeof.ts +42 -0
  59. package/src/src/ast/nodes/types.ts +40 -0
  60. package/src/src/ast/nodes/union-type.ts +62 -0
  61. package/src/src/ast/nodes/variable.ts +73 -0
  62. package/src/src/ast/references/angular.ts +24 -0
  63. package/src/src/ast/references/easy-network-stub.ts +21 -0
  64. package/src/src/ast/references/index.ts +5 -0
  65. package/src/src/ast/references/k6.ts +8 -0
  66. package/src/src/ast/references/rxjs.ts +7 -0
  67. package/src/src/ast/references/typescript.ts +35 -0
  68. package/src/src/ast/utils/get-type-script-builder-options.ts +19 -0
  69. package/src/src/ast/utils/to-ts-node.ts +27 -0
  70. package/src/src/ast/utils/write-ts-generic-parameters.ts +25 -0
  71. package/src/src/ast/utils/write-ts-members.ts +28 -0
  72. package/src/src/ast/utils/write-ts-nodes.ts +35 -0
  73. package/src/src/ast/utils/write-ts-parameters.ts +25 -0
  74. package/src/src/common-results.ts +26 -0
  75. package/src/src/config.ts +89 -0
  76. package/src/src/file-builder.ts +136 -0
  77. package/src/src/generators/file-generator.ts +15 -0
  78. package/src/src/generators/index.ts +6 -0
  79. package/src/src/generators/models/index.ts +3 -0
  80. package/src/src/generators/models/model-generator.ts +469 -0
  81. package/src/src/generators/models/models-generator.ts +108 -0
  82. package/src/src/generators/models/models.ts +121 -0
  83. package/src/src/generators/services/angular-services/angular-service-generator.ts +406 -0
  84. package/src/src/generators/services/angular-services/angular-services-generator.ts +295 -0
  85. package/src/src/generators/services/angular-services/index.ts +3 -0
  86. package/src/src/generators/services/angular-services/models.ts +277 -0
  87. package/src/src/generators/services/angular-services/refs.ts +54 -0
  88. package/src/src/generators/services/easy-network-stub/easy-network-stub-generator.ts +242 -0
  89. package/src/src/generators/services/easy-network-stub/easy-network-stubs-generator.ts +211 -0
  90. package/src/src/generators/services/easy-network-stub/index.ts +3 -0
  91. package/src/src/generators/services/easy-network-stub/models.ts +124 -0
  92. package/src/src/generators/services/easy-network-stub/refs.ts +45 -0
  93. package/src/src/generators/services/fetch-clients/fetch-client-generator.ts +267 -0
  94. package/src/src/generators/services/fetch-clients/fetch-clients-generator.ts +163 -0
  95. package/src/src/generators/services/fetch-clients/index.ts +3 -0
  96. package/src/src/generators/services/fetch-clients/models.ts +130 -0
  97. package/src/src/generators/services/fetch-clients/refs.ts +21 -0
  98. package/src/src/generators/services/k6-clients/index.ts +3 -0
  99. package/src/src/generators/services/k6-clients/k6-client-generator.ts +465 -0
  100. package/src/src/generators/services/k6-clients/k6-clients-generator.ts +171 -0
  101. package/src/src/generators/services/k6-clients/models.ts +247 -0
  102. package/src/src/generators/services/k6-clients/refs.ts +16 -0
  103. package/src/src/import-collection.ts +236 -0
  104. package/src/src/utils.ts +72 -0
@@ -1,341 +1,341 @@
1
- // @deno-types="npm:@types/k6/http"
2
- import http, { Params, Response } from 'k6/http';
3
-
4
- /**
5
- * Defines the options for appending a parameter
6
- */
7
- type ParameterOptions = {
8
- style?: string;
9
- explode?: boolean;
10
- };
11
-
12
- type BuildOptions = {
13
- accept?: string;
14
- params?: Params;
15
- };
16
-
17
- /**
18
- * Base class for a parameter
19
- */
20
- abstract class Parameter {
21
- public readonly name: string;
22
- public readonly value: any;
23
- public readonly options: ParameterOptions;
24
-
25
- constructor(name: string, value: any, options: ParameterOptions, defaultStyle: string, defaultExplode: boolean) {
26
- this.name = name;
27
- this.value = value;
28
- this.options = options || {};
29
- if (this.options.style === null || this.options.style === undefined) {
30
- this.options.style = defaultStyle;
31
- }
32
- if (this.options.explode === null || this.options.explode === undefined) {
33
- this.options.explode = defaultExplode;
34
- }
35
- }
36
-
37
- public serializeValue(value: any, separator = ','): string {
38
- if (value === null || value === undefined) {
39
- return '';
40
- } else if (value instanceof Array) {
41
- return value
42
- .map((v) => this.serializeValue(v).split(separator).join(encodeURIComponent(separator)))
43
- .join(separator);
44
- } else if (typeof value === 'object') {
45
- const array: string[] = [];
46
- for (const key of Object.keys(value)) {
47
- let propVal = value[key];
48
- if (propVal !== null && propVal !== undefined) {
49
- propVal = this.serializeValue(propVal).split(separator).join(encodeURIComponent(separator));
50
- if (this.options.explode) {
51
- array.push(`${key}=${propVal}`);
52
- } else {
53
- array.push(key);
54
- array.push(propVal);
55
- }
56
- }
57
- }
58
- return array.join(separator);
59
- } else {
60
- return String(value);
61
- }
62
- }
63
- }
64
-
65
- /**
66
- * A parameter in the operation path
67
- */
68
- class PathParameter extends Parameter {
69
- constructor(name: string, value: any, options: ParameterOptions) {
70
- super(name, value, options, 'simple', false);
71
- }
72
-
73
- public append(path: string): string {
74
- let value = this.value;
75
- if (value === null || value === undefined) {
76
- value = '';
77
- }
78
- let prefix = this.options.style === 'label' ? '.' : '';
79
- const separator = this.options.explode ? (prefix === '' ? ',' : prefix) : ',';
80
- let alreadySerialized = false;
81
- if (this.options.style === 'matrix') {
82
- // The parameter name is just used as prefix, except in some cases...
83
- prefix = `;${this.name}=`;
84
- if (this.options.explode && typeof value === 'object') {
85
- prefix = ';';
86
- if (value instanceof Array) {
87
- // For arrays we have to repeat the name for each element
88
- value = value.map((v) => `${this.name}=${this.serializeValue(v, ';')}`);
89
- value = value.join(';');
90
- alreadySerialized = true;
91
- } else {
92
- // For objects we have to put each the key / value pairs
93
- value = this.serializeValue(value, ';');
94
- alreadySerialized = true;
95
- }
96
- }
97
- }
98
- value = prefix + (alreadySerialized ? value : this.serializeValue(value, separator));
99
- // Replace both the plain variable and the corresponding variant taking in the prefix and explode into account
100
- path = path.replace(`{${this.name}}`, value);
101
- path = path.replace(`{${prefix}${this.name}${this.options.explode ? '*' : ''}}`, value);
102
- return path;
103
- }
104
-
105
- public override serializeValue(value: any, separator = ','): string {
106
- let result = typeof value === 'string' ? encodeURIComponent(value) : super.serializeValue(value, separator);
107
- result = result.replace(/%3D/g, '=');
108
- result = result.replace(/%3B/g, ';');
109
- result = result.replace(/%2C/g, ',');
110
- return result;
111
- }
112
- }
113
-
114
- /**
115
- * A parameter in the query
116
- */
117
- class QueryParameter extends Parameter {
118
- constructor(name: string, value: any, options: ParameterOptions) {
119
- super(name, value, options, 'form', true);
120
- }
121
-
122
- public append(params: string): string {
123
- if (this.value instanceof Array) {
124
- // Array serialization
125
- if (this.options.explode) {
126
- for (const v of this.value) {
127
- params = `${params}${params ? '&' : '?'}${encodeURIComponent(this.name)}=${this.serializeValue(v)}`;
128
- }
129
- } else {
130
- const separator = this.options.style === 'spaceDelimited'
131
- ? ' '
132
- : this.options.style === 'pipeDelimited'
133
- ? '|'
134
- : ',';
135
- return `${params}${params ? '&' : '?'}${encodeURIComponent(this.name)}=${
136
- this.serializeValue(this.value, separator)
137
- }`;
138
- }
139
- } else if (this.value !== null && typeof this.value === 'object') {
140
- // Object serialization
141
- if (this.options.style === 'deepObject') {
142
- // Append a parameter for each key, in the form `name[key]`
143
- for (const key of Object.keys(this.value)) {
144
- const propVal = this.value[key];
145
- if (propVal !== null && propVal !== undefined) {
146
- params = `${params}${params ? '&' : '?'}${encodeURIComponent(this.name)}[${
147
- encodeURIComponent(
148
- key,
149
- )
150
- }]=${this.serializeValue(propVal)}`;
151
- }
152
- }
153
- } else if (this.options.explode) {
154
- // Append a parameter for each key without using the parameter name
155
- for (const key of Object.keys(this.value)) {
156
- const propVal = this.value[key];
157
- if (propVal !== null && propVal !== undefined) {
158
- params = `${params}${params ? '&' : '?'}${encodeURIComponent(key)}=${this.serializeValue(propVal)}`;
159
- }
160
- }
161
- } else {
162
- // Append a single parameter whose values are a comma-separated list of key,value,key,value...
163
- const array: unknown[] = [];
164
- for (const key of Object.keys(this.value)) {
165
- const propVal = this.value[key];
166
- if (propVal !== null && propVal !== undefined) {
167
- array.push(key);
168
- array.push(propVal);
169
- }
170
- }
171
- params = `${params}${params ? '&' : '?'}${encodeURIComponent(this.name)}=${this.serializeValue(array)}`;
172
- }
173
- } else if (this.value !== null && this.value !== undefined) {
174
- // Plain value
175
- params = `${params}${params ? '&' : '?'}${encodeURIComponent(this.name)}=${this.serializeValue(this.value)}`;
176
- }
177
- return params;
178
- }
179
- }
180
-
181
- /**
182
- * A parameter in the HTTP request header
183
- */
184
- class HeaderParameter extends Parameter {
185
- constructor(name: string, value: any, options: ParameterOptions) {
186
- super(name, value, options, 'simple', false);
187
- }
188
-
189
- public append(headers: Record<string, string>): Record<string, string> {
190
- if (this.value !== null && this.value !== undefined) {
191
- if (this.value instanceof Array) {
192
- throw new Error('Array header values are not supported');
193
- } else {
194
- headers[this.name] = this.serializeValue(this.value);
195
- }
196
- }
197
- return headers;
198
- }
199
- }
200
-
201
- /**
202
- * Helper to build http requests from parameters
203
- */
204
- export class RequestBuilder {
205
- private readonly _path: Map<string, PathParameter>;
206
- private readonly _query: Map<string, QueryParameter>;
207
- private readonly _header: Map<string, HeaderParameter>;
208
- private _bodyContent: any;
209
- private _bodyContentType: string | undefined;
210
-
211
- public readonly rootUrl: string;
212
- public readonly operationPath: string;
213
- public readonly method: string;
214
-
215
- constructor(rootUrl: string, operationPath: string, method: string) {
216
- this.rootUrl = rootUrl;
217
- this.operationPath = operationPath;
218
- this.method = method;
219
- this._path = new Map();
220
- this._query = new Map();
221
- this._header = new Map();
222
- this._bodyContent = null;
223
- this._bodyContentType = undefined;
224
- }
225
-
226
- /**
227
- * Sets a path parameter
228
- */
229
- public path(name: string, value: any, options: ParameterOptions) {
230
- this._path.set(name, new PathParameter(name, value, options || {}));
231
- }
232
-
233
- /**
234
- * Sets a query parameter
235
- */
236
- public query(name: string, value: any, options: ParameterOptions) {
237
- this._query.set(name, new QueryParameter(name, value, options || {}));
238
- }
239
-
240
- /**
241
- * Sets a header parameter
242
- */
243
- public header(name: string, value: any, options: ParameterOptions) {
244
- this._header.set(name, new HeaderParameter(name, value, options || {}));
245
- }
246
-
247
- /**
248
- * Sets the body content, along with the content type
249
- */
250
- public body(value: any, contentType = 'application/json') {
251
- this._bodyContentType = contentType;
252
- if (this._bodyContentType === 'application/x-www-form-urlencoded' && value !== null && typeof value === 'object') {
253
- // Handle URL-encoded data
254
- const pairs: [string, string][] = [];
255
- for (const key of Object.keys(value)) {
256
- let val = value[key];
257
- if (!(val instanceof Array)) {
258
- val = [val];
259
- }
260
- for (const v of val) {
261
- const formValue = this.formDataValue(v);
262
- if (formValue !== null) {
263
- pairs.push([key, formValue]);
264
- }
265
- }
266
- }
267
- this._bodyContent = pairs.map((p) => `${encodeURIComponent(p[0])}=${encodeURIComponent(p[1])}`).join('&');
268
- } else if (this._bodyContentType.indexOf('json') !== -1 && value !== null && typeof value === 'object') {
269
- this._bodyContent = JSON.stringify(value);
270
- } else {
271
- // The body is the plain content
272
- this._bodyContent = value;
273
- }
274
- }
275
-
276
- private formDataValue(value: any): any {
277
- if (value === null || value === undefined) {
278
- return null;
279
- }
280
- if (typeof value === 'object') {
281
- return JSON.stringify(value);
282
- }
283
- return String(value);
284
- }
285
-
286
- /**
287
- * Builds the request with the current set parameters
288
- */
289
- public build(options?: BuildOptions): Response {
290
- // Perform the request
291
- return http.request(...this.buildRequestParams(options));
292
- }
293
-
294
- /**
295
- * Builds the request with the current set parameters
296
- */
297
- public buildAsync(options?: BuildOptions): Promise<Response> {
298
- // Perform the request
299
- return http.asyncRequest(...this.buildRequestParams(options));
300
- }
301
-
302
- private buildRequestParams(options?: BuildOptions): Parameters<typeof http.request> {
303
- options = options || {};
304
-
305
- // Path parameters
306
- let path = this.operationPath;
307
- for (const pathParam of this._path.values()) {
308
- path = pathParam.append(path);
309
- }
310
- const url = this.rootUrl + path;
311
-
312
- // Query parameters
313
- let httpParams = '';
314
- for (const queryParam of this._query.values()) {
315
- httpParams = queryParam.append(httpParams);
316
- }
317
-
318
- // Header parameters
319
- let httpHeaders: Record<string, string> = {};
320
- if (options.accept) {
321
- httpHeaders['Accept'] = options.accept;
322
- }
323
- for (const headerParam of this._header.values()) {
324
- httpHeaders = headerParam.append(httpHeaders);
325
- }
326
-
327
- // Request content headers
328
- if (this._bodyContentType) {
329
- httpHeaders['Content-Type'] = this._bodyContentType;
330
- }
331
-
332
- return [
333
- this.method.toUpperCase(),
334
- url + httpParams,
335
- this._bodyContent,
336
- Object.assign({}, options.params, {
337
- headers: Object.assign({}, httpHeaders, options.params ? options.params.headers : {}),
338
- }),
339
- ];
340
- }
341
- }
1
+ // @deno-types="npm:@types/k6/http"
2
+ import http, { Params, Response } from 'k6/http';
3
+
4
+ /**
5
+ * Defines the options for appending a parameter
6
+ */
7
+ type ParameterOptions = {
8
+ style?: string;
9
+ explode?: boolean;
10
+ };
11
+
12
+ type BuildOptions = {
13
+ accept?: string;
14
+ params?: Params;
15
+ };
16
+
17
+ /**
18
+ * Base class for a parameter
19
+ */
20
+ abstract class Parameter {
21
+ public readonly name: string;
22
+ public readonly value: any;
23
+ public readonly options: ParameterOptions;
24
+
25
+ constructor(name: string, value: any, options: ParameterOptions, defaultStyle: string, defaultExplode: boolean) {
26
+ this.name = name;
27
+ this.value = value;
28
+ this.options = options || {};
29
+ if (this.options.style === null || this.options.style === undefined) {
30
+ this.options.style = defaultStyle;
31
+ }
32
+ if (this.options.explode === null || this.options.explode === undefined) {
33
+ this.options.explode = defaultExplode;
34
+ }
35
+ }
36
+
37
+ public serializeValue(value: any, separator = ','): string {
38
+ if (value === null || value === undefined) {
39
+ return '';
40
+ } else if (value instanceof Array) {
41
+ return value
42
+ .map((v) => this.serializeValue(v).split(separator).join(encodeURIComponent(separator)))
43
+ .join(separator);
44
+ } else if (typeof value === 'object') {
45
+ const array: string[] = [];
46
+ for (const key of Object.keys(value)) {
47
+ let propVal = value[key];
48
+ if (propVal !== null && propVal !== undefined) {
49
+ propVal = this.serializeValue(propVal).split(separator).join(encodeURIComponent(separator));
50
+ if (this.options.explode) {
51
+ array.push(`${key}=${propVal}`);
52
+ } else {
53
+ array.push(key);
54
+ array.push(propVal);
55
+ }
56
+ }
57
+ }
58
+ return array.join(separator);
59
+ } else {
60
+ return String(value);
61
+ }
62
+ }
63
+ }
64
+
65
+ /**
66
+ * A parameter in the operation path
67
+ */
68
+ class PathParameter extends Parameter {
69
+ constructor(name: string, value: any, options: ParameterOptions) {
70
+ super(name, value, options, 'simple', false);
71
+ }
72
+
73
+ public append(path: string): string {
74
+ let value = this.value;
75
+ if (value === null || value === undefined) {
76
+ value = '';
77
+ }
78
+ let prefix = this.options.style === 'label' ? '.' : '';
79
+ const separator = this.options.explode ? (prefix === '' ? ',' : prefix) : ',';
80
+ let alreadySerialized = false;
81
+ if (this.options.style === 'matrix') {
82
+ // The parameter name is just used as prefix, except in some cases...
83
+ prefix = `;${this.name}=`;
84
+ if (this.options.explode && typeof value === 'object') {
85
+ prefix = ';';
86
+ if (value instanceof Array) {
87
+ // For arrays we have to repeat the name for each element
88
+ value = value.map((v) => `${this.name}=${this.serializeValue(v, ';')}`);
89
+ value = value.join(';');
90
+ alreadySerialized = true;
91
+ } else {
92
+ // For objects we have to put each the key / value pairs
93
+ value = this.serializeValue(value, ';');
94
+ alreadySerialized = true;
95
+ }
96
+ }
97
+ }
98
+ value = prefix + (alreadySerialized ? value : this.serializeValue(value, separator));
99
+ // Replace both the plain variable and the corresponding variant taking in the prefix and explode into account
100
+ path = path.replace(`{${this.name}}`, value);
101
+ path = path.replace(`{${prefix}${this.name}${this.options.explode ? '*' : ''}}`, value);
102
+ return path;
103
+ }
104
+
105
+ public override serializeValue(value: any, separator = ','): string {
106
+ let result = typeof value === 'string' ? encodeURIComponent(value) : super.serializeValue(value, separator);
107
+ result = result.replace(/%3D/g, '=');
108
+ result = result.replace(/%3B/g, ';');
109
+ result = result.replace(/%2C/g, ',');
110
+ return result;
111
+ }
112
+ }
113
+
114
+ /**
115
+ * A parameter in the query
116
+ */
117
+ class QueryParameter extends Parameter {
118
+ constructor(name: string, value: any, options: ParameterOptions) {
119
+ super(name, value, options, 'form', true);
120
+ }
121
+
122
+ public append(params: string): string {
123
+ if (this.value instanceof Array) {
124
+ // Array serialization
125
+ if (this.options.explode) {
126
+ for (const v of this.value) {
127
+ params = `${params}${params ? '&' : '?'}${encodeURIComponent(this.name)}=${this.serializeValue(v)}`;
128
+ }
129
+ } else {
130
+ const separator = this.options.style === 'spaceDelimited'
131
+ ? ' '
132
+ : this.options.style === 'pipeDelimited'
133
+ ? '|'
134
+ : ',';
135
+ return `${params}${params ? '&' : '?'}${encodeURIComponent(this.name)}=${
136
+ this.serializeValue(this.value, separator)
137
+ }`;
138
+ }
139
+ } else if (this.value !== null && typeof this.value === 'object') {
140
+ // Object serialization
141
+ if (this.options.style === 'deepObject') {
142
+ // Append a parameter for each key, in the form `name[key]`
143
+ for (const key of Object.keys(this.value)) {
144
+ const propVal = this.value[key];
145
+ if (propVal !== null && propVal !== undefined) {
146
+ params = `${params}${params ? '&' : '?'}${encodeURIComponent(this.name)}[${
147
+ encodeURIComponent(
148
+ key,
149
+ )
150
+ }]=${this.serializeValue(propVal)}`;
151
+ }
152
+ }
153
+ } else if (this.options.explode) {
154
+ // Append a parameter for each key without using the parameter name
155
+ for (const key of Object.keys(this.value)) {
156
+ const propVal = this.value[key];
157
+ if (propVal !== null && propVal !== undefined) {
158
+ params = `${params}${params ? '&' : '?'}${encodeURIComponent(key)}=${this.serializeValue(propVal)}`;
159
+ }
160
+ }
161
+ } else {
162
+ // Append a single parameter whose values are a comma-separated list of key,value,key,value...
163
+ const array: unknown[] = [];
164
+ for (const key of Object.keys(this.value)) {
165
+ const propVal = this.value[key];
166
+ if (propVal !== null && propVal !== undefined) {
167
+ array.push(key);
168
+ array.push(propVal);
169
+ }
170
+ }
171
+ params = `${params}${params ? '&' : '?'}${encodeURIComponent(this.name)}=${this.serializeValue(array)}`;
172
+ }
173
+ } else if (this.value !== null && this.value !== undefined) {
174
+ // Plain value
175
+ params = `${params}${params ? '&' : '?'}${encodeURIComponent(this.name)}=${this.serializeValue(this.value)}`;
176
+ }
177
+ return params;
178
+ }
179
+ }
180
+
181
+ /**
182
+ * A parameter in the HTTP request header
183
+ */
184
+ class HeaderParameter extends Parameter {
185
+ constructor(name: string, value: any, options: ParameterOptions) {
186
+ super(name, value, options, 'simple', false);
187
+ }
188
+
189
+ public append(headers: Record<string, string>): Record<string, string> {
190
+ if (this.value !== null && this.value !== undefined) {
191
+ if (this.value instanceof Array) {
192
+ throw new Error('Array header values are not supported');
193
+ } else {
194
+ headers[this.name] = this.serializeValue(this.value);
195
+ }
196
+ }
197
+ return headers;
198
+ }
199
+ }
200
+
201
+ /**
202
+ * Helper to build http requests from parameters
203
+ */
204
+ export class RequestBuilder {
205
+ private readonly _path: Map<string, PathParameter>;
206
+ private readonly _query: Map<string, QueryParameter>;
207
+ private readonly _header: Map<string, HeaderParameter>;
208
+ private _bodyContent: any;
209
+ private _bodyContentType: string | undefined;
210
+
211
+ public readonly rootUrl: string;
212
+ public readonly operationPath: string;
213
+ public readonly method: string;
214
+
215
+ constructor(rootUrl: string, operationPath: string, method: string) {
216
+ this.rootUrl = rootUrl;
217
+ this.operationPath = operationPath;
218
+ this.method = method;
219
+ this._path = new Map();
220
+ this._query = new Map();
221
+ this._header = new Map();
222
+ this._bodyContent = null;
223
+ this._bodyContentType = undefined;
224
+ }
225
+
226
+ /**
227
+ * Sets a path parameter
228
+ */
229
+ public path(name: string, value: any, options: ParameterOptions) {
230
+ this._path.set(name, new PathParameter(name, value, options || {}));
231
+ }
232
+
233
+ /**
234
+ * Sets a query parameter
235
+ */
236
+ public query(name: string, value: any, options: ParameterOptions) {
237
+ this._query.set(name, new QueryParameter(name, value, options || {}));
238
+ }
239
+
240
+ /**
241
+ * Sets a header parameter
242
+ */
243
+ public header(name: string, value: any, options: ParameterOptions) {
244
+ this._header.set(name, new HeaderParameter(name, value, options || {}));
245
+ }
246
+
247
+ /**
248
+ * Sets the body content, along with the content type
249
+ */
250
+ public body(value: any, contentType = 'application/json') {
251
+ this._bodyContentType = contentType;
252
+ if (this._bodyContentType === 'application/x-www-form-urlencoded' && value !== null && typeof value === 'object') {
253
+ // Handle URL-encoded data
254
+ const pairs: [string, string][] = [];
255
+ for (const key of Object.keys(value)) {
256
+ let val = value[key];
257
+ if (!(val instanceof Array)) {
258
+ val = [val];
259
+ }
260
+ for (const v of val) {
261
+ const formValue = this.formDataValue(v);
262
+ if (formValue !== null) {
263
+ pairs.push([key, formValue]);
264
+ }
265
+ }
266
+ }
267
+ this._bodyContent = pairs.map((p) => `${encodeURIComponent(p[0])}=${encodeURIComponent(p[1])}`).join('&');
268
+ } else if (this._bodyContentType.indexOf('json') !== -1 && value !== null && typeof value === 'object') {
269
+ this._bodyContent = JSON.stringify(value);
270
+ } else {
271
+ // The body is the plain content
272
+ this._bodyContent = value;
273
+ }
274
+ }
275
+
276
+ private formDataValue(value: any): any {
277
+ if (value === null || value === undefined) {
278
+ return null;
279
+ }
280
+ if (typeof value === 'object') {
281
+ return JSON.stringify(value);
282
+ }
283
+ return String(value);
284
+ }
285
+
286
+ /**
287
+ * Builds the request with the current set parameters
288
+ */
289
+ public build(options?: BuildOptions): Response {
290
+ // Perform the request
291
+ return http.request(...this.buildRequestParams(options));
292
+ }
293
+
294
+ /**
295
+ * Builds the request with the current set parameters
296
+ */
297
+ public buildAsync(options?: BuildOptions): Promise<Response> {
298
+ // Perform the request
299
+ return http.asyncRequest(...this.buildRequestParams(options));
300
+ }
301
+
302
+ private buildRequestParams(options?: BuildOptions): Parameters<typeof http.request> {
303
+ options = options || {};
304
+
305
+ // Path parameters
306
+ let path = this.operationPath;
307
+ for (const pathParam of this._path.values()) {
308
+ path = pathParam.append(path);
309
+ }
310
+ const url = this.rootUrl + path;
311
+
312
+ // Query parameters
313
+ let httpParams = '';
314
+ for (const queryParam of this._query.values()) {
315
+ httpParams = queryParam.append(httpParams);
316
+ }
317
+
318
+ // Header parameters
319
+ let httpHeaders: Record<string, string> = {};
320
+ if (options.accept) {
321
+ httpHeaders['Accept'] = options.accept;
322
+ }
323
+ for (const headerParam of this._header.values()) {
324
+ httpHeaders = headerParam.append(httpHeaders);
325
+ }
326
+
327
+ // Request content headers
328
+ if (this._bodyContentType && this._bodyContentType !== 'multipart/form-data') {
329
+ httpHeaders['Content-Type'] = this._bodyContentType;
330
+ }
331
+
332
+ return [
333
+ this.method.toUpperCase(),
334
+ url + httpParams,
335
+ this._bodyContent,
336
+ Object.assign({}, options.params, {
337
+ headers: Object.assign({}, httpHeaders, options.params ? options.params.headers : {}),
338
+ }),
339
+ ];
340
+ }
341
+ }