Skip to content

Commit

Permalink
Merge pull request #151 from hey-api/chore/even-more-parsing-cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
jordanshatford authored Mar 27, 2024
2 parents b264d32 + 76b517b commit 211ee8c
Show file tree
Hide file tree
Showing 49 changed files with 230 additions and 234 deletions.
1 change: 0 additions & 1 deletion rollup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ export function handlebarsPlugin(): Plugin {
knownHelpers: {
camelCase: true,
dataParameters: true,
debugThis: true,
enumKey: true,
enumName: true,
enumUnionType: true,
Expand Down
4 changes: 4 additions & 0 deletions src/openApi/common/interfaces/WithEnumExtension.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface WithEnumExtension {
'x-enum-descriptions'?: ReadonlyArray<string>;
'x-enum-varnames'?: ReadonlyArray<string>;
}
124 changes: 124 additions & 0 deletions src/openApi/common/interfaces/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
export interface ModelComposition extends Pick<Model, '$refs' | 'enums' | 'imports' | 'properties'> {
export: Extract<Model['export'], 'all-of' | 'any-of' | 'one-of'>;
}

export interface Enum {
'x-enum-description'?: string;
'x-enum-varname'?: string;
description?: string;
value: string | number;
}

export interface OperationError {
code: number;
description: string;
}

export interface OperationParameter extends Model {
in: 'path' | 'query' | 'header' | 'formData' | 'body' | 'cookie';
prop: string;
mediaType: string | null;
}

export interface OperationParameters extends Pick<Model, '$refs' | 'imports'> {
parameters: OperationParameter[];
parametersBody: OperationParameter | null;
parametersCookie: OperationParameter[];
parametersForm: OperationParameter[];
parametersHeader: OperationParameter[];
parametersPath: OperationParameter[];
parametersQuery: OperationParameter[];
}

export interface OperationResponse extends Model {
in: 'response' | 'header';
code: number;
}

export interface Operation extends OperationParameters {
deprecated: boolean;
description: string | null;
errors: OperationError[];
method: 'DELETE' | 'GET' | 'HEAD' | 'OPTIONS' | 'PATCH' | 'POST' | 'PUT';
/**
* Method name. Methods contain the request logic.
*/
name: string;
path: string;
responseHeader: string | null;
results: OperationResponse[];
/**
* Service name, might be without postfix. This will be used to name the
* exported class.
*/
service: string;
summary: string | null;
}

export interface Schema {
exclusiveMaximum?: boolean;
exclusiveMinimum?: boolean;
format?:
| 'binary'
| 'boolean'
| 'byte'
| 'date-time'
| 'date'
| 'double'
| 'float'
| 'int32'
| 'int64'
| 'password'
| 'string';
isDefinition: boolean;
isNullable: boolean;
isReadOnly: boolean;
isRequired: boolean;
maximum?: number;
maxItems?: number;
maxLength?: number;
maxProperties?: number;
minimum?: number;
minItems?: number;
minLength?: number;
minProperties?: number;
multipleOf?: number;
pattern?: string;
uniqueItems?: boolean;
}

export interface Model extends Schema {
/**
* **Experimental.** Contains list of original refs so they can be used
* to access the schema from anywhere instead of relying on string name.
* This allows us to do things like detect type of ref.
*/
$refs: string[];
base: string;
default?: string;
deprecated?: boolean;
description: string | null;
enum: Enum[];
enums: Model[];
export:
| 'all-of'
| 'any-of'
| 'array'
| 'const'
| 'dictionary'
| 'enum'
| 'generic'
| 'interface'
| 'one-of'
| 'reference';
imports: string[];
link: Model | null;
name: string;
properties: Model[];
template: string | null;
type: string;
}

export interface Service extends Pick<Model, '$refs' | 'imports' | 'name'> {
operations: Operation[];
}
File renamed without changes.
59 changes: 29 additions & 30 deletions src/openApi/common/parser/__tests__/sanitize.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,47 +8,46 @@ import {
} from '../sanitize';

describe('sanitizeOperationName', () => {
it('should remove/replace illegal characters', () => {
expect(sanitizeOperationName('abc')).toEqual('abc');
expect(sanitizeOperationName('æbc')).toEqual('æbc');
expect(sanitizeOperationName('æb.c')).toEqual('æb-c');
expect(sanitizeOperationName('1æb.c')).toEqual('æb-c');
it.each([
{ input: 'abc', expected: 'abc' },
{ input: 'æbc', expected: 'æbc' },
{ input: 'æb.c', expected: 'æb-c' },
{ input: '1æb.c', expected: 'æb-c' },
])('sanitizeOperationName($input) -> $expected', ({ input, expected }) => {
expect(sanitizeOperationName(input)).toEqual(expected);
});
});

describe('sanitizeOperationParameterName', () => {
it('should remove/replace illegal characters', () => {
expect(sanitizeOperationParameterName('abc')).toEqual('abc');
expect(sanitizeOperationParameterName('æbc')).toEqual('æbc');
expect(sanitizeOperationParameterName('æb.c')).toEqual('æb-c');
expect(sanitizeOperationParameterName('1æb.c')).toEqual('æb-c');
expect(sanitizeOperationParameterName('unknown[]')).toEqual('unknownArray');
it.each([
{ input: 'abc', expected: 'abc' },
{ input: 'æbc', expected: 'æbc' },
{ input: 'æb.c', expected: 'æb-c' },
{ input: '1æb.c', expected: 'æb-c' },
{ input: 'unknown[]', expected: 'unknownArray' },
])('sanitizeOperationParameterName($input) -> $expected', ({ input, expected }) => {
expect(sanitizeOperationParameterName(input)).toEqual(expected);
});
});

describe('sanitizeServiceName', () => {
it('should remove/replace illegal characters', () => {
expect(sanitizeServiceName('abc')).toEqual('abc');
expect(sanitizeServiceName('æbc')).toEqual('æbc');
expect(sanitizeServiceName('æb.c')).toEqual('æb-c');
expect(sanitizeServiceName('1æb.c')).toEqual('æb-c');
it.each([
{ input: 'abc', expected: 'abc' },
{ input: 'æbc', expected: 'æbc' },
{ input: 'æb.c', expected: 'æb-c' },
{ input: '1æb.c', expected: 'æb-c' },
])('sanitizeServiceName($input) -> $expected', ({ input, expected }) => {
expect(sanitizeServiceName(input)).toEqual(expected);
});
});

describe('sanitizeTypeName', () => {
it('should remove/replace illegal characters', () => {
expect(sanitizeTypeName('abc')).toEqual('abc');
expect(sanitizeTypeName('æbc')).toEqual('æbc');
expect(sanitizeTypeName('æb.c')).toEqual('æb_c');
expect(sanitizeTypeName('1æb.c')).toEqual('æb_c');
});
});

describe('sanitizeTypeName', () => {
it('should remove/replace illegal characters', () => {
expect(sanitizeTypeName('abc')).toEqual('abc');
expect(sanitizeTypeName('æbc')).toEqual('æbc');
expect(sanitizeTypeName('æb.c')).toEqual('æb_c');
expect(sanitizeTypeName('1æb.c')).toEqual('æb_c');
it.each([
{ input: 'abc', expected: 'abc' },
{ input: 'æbc', expected: 'æbc' },
{ input: 'æb.c', expected: 'æb_c' },
{ input: '1æb.c', expected: 'æb_c' },
])('sanitizeTypeName($input) -> $expected', ({ input, expected }) => {
expect(sanitizeTypeName(input)).toEqual(expected);
});
});
30 changes: 16 additions & 14 deletions src/openApi/common/parser/__tests__/stripNamespace.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,21 @@ import { describe, expect, it } from 'vitest';
import { stripNamespace } from '../stripNamespace';

describe('stripNamespace', () => {
it('should strip namespace', () => {
expect(stripNamespace('#/definitions/Item')).toEqual('Item');
expect(stripNamespace('#/parameters/Item')).toEqual('Item');
expect(stripNamespace('#/responses/Item')).toEqual('Item');
expect(stripNamespace('#/securityDefinitions/Item')).toEqual('Item');
expect(stripNamespace('#/components/schemas/Item')).toEqual('Item');
expect(stripNamespace('#/components/responses/Item')).toEqual('Item');
expect(stripNamespace('#/components/parameters/Item')).toEqual('Item');
expect(stripNamespace('#/components/examples/Item')).toEqual('Item');
expect(stripNamespace('#/components/requestBodies/Item')).toEqual('Item');
expect(stripNamespace('#/components/headers/Item')).toEqual('Item');
expect(stripNamespace('#/components/securitySchemes/Item')).toEqual('Item');
expect(stripNamespace('#/components/links/Item')).toEqual('Item');
expect(stripNamespace('#/components/callbacks/Item')).toEqual('Item');
it.each([
{ input: '#/definitions/Item', expected: 'Item' },
{ input: '#/parameters/Item', expected: 'Item' },
{ input: '#/responses/Item', expected: 'Item' },
{ input: '#/securityDefinitions/Item', expected: 'Item' },
{ input: '#/components/schemas/Item', expected: 'Item' },
{ input: '#/components/responses/Item', expected: 'Item' },
{ input: '#/components/parameters/Item', expected: 'Item' },
{ input: '#/components/examples/Item', expected: 'Item' },
{ input: '#/components/requestBodies/Item', expected: 'Item' },
{ input: '#/components/headers/Item', expected: 'Item' },
{ input: '#/components/securitySchemes/Item', expected: 'Item' },
{ input: '#/components/links/Item', expected: 'Item' },
{ input: '#/components/callbacks/Item', expected: 'Item' },
])('stripNamespace($input) -> $expected', ({ input, expected }) => {
expect(stripNamespace(input)).toEqual(expected);
});
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Enum, WithEnumExtension } from '../types/client';
import { unique } from './unique';
import { unique } from '../../../utils/unique';
import type { Enum } from '../interfaces/client';
import type { WithEnumExtension } from '../interfaces/WithEnumExtension';

export const getEnums = (definition: WithEnumExtension, values?: ReadonlyArray<string | number>): Enum[] => {
if (!Array.isArray(values)) {
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion src/openApi/common/parser/operation.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import camelCase from 'camelcase';

import type { OperationError, OperationResponse } from '../../../types/client';
import type { Config } from '../../../types/config';
import type { OperationError, OperationResponse } from '../interfaces/client';
import { reservedWords } from './reservedWords';
import { sanitizeOperationName, sanitizeOperationParameterName } from './sanitize';

Expand Down
1 change: 1 addition & 0 deletions src/openApi/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { OpenApi } from './common/interfaces/OpenApi';
import { parse as parseV2 } from './v2/index';
import { parse as parseV3 } from './v3/index';

export { Enum, Model, Operation, OperationParameter, Service } from './common/interfaces/client';
export { OpenApi } from './common/interfaces/OpenApi';

/**
Expand Down
2 changes: 1 addition & 1 deletion src/openApi/v2/interfaces/OpenApiItems.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { WithEnumExtension } from '../../../types/client';
import type { WithEnumExtension } from '../../common/interfaces/WithEnumExtension';

/**
* {@link} https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#items-object)
Expand Down
2 changes: 1 addition & 1 deletion src/openApi/v2/interfaces/OpenApiParameter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { WithEnumExtension } from '../../../types/client';
import type { WithEnumExtension } from '../../common/interfaces/WithEnumExtension';
import type { WithNullableExtension } from './Extensions/WithNullableExtension';
import type { OpenApiItems } from './OpenApiItems';
import type { OpenApiReference } from './OpenApiReference';
Expand Down
2 changes: 1 addition & 1 deletion src/openApi/v2/interfaces/OpenApiSchema.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { WithEnumExtension } from '../../../types/client';
import type { Dictionary } from '../../common/interfaces/Dictionary';
import type { WithEnumExtension } from '../../common/interfaces/WithEnumExtension';
import type { WithNullableExtension } from './Extensions/WithNullableExtension';
import type { OpenApiExternalDocs } from './OpenApiExternalDocs';
import type { OpenApiReference } from './OpenApiReference';
Expand Down
6 changes: 3 additions & 3 deletions src/openApi/v2/parser/getModel.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Model } from '../../../types/client';
import { getEnums } from '../../../utils/getEnums';
import { getPattern } from '../../../utils/getPattern';
import type { Model } from '../../common/interfaces/client';
import { getEnums } from '../../common/parser/getEnums';
import { getPattern } from '../../common/parser/getPattern';
import { getType } from '../../common/parser/type';
import type { OpenApi } from '../interfaces/OpenApi';
import type { OpenApiSchema } from '../interfaces/OpenApiSchema';
Expand Down
2 changes: 1 addition & 1 deletion src/openApi/v2/parser/getModelComposition.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Model, ModelComposition } from '../../../types/client';
import type { Model, ModelComposition } from '../../common/interfaces/client';
import type { OpenApi } from '../interfaces/OpenApi';
import type { OpenApiSchema } from '../interfaces/OpenApiSchema';
import type { getModel } from './getModel';
Expand Down
4 changes: 2 additions & 2 deletions src/openApi/v2/parser/getModelProperties.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Model } from '../../../types/client';
import { escapeName } from '../../../utils/escapeName';
import { getPattern } from '../../../utils/getPattern';
import type { Model } from '../../common/interfaces/client';
import { getPattern } from '../../common/parser/getPattern';
import { getType } from '../../common/parser/type';
import type { OpenApi } from '../interfaces/OpenApi';
import type { OpenApiSchema } from '../interfaces/OpenApiSchema';
Expand Down
2 changes: 1 addition & 1 deletion src/openApi/v2/parser/getModels.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Model } from '../../../types/client';
import type { Model } from '../../common/interfaces/client';
import { reservedWords } from '../../common/parser/reservedWords';
import { getType } from '../../common/parser/type';
import type { OpenApi } from '../interfaces/OpenApi';
Expand Down
2 changes: 1 addition & 1 deletion src/openApi/v2/parser/getOperation.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Operation, OperationParameters } from '../../../types/client';
import type { Config } from '../../../types/config';
import type { Operation, OperationParameters } from '../../common/interfaces/client';
import { getOperationErrors, getOperationName, getOperationResponseHeader } from '../../common/parser/operation';
import { toSortedByRequired } from '../../common/parser/sort';
import type { OpenApi } from '../interfaces/OpenApi';
Expand Down
6 changes: 3 additions & 3 deletions src/openApi/v2/parser/getOperationParameter.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { OperationParameter } from '../../../types/client';
import { getEnums } from '../../../utils/getEnums';
import { getPattern } from '../../../utils/getPattern';
import type { OperationParameter } from '../../common/interfaces/client';
import { getEnums } from '../../common/parser/getEnums';
import { getPattern } from '../../common/parser/getPattern';
import { getRef } from '../../common/parser/getRef';
import { getOperationParameterName } from '../../common/parser/operation';
import { getType } from '../../common/parser/type';
Expand Down
2 changes: 1 addition & 1 deletion src/openApi/v2/parser/getOperationParameterDefault.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { OperationParameter } from '../../../types/client';
import type { OperationParameter } from '../../common/interfaces/client';
import type { OpenApiParameter } from '../interfaces/OpenApiParameter';

export const getOperationParameterDefault = (
Expand Down
2 changes: 1 addition & 1 deletion src/openApi/v2/parser/getOperationParameters.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { OperationParameters } from '../../../types/client';
import type { OperationParameters } from '../../common/interfaces/client';
import { getRef } from '../../common/parser/getRef';
import type { OpenApi } from '../interfaces/OpenApi';
import type { OpenApiParameter } from '../interfaces/OpenApiParameter';
Expand Down
4 changes: 2 additions & 2 deletions src/openApi/v2/parser/getOperationResponse.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { OperationResponse } from '../../../types/client';
import { getPattern } from '../../../utils/getPattern';
import type { OperationResponse } from '../../common/interfaces/client';
import { getPattern } from '../../common/parser/getPattern';
import { getRef } from '../../common/parser/getRef';
import { getType } from '../../common/parser/type';
import type { OpenApi } from '../interfaces/OpenApi';
Expand Down
2 changes: 1 addition & 1 deletion src/openApi/v2/parser/getOperationResponses.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { OperationResponse } from '../../../types/client';
import type { OperationResponse } from '../../common/interfaces/client';
import { getRef } from '../../common/parser/getRef';
import { getOperationResponseCode } from '../../common/parser/operation';
import type { OpenApi } from '../interfaces/OpenApi';
Expand Down
2 changes: 1 addition & 1 deletion src/openApi/v2/parser/getOperationResults.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Model, OperationResponse } from '../../../types/client';
import type { Model, OperationResponse } from '../../common/interfaces/client';

const areEqual = (a: Model, b: Model): boolean => {
const equal = a.type === b.type && a.base === b.base && a.template === b.template;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Model } from '../../../types/client';
import type { Model } from '../../common/interfaces/client';
import { getRef } from '../../common/parser/getRef';
import type { OpenApi } from '../interfaces/OpenApi';
import type { OpenApiSchema } from '../interfaces/OpenApiSchema';
Expand Down
2 changes: 1 addition & 1 deletion src/openApi/v2/parser/getServices.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Service } from '../../../types/client';
import type { Config } from '../../../types/config';
import { unique } from '../../../utils/unique';
import type { Service } from '../../common/interfaces/client';
import type { OpenApi } from '../interfaces/OpenApi';
import { getOperation } from './getOperation';
import { getOperationParameters } from './getOperationParameters';
Expand Down
2 changes: 1 addition & 1 deletion src/openApi/v3/interfaces/OpenApiSchema.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { WithEnumExtension } from '../../../types/client';
import type { Dictionary } from '../../common/interfaces/Dictionary';
import type { WithEnumExtension } from '../../common/interfaces/WithEnumExtension';
import type { OpenApiDiscriminator } from './OpenApiDiscriminator';
import type { OpenApiExternalDocs } from './OpenApiExternalDocs';
import type { OpenApiReference } from './OpenApiReference';
Expand Down
Loading

0 comments on commit 211ee8c

Please sign in to comment.