Skip to content

Commit

Permalink
feat: add operation error type mappings
Browse files Browse the repository at this point in the history
  • Loading branch information
jordanshatford committed Apr 19, 2024
1 parent fbf5de7 commit 2c36c67
Show file tree
Hide file tree
Showing 10 changed files with 363 additions and 23 deletions.
5 changes: 5 additions & 0 deletions .changeset/short-cows-think.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hey-api/openapi-ts": minor
---

feat: add operation error type mappings
7 changes: 1 addition & 6 deletions packages/openapi-ts/src/openApi/common/interfaces/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@ export interface Enum {
value: string | number;
}

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

export interface OperationParameter extends Model {
in: 'path' | 'query' | 'header' | 'formData' | 'body' | 'cookie';
prop: string;
Expand All @@ -39,7 +34,7 @@ export interface OperationResponse extends Model {
export interface Operation extends OperationParameters {
deprecated: boolean;
description: string | null;
errors: OperationError[];
errors: OperationResponse[];
method: 'DELETE' | 'GET' | 'HEAD' | 'OPTIONS' | 'PATCH' | 'POST' | 'PUT';
/**
* Method name. Methods contain the request logic.
Expand Down
17 changes: 6 additions & 11 deletions packages/openapi-ts/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 { getConfig } from '../../../utils/config';
import type { OperationError, OperationResponse } from '../interfaces/client';
import type { OperationResponse } from '../interfaces/client';
import { reservedWords } from './reservedWords';
import {
sanitizeNamespaceIdentifier,
Expand Down Expand Up @@ -74,13 +74,8 @@ export const getOperationResponseCode = (

export const getOperationErrors = (
operationResponses: OperationResponse[],
): OperationError[] =>
operationResponses
.filter(
(operationResponse) =>
operationResponse.code >= 300 && operationResponse.description,
)
.map((response) => ({
code: response.code,
description: response.description!,
}));
): OperationResponse[] =>
operationResponses.filter(
(operationResponse) =>
operationResponse.code >= 300 && operationResponse.description,
);
21 changes: 19 additions & 2 deletions packages/openapi-ts/src/utils/write/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ const processModel = (client: Client, model: Model, onNode: OnNode) => {

const processServiceTypes = (services: Service[], onNode: OnNode) => {
type ResMap = Map<number, Model>;
type MethodMap = Map<'req' | 'res', ResMap | OperationParameter[]>;
type MethodMap = Map<'req' | 'res' | 'err', ResMap | OperationParameter[]>;

Check warning on line 137 in packages/openapi-ts/src/utils/write/models.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/utils/write/models.ts#L137

Added line #L137 was not covered by tests
type MethodKey = Service['operations'][number]['method'];
type PathMap = Map<MethodKey, MethodMap>;

Expand All @@ -144,8 +144,9 @@ const processServiceTypes = (services: Service[], onNode: OnNode) => {
service.operations.forEach((operation) => {
const hasReq = operation.parameters.length;
const hasRes = operation.results.length;
const hasErr = operation.errors.length;

Check warning on line 147 in packages/openapi-ts/src/utils/write/models.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/utils/write/models.ts#L147

Added line #L147 was not covered by tests

if (hasReq || hasRes) {
if (hasReq || hasRes || hasErr) {

Check warning on line 149 in packages/openapi-ts/src/utils/write/models.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/utils/write/models.ts#L149

Added line #L149 was not covered by tests
let pathMap = pathsMap.get(operation.path);
if (!pathMap) {
pathsMap.set(operation.path, new Map());
Expand Down Expand Up @@ -177,6 +178,22 @@ const processServiceTypes = (services: Service[], onNode: OnNode) => {
resMap.set(result.code, result);
});
}

if (hasErr) {
let resMap = methodMap.get('err');
if (!resMap) {
methodMap.set('err', new Map());
resMap = methodMap.get('err')!;
}

if (Array.isArray(resMap)) {
return;
}

operation.errors.forEach((error) => {
resMap.set(error.code, error);
});
}

Check warning on line 196 in packages/openapi-ts/src/utils/write/models.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/utils/write/models.ts#L181-L196

Added lines #L181 - L196 were not covered by tests
}
});
});
Expand Down
6 changes: 2 additions & 4 deletions packages/openapi-ts/src/utils/write/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,7 @@ const toOperationParamType = (operation: Operation): FunctionParameter[] => {
const toOperationReturnType = (operation: Operation) => {
const config = getConfig();
const baseTypePath = `${serviceExportedNamespace()}['${operation.path}']['${operation.method.toLocaleLowerCase()}']['res']`;
const results = operation.results.filter(
(result) => result.code >= 200 && result.code < 300,
);
const results = operation.results;

Check warning on line 49 in packages/openapi-ts/src/utils/write/services.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/utils/write/services.ts#L49

Added line #L49 was not covered by tests
// TODO: we should return nothing when results don't exist
// can't remove this logic without removing request/name config
// as it complicates things
Expand Down Expand Up @@ -157,7 +155,7 @@ const toRequestOptions = (operation: Operation) => {
if (operation.errors.length) {
const errors: Record<number, string> = {};
operation.errors.forEach((err) => {
errors[err.code] = escapeDescription(err.description);
errors[err.code] = escapeDescription(err.description ?? '');

Check warning on line 158 in packages/openapi-ts/src/utils/write/services.ts

View check run for this annotation

Codecov / codecov/patch

packages/openapi-ts/src/utils/write/services.ts#L158

Added line #L158 was not covered by tests
});
obj.errors = errors;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,20 @@ export type $OpenApiTs = {
*/
200: ModelWithString;
};
err: {
/**
* Message for 500 error
*/
500: ModelWithString;
/**
* Message for 501 error
*/
501: ModelWithString;
/**
* Message for 502 error
*/
502: ModelWithString;
};
};
put: {
res: {
Expand All @@ -645,6 +659,20 @@ export type $OpenApiTs = {
*/
202: ModelThatExtendsExtends;
};
err: {
/**
* Message for 500 error
*/
500: ModelWithString;
/**
* Message for 501 error
*/
501: ModelWithString;
/**
* Message for 502 error
*/
502: ModelWithString;
};
};
};
'/api/v{api-version}/multiple-tags/a': {
Expand Down Expand Up @@ -775,6 +803,16 @@ export type $OpenApiTs = {
*/
200: Array<ModelWithString>;
};
err: {
/**
* 400 server error
*/
400: unknown;
/**
* 500 server error
*/
500: unknown;
};
};
};
'/api/v{api-version}/header': {
Expand All @@ -785,6 +823,16 @@ export type $OpenApiTs = {
*/
200: string;
};
err: {
/**
* 400 server error
*/
400: unknown;
/**
* 500 server error
*/
500: unknown;
};
};
};
'/api/v{api-version}/error': {
Expand All @@ -801,6 +849,24 @@ export type $OpenApiTs = {
*/
200: unknown;
};
err: {
/**
* Custom message: Internal Server Error
*/
500: unknown;
/**
* Custom message: Not Implemented
*/
501: unknown;
/**
* Custom message: Bad Gateway
*/
502: unknown;
/**
* Custom message: Service Unavailable
*/
503: unknown;
};
};
};
'/api/v{api-version}/non-ascii-æøåÆØÅöôêÊ字符串': {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1215,6 +1215,20 @@ export type $OpenApiTs = {
*/
200: ModelWithString;
};
err: {
/**
* Message for 500 error
*/
500: ModelWithString;
/**
* Message for 501 error
*/
501: ModelWithString;
/**
* Message for 502 error
*/
502: ModelWithString;
};
};
put: {
res: {
Expand All @@ -1231,6 +1245,20 @@ export type $OpenApiTs = {
*/
202: ModelThatExtendsExtends;
};
err: {
/**
* Message for 500 error
*/
500: ModelWithString;
/**
* Message for 501 error
*/
501: ModelWithString;
/**
* Message for 502 error
*/
502: ModelWithString;
};
};
};
'/api/v{api-version}/multiple-tags/a': {
Expand Down Expand Up @@ -1391,6 +1419,16 @@ export type $OpenApiTs = {
*/
200: Array<ModelWithString>;
};
err: {
/**
* 400 `server` error
*/
400: unknown;
/**
* 500 server error
*/
500: unknown;
};
};
};
'/api/v{api-version}/complex/{id}': {
Expand Down Expand Up @@ -1455,6 +1493,16 @@ export type $OpenApiTs = {
*/
200: string;
};
err: {
/**
* 400 server error
*/
400: unknown;
/**
* 500 server error
*/
500: unknown;
};
};
};
'/api/v{api-version}/error': {
Expand All @@ -1471,6 +1519,24 @@ export type $OpenApiTs = {
*/
200: unknown;
};
err: {
/**
* Custom message: Internal Server Error
*/
500: unknown;
/**
* Custom message: Not Implemented
*/
501: unknown;
/**
* Custom message: Bad Gateway
*/
502: unknown;
/**
* Custom message: Service Unavailable
*/
503: unknown;
};
};
};
'/api/v{api-version}/non-ascii-æøåÆØÅöôêÊ字符串': {
Expand Down
Loading

0 comments on commit 2c36c67

Please sign in to comment.