diff --git a/src/index.ts b/src/index.ts index ef7a8b1b..78bf0546 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,6 +4,7 @@ import { parse as parseV2 } from './openApi/v2'; import { parse as parseV3 } from './openApi/v3'; import { getOpenApiSpec } from './utils/getOpenApiSpec'; import { getOpenApiVersion, OpenApiVersion } from './utils/getOpenApiVersion'; +import { isDefined } from './utils/isDefined'; import { isString } from './utils/isString'; import { postProcessClient } from './utils/postProcessClient'; import { registerHandlebarTemplates } from './utils/registerHandlebarTemplates'; @@ -64,6 +65,10 @@ export const generate = async ({ request, write = true, }: Options): Promise => { + if (httpClient === HttpClient.ANGULAR && isDefined(clientName)) { + throw new Error('Angular client does not support --name property'); + } + const openApi = isString(input) ? await getOpenApiSpec(input) : input; const openApiVersion = getOpenApiVersion(openApi); const templates = registerHandlebarTemplates({ diff --git a/src/templates/core/angular/getHeaders.hbs b/src/templates/core/angular/getHeaders.hbs index 009b3a84..f9f6b8a2 100644 --- a/src/templates/core/angular/getHeaders.hbs +++ b/src/templates/core/angular/getHeaders.hbs @@ -1,4 +1,4 @@ -const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptions): Promise => { +const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptions): Promise => { const token = await resolve(options, config.TOKEN); const username = await resolve(options, config.USERNAME); const password = await resolve(options, config.PASSWORD); @@ -15,7 +15,7 @@ const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptions): Pr [key]: String(value), }), {} as Record); - const headers = new Headers(defaultHeaders); + const headers = new HttpHeaders(defaultHeaders); if (isStringWithValue(token)) { headers.append('Authorization', `Bearer ${token}`); diff --git a/src/templates/core/angular/getRequestBody.hbs b/src/templates/core/angular/getRequestBody.hbs index 4d4780c4..9c404966 100644 --- a/src/templates/core/angular/getRequestBody.hbs +++ b/src/templates/core/angular/getRequestBody.hbs @@ -1,4 +1,4 @@ -const getRequestBody = (options: ApiRequestOptions): BodyInit | undefined => { +const getRequestBody = (options: ApiRequestOptions): any => { if (options.body) { if (options.mediaType?.includes('/json')) { return JSON.stringify(options.body) diff --git a/src/templates/core/angular/getResponseBody.hbs b/src/templates/core/angular/getResponseBody.hbs index 98ae33e2..9a6d359b 100644 --- a/src/templates/core/angular/getResponseBody.hbs +++ b/src/templates/core/angular/getResponseBody.hbs @@ -1,18 +1,6 @@ -const getResponseBody = async (response: Response): Promise => { - if (response.status !== 204) { - try { - const contentType = response.headers.get('Content-Type'); - if (contentType) { - const isJSON = contentType.toLowerCase().startsWith('application/json'); - if (isJSON) { - return await response.json(); - } else { - return await response.text(); - } - } - } catch (error) { - console.error(error); - } +const getResponseBody = (response: HttpResponse): T | undefined => { + if (response.status !== 204 && response.body !== null) { + return response.body; } return; }; diff --git a/src/templates/core/angular/getResponseHeader.hbs b/src/templates/core/angular/getResponseHeader.hbs index 0a63760f..291f7aec 100644 --- a/src/templates/core/angular/getResponseHeader.hbs +++ b/src/templates/core/angular/getResponseHeader.hbs @@ -1,8 +1,8 @@ -const getResponseHeader = (response: Response, responseHeader?: string): string | undefined => { +const getResponseHeader = (response: HttpResponse, responseHeader?: string): string | undefined => { if (responseHeader) { - const content = response.headers.get(responseHeader); - if (isString(content)) { - return content; + const value = response.headers.get(responseHeader); + if (isString(value)) { + return value; } } return; diff --git a/src/templates/core/angular/request.hbs b/src/templates/core/angular/request.hbs index de55c796..bfbba7fb 100644 --- a/src/templates/core/angular/request.hbs +++ b/src/templates/core/angular/request.hbs @@ -1,13 +1,11 @@ {{>header}} -import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs'; import { ApiError } from './ApiError'; import type { ApiRequestOptions } from './ApiRequestOptions'; import type { ApiResult } from './ApiResult'; -import { CancelablePromise } from './CancelablePromise'; -import type { OnCancel } from './CancelablePromise'; import type { OpenAPIConfig } from './OpenAPI'; {{>functions/isDefined}} @@ -61,37 +59,40 @@ import type { OpenAPIConfig } from './OpenAPI'; /** * Request method * @param config The OpenAPI configuration object + * @param http The Angular HTTP client * @param options The request options from the service * @returns CancelablePromise * @throws ApiError */ -export const request = (config: OpenAPIConfig, options: ApiRequestOptions): CancelablePromise => { - return new CancelablePromise(async (resolve, reject, onCancel) => { +export const request = (config: OpenAPIConfig, http: HttpClient, options: ApiRequestOptions): Observable => { + return new Observable(subscriber => { try { const url = getUrl(config, options); const formData = getFormData(options); const body = getRequestBody(options); - const headers = await getHeaders(config, options); + getHeaders(config, options).then(headers => { - if (!onCancel.isCancelled) { - const response = await sendRequest(config, options, url, formData, body, headers, onCancel); - const responseBody = await getResponseBody(response); - const responseHeader = getResponseHeader(response, options.responseHeader); + sendRequest(config, options, http, url, formData, body, headers) + .subscribe(response => { + const responseBody = getResponseBody(response); + const responseHeader = getResponseHeader(response, options.responseHeader); - const result: ApiResult = { - url, - ok: response.ok, - status: response.status, - statusText: response.statusText, - body: responseHeader ?? responseBody, - }; + const result: ApiResult = { + url, + ok: response.ok, + status: response.status, + statusText: response.statusText, + body: responseHeader ?? responseBody, + }; - catchErrors(options, result); + catchErrors(options, result); - resolve(result.body); - } + subscriber.next(result.body); + }); + }); } catch (error) { - reject(error); + subscriber.error(error); } }); }; + diff --git a/src/templates/core/angular/sendRequest.hbs b/src/templates/core/angular/sendRequest.hbs index fa10a698..16790833 100644 --- a/src/templates/core/angular/sendRequest.hbs +++ b/src/templates/core/angular/sendRequest.hbs @@ -1,26 +1,16 @@ -export const sendRequest = async ( +export const sendRequest = ( config: OpenAPIConfig, options: ApiRequestOptions, + http: HttpClient, url: string, + body: any, formData: FormData | undefined, - body: BodyInit | undefined, - headers: Headers, - onCancel: OnCancel -): Promise => { - const controller = new AbortController(); - - const request: RequestInit = { + headers: HttpHeaders +): Observable> => { + return http.request(url, options.method, { headers, - body: body || formData, - method: options.method, - signal: controller.signal, - }; - - if (config.WITH_CREDENTIALS) { - request.credentials = config.CREDENTIALS; - } - - onCancel(() => controller.abort()); - - return await fetch(url, request); + body: body ?? formData, + withCredentials: config.WITH_CREDENTIALS, + observe: 'response', + }); }; diff --git a/src/templates/core/axios/request.hbs b/src/templates/core/axios/request.hbs index ce3f2c05..1ec09e8a 100644 --- a/src/templates/core/axios/request.hbs +++ b/src/templates/core/axios/request.hbs @@ -74,7 +74,7 @@ export const request = (config: OpenAPIConfig, options: ApiRequestOptions): C const headers = await getHeaders(config, options, formData); if (!onCancel.isCancelled) { - const response = await sendRequest(config, options, url, formData, body, headers, onCancel); + const response = await sendRequest(config, options, url, body, formData, headers, onCancel); const responseBody = getResponseBody(response); const responseHeader = getResponseHeader(response, options.responseHeader); diff --git a/src/templates/core/axios/sendRequest.hbs b/src/templates/core/axios/sendRequest.hbs index 41af3b46..3f0d6e02 100644 --- a/src/templates/core/axios/sendRequest.hbs +++ b/src/templates/core/axios/sendRequest.hbs @@ -1,12 +1,12 @@ -const sendRequest = async ( +const sendRequest = async ( config: OpenAPIConfig, options: ApiRequestOptions, url: string, - formData: FormData | undefined, body: any, + formData: FormData | undefined, headers: Record, onCancel: OnCancel -): Promise> => { +): Promise> => { const source = axios.CancelToken.source(); const requestConfig: AxiosRequestConfig = { diff --git a/src/templates/core/fetch/getRequestBody.hbs b/src/templates/core/fetch/getRequestBody.hbs index 4d4780c4..9c404966 100644 --- a/src/templates/core/fetch/getRequestBody.hbs +++ b/src/templates/core/fetch/getRequestBody.hbs @@ -1,4 +1,4 @@ -const getRequestBody = (options: ApiRequestOptions): BodyInit | undefined => { +const getRequestBody = (options: ApiRequestOptions): any => { if (options.body) { if (options.mediaType?.includes('/json')) { return JSON.stringify(options.body) diff --git a/src/templates/core/fetch/request.hbs b/src/templates/core/fetch/request.hbs index 5815f6e4..13bf6a3e 100644 --- a/src/templates/core/fetch/request.hbs +++ b/src/templates/core/fetch/request.hbs @@ -71,7 +71,7 @@ export const request = (config: OpenAPIConfig, options: ApiRequestOptions): C const headers = await getHeaders(config, options); if (!onCancel.isCancelled) { - const response = await sendRequest(config, options, url, formData, body, headers, onCancel); + const response = await sendRequest(config, options, url, body, formData, headers, onCancel); const responseBody = await getResponseBody(response); const responseHeader = getResponseHeader(response, options.responseHeader); diff --git a/src/templates/core/fetch/sendRequest.hbs b/src/templates/core/fetch/sendRequest.hbs index d0a0c7c7..73f71f42 100644 --- a/src/templates/core/fetch/sendRequest.hbs +++ b/src/templates/core/fetch/sendRequest.hbs @@ -2,8 +2,8 @@ export const sendRequest = async ( config: OpenAPIConfig, options: ApiRequestOptions, url: string, + body: any, formData: FormData | undefined, - body: BodyInit | undefined, headers: Headers, onCancel: OnCancel ): Promise => { diff --git a/src/templates/core/node/getRequestBody.hbs b/src/templates/core/node/getRequestBody.hbs index 7cc68fb8..e0b420c2 100644 --- a/src/templates/core/node/getRequestBody.hbs +++ b/src/templates/core/node/getRequestBody.hbs @@ -1,4 +1,4 @@ -const getRequestBody = (options: ApiRequestOptions): BodyInit | undefined => { +const getRequestBody = (options: ApiRequestOptions): any => { if (options.body) { if (options.mediaType?.includes('/json')) { return JSON.stringify(options.body) diff --git a/src/templates/core/node/request.hbs b/src/templates/core/node/request.hbs index fdd33a26..ba82a166 100644 --- a/src/templates/core/node/request.hbs +++ b/src/templates/core/node/request.hbs @@ -75,7 +75,7 @@ export const request = (config: OpenAPIConfig, options: ApiRequestOptions): C const headers = await getHeaders(config, options); if (!onCancel.isCancelled) { - const response = await sendRequest(options, url, formData, body, headers, onCancel); + const response = await sendRequest(options, url, body, formData, headers, onCancel); const responseBody = await getResponseBody(response); const responseHeader = getResponseHeader(response, options.responseHeader); diff --git a/src/templates/core/node/sendRequest.hbs b/src/templates/core/node/sendRequest.hbs index dd6ac3df..b7b160f4 100644 --- a/src/templates/core/node/sendRequest.hbs +++ b/src/templates/core/node/sendRequest.hbs @@ -1,8 +1,8 @@ export const sendRequest = async ( options: ApiRequestOptions, url: string, + body: any, formData: FormData | undefined, - body: BodyInit | undefined, headers: Headers, onCancel: OnCancel ): Promise => { diff --git a/src/templates/core/xhr/request.hbs b/src/templates/core/xhr/request.hbs index b5f91d4b..7732cd6e 100644 --- a/src/templates/core/xhr/request.hbs +++ b/src/templates/core/xhr/request.hbs @@ -74,7 +74,7 @@ export const request = (config: OpenAPIConfig, options: ApiRequestOptions): C const headers = await getHeaders(config, options); if (!onCancel.isCancelled) { - const response = await sendRequest(config, options, url, formData, body, headers, onCancel); + const response = await sendRequest(config, options, url, body, formData, headers, onCancel); const responseBody = getResponseBody(response); const responseHeader = getResponseHeader(response, options.responseHeader); diff --git a/src/templates/core/xhr/sendRequest.hbs b/src/templates/core/xhr/sendRequest.hbs index ea2f8da5..0badf8da 100644 --- a/src/templates/core/xhr/sendRequest.hbs +++ b/src/templates/core/xhr/sendRequest.hbs @@ -2,8 +2,8 @@ export const sendRequest = async ( config: OpenAPIConfig, options: ApiRequestOptions, url: string, - formData: FormData | undefined, body: any, + formData: FormData | undefined, headers: Headers, onCancel: OnCancel ): Promise => { diff --git a/src/templates/exportService.hbs b/src/templates/exportService.hbs index f240e251..a8acd417 100644 --- a/src/templates/exportService.hbs +++ b/src/templates/exportService.hbs @@ -72,10 +72,11 @@ export class {{{name}}}{{{@root.postfix}}} { {{else}} {{#equals @root.httpClient 'angular'}} public {{{name}}}({{>parameters}}): Observable<{{>result}}> { + return __request(OpenAPI, this.http, { {{else}} public static {{{name}}}({{>parameters}}): CancelablePromise<{{>result}}> { - {{/equals}} return __request(OpenAPI, { + {{/equals}} {{/if}} method: '{{{method}}}', url: '{{{path}}}', diff --git a/src/utils/registerHandlebarTemplates.ts b/src/utils/registerHandlebarTemplates.ts index 4949013b..d2bb51c0 100644 --- a/src/utils/registerHandlebarTemplates.ts +++ b/src/utils/registerHandlebarTemplates.ts @@ -2,6 +2,12 @@ import Handlebars from 'handlebars/runtime'; import { HttpClient } from '../HttpClient'; import templateClient from '../templates/client.hbs'; +import angularGetHeaders from '../templates/core/angular/getHeaders.hbs'; +import angularGetRequestBody from '../templates/core/angular/getRequestBody.hbs'; +import angularGetResponseBody from '../templates/core/angular/getResponseBody.hbs'; +import angularGetResponseHeader from '../templates/core/angular/getResponseHeader.hbs'; +import angularRequest from '../templates/core/angular/request.hbs'; +import angularSendRequest from '../templates/core/angular/sendRequest.hbs'; import templateCoreApiError from '../templates/core/ApiError.hbs'; import templateCoreApiRequestOptions from '../templates/core/ApiRequestOptions.hbs'; import templateCoreApiResult from '../templates/core/ApiResult.hbs'; @@ -19,12 +25,6 @@ import fetchGetResponseBody from '../templates/core/fetch/getResponseBody.hbs'; import fetchGetResponseHeader from '../templates/core/fetch/getResponseHeader.hbs'; import fetchRequest from '../templates/core/fetch/request.hbs'; import fetchSendRequest from '../templates/core/fetch/sendRequest.hbs'; -import angularGetHeaders from '../templates/core/angular/getHeaders.hbs'; -import angularGetRequestBody from '../templates/core/angular/getRequestBody.hbs'; -import angularGetResponseBody from '../templates/core/angular/getResponseBody.hbs'; -import angularGetResponseHeader from '../templates/core/angular/getResponseHeader.hbs'; -import angularRequest from '../templates/core/angular/request.hbs'; -import angularSendRequest from '../templates/core/angular/sendRequest.hbs'; import functionBase64 from '../templates/core/functions/base64.hbs'; import functionCatchErrors from '../templates/core/functions/catchErrors.hbs'; import functionGetFormData from '../templates/core/functions/getFormData.hbs'; diff --git a/test/__snapshots__/index.spec.ts.snap b/test/__snapshots__/index.spec.ts.snap index f280a93b..00967140 100644 --- a/test/__snapshots__/index.spec.ts.snap +++ b/test/__snapshots__/index.spec.ts.snap @@ -399,7 +399,7 @@ const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptions): Pr return headers; }; -const getRequestBody = (options: ApiRequestOptions): BodyInit | undefined => { +const getRequestBody = (options: ApiRequestOptions): any => { if (options.body) { if (options.mediaType?.includes('/json')) { return JSON.stringify(options.body) @@ -416,8 +416,8 @@ export const sendRequest = async ( config: OpenAPIConfig, options: ApiRequestOptions, url: string, + body: any, formData: FormData | undefined, - body: BodyInit | undefined, headers: Headers, onCancel: OnCancel ): Promise => { @@ -506,7 +506,7 @@ export const request = (config: OpenAPIConfig, options: ApiRequestOptions): C const headers = await getHeaders(config, options); if (!onCancel.isCancelled) { - const response = await sendRequest(config, options, url, formData, body, headers, onCancel); + const response = await sendRequest(config, options, url, body, formData, headers, onCancel); const responseBody = await getResponseBody(response); const responseHeader = getResponseHeader(response, options.responseHeader); @@ -2193,6 +2193,7 @@ exports[`v2 should generate: ./test/generated/v2/services/ComplexService.ts 1`] /* tslint:disable */ /* eslint-disable */ import type { ModelWithString } from '../models/ModelWithString'; + import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; @@ -2260,6 +2261,7 @@ exports[`v2 should generate: ./test/generated/v2/services/DefaultsService.ts 1`] /* tslint:disable */ /* eslint-disable */ import type { ModelWithString } from '../models/ModelWithString'; + import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; @@ -2699,6 +2701,7 @@ exports[`v2 should generate: ./test/generated/v2/services/ResponseService.ts 1`] import type { ModelThatExtends } from '../models/ModelThatExtends'; import type { ModelThatExtendsExtends } from '../models/ModelThatExtendsExtends'; import type { ModelWithString } from '../models/ModelWithString'; + import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; @@ -3296,7 +3299,7 @@ const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptions): Pr return headers; }; -const getRequestBody = (options: ApiRequestOptions): BodyInit | undefined => { +const getRequestBody = (options: ApiRequestOptions): any => { if (options.body) { if (options.mediaType?.includes('/json')) { return JSON.stringify(options.body) @@ -3313,8 +3316,8 @@ export const sendRequest = async ( config: OpenAPIConfig, options: ApiRequestOptions, url: string, + body: any, formData: FormData | undefined, - body: BodyInit | undefined, headers: Headers, onCancel: OnCancel ): Promise => { @@ -3403,7 +3406,7 @@ export const request = (config: OpenAPIConfig, options: ApiRequestOptions): C const headers = await getHeaders(config, options); if (!onCancel.isCancelled) { - const response = await sendRequest(config, options, url, formData, body, headers, onCancel); + const response = await sendRequest(config, options, url, body, formData, headers, onCancel); const responseBody = await getResponseBody(response); const responseHeader = getResponseHeader(response, options.responseHeader); @@ -5670,6 +5673,7 @@ import type { ModelWithArray } from '../models/ModelWithArray'; import type { ModelWithDictionary } from '../models/ModelWithDictionary'; import type { ModelWithEnum } from '../models/ModelWithEnum'; import type { ModelWithString } from '../models/ModelWithString'; + import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; @@ -5770,6 +5774,7 @@ exports[`v3 should generate: ./test/generated/v3/services/DefaultsService.ts 1`] /* tslint:disable */ /* eslint-disable */ import type { ModelWithString } from '../models/ModelWithString'; + import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; @@ -5970,6 +5975,7 @@ exports[`v3 should generate: ./test/generated/v3/services/FormDataService.ts 1`] /* tslint:disable */ /* eslint-disable */ import type { ModelWithString } from '../models/ModelWithString'; + import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; @@ -6033,6 +6039,7 @@ exports[`v3 should generate: ./test/generated/v3/services/MultipartService.ts 1` /* tslint:disable */ /* eslint-disable */ import type { ModelWithString } from '../models/ModelWithString'; + import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; @@ -6200,6 +6207,7 @@ exports[`v3 should generate: ./test/generated/v3/services/ParametersService.ts 1 /* tslint:disable */ /* eslint-disable */ import type { ModelWithString } from '../models/ModelWithString'; + import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; @@ -6343,6 +6351,7 @@ exports[`v3 should generate: ./test/generated/v3/services/RequestBodyService.ts /* tslint:disable */ /* eslint-disable */ import type { ModelWithString } from '../models/ModelWithString'; + import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; @@ -6379,6 +6388,7 @@ exports[`v3 should generate: ./test/generated/v3/services/ResponseService.ts 1`] import type { ModelThatExtends } from '../models/ModelThatExtends'; import type { ModelThatExtendsExtends } from '../models/ModelThatExtendsExtends'; import type { ModelWithString } from '../models/ModelWithString'; + import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request';