@goast/typescript 0.2.14 → 0.2.16

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.
package/README.md CHANGED
@@ -1,11 +1,11 @@
1
- # typescript
2
-
3
- This library was generated with [Nx](https://nx.dev).
4
-
5
- ## Building
6
-
7
- Run `nx build typescript` to build the library.
8
-
9
- ## Running unit tests
10
-
11
- Run `nx test typescript` to execute the unit tests via [Jest](https://jestjs.io).
1
+ # typescript
2
+
3
+ This library was generated with [Nx](https://nx.dev).
4
+
5
+ ## Building
6
+
7
+ Run `nx build typescript` to build the library.
8
+
9
+ ## Running unit tests
10
+
11
+ Run `nx test typescript` to execute the unit tests via [Jest](https://jestjs.io).
@@ -1,14 +1,28 @@
1
1
  import { HttpErrorResponse, HttpEvent, HttpResponse } from '@angular/common/http';
2
- import { Observable, filter, firstValueFrom } from 'rxjs';
2
+ import { Observable, Subscription, filter, take, map, catchError, EMPTY } from 'rxjs';
3
3
 
4
- export async function waitForResponse<T extends HttpResponse<any> | HttpErrorResponse>(
4
+ export type AbortablePromise<T> = {
5
+ abort(): void;
6
+ then<TResult1 = T, TResult2 = never>(
7
+ onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null,
8
+ onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null,
9
+ ): AbortablePromise<TResult1 | TResult2>;
10
+ catch<TResult = never>(
11
+ onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null,
12
+ ): AbortablePromise<T | TResult>;
13
+ finally(onfinally?: (() => void) | undefined | null): AbortablePromise<T>;
14
+ };
15
+
16
+ export function waitForResponse<T extends HttpResponse<any> | HttpErrorResponse>(
5
17
  httpEvents: Observable<HttpEvent<any>>,
6
18
  options: { errorResponseTypes: Record<number, 'text' | 'json'> },
7
- ): Promise<T> {
8
- try {
9
- const response = await firstValueFrom(httpEvents.pipe(filter((event) => event instanceof HttpResponse)));
10
- return response as T;
11
- } catch (error) {
19
+ ): AbortablePromise<T> {
20
+ return firstValueFromAbortable<T>(
21
+ httpEvents.pipe(
22
+ filter((event) => event instanceof HttpResponse),
23
+ map((response) => response as T),
24
+ ),
25
+ ).catch((error) => {
12
26
  if (error instanceof HttpErrorResponse) {
13
27
  if (options.errorResponseTypes[error.status] === 'json' && typeof error.error === 'string') {
14
28
  return new HttpErrorResponse({
@@ -22,5 +36,45 @@ export async function waitForResponse<T extends HttpResponse<any> | HttpErrorRes
22
36
  return error as T;
23
37
  }
24
38
  throw error;
25
- }
39
+ });
40
+ }
41
+
42
+ function firstValueFromAbortable<T>(observable: Observable<T>): AbortablePromise<T> {
43
+ let subscription: Subscription | undefined = undefined;
44
+ let _reject: ((reason?: any) => void) | undefined = undefined;
45
+ const abortFn = () => {
46
+ if (!subscription) {
47
+ throw new Error('Not subscribed yet.');
48
+ }
49
+ subscription.unsubscribe();
50
+ _reject?.(new DOMException('The request has been aborted.', 'AbortError'));
51
+ };
52
+
53
+ return createAbortablePromise(
54
+ new Promise<T>((resolve, reject) => {
55
+ _reject = reject;
56
+ subscription = observable
57
+ .pipe(
58
+ take(1),
59
+ catchError((e: unknown) => {
60
+ reject(e);
61
+ return EMPTY;
62
+ }),
63
+ )
64
+ .subscribe((x: T) => resolve(x));
65
+ }),
66
+ abortFn,
67
+ );
68
+ }
69
+
70
+ function createAbortablePromise<T>(promise: Promise<T>, abortFn: () => void) {
71
+ const thenFn = promise.then.bind(promise);
72
+ const catchFn = promise.catch.bind(promise);
73
+ const finallyFn = promise.finally?.bind(promise);
74
+ return Object.assign(promise, {
75
+ then: (...args: any[]) => createAbortablePromise(thenFn(...args), abortFn),
76
+ catch: (...args: any[]) => createAbortablePromise(catchFn(...args), abortFn),
77
+ finally: finallyFn ? (...args: any[]) => createAbortablePromise(finallyFn(...args), abortFn) : undefined,
78
+ abort: abortFn,
79
+ });
26
80
  }
@@ -1,372 +1,372 @@
1
- import { HttpRequest, HttpParameterCodec, HttpParams, HttpHeaders, HttpContext } from '@angular/common/http';
2
-
3
- /**
4
- * Custom parameter codec to correctly handle the plus sign in parameter
5
- * values. See https://github.com/angular/angular/issues/18261
6
- */
7
- class ParameterCodec implements HttpParameterCodec {
8
- encodeKey(key: string): string {
9
- return encodeURIComponent(key);
10
- }
11
-
12
- encodeValue(value: string): string {
13
- return encodeURIComponent(value);
14
- }
15
-
16
- decodeKey(key: string): string {
17
- return decodeURIComponent(key);
18
- }
19
-
20
- decodeValue(value: string): string {
21
- return decodeURIComponent(value);
22
- }
23
- }
24
- const ParameterCodecInstance = new ParameterCodec();
25
-
26
- /**
27
- * Defines the options for appending a parameter
28
- */
29
- interface ParameterOptions {
30
- style?: string;
31
- explode?: boolean;
32
- }
33
-
34
- /**
35
- * Base class for a parameter
36
- */
37
- abstract class Parameter {
38
- constructor(
39
- public name: string,
40
- public value: any,
41
- public options: ParameterOptions,
42
- defaultStyle: string,
43
- defaultExplode: boolean,
44
- ) {
45
- this.options = options || {};
46
- if (this.options.style === null || this.options.style === undefined) {
47
- this.options.style = defaultStyle;
48
- }
49
- if (this.options.explode === null || this.options.explode === undefined) {
50
- this.options.explode = defaultExplode;
51
- }
52
- }
53
-
54
- serializeValue(value: any, separator = ','): string {
55
- if (value === null || value === undefined) {
56
- return '';
57
- } else if (value instanceof Array) {
58
- return value
59
- .map((v) => this.serializeValue(v).split(separator).join(encodeURIComponent(separator)))
60
- .join(separator);
61
- } else if (typeof value === 'object') {
62
- const array: string[] = [];
63
- for (const key of Object.keys(value)) {
64
- let propVal = value[key];
65
- if (propVal !== null && propVal !== undefined) {
66
- propVal = this.serializeValue(propVal).split(separator).join(encodeURIComponent(separator));
67
- if (this.options.explode) {
68
- array.push(`${key}=${propVal}`);
69
- } else {
70
- array.push(key);
71
- array.push(propVal);
72
- }
73
- }
74
- }
75
- return array.join(separator);
76
- } else {
77
- return String(value);
78
- }
79
- }
80
- }
81
-
82
- /**
83
- * A parameter in the operation path
84
- */
85
- class PathParameter extends Parameter {
86
- constructor(name: string, value: any, options: ParameterOptions) {
87
- super(name, value, options, 'simple', false);
88
- }
89
-
90
- append(path: string): string {
91
- let value = this.value;
92
- if (value === null || value === undefined) {
93
- value = '';
94
- }
95
- let prefix = this.options.style === 'label' ? '.' : '';
96
- const separator = this.options.explode ? (prefix === '' ? ',' : prefix) : ',';
97
- let alreadySerialized = false;
98
- if (this.options.style === 'matrix') {
99
- // The parameter name is just used as prefix, except in some cases...
100
- prefix = `;${this.name}=`;
101
- if (this.options.explode && typeof value === 'object') {
102
- prefix = ';';
103
- if (value instanceof Array) {
104
- // For arrays we have to repeat the name for each element
105
- value = value.map((v) => `${this.name}=${this.serializeValue(v, ';')}`);
106
- value = value.join(';');
107
- alreadySerialized = true;
108
- } else {
109
- // For objects we have to put each the key / value pairs
110
- value = this.serializeValue(value, ';');
111
- alreadySerialized = true;
112
- }
113
- }
114
- }
115
- value = prefix + (alreadySerialized ? value : this.serializeValue(value, separator));
116
- // Replace both the plain variable and the corresponding variant taking in the prefix and explode into account
117
- path = path.replace(`{${this.name}}`, value);
118
- path = path.replace(`{${prefix}${this.name}${this.options.explode ? '*' : ''}}`, value);
119
- return path;
120
- }
121
-
122
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
123
- // @ts-ignore
124
- serializeValue(value: any, separator = ','): string {
125
- let result = typeof value === 'string' ? encodeURIComponent(value) : super.serializeValue(value, separator);
126
- result = result.replace(/%3D/g, '=');
127
- result = result.replace(/%3B/g, ';');
128
- result = result.replace(/%2C/g, ',');
129
- return result;
130
- }
131
- }
132
-
133
- /**
134
- * A parameter in the query
135
- */
136
- class QueryParameter extends Parameter {
137
- constructor(name: string, value: any, options: ParameterOptions) {
138
- super(name, value, options, 'form', true);
139
- }
140
-
141
- append(params: HttpParams): HttpParams {
142
- if (this.value instanceof Array) {
143
- // Array serialization
144
- if (this.options.explode) {
145
- for (const v of this.value) {
146
- params = params.append(this.name, this.serializeValue(v));
147
- }
148
- } else {
149
- const separator =
150
- this.options.style === 'spaceDelimited' ? ' ' : this.options.style === 'pipeDelimited' ? '|' : ',';
151
- return params.append(this.name, this.serializeValue(this.value, separator));
152
- }
153
- } else if (this.value !== null && typeof this.value === 'object') {
154
- // Object serialization
155
- if (this.options.style === 'deepObject') {
156
- // Append a parameter for each key, in the form `name[key]`
157
- for (const key of Object.keys(this.value)) {
158
- const propVal = this.value[key];
159
- if (propVal !== null && propVal !== undefined) {
160
- params = params.append(`${this.name}[${key}]`, this.serializeValue(propVal));
161
- }
162
- }
163
- } else if (this.options.explode) {
164
- // Append a parameter for each key without using the parameter name
165
- for (const key of Object.keys(this.value)) {
166
- const propVal = this.value[key];
167
- if (propVal !== null && propVal !== undefined) {
168
- params = params.append(key, this.serializeValue(propVal));
169
- }
170
- }
171
- } else {
172
- // Append a single parameter whose values are a comma-separated list of key,value,key,value...
173
- const array: any[] = [];
174
- for (const key of Object.keys(this.value)) {
175
- const propVal = this.value[key];
176
- if (propVal !== null && propVal !== undefined) {
177
- array.push(key);
178
- array.push(propVal);
179
- }
180
- }
181
- params = params.append(this.name, this.serializeValue(array));
182
- }
183
- } else if (this.value !== null && this.value !== undefined) {
184
- // Plain value
185
- params = params.append(this.name, this.serializeValue(this.value));
186
- }
187
- return params;
188
- }
189
- }
190
-
191
- /**
192
- * A parameter in the HTTP request header
193
- */
194
- class HeaderParameter extends Parameter {
195
- constructor(name: string, value: any, options: ParameterOptions) {
196
- super(name, value, options, 'simple', false);
197
- }
198
-
199
- append(headers: HttpHeaders): HttpHeaders {
200
- if (this.value !== null && this.value !== undefined) {
201
- if (this.value instanceof Array) {
202
- for (const v of this.value) {
203
- headers = headers.append(this.name, this.serializeValue(v));
204
- }
205
- } else {
206
- headers = headers.append(this.name, this.serializeValue(this.value));
207
- }
208
- }
209
- return headers;
210
- }
211
- }
212
-
213
- /**
214
- * Helper to build http requests from parameters
215
- */
216
- export class RequestBuilder {
217
- private _path = new Map<string, PathParameter>();
218
- private _query = new Map<string, QueryParameter>();
219
- private _header = new Map<string, HeaderParameter>();
220
- _bodyContent: any | null;
221
- _bodyContentType?: string;
222
-
223
- constructor(
224
- public rootUrl: string,
225
- public operationPath: string,
226
- public method: string,
227
- ) {}
228
-
229
- /**
230
- * Sets a path parameter
231
- */
232
- path(name: string, value: any, options?: ParameterOptions): void {
233
- this._path.set(name, new PathParameter(name, value, options || {}));
234
- }
235
-
236
- /**
237
- * Sets a query parameter
238
- */
239
- query(name: string, value: any, options?: ParameterOptions): void {
240
- this._query.set(name, new QueryParameter(name, value, options || {}));
241
- }
242
-
243
- /**
244
- * Sets a header parameter
245
- */
246
- header(name: string, value: any, options?: ParameterOptions): void {
247
- this._header.set(name, new HeaderParameter(name, value, options || {}));
248
- }
249
-
250
- /**
251
- * Sets the body content, along with the content type
252
- */
253
- body(value: any, contentType = 'application/json'): void {
254
- if (value instanceof Blob) {
255
- this._bodyContentType = value.type;
256
- } else {
257
- this._bodyContentType = contentType;
258
- }
259
- if (this._bodyContentType === 'application/x-www-form-urlencoded' && value !== null && typeof value === 'object') {
260
- // Handle URL-encoded data
261
- const pairs: Array<[string, string]> = [];
262
- for (const key of Object.keys(value)) {
263
- let val = value[key];
264
- if (!(val instanceof Array)) {
265
- val = [val];
266
- }
267
- for (const v of val) {
268
- const formValue = this.formDataValue(v);
269
- if (formValue !== null) {
270
- pairs.push([key, formValue]);
271
- }
272
- }
273
- }
274
- this._bodyContent = pairs.map((p) => `${encodeURIComponent(p[0])}=${encodeURIComponent(p[1])}`).join('&');
275
- } else if (this._bodyContentType === 'multipart/form-data') {
276
- // Handle multipart form data
277
- const formData = new FormData();
278
- if (value !== null && value !== undefined) {
279
- for (const key of Object.keys(value)) {
280
- const val = value[key];
281
- if (val instanceof Array) {
282
- for (const v of val) {
283
- const toAppend = this.formDataValue(v);
284
- if (toAppend !== null) {
285
- formData.append(key, toAppend);
286
- }
287
- }
288
- } else {
289
- const toAppend = this.formDataValue(val);
290
- if (toAppend !== null) {
291
- formData.set(key, toAppend);
292
- }
293
- }
294
- }
295
- }
296
- this._bodyContent = formData;
297
- } else {
298
- // The body is the plain content
299
- this._bodyContent = value;
300
- }
301
- }
302
-
303
- private formDataValue(value: any): any {
304
- if (value === null || value === undefined) {
305
- return null;
306
- }
307
- if (value instanceof Blob) {
308
- return value;
309
- }
310
- if (typeof value === 'object') {
311
- return JSON.stringify(value);
312
- }
313
- return String(value);
314
- }
315
-
316
- /**
317
- * Builds the request with the current set parameters
318
- */
319
- build<T = any>(options?: {
320
- /** Which content types to accept */
321
- accept?: string;
322
-
323
- /** The expected response type */
324
- responseType?: 'json' | 'text' | 'blob' | 'arraybuffer';
325
-
326
- /** Whether to report progress on uploads / downloads */
327
- reportProgress?: boolean;
328
-
329
- /** Allow passing HttpContext for HttpClient */
330
- context?: HttpContext;
331
- }): HttpRequest<T> {
332
- options = options || {};
333
-
334
- // Path parameters
335
- let path = this.operationPath;
336
- for (const pathParam of this._path.values()) {
337
- path = pathParam.append(path);
338
- }
339
- const url = this.rootUrl + path;
340
-
341
- // Query parameters
342
- let httpParams = new HttpParams({
343
- encoder: ParameterCodecInstance,
344
- });
345
- for (const queryParam of this._query.values()) {
346
- httpParams = queryParam.append(httpParams);
347
- }
348
-
349
- // Header parameters
350
- let httpHeaders = new HttpHeaders();
351
- if (options.accept) {
352
- httpHeaders = httpHeaders.append('Accept', options.accept);
353
- }
354
- for (const headerParam of this._header.values()) {
355
- httpHeaders = headerParam.append(httpHeaders);
356
- }
357
-
358
- // Request content headers
359
- if (this._bodyContentType && !(this._bodyContent instanceof FormData)) {
360
- httpHeaders = httpHeaders.set('Content-Type', this._bodyContentType);
361
- }
362
-
363
- // Perform the request
364
- return new HttpRequest<T>(this.method.toUpperCase(), url, this._bodyContent, {
365
- params: httpParams,
366
- headers: httpHeaders,
367
- responseType: options.responseType,
368
- reportProgress: options.reportProgress,
369
- context: options.context,
370
- });
371
- }
372
- }
1
+ import { HttpRequest, HttpParameterCodec, HttpParams, HttpHeaders, HttpContext } from '@angular/common/http';
2
+
3
+ /**
4
+ * Custom parameter codec to correctly handle the plus sign in parameter
5
+ * values. See https://github.com/angular/angular/issues/18261
6
+ */
7
+ class ParameterCodec implements HttpParameterCodec {
8
+ encodeKey(key: string): string {
9
+ return encodeURIComponent(key);
10
+ }
11
+
12
+ encodeValue(value: string): string {
13
+ return encodeURIComponent(value);
14
+ }
15
+
16
+ decodeKey(key: string): string {
17
+ return decodeURIComponent(key);
18
+ }
19
+
20
+ decodeValue(value: string): string {
21
+ return decodeURIComponent(value);
22
+ }
23
+ }
24
+ const ParameterCodecInstance = new ParameterCodec();
25
+
26
+ /**
27
+ * Defines the options for appending a parameter
28
+ */
29
+ interface ParameterOptions {
30
+ style?: string;
31
+ explode?: boolean;
32
+ }
33
+
34
+ /**
35
+ * Base class for a parameter
36
+ */
37
+ abstract class Parameter {
38
+ constructor(
39
+ public name: string,
40
+ public value: any,
41
+ public options: ParameterOptions,
42
+ defaultStyle: string,
43
+ defaultExplode: boolean,
44
+ ) {
45
+ this.options = options || {};
46
+ if (this.options.style === null || this.options.style === undefined) {
47
+ this.options.style = defaultStyle;
48
+ }
49
+ if (this.options.explode === null || this.options.explode === undefined) {
50
+ this.options.explode = defaultExplode;
51
+ }
52
+ }
53
+
54
+ serializeValue(value: any, separator = ','): string {
55
+ if (value === null || value === undefined) {
56
+ return '';
57
+ } else if (value instanceof Array) {
58
+ return value
59
+ .map((v) => this.serializeValue(v).split(separator).join(encodeURIComponent(separator)))
60
+ .join(separator);
61
+ } else if (typeof value === 'object') {
62
+ const array: string[] = [];
63
+ for (const key of Object.keys(value)) {
64
+ let propVal = value[key];
65
+ if (propVal !== null && propVal !== undefined) {
66
+ propVal = this.serializeValue(propVal).split(separator).join(encodeURIComponent(separator));
67
+ if (this.options.explode) {
68
+ array.push(`${key}=${propVal}`);
69
+ } else {
70
+ array.push(key);
71
+ array.push(propVal);
72
+ }
73
+ }
74
+ }
75
+ return array.join(separator);
76
+ } else {
77
+ return String(value);
78
+ }
79
+ }
80
+ }
81
+
82
+ /**
83
+ * A parameter in the operation path
84
+ */
85
+ class PathParameter extends Parameter {
86
+ constructor(name: string, value: any, options: ParameterOptions) {
87
+ super(name, value, options, 'simple', false);
88
+ }
89
+
90
+ append(path: string): string {
91
+ let value = this.value;
92
+ if (value === null || value === undefined) {
93
+ value = '';
94
+ }
95
+ let prefix = this.options.style === 'label' ? '.' : '';
96
+ const separator = this.options.explode ? (prefix === '' ? ',' : prefix) : ',';
97
+ let alreadySerialized = false;
98
+ if (this.options.style === 'matrix') {
99
+ // The parameter name is just used as prefix, except in some cases...
100
+ prefix = `;${this.name}=`;
101
+ if (this.options.explode && typeof value === 'object') {
102
+ prefix = ';';
103
+ if (value instanceof Array) {
104
+ // For arrays we have to repeat the name for each element
105
+ value = value.map((v) => `${this.name}=${this.serializeValue(v, ';')}`);
106
+ value = value.join(';');
107
+ alreadySerialized = true;
108
+ } else {
109
+ // For objects we have to put each the key / value pairs
110
+ value = this.serializeValue(value, ';');
111
+ alreadySerialized = true;
112
+ }
113
+ }
114
+ }
115
+ value = prefix + (alreadySerialized ? value : this.serializeValue(value, separator));
116
+ // Replace both the plain variable and the corresponding variant taking in the prefix and explode into account
117
+ path = path.replace(`{${this.name}}`, value);
118
+ path = path.replace(`{${prefix}${this.name}${this.options.explode ? '*' : ''}}`, value);
119
+ return path;
120
+ }
121
+
122
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
123
+ // @ts-ignore
124
+ serializeValue(value: any, separator = ','): string {
125
+ let result = typeof value === 'string' ? encodeURIComponent(value) : super.serializeValue(value, separator);
126
+ result = result.replace(/%3D/g, '=');
127
+ result = result.replace(/%3B/g, ';');
128
+ result = result.replace(/%2C/g, ',');
129
+ return result;
130
+ }
131
+ }
132
+
133
+ /**
134
+ * A parameter in the query
135
+ */
136
+ class QueryParameter extends Parameter {
137
+ constructor(name: string, value: any, options: ParameterOptions) {
138
+ super(name, value, options, 'form', true);
139
+ }
140
+
141
+ append(params: HttpParams): HttpParams {
142
+ if (this.value instanceof Array) {
143
+ // Array serialization
144
+ if (this.options.explode) {
145
+ for (const v of this.value) {
146
+ params = params.append(this.name, this.serializeValue(v));
147
+ }
148
+ } else {
149
+ const separator =
150
+ this.options.style === 'spaceDelimited' ? ' ' : this.options.style === 'pipeDelimited' ? '|' : ',';
151
+ return params.append(this.name, this.serializeValue(this.value, separator));
152
+ }
153
+ } else if (this.value !== null && typeof this.value === 'object') {
154
+ // Object serialization
155
+ if (this.options.style === 'deepObject') {
156
+ // Append a parameter for each key, in the form `name[key]`
157
+ for (const key of Object.keys(this.value)) {
158
+ const propVal = this.value[key];
159
+ if (propVal !== null && propVal !== undefined) {
160
+ params = params.append(`${this.name}[${key}]`, this.serializeValue(propVal));
161
+ }
162
+ }
163
+ } else if (this.options.explode) {
164
+ // Append a parameter for each key without using the parameter name
165
+ for (const key of Object.keys(this.value)) {
166
+ const propVal = this.value[key];
167
+ if (propVal !== null && propVal !== undefined) {
168
+ params = params.append(key, this.serializeValue(propVal));
169
+ }
170
+ }
171
+ } else {
172
+ // Append a single parameter whose values are a comma-separated list of key,value,key,value...
173
+ const array: any[] = [];
174
+ for (const key of Object.keys(this.value)) {
175
+ const propVal = this.value[key];
176
+ if (propVal !== null && propVal !== undefined) {
177
+ array.push(key);
178
+ array.push(propVal);
179
+ }
180
+ }
181
+ params = params.append(this.name, this.serializeValue(array));
182
+ }
183
+ } else if (this.value !== null && this.value !== undefined) {
184
+ // Plain value
185
+ params = params.append(this.name, this.serializeValue(this.value));
186
+ }
187
+ return params;
188
+ }
189
+ }
190
+
191
+ /**
192
+ * A parameter in the HTTP request header
193
+ */
194
+ class HeaderParameter extends Parameter {
195
+ constructor(name: string, value: any, options: ParameterOptions) {
196
+ super(name, value, options, 'simple', false);
197
+ }
198
+
199
+ append(headers: HttpHeaders): HttpHeaders {
200
+ if (this.value !== null && this.value !== undefined) {
201
+ if (this.value instanceof Array) {
202
+ for (const v of this.value) {
203
+ headers = headers.append(this.name, this.serializeValue(v));
204
+ }
205
+ } else {
206
+ headers = headers.append(this.name, this.serializeValue(this.value));
207
+ }
208
+ }
209
+ return headers;
210
+ }
211
+ }
212
+
213
+ /**
214
+ * Helper to build http requests from parameters
215
+ */
216
+ export class RequestBuilder {
217
+ private _path = new Map<string, PathParameter>();
218
+ private _query = new Map<string, QueryParameter>();
219
+ private _header = new Map<string, HeaderParameter>();
220
+ _bodyContent: any | null;
221
+ _bodyContentType?: string;
222
+
223
+ constructor(
224
+ public rootUrl: string,
225
+ public operationPath: string,
226
+ public method: string,
227
+ ) {}
228
+
229
+ /**
230
+ * Sets a path parameter
231
+ */
232
+ path(name: string, value: any, options?: ParameterOptions): void {
233
+ this._path.set(name, new PathParameter(name, value, options || {}));
234
+ }
235
+
236
+ /**
237
+ * Sets a query parameter
238
+ */
239
+ query(name: string, value: any, options?: ParameterOptions): void {
240
+ this._query.set(name, new QueryParameter(name, value, options || {}));
241
+ }
242
+
243
+ /**
244
+ * Sets a header parameter
245
+ */
246
+ header(name: string, value: any, options?: ParameterOptions): void {
247
+ this._header.set(name, new HeaderParameter(name, value, options || {}));
248
+ }
249
+
250
+ /**
251
+ * Sets the body content, along with the content type
252
+ */
253
+ body(value: any, contentType = 'application/json'): void {
254
+ if (value instanceof Blob) {
255
+ this._bodyContentType = value.type;
256
+ } else {
257
+ this._bodyContentType = contentType;
258
+ }
259
+ if (this._bodyContentType === 'application/x-www-form-urlencoded' && value !== null && typeof value === 'object') {
260
+ // Handle URL-encoded data
261
+ const pairs: Array<[string, string]> = [];
262
+ for (const key of Object.keys(value)) {
263
+ let val = value[key];
264
+ if (!(val instanceof Array)) {
265
+ val = [val];
266
+ }
267
+ for (const v of val) {
268
+ const formValue = this.formDataValue(v);
269
+ if (formValue !== null) {
270
+ pairs.push([key, formValue]);
271
+ }
272
+ }
273
+ }
274
+ this._bodyContent = pairs.map((p) => `${encodeURIComponent(p[0])}=${encodeURIComponent(p[1])}`).join('&');
275
+ } else if (this._bodyContentType === 'multipart/form-data') {
276
+ // Handle multipart form data
277
+ const formData = new FormData();
278
+ if (value !== null && value !== undefined) {
279
+ for (const key of Object.keys(value)) {
280
+ const val = value[key];
281
+ if (val instanceof Array) {
282
+ for (const v of val) {
283
+ const toAppend = this.formDataValue(v);
284
+ if (toAppend !== null) {
285
+ formData.append(key, toAppend);
286
+ }
287
+ }
288
+ } else {
289
+ const toAppend = this.formDataValue(val);
290
+ if (toAppend !== null) {
291
+ formData.set(key, toAppend);
292
+ }
293
+ }
294
+ }
295
+ }
296
+ this._bodyContent = formData;
297
+ } else {
298
+ // The body is the plain content
299
+ this._bodyContent = value;
300
+ }
301
+ }
302
+
303
+ private formDataValue(value: any): any {
304
+ if (value === null || value === undefined) {
305
+ return null;
306
+ }
307
+ if (value instanceof Blob) {
308
+ return value;
309
+ }
310
+ if (typeof value === 'object') {
311
+ return JSON.stringify(value);
312
+ }
313
+ return String(value);
314
+ }
315
+
316
+ /**
317
+ * Builds the request with the current set parameters
318
+ */
319
+ build<T = any>(options?: {
320
+ /** Which content types to accept */
321
+ accept?: string;
322
+
323
+ /** The expected response type */
324
+ responseType?: 'json' | 'text' | 'blob' | 'arraybuffer';
325
+
326
+ /** Whether to report progress on uploads / downloads */
327
+ reportProgress?: boolean;
328
+
329
+ /** Allow passing HttpContext for HttpClient */
330
+ context?: HttpContext;
331
+ }): HttpRequest<T> {
332
+ options = options || {};
333
+
334
+ // Path parameters
335
+ let path = this.operationPath;
336
+ for (const pathParam of this._path.values()) {
337
+ path = pathParam.append(path);
338
+ }
339
+ const url = this.rootUrl + path;
340
+
341
+ // Query parameters
342
+ let httpParams = new HttpParams({
343
+ encoder: ParameterCodecInstance,
344
+ });
345
+ for (const queryParam of this._query.values()) {
346
+ httpParams = queryParam.append(httpParams);
347
+ }
348
+
349
+ // Header parameters
350
+ let httpHeaders = new HttpHeaders();
351
+ if (options.accept) {
352
+ httpHeaders = httpHeaders.append('Accept', options.accept);
353
+ }
354
+ for (const headerParam of this._header.values()) {
355
+ httpHeaders = headerParam.append(httpHeaders);
356
+ }
357
+
358
+ // Request content headers
359
+ if (this._bodyContentType && !(this._bodyContent instanceof FormData)) {
360
+ httpHeaders = httpHeaders.set('Content-Type', this._bodyContentType);
361
+ }
362
+
363
+ // Perform the request
364
+ return new HttpRequest<T>(this.method.toUpperCase(), url, this._bodyContent, {
365
+ params: httpParams,
366
+ headers: httpHeaders,
367
+ responseType: options.responseType,
368
+ reportProgress: options.reportProgress,
369
+ context: options.context,
370
+ });
371
+ }
372
+ }
@@ -16,6 +16,8 @@ class TsTypeAlias extends node_1.TsNode {
16
16
  this.export = (_d = options.export) !== null && _d !== void 0 ? _d : false;
17
17
  }
18
18
  onWrite(builder) {
19
+ if (this.doc)
20
+ (0, write_ts_nodes_1.writeTsNode)(builder, this.doc);
19
21
  if (this.export)
20
22
  builder.append('export ');
21
23
  builder.append('type ');
@@ -51,6 +51,10 @@ class DefaultTypeScriptModelGenerator extends file_generator_1.TypeScriptFileGen
51
51
  getEnum(ctx) {
52
52
  var _a, _b;
53
53
  return ast_1.ts.enum(this.getDeclarationTypeName(ctx, ctx.schema), {
54
+ doc: ast_1.ts.doc({
55
+ description: ctx.schema.description,
56
+ tags: [ctx.schema.deprecated ? ast_1.ts.docTag('deprecated') : null],
57
+ }),
54
58
  export: true,
55
59
  members: ((_b = (_a = ctx.schema.enum) === null || _a === void 0 ? void 0 : _a.map((x) => String(x))) !== null && _b !== void 0 ? _b : []).map((x) => ast_1.ts.enumValue((0, core_1.toCasing)(x, ctx.config.enumValueNameCasing), { value: ast_1.ts.string(x) })),
56
60
  });
@@ -58,7 +62,10 @@ class DefaultTypeScriptModelGenerator extends file_generator_1.TypeScriptFileGen
58
62
  getInterface(ctx, schema) {
59
63
  return ast_1.ts.interface(this.getDeclarationTypeName(ctx, ctx.schema), {
60
64
  export: true,
61
- doc: ast_1.ts.doc({ description: schema.description }),
65
+ doc: ast_1.ts.doc({
66
+ description: schema.description,
67
+ tags: [ctx.schema.deprecated ? ast_1.ts.docTag('deprecated') : null],
68
+ }),
62
69
  members: [...this.getProperties(ctx, schema), this.getIndexer(ctx, schema)],
63
70
  });
64
71
  }
@@ -67,7 +74,10 @@ class DefaultTypeScriptModelGenerator extends file_generator_1.TypeScriptFileGen
67
74
  const hasDiscriminator = schema.discriminator && Object.keys(schema.discriminator.mapping).length > 0;
68
75
  const result = ast_1.ts.typeAlias(this.getDeclarationTypeName(ctx, schema), (_a = (hasDiscriminator ? this.getDiscriminatorType(ctx, schema) : this.getType(ctx, schema, { skipSchemas: true }))) !== null && _a !== void 0 ? _a : this.getAnyType(ctx), {
69
76
  export: true,
70
- doc: ast_1.ts.doc({ description: schema.description }),
77
+ doc: ast_1.ts.doc({
78
+ description: schema.description,
79
+ tags: [ctx.schema.deprecated ? ast_1.ts.docTag('deprecated') : null],
80
+ }),
71
81
  });
72
82
  if (hasDiscriminator) {
73
83
  const propertyValue = this.getDiscriminatorTypeName(ctx, ctx.schema);
@@ -108,7 +118,10 @@ class DefaultTypeScriptModelGenerator extends file_generator_1.TypeScriptFileGen
108
118
  getProperties(ctx, schema) {
109
119
  return Array.from(schema.properties.values()).map((property) => {
110
120
  return ast_1.ts.property(property.name, {
111
- doc: ast_1.ts.doc({ description: property.schema.description }),
121
+ doc: ast_1.ts.doc({
122
+ description: property.schema.description,
123
+ tags: [property.schema.deprecated ? ast_1.ts.docTag('deprecated') : null],
124
+ }),
112
125
  readonly: ctx.config.immutableTypes,
113
126
  optional: !schema.required.has(property.name),
114
127
  type: ast_1.ts.unionType([this.getType(ctx, property.schema), property.schema.nullable ? 'null' : null]),
@@ -78,6 +78,10 @@ class DefaultTypeScriptAngularServiceGenerator extends file_generator_1.TypeScri
78
78
  ]),
79
79
  ast_1.ts.objectType({ members: [ast_1.ts.property('status', { type: 'TStatus' })] }),
80
80
  ]), {
81
+ doc: ast_1.ts.doc({
82
+ description: `Response model for operation ${this.getEndpointMethodName(ctx, endpoint)}`,
83
+ tags: [endpoint.deprecated ? ast_1.ts.docTag('deprecated') : null],
84
+ }),
81
85
  export: true,
82
86
  generics: [
83
87
  ast_1.ts.genericParameter('TStatus', {
@@ -132,7 +136,10 @@ class DefaultTypeScriptAngularServiceGenerator extends file_generator_1.TypeScri
132
136
  for (const parameter of endpoint.parameters) {
133
137
  const schema = parameter.schema;
134
138
  type.members.push(ast_1.ts.property((0, core_1.toCasing)(parameter.name, ctx.config.propertyNameCasing), {
135
- doc: ast_1.ts.doc({ description: parameter.description }),
139
+ doc: ast_1.ts.doc({
140
+ description: parameter.description,
141
+ tags: [parameter.deprecated ? ast_1.ts.docTag('deprecated') : null],
142
+ }),
136
143
  type: schema ? (b) => b.appendModelUsage(ctx.input.models[schema.id]) : this.getAnyType(ctx),
137
144
  optional: !parameter.required,
138
145
  }));
@@ -152,7 +159,14 @@ class DefaultTypeScriptAngularServiceGenerator extends file_generator_1.TypeScri
152
159
  }
153
160
  getClass(ctx) {
154
161
  return ast_1.ts.class(this.getServiceClassName(ctx), {
155
- doc: ast_1.ts.doc({ description: ctx.service.description }),
162
+ doc: ast_1.ts.doc({
163
+ description: ctx.service.description,
164
+ tags: [
165
+ ctx.service.endpoints.length === 0 || ctx.service.endpoints.some((x) => !x.deprecated)
166
+ ? null
167
+ : ast_1.ts.docTag('deprecated'),
168
+ ],
169
+ }),
156
170
  decorators: [
157
171
  ast_1.ts.decorator(ast_1.ts.refs.angular.injectable(), ctx.config.provideKind === 'root' ? [ast_1.ts.toNode({ providedIn: 'root' })] : []),
158
172
  ],
@@ -174,7 +188,7 @@ class DefaultTypeScriptAngularServiceGenerator extends file_generator_1.TypeScri
174
188
  const hasParams = this.hasEndpointParams(ctx, endpoint);
175
189
  const paramsOptional = !endpoint.parameters.some((p) => p.required) && !((_a = endpoint.requestBody) === null || _a === void 0 ? void 0 : _a.required);
176
190
  const responseModelType = ast_1.ts.reference(this.getResponseModelName(ctx, endpoint), this.getResponseModelFilePath(ctx));
177
- const returnType = ast_1.ts.refs.promise([responseModelType]);
191
+ const returnType = ctx.refs.abortablePromise([responseModelType]);
178
192
  const accept = (_d = (_c = (_b = this.getEndpointSuccessResponse(ctx, endpoint)) === null || _b === void 0 ? void 0 : _b.contentOptions[0]) === null || _c === void 0 ? void 0 : _c.type) !== null && _d !== void 0 ? _d : '*/*';
179
193
  const responseType = this.contentTypeToResponseType(accept);
180
194
  return ast_1.ts.method(this.getEndpointMethodName(ctx, endpoint), {
@@ -188,6 +202,10 @@ class DefaultTypeScriptAngularServiceGenerator extends file_generator_1.TypeScri
188
202
  : null,
189
203
  ast_1.ts.parameter('context', { optional: true, type: ast_1.ts.refs.angular.httpContext() }),
190
204
  ],
205
+ doc: ast_1.ts.doc({
206
+ description: endpoint.description,
207
+ tags: [endpoint.deprecated ? ast_1.ts.docTag('deprecated') : null],
208
+ }),
191
209
  returnType,
192
210
  body: (0, core_1.appendValueGroup)([
193
211
  (0, core_1.builderTemplate) `const rb = new ${ctx.refs.requestBuilder()}(this.rootUrl, ${this.getServiceClassName(ctx)}.${this.getEndpointPathPropertyName(ctx, endpoint)}, '${endpoint.method}');`,
@@ -10,6 +10,7 @@ function getReferenceFactories(options) {
10
10
  const utilsDirPath = (0, path_1.resolve)(options.outputDir, options.utilsDirPath);
11
11
  return {
12
12
  // angular-service.utils.ts
13
+ abortablePromise: ast_1.ts.reference.genericFactory('AbortablePromise', (0, path_1.join)(utilsDirPath, 'angular-service.utils.ts')),
13
14
  waitForResponse: ast_1.ts.reference.genericFactory('waitForResponse', (0, path_1.join)(utilsDirPath, 'angular-service.utils.ts')),
14
15
  // request-builder.ts
15
16
  requestBuilder: ast_1.ts.reference.factory('RequestBuilder', (0, path_1.join)(utilsDirPath, 'request-builder.ts')),
@@ -39,7 +39,14 @@ class DefaultTypeScriptFetchClientGenerator extends file_generator_1.TypeScriptF
39
39
  }
40
40
  getInterface(ctx) {
41
41
  return ast_1.ts.interface(this.getInterfaceName(ctx), {
42
- doc: ast_1.ts.doc({ description: ctx.service.description }),
42
+ doc: ast_1.ts.doc({
43
+ description: ctx.service.description,
44
+ tags: [
45
+ ctx.service.endpoints.length === 0 || ctx.service.endpoints.some((x) => !x.deprecated)
46
+ ? null
47
+ : ast_1.ts.docTag('deprecated'),
48
+ ],
49
+ }),
43
50
  export: true,
44
51
  members: ctx.service.endpoints.map((endpoint) => this.getInterfaceEndpointMethod(ctx, endpoint)),
45
52
  });
@@ -50,13 +57,14 @@ class DefaultTypeScriptFetchClientGenerator extends file_generator_1.TypeScriptF
50
57
  const bodySchema = (_b = (_a = endpoint.requestBody) === null || _a === void 0 ? void 0 : _a.content[0]) === null || _b === void 0 ? void 0 : _b.schema;
51
58
  const responseSchema = this.getResponseSchema(ctx, endpoint);
52
59
  return ast_1.ts.method((0, core_1.toCasing)(endpoint.name, ctx.config.methodCasing), {
53
- doc: ast_1.ts.doc({ description: endpoint.description }),
60
+ doc: ast_1.ts.doc({ description: endpoint.description, tags: [endpoint.deprecated ? ast_1.ts.docTag('deprecated') : null] }),
54
61
  parameters: [
55
62
  params.length > 0
56
63
  ? ast_1.ts.parameter('params', {
57
64
  description: 'Parameters for the endpoint.',
58
65
  type: ast_1.ts.objectType({
59
66
  members: params.map((x) => ast_1.ts.property((0, core_1.toCasing)(x.name, ctx.config.propertyNameCasing), {
67
+ doc: ast_1.ts.doc({ tags: [x.deprecated ? ast_1.ts.docTag('deprecated') : null] }),
60
68
  type: this.getSchemaType(ctx, x.schema),
61
69
  optional: !x.required,
62
70
  })),
@@ -92,7 +100,14 @@ class DefaultTypeScriptFetchClientGenerator extends file_generator_1.TypeScriptF
92
100
  }
93
101
  getClass(ctx) {
94
102
  return ast_1.ts.class(this.getClassName(ctx), {
95
- doc: ast_1.ts.doc({ description: ctx.service.description }),
103
+ doc: ast_1.ts.doc({
104
+ description: ctx.service.description,
105
+ tags: [
106
+ ctx.service.endpoints.length === 0 || ctx.service.endpoints.some((x) => !x.deprecated)
107
+ ? null
108
+ : ast_1.ts.docTag('deprecated'),
109
+ ],
110
+ }),
96
111
  export: true,
97
112
  implements: this.shouldGenerateInterface(ctx)
98
113
  ? [ast_1.ts.reference(this.getInterfaceName(ctx), this.getInterfaceFilePath(ctx))]
@@ -13,6 +13,8 @@ export class TsTypeAlias extends TsNode {
13
13
  this.export = (_d = options.export) !== null && _d !== void 0 ? _d : false;
14
14
  }
15
15
  onWrite(builder) {
16
+ if (this.doc)
17
+ writeTsNode(builder, this.doc);
16
18
  if (this.export)
17
19
  builder.append('export ');
18
20
  builder.append('type ');
@@ -48,6 +48,10 @@ export class DefaultTypeScriptModelGenerator extends TypeScriptFileGenerator {
48
48
  getEnum(ctx) {
49
49
  var _a, _b;
50
50
  return ts.enum(this.getDeclarationTypeName(ctx, ctx.schema), {
51
+ doc: ts.doc({
52
+ description: ctx.schema.description,
53
+ tags: [ctx.schema.deprecated ? ts.docTag('deprecated') : null],
54
+ }),
51
55
  export: true,
52
56
  members: ((_b = (_a = ctx.schema.enum) === null || _a === void 0 ? void 0 : _a.map((x) => String(x))) !== null && _b !== void 0 ? _b : []).map((x) => ts.enumValue(toCasing(x, ctx.config.enumValueNameCasing), { value: ts.string(x) })),
53
57
  });
@@ -55,7 +59,10 @@ export class DefaultTypeScriptModelGenerator extends TypeScriptFileGenerator {
55
59
  getInterface(ctx, schema) {
56
60
  return ts.interface(this.getDeclarationTypeName(ctx, ctx.schema), {
57
61
  export: true,
58
- doc: ts.doc({ description: schema.description }),
62
+ doc: ts.doc({
63
+ description: schema.description,
64
+ tags: [ctx.schema.deprecated ? ts.docTag('deprecated') : null],
65
+ }),
59
66
  members: [...this.getProperties(ctx, schema), this.getIndexer(ctx, schema)],
60
67
  });
61
68
  }
@@ -64,7 +71,10 @@ export class DefaultTypeScriptModelGenerator extends TypeScriptFileGenerator {
64
71
  const hasDiscriminator = schema.discriminator && Object.keys(schema.discriminator.mapping).length > 0;
65
72
  const result = ts.typeAlias(this.getDeclarationTypeName(ctx, schema), (_a = (hasDiscriminator ? this.getDiscriminatorType(ctx, schema) : this.getType(ctx, schema, { skipSchemas: true }))) !== null && _a !== void 0 ? _a : this.getAnyType(ctx), {
66
73
  export: true,
67
- doc: ts.doc({ description: schema.description }),
74
+ doc: ts.doc({
75
+ description: schema.description,
76
+ tags: [ctx.schema.deprecated ? ts.docTag('deprecated') : null],
77
+ }),
68
78
  });
69
79
  if (hasDiscriminator) {
70
80
  const propertyValue = this.getDiscriminatorTypeName(ctx, ctx.schema);
@@ -105,7 +115,10 @@ export class DefaultTypeScriptModelGenerator extends TypeScriptFileGenerator {
105
115
  getProperties(ctx, schema) {
106
116
  return Array.from(schema.properties.values()).map((property) => {
107
117
  return ts.property(property.name, {
108
- doc: ts.doc({ description: property.schema.description }),
118
+ doc: ts.doc({
119
+ description: property.schema.description,
120
+ tags: [property.schema.deprecated ? ts.docTag('deprecated') : null],
121
+ }),
109
122
  readonly: ctx.config.immutableTypes,
110
123
  optional: !schema.required.has(property.name),
111
124
  type: ts.unionType([this.getType(ctx, property.schema), property.schema.nullable ? 'null' : null]),
@@ -75,6 +75,10 @@ export class DefaultTypeScriptAngularServiceGenerator extends TypeScriptFileGene
75
75
  ]),
76
76
  ts.objectType({ members: [ts.property('status', { type: 'TStatus' })] }),
77
77
  ]), {
78
+ doc: ts.doc({
79
+ description: `Response model for operation ${this.getEndpointMethodName(ctx, endpoint)}`,
80
+ tags: [endpoint.deprecated ? ts.docTag('deprecated') : null],
81
+ }),
78
82
  export: true,
79
83
  generics: [
80
84
  ts.genericParameter('TStatus', {
@@ -129,7 +133,10 @@ export class DefaultTypeScriptAngularServiceGenerator extends TypeScriptFileGene
129
133
  for (const parameter of endpoint.parameters) {
130
134
  const schema = parameter.schema;
131
135
  type.members.push(ts.property(toCasing(parameter.name, ctx.config.propertyNameCasing), {
132
- doc: ts.doc({ description: parameter.description }),
136
+ doc: ts.doc({
137
+ description: parameter.description,
138
+ tags: [parameter.deprecated ? ts.docTag('deprecated') : null],
139
+ }),
133
140
  type: schema ? (b) => b.appendModelUsage(ctx.input.models[schema.id]) : this.getAnyType(ctx),
134
141
  optional: !parameter.required,
135
142
  }));
@@ -149,7 +156,14 @@ export class DefaultTypeScriptAngularServiceGenerator extends TypeScriptFileGene
149
156
  }
150
157
  getClass(ctx) {
151
158
  return ts.class(this.getServiceClassName(ctx), {
152
- doc: ts.doc({ description: ctx.service.description }),
159
+ doc: ts.doc({
160
+ description: ctx.service.description,
161
+ tags: [
162
+ ctx.service.endpoints.length === 0 || ctx.service.endpoints.some((x) => !x.deprecated)
163
+ ? null
164
+ : ts.docTag('deprecated'),
165
+ ],
166
+ }),
153
167
  decorators: [
154
168
  ts.decorator(ts.refs.angular.injectable(), ctx.config.provideKind === 'root' ? [ts.toNode({ providedIn: 'root' })] : []),
155
169
  ],
@@ -171,7 +185,7 @@ export class DefaultTypeScriptAngularServiceGenerator extends TypeScriptFileGene
171
185
  const hasParams = this.hasEndpointParams(ctx, endpoint);
172
186
  const paramsOptional = !endpoint.parameters.some((p) => p.required) && !((_a = endpoint.requestBody) === null || _a === void 0 ? void 0 : _a.required);
173
187
  const responseModelType = ts.reference(this.getResponseModelName(ctx, endpoint), this.getResponseModelFilePath(ctx));
174
- const returnType = ts.refs.promise([responseModelType]);
188
+ const returnType = ctx.refs.abortablePromise([responseModelType]);
175
189
  const accept = (_d = (_c = (_b = this.getEndpointSuccessResponse(ctx, endpoint)) === null || _b === void 0 ? void 0 : _b.contentOptions[0]) === null || _c === void 0 ? void 0 : _c.type) !== null && _d !== void 0 ? _d : '*/*';
176
190
  const responseType = this.contentTypeToResponseType(accept);
177
191
  return ts.method(this.getEndpointMethodName(ctx, endpoint), {
@@ -185,6 +199,10 @@ export class DefaultTypeScriptAngularServiceGenerator extends TypeScriptFileGene
185
199
  : null,
186
200
  ts.parameter('context', { optional: true, type: ts.refs.angular.httpContext() }),
187
201
  ],
202
+ doc: ts.doc({
203
+ description: endpoint.description,
204
+ tags: [endpoint.deprecated ? ts.docTag('deprecated') : null],
205
+ }),
188
206
  returnType,
189
207
  body: appendValueGroup([
190
208
  s `const rb = new ${ctx.refs.requestBuilder()}(this.rootUrl, ${this.getServiceClassName(ctx)}.${this.getEndpointPathPropertyName(ctx, endpoint)}, '${endpoint.method}');`,
@@ -7,6 +7,7 @@ export function getReferenceFactories(options) {
7
7
  const utilsDirPath = resolve(options.outputDir, options.utilsDirPath);
8
8
  return {
9
9
  // angular-service.utils.ts
10
+ abortablePromise: ts.reference.genericFactory('AbortablePromise', join(utilsDirPath, 'angular-service.utils.ts')),
10
11
  waitForResponse: ts.reference.genericFactory('waitForResponse', join(utilsDirPath, 'angular-service.utils.ts')),
11
12
  // request-builder.ts
12
13
  requestBuilder: ts.reference.factory('RequestBuilder', join(utilsDirPath, 'request-builder.ts')),
@@ -36,7 +36,14 @@ export class DefaultTypeScriptFetchClientGenerator extends TypeScriptFileGenerat
36
36
  }
37
37
  getInterface(ctx) {
38
38
  return ts.interface(this.getInterfaceName(ctx), {
39
- doc: ts.doc({ description: ctx.service.description }),
39
+ doc: ts.doc({
40
+ description: ctx.service.description,
41
+ tags: [
42
+ ctx.service.endpoints.length === 0 || ctx.service.endpoints.some((x) => !x.deprecated)
43
+ ? null
44
+ : ts.docTag('deprecated'),
45
+ ],
46
+ }),
40
47
  export: true,
41
48
  members: ctx.service.endpoints.map((endpoint) => this.getInterfaceEndpointMethod(ctx, endpoint)),
42
49
  });
@@ -47,13 +54,14 @@ export class DefaultTypeScriptFetchClientGenerator extends TypeScriptFileGenerat
47
54
  const bodySchema = (_b = (_a = endpoint.requestBody) === null || _a === void 0 ? void 0 : _a.content[0]) === null || _b === void 0 ? void 0 : _b.schema;
48
55
  const responseSchema = this.getResponseSchema(ctx, endpoint);
49
56
  return ts.method(toCasing(endpoint.name, ctx.config.methodCasing), {
50
- doc: ts.doc({ description: endpoint.description }),
57
+ doc: ts.doc({ description: endpoint.description, tags: [endpoint.deprecated ? ts.docTag('deprecated') : null] }),
51
58
  parameters: [
52
59
  params.length > 0
53
60
  ? ts.parameter('params', {
54
61
  description: 'Parameters for the endpoint.',
55
62
  type: ts.objectType({
56
63
  members: params.map((x) => ts.property(toCasing(x.name, ctx.config.propertyNameCasing), {
64
+ doc: ts.doc({ tags: [x.deprecated ? ts.docTag('deprecated') : null] }),
57
65
  type: this.getSchemaType(ctx, x.schema),
58
66
  optional: !x.required,
59
67
  })),
@@ -89,7 +97,14 @@ export class DefaultTypeScriptFetchClientGenerator extends TypeScriptFileGenerat
89
97
  }
90
98
  getClass(ctx) {
91
99
  return ts.class(this.getClassName(ctx), {
92
- doc: ts.doc({ description: ctx.service.description }),
100
+ doc: ts.doc({
101
+ description: ctx.service.description,
102
+ tags: [
103
+ ctx.service.endpoints.length === 0 || ctx.service.endpoints.some((x) => !x.deprecated)
104
+ ? null
105
+ : ts.docTag('deprecated'),
106
+ ],
107
+ }),
93
108
  export: true,
94
109
  implements: this.shouldGenerateInterface(ctx)
95
110
  ? [ts.reference(this.getInterfaceName(ctx), this.getInterfaceFilePath(ctx))]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goast/typescript",
3
- "version": "0.2.14",
3
+ "version": "0.2.16",
4
4
  "repository": "https://github.com/MaSch0212/goast.git",
5
5
  "author": {
6
6
  "name": "Marc Schmidt (MaSch0212)",
@@ -1,6 +1,13 @@
1
1
  import { ts } from '../../../ast';
2
2
  import type { TypeScriptAngularServicesGeneratorConfig } from './models';
3
3
  export declare function getReferenceFactories(options: TypeScriptAngularServicesGeneratorConfig): {
4
+ abortablePromise: (<TBuilder extends import("@goast/core").SourceBuilder<never>>(generics: [ts.Type<TBuilder>]) => ts.Reference<TBuilder, never>) & {
5
+ refName: string;
6
+ moduleNameOrfilePath: import("@goast/core").Nullable<string>;
7
+ infer: <TBuilder_1 extends import("@goast/core").SourceBuilder<never>>() => ts.Reference<TBuilder_1, never>;
8
+ } & {
9
+ moduleNameOrfilePath: string;
10
+ };
4
11
  waitForResponse: (<TBuilder extends import("@goast/core").SourceBuilder<never>>(generics: [ts.Type<TBuilder>]) => ts.Reference<TBuilder, never>) & {
5
12
  refName: string;
6
13
  moduleNameOrfilePath: import("@goast/core").Nullable<string>;