-
Notifications
You must be signed in to change notification settings - Fork 3
Change response types to ensure proper status and headers are set #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,12 +17,25 @@ export type Property<T, K extends keyof any, D = unknown> = | |
| export type ValueOf<T, D = never> = T extends Record<string, unknown> ? T[keyof T] : D; | ||
|
|
||
| export type EmptyObject = Record<never, never>; | ||
|
|
||
| export type StatusCode<Status> = | ||
| Status extends '4XX' ? FourXX : | ||
| Status extends '5XX' ? FiveXX : | ||
| Status extends number ? Status : | ||
| Status extends \`\${infer N extends number}\` ? N : | ||
| never; | ||
|
|
||
| export type FourXX = 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | | ||
| 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 421 | | ||
| 422 | 423 | 424 | 425 | 426 | 428 | 429 | 431 | 451; | ||
|
|
||
| export type FiveXX = 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511; | ||
| `; | ||
|
|
||
| export const requests = ` | ||
| import {Params, Request, Response} from '@openapi-ts/request-types'; | ||
| import {Params, Request} from '@openapi-ts/request-types'; | ||
| import {operations} from './spec'; | ||
| import {EmptyObject, Property, ValueOf} from './utils'; | ||
| import {EmptyObject, Property, ValueOf, StatusCode} from './utils'; | ||
|
|
||
| export type RequestBody<OperationId extends keyof operations> = | ||
| operations[OperationId] extends {requestBody: Record<string, any>} ? | ||
|
|
@@ -38,8 +51,23 @@ export type RequestQuery<OperationId extends keyof operations> = | |
| export type RequestHeaders<OperationId extends keyof operations> = | ||
| Property<Property<operations[OperationId], 'parameters', EmptyObject>, 'header', EmptyObject>; | ||
|
|
||
| export type ResponseBody<OperationId extends keyof operations> = | ||
| ValueOf<Property<ValueOf<Property<operations[OperationId], 'responses', EmptyObject>>, 'content'>, void>; | ||
| export type OperationResponse<OpName extends keyof operations> = { | ||
| [Status in keyof operations[OpName]['responses']]: | ||
| operations[OpName]['responses'][Status] extends { | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Matter of style, but personally I prefer to name keys in mapped types ... to also make it clearer since this is duplicated several times. |
||
| content: infer Content; | ||
| } | ||
| ? { | ||
| [CT in keyof Content]: { | ||
| statusCode: StatusCode<Status>; | ||
| headers: { 'Content-Type': CT }; | ||
| body: Content[CT]; | ||
| } | ||
| }[keyof Content] | ||
| : { | ||
| statusCode: StatusCode<Status>; | ||
| headers: EmptyObject; | ||
| }; | ||
| }[keyof operations[OpName]['responses']] | ||
|
|
||
| export type ResponseHeaders<OperationId extends keyof operations> = | ||
| Property<ValueOf<Property<operations[OperationId], 'responses', EmptyObject>>, 'headers'>; | ||
|
|
@@ -49,10 +77,6 @@ export type OperationRequest<OperationId extends keyof operations> = Request< | |
| Params & RequestPathParams<OperationId>, | ||
| Params & RequestQuery<OperationId>, | ||
| Params & RequestHeaders<OperationId>>; | ||
|
|
||
| export type OperationResponse<OperationId extends keyof operations> = Response< | ||
| ResponseBody<OperationId>, | ||
| Params & ResponseHeaders<OperationId>>; | ||
| `; | ||
|
|
||
| export const handlers = ` | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| export * from './types'; | ||
| export * from './errors'; | ||
| export * from './openapi'; | ||
| export * from './response'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| export function json<T>(body: T): { statusCode: 200; body: T; headers: { "Content-Type": "application/json" } }; | ||
| export function json<T, CT extends number>(body: T, status: CT): { statusCode: CT; body: T; headers: { "Content-Type": "application/json" } }; | ||
|
|
||
| export function json<T, CT extends number = 200>( | ||
| body: T, | ||
| status?: CT | ||
| ): {statusCode: CT | 200; body: T; headers: { "Content-Type": "application/json" } } { | ||
| const statusCode = status ?? 200 | ||
| return { | ||
| statusCode, | ||
| body, | ||
| headers: { | ||
| "Content-Type": "application/json", | ||
| }, | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,7 +2,7 @@ | |
| "name": "test", | ||
| "scripts": { | ||
| "pretest": "npm -w ../lib run build && openapi-ts-backend generate-types api.yml src/gen", | ||
| "test": "LOG_LEVEL=${LOG_LEVEL:=error} jest" | ||
| "test": "tsc && LOG_LEVEL=${LOG_LEVEL:=error} jest" | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why should the (Or is ts-jest not used so jest runs on the transpiled files? Too long since I worked on this so I don't remember. If so perhaps a better solution is to fix the jest setup?)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added it because the tests would also pass when there were typescript errors between the handler implemented in the test and the generated code. But you are right in that calling |
||
| }, | ||
| "devDependencies": { | ||
| "@openapi-ts/cli": "*", | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps stay consistent with naming OpName
OperationIdinstead?