Skip to content

Commit

Permalink
feat(client): add ServerQuery type and refactor request structures …
Browse files Browse the repository at this point in the history
…in OpenApiV3

Introduced a new type `ServerQuery` to handle API key queries in the OpenAPI V3 namespace, enhancing the flexibility and capability of handling security schemes that utilize query parameters. The addition complements existing types by allowing dynamic construction of query parameters based on the security scheme definitions.

Additionally, the refactoring of `RequestData` and `RequestInit` types to accommodate the new `ServerQuery` type ensures that all parts of the request are dynamically typed and cohesive, supporting more complex API specifications and improving type safety and developer experience when interacting with different API configurations.
  • Loading branch information
shorwood committed Nov 22, 2024
1 parent 64e3233 commit d7be39b
Showing 1 changed file with 31 additions and 31 deletions.
62 changes: 31 additions & 31 deletions packages/client/openapi/OpenApiV3.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Override, Pretty } from '@unshared/types'
import type { LooseDeep, Override, Pretty } from '@unshared/types'
import type { OpenAPIV2 } from './OpenApiV2'

export declare namespace OpenAPIV3 {
Expand All @@ -15,6 +15,11 @@ export declare namespace OpenAPIV3 {
: string
: never

export type ServerQuery<T> =
T extends { components: { securitySchemes: { api_key: { in: 'query'; name: infer U extends string } } } }
? Partial<Record<U, string>>
: never

/*************************************************************************/
/* Request */
/*************************************************************************/
Expand All @@ -26,52 +31,47 @@ export declare namespace OpenAPIV3 {
: object
: object

export type RequestData<T> =
export type RequestData<T, U> =
Pretty<
& OpenAPIV2.Parameters<T, 'path'>
& OpenAPIV2.Parameters<T, 'query'>
& RequestBody<T>
& OpenAPIV2.Parameters<U, 'path'>
& OpenAPIV2.Parameters<U, 'query'>
& RequestBody<U>
& ServerQuery<T>
>

export type RequestInit<T> =
export type RequestInit<T, U> =
Pretty<Override<globalThis.RequestInit, {
body?: RequestBody<T>
query?: OpenAPIV2.Parameters<T, 'query'>
headers?: OpenAPIV2.RequestHeaders<T>
parameters?: OpenAPIV2.Parameters<T, 'path'>
data?: RequestData<T>
body?: RequestBody<U>
query?: OpenAPIV2.Parameters<U, 'query'> & ServerQuery<T>
headers?: OpenAPIV2.RequestHeaders<U>
parameters?: OpenAPIV2.Parameters<U, 'path'>
data?: LooseDeep<RequestData<T, U>>
}>>

/*************************************************************************/
/* Response */
/*************************************************************************/

export type ResponseBody<T> =
T extends { responses: Record<200, { content: Record<string, { schema: infer S }> }> }
? OpenAPIV2.InferSchema<S>
export type ResponseBody<U> =
U extends { responses: Record<200, { content: Record<string, { schema: infer Schema }> }> }
? OpenAPIV2.InferSchema<Schema>
: never

export type Response<T> =
T extends { responses: infer R }
? ({ [P in Exclude<keyof R, 'default'>]: R[P] extends { content: Record<string, infer U> }
export type Response<U> =
U extends { responses: infer Responses }
? ({ [Status in keyof Responses]:
Responses[Status] extends { content: Record<'application/json', infer Schema> }

// --- Override the `json` method to match the schema.
? Override<globalThis.Response, {
status: P extends 'default' ? number : P
json: OpenAPIV2.InferSchema<U> extends infer V
? [never] extends V ? never : () => Promise<V>
: never
}>
: never
? Pretty<Override<globalThis.Response, {
status: Status
json: OpenAPIV2.InferSchema<Schema> extends infer V
? [never] extends V ? never : () => Promise<V>
: never
}>>
: never

// --- Collect all responses as an union.
}) extends infer Result ? Result[keyof Result] : never
: never

/*************************************************************************/
/* Fetch */
/*************************************************************************/

export type Fetch<T> =
<P extends OpenAPIV2.Route<T>>(name: P, options: RequestInit<OpenAPIV2.OperationByRoute<T, P>>) => Promise<Response<OpenAPIV2.OperationByRoute<T, P>>>
}

0 comments on commit d7be39b

Please sign in to comment.