diff --git a/src/openApi/common/parser/__tests__/operation.spec.ts b/src/openApi/common/parser/__tests__/operation.spec.ts new file mode 100644 index 000000000..64c0c7671 --- /dev/null +++ b/src/openApi/common/parser/__tests__/operation.spec.ts @@ -0,0 +1,198 @@ +import { describe, expect, it } from 'vitest'; + +import { getOperationName, getOperationParameterName, getOperationResponseCode } from '../operation'; + +describe('getOperationName', () => { + const options1: Parameters[2] = { + operationId: true, + }; + + const options2: Parameters[2] = { + operationId: false, + }; + + it.each([ + { + url: '/api/v{api-version}/users', + method: 'GET', + options: options1, + operationId: 'GetAllUsers', + expected: 'getAllUsers', + }, + { + url: '/api/v{api-version}/users', + method: 'GET', + options: options1, + operationId: undefined, + expected: 'getApiUsers', + }, + { + url: '/api/v{api-version}/users', + method: 'POST', + options: options1, + operationId: undefined, + expected: 'postApiUsers', + }, + { url: '/api/v1/users', method: 'GET', options: options1, operationId: 'GetAllUsers', expected: 'getAllUsers' }, + { url: '/api/v1/users', method: 'GET', options: options1, operationId: undefined, expected: 'getApiV1Users' }, + { url: '/api/v1/users', method: 'POST', options: options1, operationId: undefined, expected: 'postApiV1Users' }, + { + url: '/api/v1/users/{id}', + method: 'GET', + options: options1, + operationId: undefined, + expected: 'getApiV1UsersById', + }, + { + url: '/api/v1/users/{id}', + method: 'POST', + options: options1, + operationId: undefined, + expected: 'postApiV1UsersById', + }, + { + url: '/api/v{api-version}/users', + method: 'GET', + options: options1, + operationId: 'fooBar', + expected: 'fooBar', + }, + { + url: '/api/v{api-version}/users', + method: 'GET', + options: options1, + operationId: 'FooBar', + expected: 'fooBar', + }, + { + url: '/api/v{api-version}/users', + method: 'GET', + options: options1, + operationId: 'Foo Bar', + expected: 'fooBar', + }, + { + url: '/api/v{api-version}/users', + method: 'GET', + options: options1, + operationId: 'foo bar', + expected: 'fooBar', + }, + { + url: '/api/v{api-version}/users', + method: 'GET', + options: options1, + operationId: 'foo-bar', + expected: 'fooBar', + }, + { + url: '/api/v{api-version}/users', + method: 'GET', + options: options1, + operationId: 'foo_bar', + expected: 'fooBar', + }, + { + url: '/api/v{api-version}/users', + method: 'GET', + options: options1, + operationId: 'foo.bar', + expected: 'fooBar', + }, + { + url: '/api/v{api-version}/users', + method: 'GET', + options: options1, + operationId: '@foo.bar', + expected: 'fooBar', + }, + { + url: '/api/v{api-version}/users', + method: 'GET', + options: options1, + operationId: '$foo.bar', + expected: 'fooBar', + }, + { + url: '/api/v{api-version}/users', + method: 'GET', + options: options1, + operationId: '_foo.bar', + expected: 'fooBar', + }, + { + url: '/api/v{api-version}/users', + method: 'GET', + options: options1, + operationId: '-foo.bar', + expected: 'fooBar', + }, + { + url: '/api/v{api-version}/users', + method: 'GET', + options: options1, + operationId: '123.foo.bar', + expected: 'fooBar', + }, + { + url: '/api/v1/users', + method: 'GET', + options: options2, + operationId: 'GetAllUsers', + expected: 'getApiV1Users', + }, + { + url: '/api/v{api-version}/users', + method: 'GET', + options: options2, + operationId: 'fooBar', + expected: 'getApiUsers', + }, + { + url: '/api/v{api-version}/users/{userId}/location/{locationId}', + method: 'GET', + options: options2, + operationId: 'fooBar', + expected: 'getApiUsersByUserIdLocationByLocationId', + }, + ])( + 'getOperationName($url, $method, { operationId: $useOperationId }, $operationId) -> $expected', + ({ url, method, options, operationId, expected }) => { + expect(getOperationName(url, method, options, operationId)).toEqual(expected); + } + ); +}); + +describe('getOperationParameterName', () => { + it.each([ + { input: '', expected: '' }, + { input: 'foobar', expected: 'foobar' }, + { input: 'fooBar', expected: 'fooBar' }, + { input: 'foo_bar', expected: 'fooBar' }, + { input: 'foo-bar', expected: 'fooBar' }, + { input: 'foo.bar', expected: 'fooBar' }, + { input: '@foo.bar', expected: 'fooBar' }, + { input: '$foo.bar', expected: 'fooBar' }, + { input: '123.foo.bar', expected: 'fooBar' }, + { input: 'Foo-Bar', expected: 'fooBar' }, + { input: 'FOO-BAR', expected: 'fooBar' }, + { input: 'foo[bar]', expected: 'fooBar' }, + { input: 'foo.bar[]', expected: 'fooBarArray' }, + ])('getOperationParameterName($input) -> $expected', ({ input, expected }) => { + expect(getOperationParameterName(input)).toEqual(expected); + }); +}); + +describe('getOperationResponseCode', () => { + it.each([ + { input: '', expected: null }, + { input: 'default', expected: 200 }, + { input: '200', expected: 200 }, + { input: '300', expected: 300 }, + { input: '400', expected: 400 }, + { input: 'abc', expected: null }, + { input: '-100', expected: 100 }, + ])('getOperationResponseCode($input) -> $expected', ({ input, expected }) => { + expect(getOperationResponseCode(input)).toEqual(expected); + }); +}); diff --git a/src/openApi/common/parser/operation.ts b/src/openApi/common/parser/operation.ts new file mode 100644 index 000000000..db391fa29 --- /dev/null +++ b/src/openApi/common/parser/operation.ts @@ -0,0 +1,71 @@ +import camelCase from 'camelcase'; + +import type { OperationError, OperationResponse } from '../../../types/client'; +import type { Config } from '../../../types/config'; +import { reservedWords } from '../../../utils/reservedWords'; +import { sanitizeOperationName, sanitizeOperationParameterName } from '../../../utils/sanitize'; + +/** + * Convert the input value to a correct operation (method) classname. + * This will use the operation ID - if available - and otherwise fallback + * on a generated name from the URL + */ +export const getOperationName = ( + url: string, + method: string, + options: Pick, + operationId?: string +): string => { + if (options.operationId && operationId) { + return camelCase(sanitizeOperationName(operationId).trim()); + } + + const urlWithoutPlaceholders = url + .replace(/[^/]*?{api-version}.*?\//g, '') + .replace(/{(.*?)}/g, 'by-$1') + .replace(/\//g, '-'); + + return camelCase(`${method}-${urlWithoutPlaceholders}`); +}; + +/** + * Replaces any invalid characters from a parameter name. + * For example: 'filter.someProperty' becomes 'filterSomeProperty'. + */ +export const getOperationParameterName = (value: string): string => { + const clean = sanitizeOperationParameterName(value).trim(); + return camelCase(clean).replace(reservedWords, '_$1'); +}; + +export const getOperationResponseHeader = (operationResponses: OperationResponse[]): string | null => { + const header = operationResponses.find(operationResponses => operationResponses.in === 'header'); + if (header) { + return header.name; + } + return null; +}; + +export const getOperationResponseCode = (value: string | 'default'): number | null => { + // You can specify a "default" response, this is treated as HTTP code 200 + if (value === 'default') { + return 200; + } + + // Check if we can parse the code and return of successful. + if (/[0-9]+/g.test(value)) { + const code = parseInt(value); + if (Number.isInteger(code)) { + return Math.abs(code); + } + } + + return null; +}; + +export const getOperationErrors = (operationResponses: OperationResponse[]): OperationError[] => + operationResponses + .filter(operationResponse => operationResponse.code >= 300 && operationResponse.description) + .map(response => ({ + code: response.code, + description: response.description!, + })); diff --git a/src/openApi/v2/parser/getServer.spec.ts b/src/openApi/v2/parser/__tests__/getServer.spec.ts similarity index 92% rename from src/openApi/v2/parser/getServer.spec.ts rename to src/openApi/v2/parser/__tests__/getServer.spec.ts index 8b3772c79..3da9b20e3 100644 --- a/src/openApi/v2/parser/getServer.spec.ts +++ b/src/openApi/v2/parser/__tests__/getServer.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; -import { getServer } from './getServer'; +import { getServer } from '../getServer'; describe('getServer', () => { it('should produce correct result', () => { diff --git a/src/openApi/v2/parser/getServiceName.spec.ts b/src/openApi/v2/parser/__tests__/getServiceName.spec.ts similarity index 91% rename from src/openApi/v2/parser/getServiceName.spec.ts rename to src/openApi/v2/parser/__tests__/getServiceName.spec.ts index c1e7782f6..8925658b1 100644 --- a/src/openApi/v2/parser/getServiceName.spec.ts +++ b/src/openApi/v2/parser/__tests__/getServiceName.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; -import { getServiceName } from './getServiceName'; +import { getServiceName } from '../getServiceName'; describe('getServiceName', () => { it('should produce correct result', () => { diff --git a/src/openApi/v2/parser/getServices.spec.ts b/src/openApi/v2/parser/__tests__/getServices.spec.ts similarity index 97% rename from src/openApi/v2/parser/getServices.spec.ts rename to src/openApi/v2/parser/__tests__/getServices.spec.ts index 0fbc2faba..842d4b865 100644 --- a/src/openApi/v2/parser/getServices.spec.ts +++ b/src/openApi/v2/parser/__tests__/getServices.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; -import { getServices } from './getServices'; +import { getServices } from '../getServices'; describe('getServices', () => { it('should create a unnamed service if tags are empty', () => { diff --git a/src/openApi/v2/parser/getOperation.ts b/src/openApi/v2/parser/getOperation.ts index aea6064c2..ccd30db1f 100644 --- a/src/openApi/v2/parser/getOperation.ts +++ b/src/openApi/v2/parser/getOperation.ts @@ -1,12 +1,10 @@ import type { Operation, OperationParameters } from '../../../types/client'; import type { Config } from '../../../types/config'; -import { getOperationName } from '../../../utils/operation'; +import { getOperationErrors, getOperationName, getOperationResponseHeader } from '../../common/parser/operation'; import { toSortedByRequired } from '../../common/parser/sort'; import type { OpenApi } from '../interfaces/OpenApi'; import type { OpenApiOperation } from '../interfaces/OpenApiOperation'; -import { getOperationErrors } from './getOperationErrors'; import { getOperationParameters } from './getOperationParameters'; -import { getOperationResponseHeader } from './getOperationResponseHeader'; import { getOperationResponses } from './getOperationResponses'; import { getOperationResults } from './getOperationResults'; import { getServiceName } from './getServiceName'; diff --git a/src/openApi/v2/parser/getOperationErrors.ts b/src/openApi/v2/parser/getOperationErrors.ts deleted file mode 100644 index 1a5f6bfca..000000000 --- a/src/openApi/v2/parser/getOperationErrors.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { OperationError, OperationResponse } from '../../../types/client'; - -/** - * - * @param operationResponses - */ -export const getOperationErrors = (operationResponses: OperationResponse[]): OperationError[] => - operationResponses - .filter(operationResponse => operationResponse.code >= 300 && operationResponse.description) - .map(response => ({ - code: response.code, - description: response.description!, - })); diff --git a/src/openApi/v2/parser/getOperationParameter.ts b/src/openApi/v2/parser/getOperationParameter.ts index 2401e7695..c6059a743 100644 --- a/src/openApi/v2/parser/getOperationParameter.ts +++ b/src/openApi/v2/parser/getOperationParameter.ts @@ -3,12 +3,12 @@ import { getEnums } from '../../../utils/getEnums'; import { getPattern } from '../../../utils/getPattern'; import { getType } from '../../../utils/type'; import { getRef } from '../../common/parser/getRef'; +import { getOperationParameterName } from '../../common/parser/operation'; import type { OpenApi } from '../interfaces/OpenApi'; import type { OpenApiParameter } from '../interfaces/OpenApiParameter'; import type { OpenApiSchema } from '../interfaces/OpenApiSchema'; import { getModel } from './getModel'; import { getOperationParameterDefault } from './getOperationParameterDefault'; -import { getOperationParameterName } from './getOperationParameterName'; export const getOperationParameter = (openApi: OpenApi, parameter: OpenApiParameter): OperationParameter => { const operationParameter: OperationParameter = { diff --git a/src/openApi/v2/parser/getOperationParameterName.spec.ts b/src/openApi/v2/parser/getOperationParameterName.spec.ts deleted file mode 100644 index 8c2332400..000000000 --- a/src/openApi/v2/parser/getOperationParameterName.spec.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { describe, expect, it } from 'vitest'; - -import { getOperationParameterName } from './getOperationParameterName'; - -describe('getOperationParameterName', () => { - it('should produce correct result', () => { - expect(getOperationParameterName('')).toEqual(''); - expect(getOperationParameterName('foobar')).toEqual('foobar'); - expect(getOperationParameterName('fooBar')).toEqual('fooBar'); - expect(getOperationParameterName('foo_bar')).toEqual('fooBar'); - expect(getOperationParameterName('foo-bar')).toEqual('fooBar'); - expect(getOperationParameterName('foo.bar')).toEqual('fooBar'); - expect(getOperationParameterName('@foo.bar')).toEqual('fooBar'); - expect(getOperationParameterName('$foo.bar')).toEqual('fooBar'); - expect(getOperationParameterName('123.foo.bar')).toEqual('fooBar'); - expect(getOperationParameterName('Foo-Bar')).toEqual('fooBar'); - expect(getOperationParameterName('FOO-BAR')).toEqual('fooBar'); - }); -}); diff --git a/src/openApi/v2/parser/getOperationParameterName.ts b/src/openApi/v2/parser/getOperationParameterName.ts deleted file mode 100644 index a27ccd696..000000000 --- a/src/openApi/v2/parser/getOperationParameterName.ts +++ /dev/null @@ -1,13 +0,0 @@ -import camelCase from 'camelcase'; - -import { reservedWords } from '../../../utils/reservedWords'; -import { sanitizeOperationParameterName } from '../../../utils/sanitize'; - -/** - * Replaces any invalid characters from a parameter name. - * For example: 'filter.someProperty' becomes 'filterSomeProperty'. - */ -export const getOperationParameterName = (value: string): string => { - const clean = sanitizeOperationParameterName(value).trim(); - return camelCase(clean).replace(reservedWords, '_$1'); -}; diff --git a/src/openApi/v2/parser/getOperationResponseCode.spec.ts b/src/openApi/v2/parser/getOperationResponseCode.spec.ts deleted file mode 100644 index 429e28bdd..000000000 --- a/src/openApi/v2/parser/getOperationResponseCode.spec.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { describe, expect, it } from 'vitest'; - -import { getOperationResponseCode } from './getOperationResponseCode'; - -describe('getOperationResponseCode', () => { - it('should produce correct result', () => { - expect(getOperationResponseCode('')).toEqual(null); - expect(getOperationResponseCode('default')).toEqual(200); - expect(getOperationResponseCode('200')).toEqual(200); - expect(getOperationResponseCode('300')).toEqual(300); - expect(getOperationResponseCode('400')).toEqual(400); - expect(getOperationResponseCode('abc')).toEqual(null); - expect(getOperationResponseCode('-100')).toEqual(100); - }); -}); diff --git a/src/openApi/v2/parser/getOperationResponseCode.ts b/src/openApi/v2/parser/getOperationResponseCode.ts deleted file mode 100644 index f34c99b75..000000000 --- a/src/openApi/v2/parser/getOperationResponseCode.ts +++ /dev/null @@ -1,16 +0,0 @@ -export const getOperationResponseCode = (value: string | 'default'): number | null => { - // You can specify a "default" response, this is treated as HTTP code 200 - if (value === 'default') { - return 200; - } - - // Check if we can parse the code and return of successful. - if (/[0-9]+/g.test(value)) { - const code = parseInt(value); - if (Number.isInteger(code)) { - return Math.abs(code); - } - } - - return null; -}; diff --git a/src/openApi/v2/parser/getOperationResponseHeader.ts b/src/openApi/v2/parser/getOperationResponseHeader.ts deleted file mode 100644 index 5d6a04202..000000000 --- a/src/openApi/v2/parser/getOperationResponseHeader.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { OperationResponse } from '../../../types/client'; - -export const getOperationResponseHeader = (operationResponses: OperationResponse[]): string | null => { - const header = operationResponses.find(operationResponses => operationResponses.in === 'header'); - if (header) { - return header.name; - } - return null; -}; diff --git a/src/openApi/v2/parser/getOperationResponses.ts b/src/openApi/v2/parser/getOperationResponses.ts index 7c6abddcc..a50fc6767 100644 --- a/src/openApi/v2/parser/getOperationResponses.ts +++ b/src/openApi/v2/parser/getOperationResponses.ts @@ -1,10 +1,10 @@ import type { OperationResponse } from '../../../types/client'; import { getRef } from '../../common/parser/getRef'; +import { getOperationResponseCode } from '../../common/parser/operation'; import type { OpenApi } from '../interfaces/OpenApi'; import type { OpenApiResponse } from '../interfaces/OpenApiResponse'; import type { OpenApiResponses } from '../interfaces/OpenApiResponses'; import { getOperationResponse } from './getOperationResponse'; -import { getOperationResponseCode } from './getOperationResponseCode'; export const getOperationResponses = (openApi: OpenApi, responses: OpenApiResponses): OperationResponse[] => { const operationResponses: OperationResponse[] = []; diff --git a/src/openApi/v3/parser/getModel.spec.ts b/src/openApi/v3/parser/__tests__/getModel.spec.ts similarity index 95% rename from src/openApi/v3/parser/getModel.spec.ts rename to src/openApi/v3/parser/__tests__/getModel.spec.ts index 21846e0e5..280f9b9e5 100644 --- a/src/openApi/v3/parser/getModel.spec.ts +++ b/src/openApi/v3/parser/__tests__/getModel.spec.ts @@ -1,8 +1,8 @@ import { describe, expect, it } from 'vitest'; -import { reservedWords } from '../../../utils/reservedWords'; -import { getType } from '../../../utils/type'; -import { getModel } from './getModel'; +import { reservedWords } from '../../../../utils/reservedWords'; +import { getType } from '../../../../utils/type'; +import { getModel } from '../getModel'; const openApi = { openapi: '3.0', diff --git a/src/openApi/v3/parser/getServer.spec.ts b/src/openApi/v3/parser/__tests__/getServer.spec.ts similarity index 97% rename from src/openApi/v3/parser/getServer.spec.ts rename to src/openApi/v3/parser/__tests__/getServer.spec.ts index 0c13ee896..e26ef7d17 100644 --- a/src/openApi/v3/parser/getServer.spec.ts +++ b/src/openApi/v3/parser/__tests__/getServer.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; -import { getServer } from './getServer'; +import { getServer } from '../getServer'; describe('getServer', () => { it('should produce correct result', () => { diff --git a/src/utils/discriminator.ts b/src/openApi/v3/parser/discriminator.ts similarity index 81% rename from src/utils/discriminator.ts rename to src/openApi/v3/parser/discriminator.ts index b398621e4..8793d4054 100644 --- a/src/utils/discriminator.ts +++ b/src/openApi/v3/parser/discriminator.ts @@ -1,8 +1,8 @@ -import type { OpenApi } from '../openApi/v3/interfaces/OpenApi'; -import type { OpenApiDiscriminator } from '../openApi/v3/interfaces/OpenApiDiscriminator'; -import type { Model } from '../types/client'; -import type { Dictionary } from '../types/generic'; -import { stripNamespace } from './stripNamespace'; +import type { Model } from '../../../types/client'; +import type { Dictionary } from '../../../types/generic'; +import { stripNamespace } from '../../../utils/stripNamespace'; +import type { OpenApi } from '../interfaces/OpenApi'; +import type { OpenApiDiscriminator } from '../interfaces/OpenApiDiscriminator'; const inverseDictionary = (map: Dictionary): Dictionary => { const m2: Dictionary = {}; diff --git a/src/openApi/v3/parser/getModelProperties.ts b/src/openApi/v3/parser/getModelProperties.ts index fb8d02c24..fdf17cbd9 100644 --- a/src/openApi/v3/parser/getModelProperties.ts +++ b/src/openApi/v3/parser/getModelProperties.ts @@ -1,10 +1,10 @@ import type { Model } from '../../../types/client'; -import { findOneOfParentDiscriminator, mapPropertyValue } from '../../../utils/discriminator'; import { escapeName } from '../../../utils/escapeName'; import { getPattern } from '../../../utils/getPattern'; import { getType } from '../../../utils/type'; import type { OpenApi } from '../interfaces/OpenApi'; import type { OpenApiSchema } from '../interfaces/OpenApiSchema'; +import { findOneOfParentDiscriminator, mapPropertyValue } from './discriminator'; import type { getModel } from './getModel'; import { getModelDefault } from './getModelDefault'; diff --git a/src/openApi/v3/parser/getOperationErrors.ts b/src/openApi/v3/parser/getOperationErrors.ts deleted file mode 100644 index 52a4950c2..000000000 --- a/src/openApi/v3/parser/getOperationErrors.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { OperationError, OperationResponse } from '../../../types/client'; - -export const getOperationErrors = (operationResponses: OperationResponse[]): OperationError[] => - operationResponses - .filter(operationResponse => operationResponse.code >= 300 && operationResponse.description) - .map(response => ({ - code: response.code, - description: response.description!, - })); diff --git a/src/openApi/v3/parser/getOperationParameter.ts b/src/openApi/v3/parser/getOperationParameter.ts index aa24294db..ab933563d 100644 --- a/src/openApi/v3/parser/getOperationParameter.ts +++ b/src/openApi/v3/parser/getOperationParameter.ts @@ -2,12 +2,12 @@ import type { OperationParameter } from '../../../types/client'; import { getPattern } from '../../../utils/getPattern'; import { getType } from '../../../utils/type'; import { getRef } from '../../common/parser/getRef'; +import { getOperationParameterName } from '../../common/parser/operation'; import type { OpenApi } from '../interfaces/OpenApi'; import type { OpenApiParameter } from '../interfaces/OpenApiParameter'; import type { OpenApiSchema } from '../interfaces/OpenApiSchema'; import { getModel } from './getModel'; import { getModelDefault } from './getModelDefault'; -import { getOperationParameterName } from './getOperationParameterName'; export const getOperationParameter = (openApi: OpenApi, parameter: OpenApiParameter): OperationParameter => { const operationParameter: OperationParameter = { diff --git a/src/openApi/v3/parser/getOperationParameterName.spec.ts b/src/openApi/v3/parser/getOperationParameterName.spec.ts deleted file mode 100644 index acfc04595..000000000 --- a/src/openApi/v3/parser/getOperationParameterName.spec.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { describe, expect, it } from 'vitest'; - -import { getOperationParameterName } from './getOperationParameterName'; - -describe('getOperationParameterName', () => { - it('should produce correct result', () => { - expect(getOperationParameterName('')).toEqual(''); - expect(getOperationParameterName('foobar')).toEqual('foobar'); - expect(getOperationParameterName('fooBar')).toEqual('fooBar'); - expect(getOperationParameterName('foo_bar')).toEqual('fooBar'); - expect(getOperationParameterName('foo-bar')).toEqual('fooBar'); - expect(getOperationParameterName('foo.bar')).toEqual('fooBar'); - expect(getOperationParameterName('@foo.bar')).toEqual('fooBar'); - expect(getOperationParameterName('$foo.bar')).toEqual('fooBar'); - expect(getOperationParameterName('123.foo.bar')).toEqual('fooBar'); - expect(getOperationParameterName('Foo-Bar')).toEqual('fooBar'); - expect(getOperationParameterName('FOO-BAR')).toEqual('fooBar'); - expect(getOperationParameterName('foo[bar]')).toEqual('fooBar'); - expect(getOperationParameterName('foo.bar[]')).toEqual('fooBarArray'); - }); -}); diff --git a/src/openApi/v3/parser/getOperationParameterName.ts b/src/openApi/v3/parser/getOperationParameterName.ts deleted file mode 100644 index a27ccd696..000000000 --- a/src/openApi/v3/parser/getOperationParameterName.ts +++ /dev/null @@ -1,13 +0,0 @@ -import camelCase from 'camelcase'; - -import { reservedWords } from '../../../utils/reservedWords'; -import { sanitizeOperationParameterName } from '../../../utils/sanitize'; - -/** - * Replaces any invalid characters from a parameter name. - * For example: 'filter.someProperty' becomes 'filterSomeProperty'. - */ -export const getOperationParameterName = (value: string): string => { - const clean = sanitizeOperationParameterName(value).trim(); - return camelCase(clean).replace(reservedWords, '_$1'); -}; diff --git a/src/openApi/v3/parser/getOperationResponseCode.spec.ts b/src/openApi/v3/parser/getOperationResponseCode.spec.ts deleted file mode 100644 index 429e28bdd..000000000 --- a/src/openApi/v3/parser/getOperationResponseCode.spec.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { describe, expect, it } from 'vitest'; - -import { getOperationResponseCode } from './getOperationResponseCode'; - -describe('getOperationResponseCode', () => { - it('should produce correct result', () => { - expect(getOperationResponseCode('')).toEqual(null); - expect(getOperationResponseCode('default')).toEqual(200); - expect(getOperationResponseCode('200')).toEqual(200); - expect(getOperationResponseCode('300')).toEqual(300); - expect(getOperationResponseCode('400')).toEqual(400); - expect(getOperationResponseCode('abc')).toEqual(null); - expect(getOperationResponseCode('-100')).toEqual(100); - }); -}); diff --git a/src/openApi/v3/parser/getOperationResponseCode.ts b/src/openApi/v3/parser/getOperationResponseCode.ts deleted file mode 100644 index f34c99b75..000000000 --- a/src/openApi/v3/parser/getOperationResponseCode.ts +++ /dev/null @@ -1,16 +0,0 @@ -export const getOperationResponseCode = (value: string | 'default'): number | null => { - // You can specify a "default" response, this is treated as HTTP code 200 - if (value === 'default') { - return 200; - } - - // Check if we can parse the code and return of successful. - if (/[0-9]+/g.test(value)) { - const code = parseInt(value); - if (Number.isInteger(code)) { - return Math.abs(code); - } - } - - return null; -}; diff --git a/src/openApi/v3/parser/getOperationResponseHeader.ts b/src/openApi/v3/parser/getOperationResponseHeader.ts deleted file mode 100644 index 5d6a04202..000000000 --- a/src/openApi/v3/parser/getOperationResponseHeader.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { OperationResponse } from '../../../types/client'; - -export const getOperationResponseHeader = (operationResponses: OperationResponse[]): string | null => { - const header = operationResponses.find(operationResponses => operationResponses.in === 'header'); - if (header) { - return header.name; - } - return null; -}; diff --git a/src/openApi/v3/parser/getOperationResponses.ts b/src/openApi/v3/parser/getOperationResponses.ts index 7c6abddcc..a50fc6767 100644 --- a/src/openApi/v3/parser/getOperationResponses.ts +++ b/src/openApi/v3/parser/getOperationResponses.ts @@ -1,10 +1,10 @@ import type { OperationResponse } from '../../../types/client'; import { getRef } from '../../common/parser/getRef'; +import { getOperationResponseCode } from '../../common/parser/operation'; import type { OpenApi } from '../interfaces/OpenApi'; import type { OpenApiResponse } from '../interfaces/OpenApiResponse'; import type { OpenApiResponses } from '../interfaces/OpenApiResponses'; import { getOperationResponse } from './getOperationResponse'; -import { getOperationResponseCode } from './getOperationResponseCode'; export const getOperationResponses = (openApi: OpenApi, responses: OpenApiResponses): OperationResponse[] => { const operationResponses: OperationResponse[] = []; diff --git a/src/openApi/v3/parser/operation.ts b/src/openApi/v3/parser/operation.ts index 97f8ce3d2..6b084c1ce 100644 --- a/src/openApi/v3/parser/operation.ts +++ b/src/openApi/v3/parser/operation.ts @@ -1,15 +1,13 @@ import type { Operation, OperationParameter, OperationParameters } from '../../../types/client'; import type { Config } from '../../../types/config'; -import { getOperationName } from '../../../utils/operation'; import { getRef } from '../../common/parser/getRef'; +import { getOperationErrors, getOperationName, getOperationResponseHeader } from '../../common/parser/operation'; import { toSortedByRequired } from '../../common/parser/sort'; import type { OpenApi } from '../interfaces/OpenApi'; import type { OpenApiOperation } from '../interfaces/OpenApiOperation'; import type { OpenApiRequestBody } from '../interfaces/OpenApiRequestBody'; -import { getOperationErrors } from './getOperationErrors'; import { getOperationParameters } from './getOperationParameters'; import { getOperationRequestBody } from './getOperationRequestBody'; -import { getOperationResponseHeader } from './getOperationResponseHeader'; import { getOperationResponses } from './getOperationResponses'; import { getOperationResults } from './getOperationResults'; import { getServiceName } from './service'; diff --git a/src/utils/__tests__/operation.spec.ts b/src/utils/__tests__/operation.spec.ts deleted file mode 100644 index be4da8cb9..000000000 --- a/src/utils/__tests__/operation.spec.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { describe, expect, it } from 'vitest'; - -import { getOperationName } from '../operation'; - -describe('getOperationName', () => { - it('should produce correct result', () => { - const options: Parameters[2] = { - operationId: true, - }; - expect(getOperationName('/api/v{api-version}/users', 'GET', options, 'GetAllUsers')).toEqual('getAllUsers'); - expect(getOperationName('/api/v{api-version}/users', 'GET', options, undefined)).toEqual('getApiUsers'); - expect(getOperationName('/api/v{api-version}/users', 'POST', options, undefined)).toEqual('postApiUsers'); - expect(getOperationName('/api/v1/users', 'GET', options, 'GetAllUsers')).toEqual('getAllUsers'); - expect(getOperationName('/api/v1/users', 'GET', options, undefined)).toEqual('getApiV1Users'); - expect(getOperationName('/api/v1/users', 'POST', options, undefined)).toEqual('postApiV1Users'); - expect(getOperationName('/api/v1/users/{id}', 'GET', options, undefined)).toEqual('getApiV1UsersById'); - expect(getOperationName('/api/v1/users/{id}', 'POST', options, undefined)).toEqual('postApiV1UsersById'); - - expect(getOperationName('/api/v{api-version}/users', 'GET', options, 'fooBar')).toEqual('fooBar'); - expect(getOperationName('/api/v{api-version}/users', 'GET', options, 'FooBar')).toEqual('fooBar'); - expect(getOperationName('/api/v{api-version}/users', 'GET', options, 'Foo Bar')).toEqual('fooBar'); - expect(getOperationName('/api/v{api-version}/users', 'GET', options, 'foo bar')).toEqual('fooBar'); - expect(getOperationName('/api/v{api-version}/users', 'GET', options, 'foo-bar')).toEqual('fooBar'); - expect(getOperationName('/api/v{api-version}/users', 'GET', options, 'foo_bar')).toEqual('fooBar'); - expect(getOperationName('/api/v{api-version}/users', 'GET', options, 'foo.bar')).toEqual('fooBar'); - expect(getOperationName('/api/v{api-version}/users', 'GET', options, '@foo.bar')).toEqual('fooBar'); - expect(getOperationName('/api/v{api-version}/users', 'GET', options, '$foo.bar')).toEqual('fooBar'); - expect(getOperationName('/api/v{api-version}/users', 'GET', options, '_foo.bar')).toEqual('fooBar'); - expect(getOperationName('/api/v{api-version}/users', 'GET', options, '-foo.bar')).toEqual('fooBar'); - expect(getOperationName('/api/v{api-version}/users', 'GET', options, '123.foo.bar')).toEqual('fooBar'); - - const optionsIgnoreOperationId: Parameters[2] = { - operationId: false, - }; - expect(getOperationName('/api/v1/users', 'GET', optionsIgnoreOperationId, 'GetAllUsers')).toEqual( - 'getApiV1Users' - ); - expect(getOperationName('/api/v{api-version}/users', 'GET', optionsIgnoreOperationId, 'fooBar')).toEqual( - 'getApiUsers' - ); - expect( - getOperationName( - '/api/v{api-version}/users/{userId}/location/{locationId}', - 'GET', - optionsIgnoreOperationId, - 'fooBar' - ) - ).toEqual('getApiUsersByUserIdLocationByLocationId'); - }); -}); diff --git a/src/utils/isEqual.ts b/src/utils/isEqual.ts deleted file mode 100644 index 678071e33..000000000 --- a/src/utils/isEqual.ts +++ /dev/null @@ -1,40 +0,0 @@ -export const isEqual = (a: A, b: B): boolean => { - // @ts-ignore - if (a === b) { - return true; - } - - if (a && b && typeof a === 'object' && typeof b === 'object') { - if (Array.isArray(a) && Array.isArray(b)) { - if (a.length !== b.length) { - return false; - } - for (let i = 0; i < a.length; i++) { - if (!isEqual(a[i], b[i])) { - return false; - } - } - return true; - } - - const keysA = Object.keys(a); - const keysB = Object.keys(b); - if (keysA.length !== keysB.length) { - return false; - } - - for (let i = 0; i < keysA.length; i++) { - const key = keysA[i]; - if (!Object.prototype.hasOwnProperty.call(b, key)) { - return false; - } - // @ts-ignore - if (!isEqual(a[key], b[key])) { - return false; - } - } - return true; - } - - return a !== a && b !== b; -}; diff --git a/src/utils/operation.ts b/src/utils/operation.ts deleted file mode 100644 index 6fd0bebaa..000000000 --- a/src/utils/operation.ts +++ /dev/null @@ -1,27 +0,0 @@ -import camelCase from 'camelcase'; - -import type { Config } from '../types/config'; -import { sanitizeOperationName } from './sanitize'; - -/** - * Convert the input value to a correct operation (method) classname. - * This will use the operation ID - if available - and otherwise fallback - * on a generated name from the URL - */ -export const getOperationName = ( - url: string, - method: string, - options: Pick, - operationId?: string -): string => { - if (options.operationId && operationId) { - return camelCase(sanitizeOperationName(operationId).trim()); - } - - const urlWithoutPlaceholders = url - .replace(/[^/]*?{api-version}.*?\//g, '') - .replace(/{(.*?)}/g, 'by-$1') - .replace(/\//g, '-'); - - return camelCase(`${method}-${urlWithoutPlaceholders}`); -};