Skip to content

Commit 9b26c16

Browse files
committed
feat(cli): allow for overriding the status code and description
1 parent 6cf3864 commit 9b26c16

File tree

4 files changed

+106
-13
lines changed

4 files changed

+106
-13
lines changed

README.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,51 @@ paths:
358358
> **Note**
359359
> Any fields added will take precedence over the defaults for `in` and `schema`
360360

361+
### Changing the response status code and description
362+
363+
By default the response status code will be an HTTP 200 with a description of "OK". You can customize these in the `output`, e.g. for describing what "success" means or using a more appropriate response status code.
364+
365+
```yaml
366+
operations:
367+
mutations:
368+
createWidget:
369+
description: Creates the specified widget
370+
371+
input:
372+
schema: { $ref: '#/components/schemas/CreateWidgetInput' }
373+
output:
374+
description: Widget created without issue
375+
statusCode: 201
376+
schema: { $ref: '#/components/schemas/Widget' }
377+
errors:
378+
400: { $ref: '#/components/responses/BadRequest' }
379+
404: { $ref: '#/components/responses/NotFound' }
380+
```
381+
382+
This will result in the following paths object:
383+
384+
<details>
385+
<summary>Resulting OpenAPI paths</summary>
386+
387+
```yaml
388+
paths:
389+
/mutations/createWidget:
390+
post:
391+
operationId: createWidget
392+
requestBody:
393+
application/json:
394+
schema: { $ref: '#/components/schemas/CreateWidgetInput' }
395+
responses:
396+
201:
397+
description: Widget created without issue
398+
content:
399+
application/json:
400+
schema: { $ref: '#/components/schemas/Widget' }
401+
400: { $ref: '#/components/responses/BadRequest' }
402+
404: { $ref: '#/components/responses/NotFound' }
403+
```
404+
</details>
405+
361406
### (TODO) Changing the HTTP method and URL
362407

363408
> **Warning**

packages/cli/src/transformers/operation-transformer.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,4 +155,35 @@ test("OperationTransformer#transformQueryOperation", async (t) => {
155155
assert.deepStrictEqual(actualByName, expectedByName);
156156
}
157157
);
158+
159+
await t.test(
160+
"allows for overriding the successful response status code and description",
161+
async () => {
162+
const actual = await transformer.transformQueryOperation(
163+
"listUserWidgets",
164+
{
165+
...operations.listUserWidgets,
166+
method: "post",
167+
path: "/widgets",
168+
output: {
169+
...operations.listUserWidgets.output,
170+
statusCode: 418,
171+
description: "I'm a teapot",
172+
},
173+
}
174+
);
175+
176+
const expectedResponseLength =
177+
Object.keys(listUserWidgetsOAS.responses).length + 1;
178+
assert.equal(Object.keys(actual.responses), expectedResponseLength);
179+
assert.strictEqual(actual.responses["418"], {
180+
description: "I'm a teapot",
181+
content: {
182+
418: {
183+
"application/json": operations.listUserWidgets.output,
184+
},
185+
},
186+
});
187+
}
188+
);
158189
});

packages/cli/src/transformers/operation-transformer.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -125,21 +125,23 @@ export class OperationTransformer {
125125
}
126126

127127
private transformOperationResponses(
128-
output?: RPCOutputObject,
129-
errors?: ResponsesObject
128+
output: RPCOutputObject = {},
129+
errors: ResponsesObject = {}
130130
): OperationObject["responses"] {
131-
const successResponse = output
132-
? {
133-
description: "OK",
134-
content: {
135-
"application/json": output,
136-
},
137-
}
138-
: DEFAULT_RESPONSE;
131+
const { description = "OK", statusCode = 200, ...mediaType } = output;
132+
133+
const successResponse =
134+
Object.keys(mediaType).length > 0
135+
? {
136+
description,
137+
content: {
138+
"application/json": mediaType,
139+
},
140+
}
141+
: DEFAULT_RESPONSE;
139142

140143
return {
141-
// @todo support other status codes
142-
200: successResponse,
144+
[statusCode]: successResponse,
143145
...errors,
144146
};
145147
}

packages/cli/src/types/operations.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { ParameterLocation } from "openapi3-ts/oas31.js";
22
import {
3+
HttpMethod,
34
MediaTypeObject,
45
ParameterObject as OASParameterObject,
56
OperationObject,
@@ -32,10 +33,24 @@ export interface RPCInputObject extends MediaTypeObject {
3233
parameters?: RPCParametersObject;
3334
}
3435
// eslint-disable-next-line @typescript-eslint/no-empty-interface
35-
export interface RPCOutputObject extends MediaTypeObject {}
36+
export interface RPCOutputObject extends MediaTypeObject {
37+
/**
38+
* Description of what success means for this operation
39+
*
40+
* This field will be mapped to the `description` field of the `200` response
41+
*/
42+
description?: string;
43+
/**
44+
* Allows for overriding the default "200" status code
45+
*/
46+
statusCode?: number;
47+
}
3648

3749
export interface RPCOperationObject
3850
extends Omit<OperationObject, "operationId" | "requestBody" | "responses"> {
51+
method?: HttpMethod;
52+
path?: string;
53+
3954
/**
4055
* The input object for the operation
4156
*

0 commit comments

Comments
 (0)