Projekt

Obecné

Profil

Stáhnout (10.8 KB) Statistiky
| Větev: | Tag: | Revize:
1 37487772 Lukáš Moučka
/* tslint:disable */
2
/* eslint-disable */
3
import { HttpRequest, HttpParameterCodec, HttpParams, HttpHeaders } from '@angular/common/http';
4
5
/**
6
 * Custom parameter codec to correctly handle the plus sign in parameter
7
 * values. See https://github.com/angular/angular/issues/18261
8
 */
9
class ParameterCodec implements HttpParameterCodec {
10
  encodeKey(key: string): string {
11
    return encodeURIComponent(key);
12
  }
13
14
  encodeValue(value: string): string {
15
    return encodeURIComponent(value);
16
  }
17
18
  decodeKey(key: string): string {
19
    return decodeURIComponent(key);
20
  }
21
22
  decodeValue(value: string): string {
23
    return decodeURIComponent(value);
24
  }
25
}
26
const ParameterCodecInstance = new ParameterCodec();
27
28
/**
29
 * Defines the options for appending a parameter
30
 */
31
interface ParameterOptions {
32
  style?: string;
33
  explode?: boolean;
34
}
35
36
/**
37
 * Base class for a parameter
38
 */
39
abstract class Parameter {
40
  constructor(public name: string, public value: any, public options: ParameterOptions, defaultStyle: string, defaultExplode: boolean) {
41
    this.options = options || {};
42
    if (this.options.style === null || this.options.style === undefined) {
43
      this.options.style = defaultStyle;
44
    }
45
    if (this.options.explode === null || this.options.explode === undefined) {
46
      this.options.explode = defaultExplode;
47
    }
48
  }
49
50
  serializeValue(value: any, separator = ','): string {
51
    if (value === null || value === undefined) {
52
      return '';
53
    } else if (value instanceof Array) {
54
      return value.map(v => this.serializeValue(v).split(separator).join(encodeURIComponent(separator))).join(separator);
55
    } else if (typeof value === 'object') {
56
      const array: string[] = [];
57
      for (const key of Object.keys(value)) {
58
        let propVal = value[key];
59
        if (propVal !== null && propVal !== undefined) {
60
          propVal = this.serializeValue(propVal).split(separator).join(encodeURIComponent(separator));
61
          if (this.options.explode) {
62
            array.push(`${key}=${propVal}`);
63
          } else {
64
            array.push(key);
65
            array.push(propVal);
66
          }
67
        }
68
      }
69
      return array.join(separator);
70
    } else {
71
      return String(value);
72
    }
73
  }
74
}
75
76
/**
77
 * A parameter in the operation path
78
 */
