Skip to content

Commit

Permalink
Merge pull request #140 from hey-api/chore/cleanup-files
Browse files Browse the repository at this point in the history
  • Loading branch information
jordanshatford authored Mar 26, 2024
2 parents 6436f68 + 9639dfb commit 93f5481
Show file tree
Hide file tree
Showing 30 changed files with 288 additions and 308 deletions.
198 changes: 198 additions & 0 deletions src/openApi/common/parser/__tests__/operation.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
import { describe, expect, it } from 'vitest';

import { getOperationName, getOperationParameterName, getOperationResponseCode } from '../operation';

describe('getOperationName', () => {
const options1: Parameters<typeof getOperationName>[2] = {
operationId: true,
};

const options2: Parameters<typeof getOperationName>[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);
});
});
71 changes: 71 additions & 0 deletions src/openApi/common/parser/operation.ts
Original file line number Diff line number Diff line change
@@ -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<Config, 'operationId'>,
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!,
}));
Original file line number Diff line number Diff line change
@@ -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', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -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', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -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', () => {
Expand Down
4 changes: 1 addition & 3 deletions src/openApi/v2/parser/getOperation.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down
13 changes: 0 additions & 13 deletions src/openApi/v2/parser/getOperationErrors.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/openApi/v2/parser/getOperationParameter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
19 changes: 0 additions & 19 deletions src/openApi/v2/parser/getOperationParameterName.spec.ts

This file was deleted.

13 changes: 0 additions & 13 deletions src/openApi/v2/parser/getOperationParameterName.ts

This file was deleted.

15 changes: 0 additions & 15 deletions src/openApi/v2/parser/getOperationResponseCode.spec.ts

This file was deleted.

Loading

0 comments on commit 93f5481

Please sign in to comment.