diff --git a/CHANGELOG.md b/CHANGELOG.md index 659694d86..48ed4fac5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,15 @@ # Changelog All notable changes to this project will be documented in this file. +## unreleased +### Added +- Added `requestApiResult` as additional request function +### Changed +- Changed ApiResult to be generic and also contain response header +### Fixed +- Fixed binary response type to process as a Blob rather than text/string (#986) +- Use type-only imports for axios (#1037) + ## [0.22.0] - 2022-04-26 ### Fixed - Upgraded dependencies diff --git a/src/openApi/v2/parser/getOperation.ts b/src/openApi/v2/parser/getOperation.ts index 9aa157460..8e9bca205 100644 --- a/src/openApi/v2/parser/getOperation.ts +++ b/src/openApi/v2/parser/getOperation.ts @@ -1,5 +1,6 @@ import type { Operation } from '../../../client/interfaces/Operation'; import type { OperationParameters } from '../../../client/interfaces/OperationParameters'; +import type { OperationResponse } from '../../../client/interfaces/OperationResponse'; import type { OpenApi } from '../interfaces/OpenApi'; import type { OpenApiOperation } from '../interfaces/OpenApiOperation'; import { getOperationErrors } from './getOperationErrors'; @@ -11,6 +12,10 @@ import { getOperationResults } from './getOperationResults'; import { getServiceName } from './getServiceName'; import { sortByRequired } from './sortByRequired'; +const getOperationResultsWithoutHeader = (operationResults: OperationResponse[]) => { + return operationResults.filter(operationResult => operationResult.in !== 'header'); +}; + export const getOperation = ( openApi: OpenApi, url: string, @@ -63,8 +68,9 @@ export const getOperation = ( const operationResults = getOperationResults(operationResponses); operation.errors = getOperationErrors(operationResponses); operation.responseHeader = getOperationResponseHeader(operationResults); + const operationResultsWithoutHeader = getOperationResultsWithoutHeader(operationResults); - operationResults.forEach(operationResult => { + operationResultsWithoutHeader.forEach(operationResult => { operation.results.push(operationResult); operation.imports.push(...operationResult.imports); }); diff --git a/src/openApi/v2/parser/getOperationResponse.ts b/src/openApi/v2/parser/getOperationResponse.ts index 8f6c3ca56..db640123d 100644 --- a/src/openApi/v2/parser/getOperationResponse.ts +++ b/src/openApi/v2/parser/getOperationResponse.ts @@ -7,12 +7,8 @@ import { getModel } from './getModel'; import { getRef } from './getRef'; import { getType } from './getType'; -export const getOperationResponse = ( - openApi: OpenApi, - response: OpenApiResponse, - responseCode: number -): OperationResponse => { - const operationResponse: OperationResponse = { +const getDefaultOperationResponse = (responseCode: number, response: OpenApiResponse): OperationResponse => { + return { in: 'response', name: '', code: responseCode, @@ -31,6 +27,14 @@ export const getOperationResponse = ( enums: [], properties: [], }; +}; + +export const getOperationResponseContent = ( + openApi: OpenApi, + response: OpenApiResponse, + responseCode: number +): OperationResponse => { + const operationResponse = getDefaultOperationResponse(responseCode, response); // If this response has a schema, then we need to check two things: // if this is a reference then the parameter is just the 'name' of @@ -80,6 +84,15 @@ export const getOperationResponse = ( return operationResponse; } } + return operationResponse; +}; + +export const getOperationResponseHeaders = ( + openApi: OpenApi, + response: OpenApiResponse, + responseCode: number +): OperationResponse | null => { + const operationResponse = getDefaultOperationResponse(responseCode, response); // We support basic properties from response headers, since both // fetch and XHR client just support string types. @@ -94,6 +107,5 @@ export const getOperationResponse = ( } } } - - return operationResponse; + return null; }; diff --git a/src/openApi/v2/parser/getOperationResponses.ts b/src/openApi/v2/parser/getOperationResponses.ts index ed628e857..a628b822c 100644 --- a/src/openApi/v2/parser/getOperationResponses.ts +++ b/src/openApi/v2/parser/getOperationResponses.ts @@ -2,7 +2,7 @@ import type { OperationResponse } from '../../../client/interfaces/OperationResp import type { OpenApi } from '../interfaces/OpenApi'; import type { OpenApiResponse } from '../interfaces/OpenApiResponse'; import type { OpenApiResponses } from '../interfaces/OpenApiResponses'; -import { getOperationResponse } from './getOperationResponse'; +import { getOperationResponseContent, getOperationResponseHeaders } from './getOperationResponse'; import { getOperationResponseCode } from './getOperationResponseCode'; import { getRef } from './getRef'; @@ -18,8 +18,12 @@ export const getOperationResponses = (openApi: OpenApi, responses: OpenApiRespon const responseCode = getOperationResponseCode(code); if (responseCode) { - const operationResponse = getOperationResponse(openApi, response, responseCode); - operationResponses.push(operationResponse); + const operationResponseContent = getOperationResponseContent(openApi, response, responseCode); + operationResponses.push(operationResponseContent); + const operationResponseHeaders = getOperationResponseHeaders(openApi, response, responseCode); + if (operationResponseHeaders !== null) { + operationResponses.push(operationResponseHeaders); + } } } } diff --git a/src/openApi/v3/parser/getOperation.ts b/src/openApi/v3/parser/getOperation.ts index aee4bd0c2..954cfd9b5 100644 --- a/src/openApi/v3/parser/getOperation.ts +++ b/src/openApi/v3/parser/getOperation.ts @@ -1,5 +1,6 @@ import type { Operation } from '../../../client/interfaces/Operation'; import type { OperationParameters } from '../../../client/interfaces/OperationParameters'; +import type { OperationResponse } from '../../../client/interfaces/OperationResponse'; import type { OpenApi } from '../interfaces/OpenApi'; import type { OpenApiOperation } from '../interfaces/OpenApiOperation'; import type { OpenApiRequestBody } from '../interfaces/OpenApiRequestBody'; @@ -14,6 +15,10 @@ import { getRef } from './getRef'; import { getServiceName } from './getServiceName'; import { sortByRequired } from './sortByRequired'; +const getOperationResultsWithoutHeader = (operationResults: OperationResponse[]) => { + return operationResults.filter(operationResult => operationResult.in !== 'header'); +}; + export const getOperation = ( openApi: OpenApi, url: string, @@ -74,8 +79,9 @@ export const getOperation = ( const operationResults = getOperationResults(operationResponses); operation.errors = getOperationErrors(operationResponses); operation.responseHeader = getOperationResponseHeader(operationResults); + const operationResultsWithoutHeader = getOperationResultsWithoutHeader(operationResults); - operationResults.forEach(operationResult => { + operationResultsWithoutHeader.forEach(operationResult => { operation.results.push(operationResult); operation.imports.push(...operationResult.imports); }); diff --git a/src/openApi/v3/parser/getOperationResponse.ts b/src/openApi/v3/parser/getOperationResponse.ts index dff19ec13..caeb0e3ba 100644 --- a/src/openApi/v3/parser/getOperationResponse.ts +++ b/src/openApi/v3/parser/getOperationResponse.ts @@ -8,12 +8,8 @@ import { getModel } from './getModel'; import { getRef } from './getRef'; import { getType } from './getType'; -export const getOperationResponse = ( - openApi: OpenApi, - response: OpenApiResponse, - responseCode: number -): OperationResponse => { - const operationResponse: OperationResponse = { +const getDefaultOperationResponse = (responseCode: number, response: OpenApiResponse): OperationResponse => { + return { in: 'response', name: '', code: responseCode, @@ -32,6 +28,14 @@ export const getOperationResponse = ( enums: [], properties: [], }; +}; + +export const getOperationResponseContent = ( + openApi: OpenApi, + response: OpenApiResponse, + responseCode: number +): OperationResponse => { + const operationResponse = getDefaultOperationResponse(responseCode, response); if (response.content) { const content = getContent(openApi, response.content); @@ -79,6 +83,15 @@ export const getOperationResponse = ( } } } + return operationResponse; +}; + +export const getOperationResponseHeaders = ( + openApi: OpenApi, + response: OpenApiResponse, + responseCode: number +): OperationResponse | null => { + const operationResponse = getDefaultOperationResponse(responseCode, response); // We support basic properties from response headers, since both // fetch and XHR client just support string types. @@ -93,6 +106,5 @@ export const getOperationResponse = ( } } } - - return operationResponse; + return null; }; diff --git a/src/openApi/v3/parser/getOperationResponses.ts b/src/openApi/v3/parser/getOperationResponses.ts index ed628e857..a628b822c 100644 --- a/src/openApi/v3/parser/getOperationResponses.ts +++ b/src/openApi/v3/parser/getOperationResponses.ts @@ -2,7 +2,7 @@ import type { OperationResponse } from '../../../client/interfaces/OperationResp import type { OpenApi } from '../interfaces/OpenApi'; import type { OpenApiResponse } from '../interfaces/OpenApiResponse'; import type { OpenApiResponses } from '../interfaces/OpenApiResponses'; -import { getOperationResponse } from './getOperationResponse'; +import { getOperationResponseContent, getOperationResponseHeaders } from './getOperationResponse'; import { getOperationResponseCode } from './getOperationResponseCode'; import { getRef } from './getRef'; @@ -18,8 +18,12 @@ export const getOperationResponses = (openApi: OpenApi, responses: OpenApiRespon const responseCode = getOperationResponseCode(code); if (responseCode) { - const operationResponse = getOperationResponse(openApi, response, responseCode); - operationResponses.push(operationResponse); + const operationResponseContent = getOperationResponseContent(openApi, response, responseCode); + operationResponses.push(operationResponseContent); + const operationResponseHeaders = getOperationResponseHeaders(openApi, response, responseCode); + if (operationResponseHeaders !== null) { + operationResponses.push(operationResponseHeaders); + } } } } diff --git a/src/templates/core/ApiError.hbs b/src/templates/core/ApiError.hbs index 19af17e1a..7cafab80a 100644 --- a/src/templates/core/ApiError.hbs +++ b/src/templates/core/ApiError.hbs @@ -8,7 +8,7 @@ export class ApiError extends Error { public readonly statusText: string; public readonly body: any; - constructor(response: ApiResult, message: string) { + constructor(response: ApiResult, message: string) { super(message); this.name = 'ApiError'; diff --git a/src/templates/core/ApiRequestOptions.hbs b/src/templates/core/ApiRequestOptions.hbs index 355929a71..0998ce569 100644 --- a/src/templates/core/ApiRequestOptions.hbs +++ b/src/templates/core/ApiRequestOptions.hbs @@ -10,6 +10,7 @@ export type ApiRequestOptions = { readonly formData?: Record; readonly body?: any; readonly mediaType?: string; + readonly responseType?: 'blob'; readonly responseHeader?: string; readonly errors?: Record; }; diff --git a/src/templates/core/ApiResult.hbs b/src/templates/core/ApiResult.hbs index a768b8c5a..c97f80eaa 100644 --- a/src/templates/core/ApiResult.hbs +++ b/src/templates/core/ApiResult.hbs @@ -1,9 +1,10 @@ {{>header}} -export type ApiResult = { +export type ApiResult = { readonly url: string; readonly ok: boolean; readonly status: number; readonly statusText: string; - readonly body: any; + readonly body: T; + readonly header: string | undefined; }; diff --git a/src/templates/core/BaseHttpRequest.hbs b/src/templates/core/BaseHttpRequest.hbs index 43ff79cbb..9b251ffce 100644 --- a/src/templates/core/BaseHttpRequest.hbs +++ b/src/templates/core/BaseHttpRequest.hbs @@ -5,9 +5,11 @@ import type { HttpClient } from '@angular/common/http'; import type { Observable } from 'rxjs'; import type { ApiRequestOptions } from './ApiRequestOptions'; +import type { ApiResult } from './ApiResult'; import type { OpenAPIConfig } from './OpenAPI'; {{else}} import type { ApiRequestOptions } from './ApiRequestOptions'; +import type { ApiResult } from './ApiResult'; import type { CancelablePromise } from './CancelablePromise'; import type { OpenAPIConfig } from './OpenAPI'; {{/equals}} @@ -25,7 +27,9 @@ export abstract class BaseHttpRequest { {{#equals @root.httpClient 'angular'}} public abstract request(options: ApiRequestOptions): Observable; + public abstract requestApiResult(options: ApiRequestOptions): Observable>; {{else}} public abstract request(options: ApiRequestOptions): CancelablePromise; + public abstract requestApiResult(options: ApiRequestOptions): CancelablePromise>; {{/equals}} } diff --git a/src/templates/core/HttpRequest.hbs b/src/templates/core/HttpRequest.hbs index e1620a3c0..97c93883b 100644 --- a/src/templates/core/HttpRequest.hbs +++ b/src/templates/core/HttpRequest.hbs @@ -6,16 +6,18 @@ import { HttpClient } from '@angular/common/http'; import type { Observable } from 'rxjs'; import type { ApiRequestOptions } from './ApiRequestOptions'; +import type { ApiResult } from './ApiResult'; import { BaseHttpRequest } from './BaseHttpRequest'; import type { OpenAPIConfig } from './OpenAPI'; import { OpenAPI } from './OpenAPI'; -import { request as __request } from './request'; +import { request as __request, requestApiResult as __requestApiResult } from './request'; {{else}} import type { ApiRequestOptions } from './ApiRequestOptions'; +import type { ApiResult } from './ApiResult'; import { BaseHttpRequest } from './BaseHttpRequest'; import type { CancelablePromise } from './CancelablePromise'; import type { OpenAPIConfig } from './OpenAPI'; -import { request as __request } from './request'; +import { request as __request, requestApiResult as __requestApiResult } from './request'; {{/equals}} {{#equals @root.httpClient 'angular'}} @@ -47,6 +49,15 @@ export class {{httpRequest}} extends BaseHttpRequest { public override request(options: ApiRequestOptions): Observable { return __request(this.config, this.http, options); } + /** + * Request method with ResponseHeader + * @param options The request options from the service + * @returns Observable> + * @throws ApiError + */ + public override requestApiResult(options: ApiRequestOptions): Observable> { + return __requestApiResult(this.config, this.http, options); + } {{else}} /** * Request method @@ -57,5 +68,14 @@ export class {{httpRequest}} extends BaseHttpRequest { public override request(options: ApiRequestOptions): CancelablePromise { return __request(this.config, options); } + /** + * Request method with ResponseHeader + * @param options The request options from the service + * @returns CancelablePromise> + * @throws ApiError + */ + public override requestApiResult(options: ApiRequestOptions): CancelablePromise> { + return __requestApiResult(this.config, options); + } {{/equals}} } diff --git a/src/templates/core/angular/request.hbs b/src/templates/core/angular/request.hbs index 57c98516e..0494b7f25 100644 --- a/src/templates/core/angular/request.hbs +++ b/src/templates/core/angular/request.hbs @@ -59,6 +59,57 @@ import type { OpenAPIConfig } from './OpenAPI'; {{>functions/catchErrorCodes}} +/** + * Request method with header + * @param config The OpenAPI configuration object + * @param http The Angular HTTP client + * @param options The request options from the service + * @returns Observable> + * @throws ApiError + */ +export const requestApiResult = (config: OpenAPIConfig, http: HttpClient, options: ApiRequestOptions): Observable> => { + const url = getUrl(config, options); + const formData = getFormData(options); + const body = getRequestBody(options); + + return getHeaders(config, options).pipe( + switchMap(headers => { + return sendRequest(config, options, http, url, formData, body, headers); + }), + map(response => { + const responseBody = getResponseBody(response); + const responseHeader = getResponseHeader(response, options.responseHeader); + return { + url, + ok: response.ok, + status: response.status, + statusText: response.statusText, + body: responseBody, + header: responseHeader, + } as ApiResult; + }), + catchError((error: HttpErrorResponse) => { + if (!error.status) { + return throwError(error); + } + return of({ + url, + ok: error.ok, + status: error.status, + statusText: error.statusText, + body: error.error ?? error.statusText, + } as ApiResult); + }), + map(result => { + catchErrorCodes(options, result); + return result as ApiResult; + }), + catchError((error: ApiError) => { + return throwError(error); + }), + ); +}; + /** * Request method * @param config The OpenAPI configuration object @@ -84,8 +135,9 @@ export const request = (config: OpenAPIConfig, http: HttpClient, options: Api ok: response.ok, status: response.status, statusText: response.statusText, - body: responseHeader ?? responseBody, - } as ApiResult; + body: responseBody, + header: responseHeader, + } as ApiResult; }), catchError((error: HttpErrorResponse) => { if (!error.status) { @@ -97,7 +149,7 @@ export const request = (config: OpenAPIConfig, http: HttpClient, options: Api status: error.status, statusText: error.statusText, body: error.error ?? error.statusText, - } as ApiResult); + } as ApiResult); }), map(result => { catchErrorCodes(options, result); diff --git a/src/templates/core/angular/sendRequest.hbs b/src/templates/core/angular/sendRequest.hbs index ad73d8332..79ada8bdf 100644 --- a/src/templates/core/angular/sendRequest.hbs +++ b/src/templates/core/angular/sendRequest.hbs @@ -7,10 +7,11 @@ export const sendRequest = ( formData: FormData | undefined, headers: HttpHeaders ): Observable> => { - return http.request(options.method, url, { + return http.request(options.method, url, { headers, body: body ?? formData, withCredentials: config.WITH_CREDENTIALS, observe: 'response', + responseType: options.responseType, }); }; diff --git a/src/templates/core/axios/request.hbs b/src/templates/core/axios/request.hbs index 439aebe87..0af00157c 100644 --- a/src/templates/core/axios/request.hbs +++ b/src/templates/core/axios/request.hbs @@ -1,6 +1,6 @@ {{>header}} -import axios, { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios'; +import axios, { AxiosError, type AxiosRequestConfig, type AxiosResponse } from 'axios'; import FormData from 'form-data'; import { ApiError } from './ApiError'; @@ -59,13 +59,13 @@ import type { OpenAPIConfig } from './OpenAPI'; /** - * Request method + * Request method to get ApiResult * @param config The OpenAPI configuration object * @param options The request options from the service - * @returns CancelablePromise + * @returns CancelablePromise> * @throws ApiError */ -export const request = (config: OpenAPIConfig, options: ApiRequestOptions): CancelablePromise => { +export const requestApiResult = (config: OpenAPIConfig, options: ApiRequestOptions): CancelablePromise> => { return new CancelablePromise(async (resolve, reject, onCancel) => { try { const url = getUrl(config, options); @@ -78,17 +78,39 @@ export const request = (config: OpenAPIConfig, options: ApiRequestOptions): C const responseBody = getResponseBody(response); const responseHeader = getResponseHeader(response, options.responseHeader); - const result: ApiResult = { + const result: ApiResult = { url, ok: isSuccess(response.status), status: response.status, statusText: response.statusText, - body: responseHeader ?? responseBody, + body: responseBody, + header: responseHeader, }; catchErrorCodes(options, result); - resolve(result.body); + resolve(result); + } + } catch (error) { + reject(error); + } + }); +}; + + +/** + * Request method + * @param config The OpenAPI configuration object + * @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) => { + try { + if (!onCancel.isCancelled) { + const result = await requestApiResult(config, options) + resolve(result.body) } } catch (error) { reject(error); diff --git a/src/templates/core/axios/sendRequest.hbs b/src/templates/core/axios/sendRequest.hbs index 0b871ea36..0da8a1962 100644 --- a/src/templates/core/axios/sendRequest.hbs +++ b/src/templates/core/axios/sendRequest.hbs @@ -15,6 +15,7 @@ const sendRequest = async ( data: body ?? formData, method: options.method, withCredentials: config.WITH_CREDENTIALS, + responseType: options.responseType, cancelToken: source.token, }; diff --git a/src/templates/core/fetch/getResponseBody.hbs b/src/templates/core/fetch/getResponseBody.hbs index 083cd16e9..0f7ad8681 100644 --- a/src/templates/core/fetch/getResponseBody.hbs +++ b/src/templates/core/fetch/getResponseBody.hbs @@ -1,4 +1,4 @@ -const getResponseBody = async (response: Response): Promise => { +const getResponseBody = async (response: Response, options: ApiRequestOptions): Promise => { if (response.status !== 204) { try { const contentType = response.headers.get('Content-Type'); @@ -6,6 +6,8 @@ const getResponseBody = async (response: Response): Promise => { const isJSON = contentType.toLowerCase().startsWith('application/json'); if (isJSON) { return await response.json(); + } else if (options.responseType === 'blob') { + return await response.blob(); } else { return await response.text(); } diff --git a/src/templates/core/fetch/request.hbs b/src/templates/core/fetch/request.hbs index 4af6f9440..28732e76d 100644 --- a/src/templates/core/fetch/request.hbs +++ b/src/templates/core/fetch/request.hbs @@ -56,13 +56,13 @@ import type { OpenAPIConfig } from './OpenAPI'; /** - * Request method + * Request method to get ApiResult * @param config The OpenAPI configuration object * @param options The request options from the service - * @returns CancelablePromise + * @returns CancelablePromise> * @throws ApiError */ -export const request = (config: OpenAPIConfig, options: ApiRequestOptions): CancelablePromise => { +export const requestApiResult = (config: OpenAPIConfig, options: ApiRequestOptions): CancelablePromise> => { return new CancelablePromise(async (resolve, reject, onCancel) => { try { const url = getUrl(config, options); @@ -72,20 +72,41 @@ export const request = (config: OpenAPIConfig, options: ApiRequestOptions): C if (!onCancel.isCancelled) { const response = await sendRequest(config, options, url, body, formData, headers, onCancel); - const responseBody = await getResponseBody(response); + const responseBody = await getResponseBody(response, options); const responseHeader = getResponseHeader(response, options.responseHeader); - const result: ApiResult = { + const result: ApiResult = { url, ok: response.ok, status: response.status, statusText: response.statusText, - body: responseHeader ?? responseBody, + body: responseBody, + header: responseHeader, }; catchErrorCodes(options, result); - resolve(result.body); + resolve(result); + } + } catch (error) { + reject(error); + } + }); +}; + +/** + * Request method + * @param config The OpenAPI configuration object + * @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) => { + try { + if (!onCancel.isCancelled) { + const result = await requestApiResult(config, options) + resolve(result.body) } } catch (error) { reject(error); diff --git a/src/templates/core/functions/catchErrorCodes.hbs b/src/templates/core/functions/catchErrorCodes.hbs index b99916a83..b9a6ad192 100644 --- a/src/templates/core/functions/catchErrorCodes.hbs +++ b/src/templates/core/functions/catchErrorCodes.hbs @@ -1,4 +1,4 @@ -const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult): void => { +const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult): void => { const errors: Record = { 400: 'Bad Request', 401: 'Unauthorized', diff --git a/src/templates/core/node/getResponseBody.hbs b/src/templates/core/node/getResponseBody.hbs index 083cd16e9..0f7ad8681 100644 --- a/src/templates/core/node/getResponseBody.hbs +++ b/src/templates/core/node/getResponseBody.hbs @@ -1,4 +1,4 @@ -const getResponseBody = async (response: Response): Promise => { +const getResponseBody = async (response: Response, options: ApiRequestOptions): Promise => { if (response.status !== 204) { try { const contentType = response.headers.get('Content-Type'); @@ -6,6 +6,8 @@ const getResponseBody = async (response: Response): Promise => { const isJSON = contentType.toLowerCase().startsWith('application/json'); if (isJSON) { return await response.json(); + } else if (options.responseType === 'blob') { + return await response.blob(); } else { return await response.text(); } diff --git a/src/templates/core/node/request.hbs b/src/templates/core/node/request.hbs index 3e6f2d0bb..d8a679709 100644 --- a/src/templates/core/node/request.hbs +++ b/src/templates/core/node/request.hbs @@ -59,13 +59,13 @@ import type { OpenAPIConfig } from './OpenAPI'; /** - * Request method + * Request method to get ApiResult * @param config The OpenAPI configuration object * @param options The request options from the service - * @returns CancelablePromise + * @returns CancelablePromise> * @throws ApiError */ -export const request = (config: OpenAPIConfig, options: ApiRequestOptions): CancelablePromise => { +export const requestApiResult = (config: OpenAPIConfig, options: ApiRequestOptions): CancelablePromise> => { return new CancelablePromise(async (resolve, reject, onCancel) => { try { const url = getUrl(config, options); @@ -75,23 +75,45 @@ export const request = (config: OpenAPIConfig, options: ApiRequestOptions): C if (!onCancel.isCancelled) { const response = await sendRequest(options, url, body, formData, headers, onCancel); - const responseBody = await getResponseBody(response); + const responseBody = await getResponseBody(response, options); const responseHeader = getResponseHeader(response, options.responseHeader); - const result: ApiResult = { + const result: ApiResult = { url, ok: response.ok, status: response.status, statusText: response.statusText, - body: responseHeader ?? responseBody, + body: responseBody, + header: responseHeader, }; catchErrorCodes(options, result); - resolve(result.body); + resolve(result); + } + } catch (error) { + reject(error); + } + }); +}; + +/** + * Request method + * @param config The OpenAPI configuration object + * @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) => { + try { + if (!onCancel.isCancelled) { + const result = await requestApiResult(config, options) + resolve(result.body) } } catch (error) { reject(error); } }); }; + diff --git a/src/templates/core/xhr/getResponseBody.hbs b/src/templates/core/xhr/getResponseBody.hbs index 596733a8a..af30434c6 100644 --- a/src/templates/core/xhr/getResponseBody.hbs +++ b/src/templates/core/xhr/getResponseBody.hbs @@ -1,4 +1,4 @@ -const getResponseBody = (xhr: XMLHttpRequest): any => { +const getResponseBody = (xhr: XMLHttpRequest, options: ApiRequestOptions): any => { if (xhr.status !== 204) { try { const contentType = xhr.getResponseHeader('Content-Type'); @@ -6,6 +6,8 @@ const getResponseBody = (xhr: XMLHttpRequest): any => { const isJSON = contentType.toLowerCase().startsWith('application/json'); if (isJSON) { return JSON.parse(xhr.responseText); + } else if (options.responseType === 'blob') { + return xhr.response; } else { return xhr.responseText; } diff --git a/src/templates/core/xhr/request.hbs b/src/templates/core/xhr/request.hbs index 47f92870b..e17c61cad 100644 --- a/src/templates/core/xhr/request.hbs +++ b/src/templates/core/xhr/request.hbs @@ -59,13 +59,13 @@ import type { OpenAPIConfig } from './OpenAPI'; /** - * Request method + * Request method to get ApiResult * @param config The OpenAPI configuration object * @param options The request options from the service - * @returns CancelablePromise + * @returns CancelablePromise> * @throws ApiError */ -export const request = (config: OpenAPIConfig, options: ApiRequestOptions): CancelablePromise => { +export const requestApiResult = (config: OpenAPIConfig, options: ApiRequestOptions): CancelablePromise> => { return new CancelablePromise(async (resolve, reject, onCancel) => { try { const url = getUrl(config, options); @@ -75,20 +75,41 @@ export const request = (config: OpenAPIConfig, options: ApiRequestOptions): C if (!onCancel.isCancelled) { const response = await sendRequest(config, options, url, body, formData, headers, onCancel); - const responseBody = getResponseBody(response); + const responseBody = getResponseBody(response, options); const responseHeader = getResponseHeader(response, options.responseHeader); - const result: ApiResult = { + const result: ApiResult = { url, ok: isSuccess(response.status), status: response.status, statusText: response.statusText, - body: responseHeader ?? responseBody, + body: responseBody, + header: responseHeader, }; catchErrorCodes(options, result); - resolve(result.body); + resolve(result); + } + } catch (error) { + reject(error); + } + }); +}; + +/** + * Request method + * @param config The OpenAPI configuration object + * @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) => { + try { + if (!onCancel.isCancelled) { + const result = await requestApiResult(config, options) + resolve(result.body) } } catch (error) { reject(error); diff --git a/src/templates/core/xhr/sendRequest.hbs b/src/templates/core/xhr/sendRequest.hbs index 0badf8daa..1a77c1c66 100644 --- a/src/templates/core/xhr/sendRequest.hbs +++ b/src/templates/core/xhr/sendRequest.hbs @@ -10,6 +10,7 @@ export const sendRequest = async ( const xhr = new XMLHttpRequest(); xhr.open(options.method, url, true); xhr.withCredentials = config.WITH_CREDENTIALS; + xhr.responseType = options.responseType ?? ""; headers.forEach((value, key) => { xhr.setRequestHeader(key, value); diff --git a/src/templates/exportService.hbs b/src/templates/exportService.hbs index 2fdd9af58..bad7fc3ed 100644 --- a/src/templates/exportService.hbs +++ b/src/templates/exportService.hbs @@ -23,12 +23,16 @@ import type { CancelablePromise } from '../core/CancelablePromise'; {{#if @root.exportClient}} {{#equals @root.httpClient 'angular'}} import { BaseHttpRequest } from '../core/BaseHttpRequest'; +import type { ApiResult } from '../core/ApiResult'; {{else}} import type { BaseHttpRequest } from '../core/BaseHttpRequest'; +import type { ApiResult } from '../core/ApiResult'; {{/equals}} {{else}} +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; {{/if}} {{#equals @root.httpClient 'angular'}} @@ -63,9 +67,15 @@ export class {{{name}}}{{{@root.postfix}}} { {{/each}} {{/if}} {{/unless}} - {{#each results}} + {{#if responseHeader}} + {{#each results}} + * @returns ApiResult<{{{type}}}> {{#if description}}{{{escapeComment description}}}{{/if}} + {{/each}} + {{else}} + {{#each results}} * @returns {{{type}}} {{#if description}}{{{escapeComment description}}}{{/if}} - {{/each}} + {{/each}} + {{/if}} * @throws ApiError */ {{#if @root.exportClient}} @@ -73,16 +83,26 @@ export class {{{name}}}{{{@root.postfix}}} { public {{{name}}}({{>parameters}}): Observable<{{>result}}> { return this.httpRequest.request({ {{else}} + {{#if responseHeader}} + public {{{name}}}({{>parameters}}): CancelablePromiseresult}}>> { + return this.httpRequest.requestApiResult({ + {{else}} public {{{name}}}({{>parameters}}): CancelablePromise<{{>result}}> { return this.httpRequest.request({ + {{/if}} {{/equals}} {{else}} {{#equals @root.httpClient 'angular'}} public {{{name}}}({{>parameters}}): Observable<{{>result}}> { return __request(OpenAPI, this.http, { {{else}} + {{#if responseHeader}} + public {{{name}}}({{>parameters}}): CancelablePromiseresult}}>> { + return __requestApiResult(OpenAPI, { + {{else}} public static {{{name}}}({{>parameters}}): CancelablePromise<{{>result}}> { return __request(OpenAPI, { + {{/if}} {{/equals}} {{/if}} method: '{{{method}}}', @@ -133,6 +153,9 @@ export class {{{name}}}{{{@root.postfix}}} { mediaType: '{{{parametersBody.mediaType}}}', {{/if}} {{/if}} + {{#if results}} + {{>responseType}} + {{/if}} {{#if responseHeader}} responseHeader: '{{{responseHeader}}}', {{/if}} diff --git a/src/templates/partials/responseType.hbs b/src/templates/partials/responseType.hbs new file mode 100644 index 000000000..807ea66ca --- /dev/null +++ b/src/templates/partials/responseType.hbs @@ -0,0 +1,3 @@ +{{~#equals results.0.base 'binary'~}} + responseType: 'blob', +{{/equals}} diff --git a/src/utils/registerHandlebarTemplates.ts b/src/utils/registerHandlebarTemplates.ts index bf77cbdc1..cfd60b8ae 100644 --- a/src/utils/registerHandlebarTemplates.ts +++ b/src/utils/registerHandlebarTemplates.ts @@ -66,6 +66,7 @@ import partialIsNullable from '../templates/partials/isNullable.hbs'; import partialIsReadOnly from '../templates/partials/isReadOnly.hbs'; import partialIsRequired from '../templates/partials/isRequired.hbs'; import partialParameters from '../templates/partials/parameters.hbs'; +import partialResponseType from '../templates/partials/responseType.hbs'; import partialResult from '../templates/partials/result.hbs'; import partialSchema from '../templates/partials/schema.hbs'; import partialSchemaArray from '../templates/partials/schemaArray.hbs'; @@ -147,6 +148,7 @@ export const registerHandlebarTemplates = (root: { Handlebars.registerPartial('isReadOnly', Handlebars.template(partialIsReadOnly)); Handlebars.registerPartial('isRequired', Handlebars.template(partialIsRequired)); Handlebars.registerPartial('parameters', Handlebars.template(partialParameters)); + Handlebars.registerPartial('responseType', Handlebars.template(partialResponseType)); Handlebars.registerPartial('result', Handlebars.template(partialResult)); Handlebars.registerPartial('schema', Handlebars.template(partialSchema)); Handlebars.registerPartial('schemaArray', Handlebars.template(partialSchemaArray)); diff --git a/test/__snapshots__/index.spec.ts.snap b/test/__snapshots__/index.spec.ts.snap index 34df5ffcd..144f96641 100644 --- a/test/__snapshots__/index.spec.ts.snap +++ b/test/__snapshots__/index.spec.ts.snap @@ -12,7 +12,7 @@ export class ApiError extends Error { public readonly statusText: string; public readonly body: any; - constructor(response: ApiResult, message: string) { + constructor(response: ApiResult, message: string) { super(message); this.name = 'ApiError'; @@ -38,6 +38,7 @@ export type ApiRequestOptions = { readonly formData?: Record; readonly body?: any; readonly mediaType?: string; + readonly responseType?: 'blob'; readonly responseHeader?: string; readonly errors?: Record; };" @@ -47,12 +48,13 @@ exports[`v2 should generate: ./test/generated/v2/core/ApiResult.ts 1`] = ` "/* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -export type ApiResult = { +export type ApiResult = { readonly url: string; readonly ok: boolean; readonly status: number; readonly statusText: string; - readonly body: any; + readonly body: T; + readonly header: string | undefined; };" `; @@ -450,7 +452,7 @@ const getResponseHeader = (response: Response, responseHeader?: string): string return undefined; }; -const getResponseBody = async (response: Response): Promise => { +const getResponseBody = async (response: Response, options: ApiRequestOptions): Promise => { if (response.status !== 204) { try { const contentType = response.headers.get('Content-Type'); @@ -458,6 +460,8 @@ const getResponseBody = async (response: Response): Promise => { const isJSON = contentType.toLowerCase().startsWith('application/json'); if (isJSON) { return await response.json(); + } else if (options.responseType === 'blob') { + return await response.blob(); } else { return await response.text(); } @@ -469,7 +473,7 @@ const getResponseBody = async (response: Response): Promise => { return undefined; }; -const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult): void => { +const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult): void => { const errors: Record = { 400: 'Bad Request', 401: 'Unauthorized', @@ -492,13 +496,13 @@ const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult): void => }; /** - * Request method + * Request method to get ApiResult * @param config The OpenAPI configuration object * @param options The request options from the service - * @returns CancelablePromise + * @returns CancelablePromise> * @throws ApiError */ -export const request = (config: OpenAPIConfig, options: ApiRequestOptions): CancelablePromise => { +export const requestApiResult = (config: OpenAPIConfig, options: ApiRequestOptions): CancelablePromise> => { return new CancelablePromise(async (resolve, reject, onCancel) => { try { const url = getUrl(config, options); @@ -508,20 +512,41 @@ export const request = (config: OpenAPIConfig, options: ApiRequestOptions): C if (!onCancel.isCancelled) { const response = await sendRequest(config, options, url, body, formData, headers, onCancel); - const responseBody = await getResponseBody(response); + const responseBody = await getResponseBody(response, options); const responseHeader = getResponseHeader(response, options.responseHeader); - const result: ApiResult = { + const result: ApiResult = { url, ok: response.ok, status: response.status, statusText: response.statusText, - body: responseHeader ?? responseBody, + body: responseBody, + header: responseHeader, }; catchErrorCodes(options, result); - resolve(result.body); + resolve(result); + } + } catch (error) { + reject(error); + } + }); +}; + +/** + * Request method + * @param config The OpenAPI configuration object + * @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) => { + try { + if (!onCancel.isCancelled) { + const result = await requestApiResult(config, options) + resolve(result.body) } } catch (error) { reject(error); @@ -2145,8 +2170,10 @@ exports[`v2 should generate: ./test/generated/v2/services/CollectionFormatServic /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class CollectionFormatService { @@ -2188,8 +2215,10 @@ exports[`v2 should generate: ./test/generated/v2/services/ComplexService.ts 1`] import type { ModelWithString } from '../models/ModelWithString'; import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class ComplexService { @@ -2231,8 +2260,10 @@ exports[`v2 should generate: ./test/generated/v2/services/DefaultService.ts 1`] /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class DefaultService { @@ -2256,8 +2287,10 @@ exports[`v2 should generate: ./test/generated/v2/services/DefaultsService.ts 1`] import type { ModelWithString } from '../models/ModelWithString'; import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class DefaultsService { @@ -2366,8 +2399,10 @@ exports[`v2 should generate: ./test/generated/v2/services/DescriptionsService.ts /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class DescriptionsService { @@ -2413,8 +2448,10 @@ exports[`v2 should generate: ./test/generated/v2/services/DuplicateService.ts 1` /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class DuplicateService { @@ -2466,8 +2503,10 @@ exports[`v2 should generate: ./test/generated/v2/services/ErrorService.ts 1`] = /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class ErrorService { @@ -2502,17 +2541,19 @@ exports[`v2 should generate: ./test/generated/v2/services/HeaderService.ts 1`] = /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class HeaderService { /** - * @returns string Successful response + * @returns ApiResult Successful response * @throws ApiError */ - public static callWithResultFromHeader(): CancelablePromise { - return __request(OpenAPI, { + public callWithResultFromHeader(): CancelablePromise> { + return __requestApiResult(OpenAPI, { method: 'POST', url: '/api/v{api-version}/header', responseHeader: 'operation-location', @@ -2523,6 +2564,23 @@ export class HeaderService { }); } + /** + * @returns ApiResult Successful response + * @throws ApiError + */ + public callWithResultFromContentAndHeader(): CancelablePromise> { + return __requestApiResult(OpenAPI, { + method: 'POST', + url: '/api/v{api-version}/content/header', + responseType: 'blob', + responseHeader: 'content-disposition', + errors: { + 400: \`400 server error\`, + 500: \`500 server error\`, + }, + }); + } + }" `; @@ -2531,8 +2589,10 @@ exports[`v2 should generate: ./test/generated/v2/services/MultipleTags1Service.t /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class MultipleTags1Service { @@ -2566,8 +2626,10 @@ exports[`v2 should generate: ./test/generated/v2/services/MultipleTags2Service.t /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class MultipleTags2Service { @@ -2601,8 +2663,10 @@ exports[`v2 should generate: ./test/generated/v2/services/MultipleTags3Service.t /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class MultipleTags3Service { @@ -2625,8 +2689,10 @@ exports[`v2 should generate: ./test/generated/v2/services/NoContentService.ts 1` /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class NoContentService { @@ -2649,8 +2715,10 @@ exports[`v2 should generate: ./test/generated/v2/services/ParametersService.ts 1 /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class ParametersService { @@ -2743,8 +2811,10 @@ import type { ModelThatExtendsExtends } from '../models/ModelThatExtendsExtends' import type { ModelWithString } from '../models/ModelWithString'; import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class ResponseService { @@ -2806,8 +2876,10 @@ exports[`v2 should generate: ./test/generated/v2/services/SimpleService.ts 1`] = /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class SimpleService { @@ -2889,8 +2961,10 @@ exports[`v2 should generate: ./test/generated/v2/services/TypesService.ts 1`] = /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class TypesService { @@ -2952,7 +3026,7 @@ export class ApiError extends Error { public readonly statusText: string; public readonly body: any; - constructor(response: ApiResult, message: string) { + constructor(response: ApiResult, message: string) { super(message); this.name = 'ApiError'; @@ -2978,6 +3052,7 @@ export type ApiRequestOptions = { readonly formData?: Record; readonly body?: any; readonly mediaType?: string; + readonly responseType?: 'blob'; readonly responseHeader?: string; readonly errors?: Record; };" @@ -2987,12 +3062,13 @@ exports[`v3 should generate: ./test/generated/v3/core/ApiResult.ts 1`] = ` "/* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -export type ApiResult = { +export type ApiResult = { readonly url: string; readonly ok: boolean; readonly status: number; readonly statusText: string; - readonly body: any; + readonly body: T; + readonly header: string | undefined; };" `; @@ -3390,7 +3466,7 @@ const getResponseHeader = (response: Response, responseHeader?: string): string return undefined; }; -const getResponseBody = async (response: Response): Promise => { +const getResponseBody = async (response: Response, options: ApiRequestOptions): Promise => { if (response.status !== 204) { try { const contentType = response.headers.get('Content-Type'); @@ -3398,6 +3474,8 @@ const getResponseBody = async (response: Response): Promise => { const isJSON = contentType.toLowerCase().startsWith('application/json'); if (isJSON) { return await response.json(); + } else if (options.responseType === 'blob') { + return await response.blob(); } else { return await response.text(); } @@ -3409,7 +3487,7 @@ const getResponseBody = async (response: Response): Promise => { return undefined; }; -const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult): void => { +const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult): void => { const errors: Record = { 400: 'Bad Request', 401: 'Unauthorized', @@ -3432,13 +3510,13 @@ const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult): void => }; /** - * Request method + * Request method to get ApiResult * @param config The OpenAPI configuration object * @param options The request options from the service - * @returns CancelablePromise + * @returns CancelablePromise> * @throws ApiError */ -export const request = (config: OpenAPIConfig, options: ApiRequestOptions): CancelablePromise => { +export const requestApiResult = (config: OpenAPIConfig, options: ApiRequestOptions): CancelablePromise> => { return new CancelablePromise(async (resolve, reject, onCancel) => { try { const url = getUrl(config, options); @@ -3448,20 +3526,41 @@ export const request = (config: OpenAPIConfig, options: ApiRequestOptions): C if (!onCancel.isCancelled) { const response = await sendRequest(config, options, url, body, formData, headers, onCancel); - const responseBody = await getResponseBody(response); + const responseBody = await getResponseBody(response, options); const responseHeader = getResponseHeader(response, options.responseHeader); - const result: ApiResult = { + const result: ApiResult = { url, ok: response.ok, status: response.status, statusText: response.statusText, - body: responseHeader ?? responseBody, + body: responseBody, + header: responseHeader, }; catchErrorCodes(options, result); - resolve(result.body); + resolve(result); + } + } catch (error) { + reject(error); + } + }); +}; + +/** + * Request method + * @param config The OpenAPI configuration object + * @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) => { + try { + if (!onCancel.isCancelled) { + const result = await requestApiResult(config, options) + resolve(result.body) } } catch (error) { reject(error); @@ -5827,8 +5926,10 @@ exports[`v3 should generate: ./test/generated/v3/services/CollectionFormatServic /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class CollectionFormatService { @@ -5873,8 +5974,10 @@ import type { ModelWithEnum } from '../models/ModelWithEnum'; import type { ModelWithString } from '../models/ModelWithString'; import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class ComplexService { @@ -5949,8 +6052,10 @@ exports[`v3 should generate: ./test/generated/v3/services/DefaultService.ts 1`] /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class DefaultService { @@ -5974,8 +6079,10 @@ exports[`v3 should generate: ./test/generated/v3/services/DefaultsService.ts 1`] import type { ModelWithString } from '../models/ModelWithString'; import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class DefaultsService { @@ -6084,8 +6191,10 @@ exports[`v3 should generate: ./test/generated/v3/services/DescriptionsService.ts /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class DescriptionsService { @@ -6131,8 +6240,10 @@ exports[`v3 should generate: ./test/generated/v3/services/DuplicateService.ts 1` /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class DuplicateService { @@ -6184,8 +6295,10 @@ exports[`v3 should generate: ./test/generated/v3/services/ErrorService.ts 1`] = /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class ErrorService { @@ -6222,8 +6335,10 @@ exports[`v3 should generate: ./test/generated/v3/services/FormDataService.ts 1`] import type { ModelWithString } from '../models/ModelWithString'; import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class FormDataService { @@ -6255,17 +6370,19 @@ exports[`v3 should generate: ./test/generated/v3/services/HeaderService.ts 1`] = /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class HeaderService { /** - * @returns string Successful response + * @returns ApiResult Successful response * @throws ApiError */ - public static callWithResultFromHeader(): CancelablePromise { - return __request(OpenAPI, { + public callWithResultFromHeader(): CancelablePromise> { + return __requestApiResult(OpenAPI, { method: 'POST', url: '/api/v{api-version}/header', responseHeader: 'operation-location', @@ -6276,6 +6393,23 @@ export class HeaderService { }); } + /** + * @returns ApiResult Successful response + * @throws ApiError + */ + public callWithResultFromContentAndHeader(): CancelablePromise> { + return __requestApiResult(OpenAPI, { + method: 'POST', + url: '/api/v{api-version}/content/header', + responseType: 'blob', + responseHeader: 'content-disposition', + errors: { + 400: \`400 server error\`, + 500: \`500 server error\`, + }, + }); + } + }" `; @@ -6286,8 +6420,10 @@ exports[`v3 should generate: ./test/generated/v3/services/MultipartService.ts 1` import type { ModelWithString } from '../models/ModelWithString'; import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class MultipartService { @@ -6334,8 +6470,10 @@ exports[`v3 should generate: ./test/generated/v3/services/MultipleTags1Service.t /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class MultipleTags1Service { @@ -6369,8 +6507,10 @@ exports[`v3 should generate: ./test/generated/v3/services/MultipleTags2Service.t /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class MultipleTags2Service { @@ -6404,8 +6544,10 @@ exports[`v3 should generate: ./test/generated/v3/services/MultipleTags3Service.t /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class MultipleTags3Service { @@ -6428,8 +6570,10 @@ exports[`v3 should generate: ./test/generated/v3/services/NoContentService.ts 1` /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class NoContentService { @@ -6455,8 +6599,10 @@ import type { ModelWithString } from '../models/ModelWithString'; import type { Pageable } from '../models/Pageable'; import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class ParametersService { @@ -6599,8 +6745,10 @@ exports[`v3 should generate: ./test/generated/v3/services/RequestBodyService.ts import type { ModelWithString } from '../models/ModelWithString'; import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class RequestBodyService { @@ -6636,8 +6784,10 @@ import type { ModelThatExtendsExtends } from '../models/ModelThatExtendsExtends' import type { ModelWithString } from '../models/ModelWithString'; import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class ResponseService { @@ -6699,8 +6849,10 @@ exports[`v3 should generate: ./test/generated/v3/services/SimpleService.ts 1`] = /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class SimpleService { @@ -6782,8 +6934,10 @@ exports[`v3 should generate: ./test/generated/v3/services/TypesService.ts 1`] = /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class TypesService { @@ -6838,8 +6992,10 @@ exports[`v3 should generate: ./test/generated/v3/services/UploadService.ts 1`] = /* tslint:disable */ /* eslint-disable */ import type { CancelablePromise } from '../core/CancelablePromise'; +import type { ApiResult } from '../core/ApiResult'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; +import { requestApiResult as __requestApiResult } from '../core/request'; export class UploadService { diff --git a/test/spec/v2.json b/test/spec/v2.json index 2cc00b367..1812940bf 100644 --- a/test/spec/v2.json +++ b/test/spec/v2.json @@ -872,6 +872,36 @@ } } }, + "/api/v{api-version}/content/header": { + "post": { + "tags": [ + "Header" + ], + "operationId": "CallWithResultFromContentAndHeader", + "produces": [ + "application/pdf" + ], + "responses": { + "200": { + "description": "Successful response", + "schema": { + "type": "file" + }, + "headers": { + "content-disposition": { + "type": "string" + } + } + }, + "400": { + "description": "400 server error" + }, + "500": { + "description": "500 server error" + } + } + } + }, "/api/v{api-version}/error": { "post": { "tags": [ diff --git a/test/spec/v3.json b/test/spec/v3.json index 70373897d..4c1c55613 100644 --- a/test/spec/v3.json +++ b/test/spec/v3.json @@ -1407,6 +1407,35 @@ } } }, + "/api/v{api-version}/content/header": { + "post": { + "tags": [ + "Header" + ], + "operationId": "CallWithResultFromContentAndHeader", + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/pdf": {"schema": {"type": "string", "format": "binary"}} + }, + "headers": { + "content-disposition": { + "schema": { + "type": "string" + } + } + } + }, + "400": { + "description": "400 server error" + }, + "500": { + "description": "500 server error" + } + } + } + }, "/api/v{api-version}/error": { "post": { "tags": [