diff --git a/jest.config.js b/jest.config.js index b8a467c6..adc60c0b 100644 --- a/jest.config.js +++ b/jest.config.js @@ -15,11 +15,11 @@ module.exports = { displayName: 'E2E', testEnvironment: 'node', testMatch: [ - '/test/e2e/v2.fetch.spec.js', - '/test/e2e/v2.xhr.spec.js', - // '/test/e2e/v2.node.spec.js', - '/test/e2e/v3.fetch.spec.js', - '/test/e2e/v3.xhr.spec.js', + // '/test/e2e/v2.fetch.spec.js', + // '/test/e2e/v2.xhr.spec.js', + '/test/e2e/v2.node.spec.js', + // '/test/e2e/v3.fetch.spec.js', + // '/test/e2e/v3.xhr.spec.js', // '/test/e2e/v3.node.spec.js', ], }, diff --git a/package.json b/package.json index 08417c39..c04bc27a 100644 --- a/package.json +++ b/package.json @@ -63,11 +63,14 @@ "aap": "node test/e2e/index.js" }, "dependencies": { + "@types/node-fetch": "2.5.7", "camelcase": "6.0.0", "commander": "6.1.0", + "form-data": "3.0.0", "handlebars": "4.7.6", "js-yaml": "3.14.0", "mkdirp": "1.0.4", + "node-fetch": "2.6.1", "path": "0.12.7", "rimraf": "3.0.2" }, diff --git a/src/openApi/v2/parser/getOperation.ts b/src/openApi/v2/parser/getOperation.ts index a82880e0..b89b7101 100644 --- a/src/openApi/v2/parser/getOperation.ts +++ b/src/openApi/v2/parser/getOperation.ts @@ -26,7 +26,7 @@ export function getOperation(openApi: OpenApi, url: string, method: string, op: summary: getComment(op.summary), description: getComment(op.description), deprecated: op.deprecated === true, - method: method, + method: method.toUpperCase(), path: operationPath, parameters: [...pathParams.parameters], parametersPath: [...pathParams.parametersPath], diff --git a/src/openApi/v3/parser/getOperation.ts b/src/openApi/v3/parser/getOperation.ts index c9f9cb38..622f11ec 100644 --- a/src/openApi/v3/parser/getOperation.ts +++ b/src/openApi/v3/parser/getOperation.ts @@ -30,7 +30,7 @@ export function getOperation(openApi: OpenApi, url: string, method: string, op: summary: getComment(op.summary), description: getComment(op.description), deprecated: op.deprecated === true, - method: method, + method: method.toUpperCase(), path: operationPath, parameters: [...pathParams.parameters], parametersPath: [...pathParams.parametersPath], diff --git a/src/templates/core/ApiError.hbs b/src/templates/core/ApiError.hbs index 72a36587..0bbe19a2 100644 --- a/src/templates/core/ApiError.hbs +++ b/src/templates/core/ApiError.hbs @@ -1,43 +1,19 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ +{{>header}} -import { isSuccess } from './isSuccess'; -import { Result } from './Result'; +import { ApiResponse } from './ApiResponse'; export class ApiError extends Error { - public readonly url: string; public readonly status: number; public readonly statusText: string; public readonly body: any; - constructor(result: Readonly, message: string) { + constructor(response: ApiResponse, message: string) { super(message); - this.url = result.url; - this.status = result.status; - this.statusText = result.statusText; - this.body = result.body; - } -} - -/** - * Catch common errors (based on status code). - * @param result - */ -export function catchGenericError(result: Result): void { - switch (result.status) { - case 400: throw new ApiError(result, 'Bad Request'); - case 401: throw new ApiError(result, 'Unauthorized'); - case 403: throw new ApiError(result, 'Forbidden'); - case 404: throw new ApiError(result, 'Not Found'); - case 500: throw new ApiError(result, 'Internal Server Error'); - case 502: throw new ApiError(result, 'Bad Gateway'); - case 503: throw new ApiError(result, 'Service Unavailable'); - } - - if (!isSuccess(result.status)) { - throw new ApiError(result, 'Generic Error'); + this.url = response.url; + this.status = response.status; + this.statusText = response.statusText; + this.body = response.body; } } diff --git a/src/templates/core/ApiRequestOptions.hbs b/src/templates/core/ApiRequestOptions.hbs new file mode 100644 index 00000000..c54b55d3 --- /dev/null +++ b/src/templates/core/ApiRequestOptions.hbs @@ -0,0 +1,13 @@ +{{>header}} + +export interface RequestOptions { + readonly method: 'GET' | 'PUT' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'PATCH'; + readonly path: string; + readonly cookies?: Record; + readonly headers?: Record; + readonly query?: Record; + readonly formData?: Record; + readonly body?: any; + readonly responseHeader?: string; + readonly errors?: Record; +} diff --git a/src/templates/core/ApiResponse.hbs b/src/templates/core/ApiResponse.hbs new file mode 100644 index 00000000..f550a68a --- /dev/null +++ b/src/templates/core/ApiResponse.hbs @@ -0,0 +1,9 @@ +{{>header}} + +export interface Response { + readonly url: string; + readonly ok: boolean; + readonly status: number; + readonly statusText: string; + readonly body: any; +} diff --git a/src/templates/core/OpenAPI.hbs b/src/templates/core/OpenAPI.hbs index f24b4756..c6009575 100644 --- a/src/templates/core/OpenAPI.hbs +++ b/src/templates/core/OpenAPI.hbs @@ -1,6 +1,4 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ +{{>header}} interface Config { BASE: string; diff --git a/src/templates/core/RequestOptions.hbs b/src/templates/core/RequestOptions.hbs deleted file mode 100644 index a49fa3e6..00000000 --- a/src/templates/core/RequestOptions.hbs +++ /dev/null @@ -1,14 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -export interface RequestOptions { - method: 'get' | 'put' | 'post' | 'delete' | 'options' | 'head' | 'patch'; - path: string; - cookies?: { [key: string]: any }; - headers?: { [key: string]: any }; - query?: { [key: string]: any }; - formData?: { [key: string]: any }; - body?: any; - responseHeader?: string; -} diff --git a/src/templates/core/Result.hbs b/src/templates/core/Result.hbs deleted file mode 100644 index 330d5416..00000000 --- a/src/templates/core/Result.hbs +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -export interface Result { - url: string; - ok: boolean; - status: number; - statusText: string; - body: any; -} diff --git a/src/templates/core/functions/catchErrors.hbs b/src/templates/core/functions/catchErrors.hbs new file mode 100644 index 00000000..cece7905 --- /dev/null +++ b/src/templates/core/functions/catchErrors.hbs @@ -0,0 +1,21 @@ +function catchErrors(options: ApiRequestOptions, response: ApiResponse): void { + const errors = { + 400: 'Bad Request', + 401: 'Unauthorized', + 403: 'Forbidden', + 404: 'Not Found', + 500: 'Internal Server Error', + 502: 'Bad Gateway', + 503: 'Service Unavailable', + ...options.errors, + } + + const error = errors[response.status]; + if (error) { + throw new ApiError(response, error); + } + + if (!result.ok) { + throw new ApiError(response, 'Generic Error'); + } +} diff --git a/src/templates/core/functions/getFormData.hbs b/src/templates/core/functions/getFormData.hbs new file mode 100644 index 00000000..a1c33ee5 --- /dev/null +++ b/src/templates/core/functions/getFormData.hbs @@ -0,0 +1,12 @@ +function getFormData(params: Record): FormData { + const formData = new FormData(); + + Object.keys(params).forEach(key => { + const value = params[key]; + if (isDefined(value)) { + formData.append(key, value); + } + }); + + return formData; +} diff --git a/src/templates/core/functions/getHeaders.hbs b/src/templates/core/functions/getHeaders.hbs new file mode 100644 index 00000000..27951f1d --- /dev/null +++ b/src/templates/core/functions/getHeaders.hbs @@ -0,0 +1,24 @@ +function getHeaders(options: ApiRequestOptions): Headers { + const headers = new Headers({ + ...options.headers, + Accept: 'application/json', + }); + + if (OpenAPI.TOKEN !== null && OpenAPI.TOKEN !== '') { + headers.append('Authorization', `Bearer ${OpenAPI.TOKEN}`); + } + + if (options.body) { + if (options.body instanceof Blob) { + if (options.body.type) { + headers.append('Content-Type', options.body.type); + } + } else if (typeof options.body === 'string') { + headers.append('Content-Type', 'text/plain'); + } else { + headers.append('Content-Type', 'application/json'); + } + } + + return headers; +} diff --git a/src/templates/core/functions/getQueryString.hbs b/src/templates/core/functions/getQueryString.hbs new file mode 100644 index 00000000..bd160e32 --- /dev/null +++ b/src/templates/core/functions/getQueryString.hbs @@ -0,0 +1,22 @@ +function getQueryString(params: Record): string { + const qs: string[] = []; + + Object.keys(params).forEach(key => { + const value = params[key]; + if (isDefined(value)) { + if (Array.isArray(value)) { + value.forEach(value => { + qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`); + }); + } else { + qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`); + } + } + }); + + if (qs.length > 0) { + return `?${qs.join('&')}`; + } + + return ''; +} diff --git a/src/templates/core/functions/getUrl.hbs b/src/templates/core/functions/getUrl.hbs new file mode 100644 index 00000000..10095670 --- /dev/null +++ b/src/templates/core/functions/getUrl.hbs @@ -0,0 +1,10 @@ +function getUrl(options: ApiRequestOptions): string { + const path = options.path.replace(/[:]/g, '_'); + const url = `${OpenAPI.BASE}${path}`; + + if (options.query) { + return url + getQueryString(options.query); + } + + return url; +} diff --git a/src/templates/core/functions/isDefined.hbs b/src/templates/core/functions/isDefined.hbs new file mode 100644 index 00000000..0f76dfd5 --- /dev/null +++ b/src/templates/core/functions/isDefined.hbs @@ -0,0 +1,3 @@ +function isDefined(value: T | null | undefined): value is Exclude { + return value !== undefined && value !== null; +} diff --git a/src/templates/core/functions/isSuccess.hbs b/src/templates/core/functions/isSuccess.hbs new file mode 100644 index 00000000..e61ffe29 --- /dev/null +++ b/src/templates/core/functions/isSuccess.hbs @@ -0,0 +1,3 @@ +function isSuccess(status: number): boolean { + return status >= 200 && status < 300; +} diff --git a/src/templates/core/getFormData.hbs b/src/templates/core/getFormData.hbs deleted file mode 100644 index a1c1e5e4..00000000 --- a/src/templates/core/getFormData.hbs +++ /dev/null @@ -1,21 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -/** - * Get FormData from object. This method is needed to upload - * multipart form data to the REST API. - * @param params Key value based object. - */ -export function getFormData(params: { [key: string]: any }): FormData { - const formData = new FormData(); - for (const key in params) { - if (typeof params[key] !== 'undefined') { - const value: any = params[key]; - if (value !== undefined && value !== null) { - formData.append(key, value); - } - } - } - return formData; -} diff --git a/src/templates/core/getQueryString.hbs b/src/templates/core/getQueryString.hbs deleted file mode 100644 index 1f48a4e8..00000000 --- a/src/templates/core/getQueryString.hbs +++ /dev/null @@ -1,30 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -/** - * Get query string from query parameters object. This method also - * supports multi-value items by creating a key for each item. - * @param params Key value based object. - */ -export function getQueryString(params: { [key: string]: any }): string { - const qs: string[] = []; - for (const key in params) { - if (typeof params[key] !== 'undefined') { - const value: any = params[key]; - if (value !== undefined && value !== null) { - if (Array.isArray(value)) { - value.forEach(value => { - qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`); - }); - } else { - qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`); - } - } - } - } - if (qs.length > 0) { - return `?${qs.join('&')}`; - } - return ''; -} diff --git a/src/templates/core/isSuccess.hbs b/src/templates/core/isSuccess.hbs deleted file mode 100644 index 272e7122..00000000 --- a/src/templates/core/isSuccess.hbs +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -/** - * Check success response code. - * @param status Status code - */ -export function isSuccess(status: number): boolean { - return status >= 200 && status < 300; -} diff --git a/src/templates/core/request.hbs b/src/templates/core/request.hbs index 5a0903b1..9ba77ad2 100644 --- a/src/templates/core/request.hbs +++ b/src/templates/core/request.hbs @@ -1,92 +1,2 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import { getFormData } from './getFormData'; -import { getQueryString } from './getQueryString'; -import { OpenAPI } from './OpenAPI'; -import { RequestOptions } from './RequestOptions'; -import { requestUsingFetch } from './requestUsingFetch'; -import { requestUsingXHR } from './requestUsingXHR'; -import { Result } from './Result'; - -/** - * Create the request. - * @param options Request method options. - * @returns Result object (see above) - */ -export async function request(options: Readonly): Promise { - - // Escape path (RFC3986) and create the request URL - let path = options.path.replace(/[:]/g, '_'); - let url = `${OpenAPI.BASE}${path}`; - - // Create request headers - const headers = new Headers({ - ...options.headers, - Accept: 'application/json', - }); - - // Create request settings - const request: RequestInit = { - headers, - method: options.method, - }; - - // If we specified to send requests with credentials, then we - // set the request credentials options to include. This is only - // needed if you make cross-origin calls. - if (OpenAPI.WITH_CREDENTIALS) { - request.credentials = 'include'; - } - - // If we have a bearer token then we set the authentication header. - if (OpenAPI.TOKEN !== null && OpenAPI.TOKEN !== '') { - headers.append('Authorization', `Bearer ${OpenAPI.TOKEN}`); - } - - // Add the query parameters (if defined). - if (options.query) { - url += getQueryString(options.query); - } - - // Append formData as body, this needs to be parsed to key=value pairs - // so the backend can parse this just like a regular HTML form. - if (options.formData) { - request.body = getFormData(options.formData); - headers.append('Content-Type', 'application/x-www-form-urlencoded'); - } else if (options.body) { - - // If this is blob data, then pass it directly to the body and set content type. - // Otherwise we just convert request data to JSON string (needed for fetch api) - if (options.body instanceof Blob) { - request.body = options.body; - if (options.body.type) { - headers.append('Content-Type', options.body.type); - } - } else if (typeof options.body === 'string') { - request.body = options.body; - headers.append('Content-Type', 'text/plain'); - } else { - request.body = JSON.stringify(options.body); - headers.append('Content-Type', 'application/json'); - } - } - - try { - switch (OpenAPI.CLIENT) { - case 'xhr': - return await requestUsingXHR(url, request, options.responseHeader); - default: - return await requestUsingFetch(url, request, options.responseHeader); - } - } catch (error) { - return { - url, - ok: false, - status: 0, - statusText: '', - body: error, - }; - } -} +{{>header}} +{{>requestUsingFetch}} diff --git a/src/templates/core/requestUsingFetch.hbs b/src/templates/core/requestUsingFetch.hbs deleted file mode 100644 index 7885007e..00000000 --- a/src/templates/core/requestUsingFetch.hbs +++ /dev/null @@ -1,72 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import { Result } from './Result'; - -/** - * Try to parse the content for any response status code. - * We check the "Content-Type" header to see if we need to parse the - * content as json or as plain text. - * @param response Response object from fetch - */ -async function parseBody(response: Response): Promise { - try { - const contentType = response.headers.get('Content-Type'); - if (contentType) { - switch (contentType.toLowerCase()) { - case 'application/json': - case 'application/json; charset=utf-8': - return await response.json(); - - default: - return await response.text(); - } - } - } catch (e) { - console.error(e); - } - return null; -} - -/** - * Fetch the response header (if specified) - * @param response Response object from fetch - * @param responseHeader The name of the header to fetch - */ -function parseHeader(response: Response, responseHeader?: string): string | null { - if (responseHeader) { - const content = response.headers.get(responseHeader); - if (typeof content === 'string') { - return content; - } - } - return null; -} - -/** - * Request content using the new Fetch API. This is the default API that is used and - * is create for all JSON, XML and text objects. However it is limited to UTF-8. - * This is a problem for some of the Docs content, since that requires UTF-16! - * @param url The url to request. - * @param request The request object, containing method, headers, body, etc. - * @param responseHeader The header we want to parse. - */ -export async function requestUsingFetch(url: string, request: Readonly, responseHeader?: string): Promise { - - // Fetch response using fetch API. - const response = await fetch(url, request); - - // Get content of response header or response body - const contentHeader = parseHeader(response, responseHeader); - const contentBody = await parseBody(response); - - // Create result object. - return { - url, - ok: response.ok, - status: response.status, - statusText: response.statusText, - body: contentHeader || contentBody, - }; -} diff --git a/src/templates/core/requestUsingFetch/getRequest.hbs b/src/templates/core/requestUsingFetch/getRequest.hbs new file mode 100644 index 00000000..eee4e166 --- /dev/null +++ b/src/templates/core/requestUsingFetch/getRequest.hbs @@ -0,0 +1,26 @@ +function getRequest(options: ApiRequestOptions): RequestInit { + const request: RequestInit = { + headers: getHeaders(options), + method: options.method, + }; + + if (OpenAPI.WITH_CREDENTIALS) { + request.credentials = 'include'; + } + + if (options.formData) { + request.body = getFormData(options.formData); + } + + if (options.body) { + if (options.body instanceof Blob) { + request.body = options.body; + } else if (typeof options.body === 'string') { + request.body = options.body; + } else { + request.body = JSON.stringify(options.body); + } + } + + return request; +} diff --git a/src/templates/core/requestUsingFetch/getRequestBody.hbs b/src/templates/core/requestUsingFetch/getRequestBody.hbs new file mode 100644 index 00000000..0bbe6b0c --- /dev/null +++ b/src/templates/core/requestUsingFetch/getRequestBody.hbs @@ -0,0 +1,17 @@ +function getRequestBody(options: ApiRequestOptions): any { + if (options.formData) { + return getFormData(options.formData); + } + + if (options.body) { + if (options.body instanceof Blob) { + return options.body; + } else if (typeof options.body === 'string') { + return options.body; + } else { + return JSON.stringify(options.body); + } + } + + return undefined; +} diff --git a/src/templates/core/requestUsingFetch/getResponseBody.hbs b/src/templates/core/requestUsingFetch/getResponseBody.hbs new file mode 100644 index 00000000..724b26b5 --- /dev/null +++ b/src/templates/core/requestUsingFetch/getResponseBody.hbs @@ -0,0 +1,19 @@ +async function getResponseBody(response: Response): Promise { + try { + const contentType = response.headers.get('Content-Type'); + if (contentType) { + switch (contentType.toLowerCase()) { + case 'application/json': + case 'application/json; charset=utf-8': + return await response.json(); + + default: + return await response.text(); + } + } + } catch (e) { + console.error(e); + } + + return null; +} diff --git a/src/templates/core/requestUsingFetch/getResponseHeader.hbs b/src/templates/core/requestUsingFetch/getResponseHeader.hbs new file mode 100644 index 00000000..e9064d4c --- /dev/null +++ b/src/templates/core/requestUsingFetch/getResponseHeader.hbs @@ -0,0 +1,10 @@ +function getResponseHeader(response: Response, responseHeader?: string): string | null { + if (responseHeader) { + const content = response.headers.get(responseHeader); + if (typeof content === 'string') { + return content; + } + } + + return null; +} diff --git a/src/templates/core/requestUsingFetch/index.hbs b/src/templates/core/requestUsingFetch/index.hbs new file mode 100644 index 00000000..9ed27bf4 --- /dev/null +++ b/src/templates/core/requestUsingFetch/index.hbs @@ -0,0 +1,55 @@ +import { ApiError } from './ApiError'; +import { ApiRequestOptions } from './ApiRequestOptions'; +import { ApiResponse } from './ApiResponse'; +import { OpenAPI } from './OpenAPI'; + +import fetch, { Headers } from 'node-fetch'; +import FormData from 'form-data'; + +{{>isDefined}} + +{{>isSuccess}} + +{{>getQueryString}} + +{{>getUrl}} + +{{>catchErrors}} + +{{>getFormData}} + +{{>getHeaders}} + +{{>getRequestBody}} + +{{>getRequest}} + +{{>getResponseHeader}} + +{{>getResponseBody}} + +/** + * Request using fetch + * @param options Request options + * @result ApiResponse + * @throws ApiError + */ +export async function request(options: ApiRequestOptions): Promise { + const url = getUrl(options); + const request = getRequest(options); + const response = await fetch(url, request); + const responseBody = await getResponseBody(response); + const responseHeader = getResponseHeader(response, options.responseHeader); + + const response: ApiResponse = { + url, + ok: isSuccess(xhr.status), + status: xhr.status, + statusText: xhr.statusText, + body: responseHeader || responseBody, + }; + + catchErrors(options, response); + + return response; +} diff --git a/src/templates/core/requestUsingXHR.hbs b/src/templates/core/requestUsingXHR.hbs deleted file mode 100644 index 8c3663d3..00000000 --- a/src/templates/core/requestUsingXHR.hbs +++ /dev/null @@ -1,101 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import { isSuccess } from './isSuccess'; -import { Result } from './Result'; - -/** - * Try to parse the content for any response status code. - * We check the "Content-Type" header to see if we need to parse the - * content as json or as plain text. - * @param xhr XHR request object - */ -function parseBody(xhr: XMLHttpRequest): any { - try { - const contentType = xhr.getResponseHeader('Content-Type'); - if (contentType) { - switch (contentType.toLowerCase()) { - case 'application/json': - case 'application/json; charset=utf-8': - return JSON.parse(xhr.responseText); - - default: - return xhr.responseText; - } - } - } catch (e) { - console.error(e); - } - return null; -} - -/** - * Fetch the response header (if specified) - * @param xhr XHR request object - * @param responseHeader The name of the header to fetch - */ -function parseHeader(xhr: XMLHttpRequest, responseHeader?: string): string | null { - if (responseHeader) { - const content = xhr.getResponseHeader(responseHeader); - if (typeof content === 'string') { - return content; - } - } - return null; -} - -/** - * Request content using the new legacy XMLHttpRequest API. This method is useful - * when we want to request UTF-16 content, since it natively supports loading UTF-16. - * We could do the same with the Fetch API, but then we will need to convert the - * content using JavaScript... And that is very very slow. - * @param url The url to request. - * @param request The request object, containing method, headers, body, etc. - * @param responseHeader The header we want to parse. - */ -export async function requestUsingXHR(url: string, request: Readonly, responseHeader?: string): Promise { - return new Promise(resolve => { - const xhr = new XMLHttpRequest(); - - // Open the request, remember to do this before adding any headers, - // because the request needs to be initialized! - xhr.open(request.method!, url, true); - - // When request credentials are set to include then this is - // the same behaviour as withCredentials = true in XHR: - // https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials - xhr.withCredentials = request.credentials === 'include'; - - // Add the headers (required when dealing with JSON) - const headers = request.headers as Headers; - headers.forEach((value: string, key: string): void => { - xhr.setRequestHeader(key, value); - }); - - // Register the readystate handler, this will fire when the request is done. - xhr.onreadystatechange = () => { - if (xhr.readyState === XMLHttpRequest.DONE) { - - // Get content of response header or response body - const contentHeader = parseHeader(xhr, responseHeader); - const contentBody = parseBody(xhr); - - // Create result object. - const result: Result = { - url, - ok: isSuccess(xhr.status), - status: xhr.status, - statusText: xhr.statusText, - body: contentHeader || contentBody, - }; - - // Done! - resolve(result); - } - }; - - // Start the request! - xhr.send(request.body); - }); -} diff --git a/src/templates/core/requestUsingXHR/getRequest.hbs b/src/templates/core/requestUsingXHR/getRequest.hbs new file mode 100644 index 00000000..5611597f --- /dev/null +++ b/src/templates/core/requestUsingXHR/getRequest.hbs @@ -0,0 +1,25 @@ +function getRequest(options: ApiRequestOptions, url: string, listener: (xhr: XMLHttpRequest) => ApiResponse): Promise { + return new Promise((resolve, reject) => { + try { + const xhr = new XMLHttpRequest(); + xhr.open(options.method, url, true); + xhr.withCredentials = OpenAPI.WITH_CREDENTIALS; + + const headers = getHeaders(options); + headers.forEach((value, key) => { + xhr.setRequestHeader(key, value); + }); + + xhr.onreadystatechange = () => { + if (xhr.readyState === XMLHttpRequest.DONE) { + const response = listener(xhr); + resolve(response); + } + }; + + xhr.send(getRequestBody()); + } catch (error) { + reject(error); + } + ); +} diff --git a/src/templates/core/requestUsingXHR/getRequestBody.hbs b/src/templates/core/requestUsingXHR/getRequestBody.hbs new file mode 100644 index 00000000..0bbe6b0c --- /dev/null +++ b/src/templates/core/requestUsingXHR/getRequestBody.hbs @@ -0,0 +1,17 @@ +function getRequestBody(options: ApiRequestOptions): any { + if (options.formData) { + return getFormData(options.formData); + } + + if (options.body) { + if (options.body instanceof Blob) { + return options.body; + } else if (typeof options.body === 'string') { + return options.body; + } else { + return JSON.stringify(options.body); + } + } + + return undefined; +} diff --git a/src/templates/core/requestUsingXHR/getResponseBody.hbs b/src/templates/core/requestUsingXHR/getResponseBody.hbs new file mode 100644 index 00000000..5e542fbb --- /dev/null +++ b/src/templates/core/requestUsingXHR/getResponseBody.hbs @@ -0,0 +1,19 @@ +function getResponseBody(xhr: XMLHttpRequest): Promise { + try { + const contentType = xhr.getResponseHeader('Content-Type'); + if (contentType) { + switch (contentType.toLowerCase()) { + case 'application/json': + case 'application/json; charset=utf-8': + return JSON.parse(xhr.responseText); + + default: + return xhr.responseText; + } + } + } catch (e) { + console.error(e); + } + + return null; +} diff --git a/src/templates/core/requestUsingXHR/getResponseHeader.hbs b/src/templates/core/requestUsingXHR/getResponseHeader.hbs new file mode 100644 index 00000000..047a8c02 --- /dev/null +++ b/src/templates/core/requestUsingXHR/getResponseHeader.hbs @@ -0,0 +1,10 @@ +function getResponseHeader(xhr: XMLHttpRequest, responseHeader?: string): string | null { + if (responseHeader) { + const content = xhr.getResponseHeader(responseHeader); + if (typeof content === 'string') { + return content; + } + } + + return null; +} diff --git a/src/templates/core/requestUsingXHR/index.hbs b/src/templates/core/requestUsingXHR/index.hbs new file mode 100644 index 00000000..702554ac --- /dev/null +++ b/src/templates/core/requestUsingXHR/index.hbs @@ -0,0 +1,52 @@ +import { ApiError } from './ApiError'; +import { ApiRequestOptions } from './ApiRequestOptions'; +import { ApiResponse } from './ApiResponse'; +import { OpenAPI } from './OpenAPI'; + +{{>isDefined}} + +{{>isSuccess}} + +{{>getQueryString}} + +{{>getUrl}} + +{{>catchErrors}} + +{{>getFormData}} + +{{>getHeaders}} + +{{>getRequestBody}} + +{{>getRequest}} + +{{>getResponseHeader}} + +{{>getResponseBody}} + +/** + * Request using XHR + * @param options Request options + * @result ApiResponse + * @throws ApiError + */ +export async function request(options: ApiRequestOptions): Promise { + const url = getUrl(options); + + return await getRequest(options.method, url, xhr => { + const responseBody = getResponseBody(response); + const responseHeader = getResponseHeader(response, options.responseHeader); + + const response: ApiResponse = { + url, + ok: isSuccess(xhr.status), + status: xhr.status, + statusText: xhr.statusText, + body: responseHeader || responseBody, + }; + + catchErrors(options, response); + return response; + }); +} diff --git a/src/templates/exportModel.hbs b/src/templates/export/exportModel.hbs similarity index 77% rename from src/templates/exportModel.hbs rename to src/templates/export/exportModel.hbs index 696757d6..5bc017a7 100644 --- a/src/templates/exportModel.hbs +++ b/src/templates/export/exportModel.hbs @@ -1,8 +1,6 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - +{{>header}} {{#if imports}} + {{#each imports}} import { {{{this}}} } from './{{{this}}}'; {{/each}} diff --git a/src/templates/exportSchema.hbs b/src/templates/export/exportSchema.hbs similarity index 66% rename from src/templates/exportSchema.hbs rename to src/templates/export/exportSchema.hbs index 42e09fdd..d0f33fb7 100644 --- a/src/templates/exportSchema.hbs +++ b/src/templates/export/exportSchema.hbs @@ -1,6 +1,4 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ +{{>header}} {{#if extends}} {{#each extends}} diff --git a/src/templates/exportService.hbs b/src/templates/export/exportService.hbs similarity index 77% rename from src/templates/exportService.hbs rename to src/templates/export/exportService.hbs index b721253c..75b23d76 100644 --- a/src/templates/exportService.hbs +++ b/src/templates/export/exportService.hbs @@ -1,19 +1,12 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ +{{>header}} {{#if imports}} {{#each imports}} import { {{{this}}} } from '../models/{{{this}}}'; {{/each}} {{/if}} -{{#if hasApiErrors}} -import { ApiError, catchGenericError } from '../core/ApiError'; -{{else}} -import { catchGenericError } from '../core/ApiError'; -{{/if}} import { request as __request } from '../core/request'; -{{#if hasApiVersion}} +{{#if useVersion}} import { OpenAPI } from '../core/OpenAPI'; {{/if}} @@ -42,7 +35,7 @@ export class {{{name}}} { */ public static async {{{name}}}({{>parameters}}): Promise<{{>result}}> { - const result = await __request({ + const response = await __request({ method: '{{{method}}}', path: `{{{path}}}`, {{#if parametersCookie~}} @@ -79,21 +72,16 @@ export class {{{name}}} { {{#if responseHeader~}} responseHeader: '{{{responseHeader}}}', {{/if}} - }); - {{#if errors}} - - if (!result.ok) { - switch (result.status) { + {{#if errors~}} + errors: { {{#each errors}} - case {{{code}}}: throw new ApiError(result, `{{{description}}}`); + {{{code}}}: `{{{description}}}`, {{/each}} - } - } - {{/if}} + }, + {{/if}} + }); - catchGenericError(result); - - return result.body; + return response.body; } {{/each}} diff --git a/src/templates/index.hbs b/src/templates/export/index.hbs similarity index 85% rename from src/templates/index.hbs rename to src/templates/export/index.hbs index 7633a13d..b530e09f 100644 --- a/src/templates/index.hbs +++ b/src/templates/export/index.hbs @@ -1,10 +1,7 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ +{{>header}} {{#if exportCore}} export { ApiError } from './core/ApiError'; -export { isSuccess } from './core/isSuccess'; export { OpenAPI } from './core/OpenAPI'; {{/if}} {{#if exportModels}} diff --git a/src/templates/partials/exportEnum.hbs b/src/templates/export/partials/exportEnum.hbs similarity index 100% rename from src/templates/partials/exportEnum.hbs rename to src/templates/export/partials/exportEnum.hbs diff --git a/src/templates/partials/exportInterface.hbs b/src/templates/export/partials/exportInterface.hbs similarity index 100% rename from src/templates/partials/exportInterface.hbs rename to src/templates/export/partials/exportInterface.hbs diff --git a/src/templates/partials/exportType.hbs b/src/templates/export/partials/exportType.hbs similarity index 100% rename from src/templates/partials/exportType.hbs rename to src/templates/export/partials/exportType.hbs diff --git a/src/templates/partials/extends.hbs b/src/templates/export/partials/extends.hbs similarity index 100% rename from src/templates/partials/extends.hbs rename to src/templates/export/partials/extends.hbs diff --git a/src/templates/export/partials/header.hbs b/src/templates/export/partials/header.hbs new file mode 100644 index 00000000..d592379e --- /dev/null +++ b/src/templates/export/partials/header.hbs @@ -0,0 +1,3 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ diff --git a/src/templates/partials/isNullable.hbs b/src/templates/export/partials/isNullable.hbs similarity index 100% rename from src/templates/partials/isNullable.hbs rename to src/templates/export/partials/isNullable.hbs diff --git a/src/templates/partials/isReadOnly.hbs b/src/templates/export/partials/isReadOnly.hbs similarity index 100% rename from src/templates/partials/isReadOnly.hbs rename to src/templates/export/partials/isReadOnly.hbs diff --git a/src/templates/partials/isRequired.hbs b/src/templates/export/partials/isRequired.hbs similarity index 100% rename from src/templates/partials/isRequired.hbs rename to src/templates/export/partials/isRequired.hbs diff --git a/src/templates/partials/parameters.hbs b/src/templates/export/partials/parameters.hbs similarity index 100% rename from src/templates/partials/parameters.hbs rename to src/templates/export/partials/parameters.hbs diff --git a/src/templates/partials/result.hbs b/src/templates/export/partials/result.hbs similarity index 100% rename from src/templates/partials/result.hbs rename to src/templates/export/partials/result.hbs diff --git a/src/templates/partials/schema.hbs b/src/templates/export/partials/schema.hbs similarity index 100% rename from src/templates/partials/schema.hbs rename to src/templates/export/partials/schema.hbs diff --git a/src/templates/partials/schemaArray.hbs b/src/templates/export/partials/schemaArray.hbs similarity index 100% rename from src/templates/partials/schemaArray.hbs rename to src/templates/export/partials/schemaArray.hbs diff --git a/src/templates/partials/schemaDictionary.hbs b/src/templates/export/partials/schemaDictionary.hbs similarity index 100% rename from src/templates/partials/schemaDictionary.hbs rename to src/templates/export/partials/schemaDictionary.hbs diff --git a/src/templates/partials/schemaEnum.hbs b/src/templates/export/partials/schemaEnum.hbs similarity index 100% rename from src/templates/partials/schemaEnum.hbs rename to src/templates/export/partials/schemaEnum.hbs diff --git a/src/templates/partials/schemaGeneric.hbs b/src/templates/export/partials/schemaGeneric.hbs similarity index 100% rename from src/templates/partials/schemaGeneric.hbs rename to src/templates/export/partials/schemaGeneric.hbs diff --git a/src/templates/partials/schemaInterface.hbs b/src/templates/export/partials/schemaInterface.hbs similarity index 100% rename from src/templates/partials/schemaInterface.hbs rename to src/templates/export/partials/schemaInterface.hbs diff --git a/src/templates/partials/type.hbs b/src/templates/export/partials/type.hbs similarity index 100% rename from src/templates/partials/type.hbs rename to src/templates/export/partials/type.hbs diff --git a/src/templates/partials/typeArray.hbs b/src/templates/export/partials/typeArray.hbs similarity index 100% rename from src/templates/partials/typeArray.hbs rename to src/templates/export/partials/typeArray.hbs diff --git a/src/templates/partials/typeDictionary.hbs b/src/templates/export/partials/typeDictionary.hbs similarity index 100% rename from src/templates/partials/typeDictionary.hbs rename to src/templates/export/partials/typeDictionary.hbs diff --git a/src/templates/partials/typeEnum.hbs b/src/templates/export/partials/typeEnum.hbs similarity index 100% rename from src/templates/partials/typeEnum.hbs rename to src/templates/export/partials/typeEnum.hbs diff --git a/src/templates/partials/typeGeneric.hbs b/src/templates/export/partials/typeGeneric.hbs similarity index 100% rename from src/templates/partials/typeGeneric.hbs rename to src/templates/export/partials/typeGeneric.hbs diff --git a/src/templates/partials/typeInterface.hbs b/src/templates/export/partials/typeInterface.hbs similarity index 100% rename from src/templates/partials/typeInterface.hbs rename to src/templates/export/partials/typeInterface.hbs diff --git a/src/templates/partials/typeReference.hbs b/src/templates/export/partials/typeReference.hbs similarity index 100% rename from src/templates/partials/typeReference.hbs rename to src/templates/export/partials/typeReference.hbs diff --git a/src/utils/registerHandlebarTemplates.ts b/src/utils/registerHandlebarTemplates.ts index b4c2dcb1..a706d152 100644 --- a/src/utils/registerHandlebarTemplates.ts +++ b/src/utils/registerHandlebarTemplates.ts @@ -1,15 +1,18 @@ import * as Handlebars from 'handlebars/runtime'; -import templateCoreApiError from '../templates/core/ApiError.hbs'; -import templateCoreGetFormData from '../templates/core/getFormData.hbs'; -import templateCoreGetQueryString from '../templates/core/getQueryString.hbs'; -import templateCoreIsSuccess from '../templates/core/isSuccess.hbs'; +import templateCoreCatchGenericError from '../templates/core/catchGenericError.hbs'; +import templateCoreGetFormData from '../templates/core/functions/getFormData.hbs'; +import templateCoreGetQueryString from '../templates/core/functions/getQueryString.hbs'; +import templateCoreGetUrl from '../templates/core/functions/getUrl.hbs'; +import templateCoreIsSuccess from '../templates/core/functions/isSuccess.hbs'; import templateCoreSettings from '../templates/core/OpenAPI.hbs'; import templateCoreRequest from '../templates/core/request.hbs'; import templateCoreRequestOptions from '../templates/core/RequestOptions.hbs'; -import templateCoreRequestUsingFetch from '../templates/core/requestUsingFetch.hbs'; -import templateCoreRequestUsingXHR from '../templates/core/requestUsingXHR.hbs'; -import templateCoreResult from '../templates/core/Result.hbs'; +import templateCoreRequestUsingFetch from '../templates/core/functions/requestUsingFetch.hbs'; +import templateCoreRequestUsingNode from '../templates/core/functions/requestUsingNode.hbs'; +import templateCoreRequestUsingXHR from '../templates/core/functions/requestUsingXHR.hbs'; +import templateCoreResponse from '../templates/core/Response.hbs'; +import templateCoreResponseError from '../templates/core/ResponseError.hbs'; import templateExportModel from '../templates/exportModel.hbs'; import templateExportSchema from '../templates/exportSchema.hbs'; import templateExportService from '../templates/exportService.hbs'; @@ -47,15 +50,18 @@ export interface Templates { }; core: { settings: Handlebars.TemplateDelegate; - apiError: Handlebars.TemplateDelegate; getFormData: Handlebars.TemplateDelegate; getQueryString: Handlebars.TemplateDelegate; + getUrl: Handlebars.TemplateDelegate; isSuccess: Handlebars.TemplateDelegate; + catchGenericError: Handlebars.TemplateDelegate; request: Handlebars.TemplateDelegate; requestOptions: Handlebars.TemplateDelegate; requestUsingFetch: Handlebars.TemplateDelegate; requestUsingXHR: Handlebars.TemplateDelegate; - result: Handlebars.TemplateDelegate; + requestUsingNode: Handlebars.TemplateDelegate; + response: Handlebars.TemplateDelegate; + responseError: Handlebars.TemplateDelegate; }; } @@ -75,15 +81,18 @@ export function registerHandlebarTemplates(): Templates { }, core: { settings: Handlebars.template(templateCoreSettings), - apiError: Handlebars.template(templateCoreApiError), getFormData: Handlebars.template(templateCoreGetFormData), getQueryString: Handlebars.template(templateCoreGetQueryString), + getUrl: Handlebars.template(templateCoreGetUrl), isSuccess: Handlebars.template(templateCoreIsSuccess), + catchGenericError: Handlebars.template(templateCoreCatchGenericError), request: Handlebars.template(templateCoreRequest), requestOptions: Handlebars.template(templateCoreRequestOptions), requestUsingFetch: Handlebars.template(templateCoreRequestUsingFetch), requestUsingXHR: Handlebars.template(templateCoreRequestUsingXHR), - result: Handlebars.template(templateCoreResult), + requestUsingNode: Handlebars.template(templateCoreRequestUsingNode), + response: Handlebars.template(templateCoreResponse), + responseError: Handlebars.template(templateCoreResponseError), }, }; diff --git a/src/utils/writeClient.spec.ts b/src/utils/writeClient.spec.ts index 3b454895..d909ca6f 100644 --- a/src/utils/writeClient.spec.ts +++ b/src/utils/writeClient.spec.ts @@ -24,15 +24,18 @@ describe('writeClient', () => { }, core: { settings: () => 'settings', - apiError: () => 'apiError', getFormData: () => 'getFormData', getQueryString: () => 'getQueryString', + getUrl: () => 'getUrl', isSuccess: () => 'isSuccess', + catchGenericError: () => 'catchGenericError', request: () => 'request', requestOptions: () => 'requestOptions', requestUsingFetch: () => 'requestUsingFetch', requestUsingXHR: () => 'requestUsingXHR', - result: () => 'result', + requestUsingNode: () => 'requestUsingNode', + response: () => 'response', + responseError: () => 'responseError', }, }; diff --git a/src/utils/writeClientCore.spec.ts b/src/utils/writeClientCore.spec.ts index a5260ae3..47d503ce 100644 --- a/src/utils/writeClientCore.spec.ts +++ b/src/utils/writeClientCore.spec.ts @@ -24,29 +24,35 @@ describe('writeClientCore', () => { }, core: { settings: () => 'settings', - apiError: () => 'apiError', getFormData: () => 'getFormData', getQueryString: () => 'getQueryString', + getUrl: () => 'getUrl', isSuccess: () => 'isSuccess', + catchGenericError: () => 'catchGenericError', request: () => 'request', requestOptions: () => 'requestOptions', requestUsingFetch: () => 'requestUsingFetch', requestUsingXHR: () => 'requestUsingXHR', - result: () => 'result', + requestUsingNode: () => 'requestUsingNode', + response: () => 'response', + responseError: () => 'responseError', }, }; await writeClientCore(client, templates, '/', HttpClient.FETCH); expect(writeFile).toBeCalledWith('/OpenAPI.ts', 'settings'); - expect(writeFile).toBeCalledWith('/ApiError.ts', 'apiError'); expect(writeFile).toBeCalledWith('/getFormData.ts', 'getFormData'); expect(writeFile).toBeCalledWith('/getQueryString.ts', 'getQueryString'); + expect(writeFile).toBeCalledWith('/getUrl.ts', 'getUrl'); expect(writeFile).toBeCalledWith('/isSuccess.ts', 'isSuccess'); + expect(writeFile).toBeCalledWith('/catchGenericError.ts', 'catchGenericError'); expect(writeFile).toBeCalledWith('/request.ts', 'request'); expect(writeFile).toBeCalledWith('/RequestOptions.ts', 'requestOptions'); expect(writeFile).toBeCalledWith('/requestUsingFetch.ts', 'requestUsingFetch'); expect(writeFile).toBeCalledWith('/requestUsingXHR.ts', 'requestUsingXHR'); - expect(writeFile).toBeCalledWith('/Result.ts', 'result'); + expect(writeFile).toBeCalledWith('/requestUsingNode.ts', 'requestUsingNode'); + expect(writeFile).toBeCalledWith('/Response.ts', 'response'); + expect(writeFile).toBeCalledWith('/ResponseError.ts', 'responseError'); }); }); diff --git a/src/utils/writeClientCore.ts b/src/utils/writeClientCore.ts index 792a6c59..74045466 100644 --- a/src/utils/writeClientCore.ts +++ b/src/utils/writeClientCore.ts @@ -19,13 +19,16 @@ export async function writeClientCore(client: Client, templates: Templates, outp version: client.version, }; await writeFile(path.resolve(outputPath, 'OpenAPI.ts'), templates.core.settings(context)); - await writeFile(path.resolve(outputPath, 'ApiError.ts'), templates.core.apiError(context)); await writeFile(path.resolve(outputPath, 'getFormData.ts'), templates.core.getFormData(context)); await writeFile(path.resolve(outputPath, 'getQueryString.ts'), templates.core.getQueryString(context)); + await writeFile(path.resolve(outputPath, 'getUrl.ts'), templates.core.getUrl(context)); await writeFile(path.resolve(outputPath, 'isSuccess.ts'), templates.core.isSuccess(context)); + await writeFile(path.resolve(outputPath, 'catchGenericError.ts'), templates.core.catchGenericError(context)); await writeFile(path.resolve(outputPath, 'request.ts'), templates.core.request(context)); await writeFile(path.resolve(outputPath, 'RequestOptions.ts'), templates.core.requestOptions(context)); await writeFile(path.resolve(outputPath, 'requestUsingFetch.ts'), templates.core.requestUsingFetch(context)); await writeFile(path.resolve(outputPath, 'requestUsingXHR.ts'), templates.core.requestUsingXHR(context)); - await writeFile(path.resolve(outputPath, 'Result.ts'), templates.core.result(context)); + await writeFile(path.resolve(outputPath, 'requestUsingNode.ts'), templates.core.requestUsingNode(context)); + await writeFile(path.resolve(outputPath, 'Response.ts'), templates.core.response(context)); + await writeFile(path.resolve(outputPath, 'ResponseError.ts'), templates.core.responseError(context)); } diff --git a/src/utils/writeClientIndex.spec.ts b/src/utils/writeClientIndex.spec.ts index f7a40eba..a929686c 100644 --- a/src/utils/writeClientIndex.spec.ts +++ b/src/utils/writeClientIndex.spec.ts @@ -23,15 +23,18 @@ describe('writeClientIndex', () => { }, core: { settings: () => 'settings', - apiError: () => 'apiError', getFormData: () => 'getFormData', getQueryString: () => 'getQueryString', + getUrl: () => 'getUrl', isSuccess: () => 'isSuccess', + catchGenericError: () => 'catchGenericError', request: () => 'request', requestOptions: () => 'requestOptions', requestUsingFetch: () => 'requestUsingFetch', requestUsingXHR: () => 'requestUsingXHR', - result: () => 'result', + requestUsingNode: () => 'requestUsingNode', + response: () => 'response', + responseError: () => 'responseError', }, }; diff --git a/src/utils/writeClientModels.spec.ts b/src/utils/writeClientModels.spec.ts index bcf9713f..269e7ab0 100644 --- a/src/utils/writeClientModels.spec.ts +++ b/src/utils/writeClientModels.spec.ts @@ -37,15 +37,18 @@ describe('writeClientModels', () => { }, core: { settings: () => 'settings', - apiError: () => 'apiError', getFormData: () => 'getFormData', getQueryString: () => 'getQueryString', + getUrl: () => 'getUrl', isSuccess: () => 'isSuccess', + catchGenericError: () => 'catchGenericError', request: () => 'request', requestOptions: () => 'requestOptions', requestUsingFetch: () => 'requestUsingFetch', requestUsingXHR: () => 'requestUsingXHR', - result: () => 'result', + requestUsingNode: () => 'requestUsingNode', + response: () => 'response', + responseError: () => 'responseError', }, }; diff --git a/src/utils/writeClientSchemas.spec.ts b/src/utils/writeClientSchemas.spec.ts index 10169be3..23a4bfbd 100644 --- a/src/utils/writeClientSchemas.spec.ts +++ b/src/utils/writeClientSchemas.spec.ts @@ -37,15 +37,18 @@ describe('writeClientSchemas', () => { }, core: { settings: () => 'settings', - apiError: () => 'apiError', getFormData: () => 'getFormData', getQueryString: () => 'getQueryString', + getUrl: () => 'getUrl', isSuccess: () => 'isSuccess', + catchGenericError: () => 'catchGenericError', request: () => 'request', requestOptions: () => 'requestOptions', requestUsingFetch: () => 'requestUsingFetch', requestUsingXHR: () => 'requestUsingXHR', - result: () => 'result', + requestUsingNode: () => 'requestUsingNode', + response: () => 'response', + responseError: () => 'responseError', }, }; diff --git a/src/utils/writeClientServices.spec.ts b/src/utils/writeClientServices.spec.ts index 98665d22..d52bdd6b 100644 --- a/src/utils/writeClientServices.spec.ts +++ b/src/utils/writeClientServices.spec.ts @@ -24,15 +24,18 @@ describe('writeClientServices', () => { }, core: { settings: () => 'settings', - apiError: () => 'apiError', getFormData: () => 'getFormData', getQueryString: () => 'getQueryString', + getUrl: () => 'getUrl', isSuccess: () => 'isSuccess', + catchGenericError: () => 'catchGenericError', request: () => 'request', requestOptions: () => 'requestOptions', requestUsingFetch: () => 'requestUsingFetch', requestUsingXHR: () => 'requestUsingXHR', - result: () => 'result', + requestUsingNode: () => 'requestUsingNode', + response: () => 'response', + responseError: () => 'responseError', }, }; diff --git a/src/utils/writeClientServices.ts b/src/utils/writeClientServices.ts index 9feaa670..92e083d3 100644 --- a/src/utils/writeClientServices.ts +++ b/src/utils/writeClientServices.ts @@ -17,12 +17,10 @@ const VERSION_TEMPLATE_STRING = 'OpenAPI.VERSION'; export async function writeClientServices(services: Service[], templates: Templates, outputPath: string, useOptions: boolean): Promise { for (const service of services) { const file = path.resolve(outputPath, `${service.name}.ts`); - const hasApiErrors = service.operations.some(operation => operation.errors.length); - const hasApiVersion = service.operations.some(operation => operation.path.includes(VERSION_TEMPLATE_STRING)); + const useVersion = service.operations.some(operation => operation.path.includes(VERSION_TEMPLATE_STRING)); const templateResult = templates.exports.service({ ...service, - hasApiErrors, - hasApiVersion, + useVersion, useOptions, }); await writeFile(file, format(templateResult)); diff --git a/yarn.lock b/yarn.lock index 901d630b..fcbef471 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1325,6 +1325,14 @@ dependencies: "@types/node" "*" +"@types/node-fetch@2.5.7": + version "2.5.7" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.7.tgz#20a2afffa882ab04d44ca786449a276f9f6bbf3c" + integrity sha512-o2WVNf5UhWRkxlf6eq+jMZDu7kjgpgJfl4xVNlvryc95O/6F2ld8ztKX+qu+Rjyet93WAWm5LjeX9H5FGkODvw== + dependencies: + "@types/node" "*" + form-data "^3.0.0" + "@types/node@*", "@types/node@14.11.2": version "14.11.2" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.11.2.tgz#2de1ed6670439387da1c9f549a2ade2b0a799256" @@ -2024,7 +2032,7 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -combined-stream@^1.0.6, combined-stream@~1.0.6: +combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -2845,6 +2853,15 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= +form-data@3.0.0, form-data@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682" + integrity sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -4288,7 +4305,7 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== -node-fetch@^2.2.0: +node-fetch@2.6.1, node-fetch@^2.2.0: version "2.6.1" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==