79
class PathParameter extends Parameter {
80
  constructor(name: string, value: any, options: ParameterOptions) {
81
    super(name, value, options, 'simple', false);
82
  }
83
84
  append(path: string): string {
85
    let value = this.value;
86
    if (value === null || value === undefined) {
87
      value = '';
88
    }
89
    let prefix = this.options.style === 'label' ? '.' : '';
90
    let separator = this.options.explode ? prefix === '' ? ',' : prefix : ',';
91
    if (this.options.style === 'matrix') {
92
      // The parameter name is just used as prefix, except in some cases...
93
      prefix = `;${this.name}=`;
94
      if (this.options.explode && typeof value === 'object') {
95
        prefix = ';';
96
        if (value instanceof Array) {
97
          // For arrays we have to repeat the name for each element
98
          value = value.map(v => `${this.name}=${this.serializeValue(v, ';')}`);
99
          separator = ';';
100
        } else {
101
          // For objects we have to put each the key / value pairs
102
          value = this.serializeValue(value, ';');
103
        }
104
      }
105
    }
106
    value = prefix + this.serializeValue(value, separator);
107
    // Replace both the plain variable and the corresponding variant taking in the prefix and explode into account
108
    path = path.replace(`{${this.name}}`, value);
109
    path = path.replace(`{${prefix}${this.name}${this.options.explode ? '*' : ''}}`, value);
110
    return path;
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
  append(params: HttpParams): HttpParams {
123
    if (this.value instanceof Array) {
124
      // Array serialization
125
      if (this.options.explode) {
126
        for (const v of this.value) {
127
          params = params.append(this.name, this.serializeValue(v));
128
        }
129
      } else {
130
        const separator = this.options.style === 'spaceDelimited'
131
          ? ' ' : this.options.style === 'pipeDelimited'
132
            ? '|' : ',';
133
        return params.append(this.name, this.serializeValue(this.value, separator));
134
      }
135
    } else if (this.value !== null && typeof this.value === 'object') {
136
      // Object serialization
137
      if (this.options.style === 'deepObject') {
138
        // Append a parameter for each key, in the form `name[key]`
139
        for (const key of Object.keys(this.value)) {
140
          const propVal = this.value[key];
141
          if (propVal !== null && propVal !== undefined) {
142
            params = params.append(`${this.name}[${key}]`, this.serializeValue(propVal));
143
          }
144
        }
145
      } else if (this.options.explode) {
146
        // Append a parameter for each key without using the parameter name
147
        for (const key of Object.keys(this.value)) {
148
          const propVal = this.value[key];
149
          if (propVal !== null && propVal !== undefined) {
150
            params = params.append(key, this.serializeValue(propVal));
151
          }
152
        }
153
      } else {
154
        // Append a single parameter whose values are a comma-separated list of key,value,key,value...
155
        const array: any[] = [];
156
        for (const key of Object.keys(this.value)) {
157
          const propVal = this.value[key];
158
          if (propVal !== null && propVal !== undefined) {
159
            array.push(key);
160
            array.push(propVal);
161
          }
162
        }
163
        params = params.append(this.name, this.serializeValue(array));
164
      }
165
    } else if (this.value !== null && this.value !== undefined) {
166
      // Plain value
167
      params = params.append(this.name, this.serializeValue(this.value));
168
    }
169
    return params;
170
  }
171
}
172
173
/**
174
 * A parameter in the HTTP request header
175
 */
176
class HeaderParameter extends Parameter {
177
  constructor(name: string, value: any, options: ParameterOptions) {
178
    super(name, value, options, 'simple', false);
179
  }
180
181
  append(headers: HttpHeaders): HttpHeaders {
182
    if (this.value !== null && this.value !== undefined) {
183
      if (this.value instanceof Array) {
184
        for (const v of this.value) {
185
          headers = headers.append(this.name, this.serializeValue(v));
186
        }
187
      } else {
188
        headers = headers.append(this.name, this.serializeValue(this.value));
189
      }
190
    }
191
    return headers;
192
  }
193
}
194
195
/**
196
 * Helper to build http requests from parameters
197
 */
198
export class RequestBuilder {
199
200
  private _path = new Map<string, PathParameter>();
201
  private _query = new Map<string, QueryParameter>();
202
  private _header = new Map<string, HeaderParameter>();
203
  _bodyContent: any | null;
204
  _bodyContentType?: string;
205
206
  constructor(
207
    public rootUrl: string,
208
    public operationPath: string,
209
    public method: string) {
210
  }
211
212
  /**
213
   * Sets a path parameter
214
   */
215
  path(name: string, value: any, options?: ParameterOptions): void {
216
    this._path.set(name, new PathParameter(name, value, options || {}));
217
  }
218
219
  /**
220
   * Sets a query parameter
221
   */
222
  query(name: string, value: any, options?: ParameterOptions): void {
223
    this._query.set(name, new QueryParameter(name, value, options || {}));
224
  }
225
226
  /**
227
   * Sets a header parameter
228
   */
229
  header(name: string, value: any, options?: ParameterOptions): void {
230
    this._header.set(name, new HeaderParameter(name, value, options || {}));
231
  }
232
233
  /**
234
   * Sets the body content, along with the content type
235
   */
236
  body(value: any, contentType = 'application/json'): void {
237
    if (value instanceof Blob) {
238
      this._bodyContentType = value.type;
239
    } else {
240
      this._bodyContentType = contentType;
241
    }
242
    if (this._bodyContentType === 'application/x-www-form-urlencoded' && value !== null && typeof value === 'object') {
243
      // Handle URL-encoded data
244
      const pairs: string[][] = [];
245
      for (const key of Object.keys(value)) {
246
        let val = value[key];
247
        if (!(val instanceof Array)) {
248
          val = [val];
249
        }
250
        for (const v of val) {
251
          const formValue = this.formDataValue(v);
252
          if (formValue !== null) {
253
            pairs.push([key, formValue]);
254
          }
255
        }
256
      }
257
      this._bodyContent = pairs.map(p => `${encodeURIComponent(p[0])}=${encodeURIComponent(p[1])}`).join('&');
258
    } else if (this._bodyContentType === 'multipart/form-data') {
259
      // Handle multipart form data
260
      const formData = new FormData();
261
      if (value !== null && value !== undefined) {
262
        for (const key of Object.keys(value)) {
263
          const val = value[key];
264
          if (val instanceof Array) {
265
            for (const v of val) {
266
              const toAppend = this.formDataValue(v);
267
              if (toAppend !== null) {
268
                formData.append(key, toAppend);
269
              }
270
            }
271
          } else {
272
            const toAppend = this.formDataValue(val);
273
            if (toAppend !== null) {
274
              formData.set(key, toAppend);
275
            }
276
          }
277
        }
278
      }
279
      this._bodyContent = formData;
280
    } else {
281
      // The body is the plain content
282
      this._bodyContent = value;
283
    }
284
  }
285
286
  private formDataValue(value: any): any {
287
    if (value === null || value === undefined) {
288
      return null;
289
    }
290
    if (value instanceof Blob) {
291
      return value;
292
    }
293
    if (typeof value === 'object') {
294
      return JSON.stringify(value);
295
    }
296
    return String(value);
297
  }
298
299
  /**
300
   * Builds the request with the current set parameters
301
   */
302
  build<T = any>(options?: {
303
    /** Which content types to accept */
304
    accept?: string;
305
306
    /** The expected response type */
307
    responseType?: 'json' | 'text' | 'blob' | 'arraybuffer';
308
309
    /** Whether to report progress on uploads / downloads */
310
    reportProgress?: boolean;
311
  }): HttpRequest<T> {
312
313
    options = options || {};
314
315
    // Path parameters
316
    let path = this.operationPath;
317
    for (const pathParam of this._path.values()) {
318
      path = pathParam.append(path);
319
    }
320
    const url = this.rootUrl + path;
321
322
    // Query parameters
323
    let httpParams = new HttpParams({
324
      encoder: ParameterCodecInstance
325
    });
326
    for (const queryParam of this._query.values()) {
327
      httpParams = queryParam.append(httpParams);
328
    }
329
330
    // Header parameters
331
    let httpHeaders = new HttpHeaders();
332
    if (options.accept) {
333
      httpHeaders = httpHeaders.append('Accept', options.accept);
334
    }
335
    for (const headerParam of this._header.values()) {
336
      httpHeaders = headerParam.append(httpHeaders);
337
    }
338
339
    // Request content headers
340
    if (this._bodyContentType && !(this._bodyContent instanceof FormData)) {
341
      httpHeaders = httpHeaders.set('Content-Type', this._bodyContentType);
342
    }
343
344
    // Perform the request
345
    return new HttpRequest<T>(this.method.toUpperCase(), url, this._bodyContent, {
346
      params: httpParams,
347
      headers: httpHeaders,
348
      responseType: options.responseType,
349
      reportProgress: options.reportProgress
350
    });
351
  }
352
}