Migrate to latest openapi-ts (#1430)

This commit is contained in:
Patrick Arminio
2024-11-27 12:06:59 +01:00
committed by GitHub
parent e34527325b
commit a21c57ab2b
12 changed files with 1707 additions and 578 deletions

View File

@@ -1,20 +1,21 @@
export type ApiRequestOptions = {
readonly method:
| "GET"
| "PUT"
| "POST"
| "DELETE"
| "OPTIONS"
| "HEAD"
| "PATCH"
readonly url: string
readonly path?: Record<string, unknown>
readonly cookies?: Record<string, unknown>
readonly headers?: Record<string, unknown>
readonly query?: Record<string, unknown>
readonly formData?: Record<string, unknown>
export type ApiRequestOptions<T = unknown> = {
readonly body?: any
readonly cookies?: Record<string, unknown>
readonly errors?: Record<number | string, string>
readonly formData?: Record<string, unknown> | any[] | Blob | File
readonly headers?: Record<string, unknown>
readonly mediaType?: string
readonly method:
| "DELETE"
| "GET"
| "HEAD"
| "OPTIONS"
| "PATCH"
| "POST"
| "PUT"
readonly path?: Record<string, unknown>
readonly query?: Record<string, unknown>
readonly responseHeader?: string
readonly errors?: Record<number, string>
readonly responseTransformer?: (data: unknown) => Promise<T>
readonly url: string
}

View File

@@ -1,10 +1,9 @@
import type { AxiosRequestConfig, AxiosResponse } from "axios"
import type { ApiRequestOptions } from "./ApiRequestOptions"
import type { TResult } from "./types"
type Headers = Record<string, string>
type Middleware<T> = (value: T) => T | Promise<T>
type Resolver<T> = (options: ApiRequestOptions) => Promise<T>
type Resolver<T> = (options: ApiRequestOptions<T>) => Promise<T>
export class Interceptors<T> {
_fns: Middleware<T>[]
@@ -13,14 +12,14 @@ export class Interceptors<T> {
this._fns = []
}
eject(fn: Middleware<T>) {
eject(fn: Middleware<T>): void {
const index = this._fns.indexOf(fn)
if (index !== -1) {
this._fns = [...this._fns.slice(0, index), ...this._fns.slice(index + 1)]
}
}
use(fn: Middleware<T>) {
use(fn: Middleware<T>): void {
this._fns = [...this._fns, fn]
}
}
@@ -31,7 +30,6 @@ export type OpenAPIConfig = {
ENCODE_PATH?: ((path: string) => string) | undefined
HEADERS?: Headers | Resolver<Headers> | undefined
PASSWORD?: string | Resolver<string> | undefined
RESULT?: TResult
TOKEN?: string | Resolver<string> | undefined
USERNAME?: string | Resolver<string> | undefined
VERSION: string
@@ -48,10 +46,12 @@ export const OpenAPI: OpenAPIConfig = {
ENCODE_PATH: undefined,
HEADERS: undefined,
PASSWORD: undefined,
RESULT: "body",
TOKEN: undefined,
USERNAME: undefined,
VERSION: "0.1.0",
WITH_CREDENTIALS: false,
interceptors: { request: new Interceptors(), response: new Interceptors() },
interceptors: {
request: new Interceptors(),
response: new Interceptors(),
},
}

View File

@@ -54,7 +54,9 @@ export const getQueryString = (params: Record<string, unknown>): string => {
return
}
if (Array.isArray(value)) {
if (value instanceof Date) {
append(key, value.toISOString())
} else if (Array.isArray(value)) {
value.forEach((v) => encodePair(key, v))
} else if (typeof value === "object") {
Object.entries(value).forEach(([k, v]) => encodePair(`${key}[${k}]`, v))
@@ -113,10 +115,10 @@ export const getFormData = (
return undefined
}
type Resolver<T> = (options: ApiRequestOptions) => Promise<T>
type Resolver<T> = (options: ApiRequestOptions<T>) => Promise<T>
export const resolve = async <T>(
options: ApiRequestOptions,
options: ApiRequestOptions<T>,
resolver?: T | Resolver<T>,
): Promise<T | undefined> => {
if (typeof resolver === "function") {
@@ -125,14 +127,18 @@ export const resolve = async <T>(
return resolver
}
export const getHeaders = async (
export const getHeaders = async <T>(
config: OpenAPIConfig,
options: ApiRequestOptions,
options: ApiRequestOptions<T>,
): Promise<Record<string, string>> => {
const [token, username, password, additionalHeaders] = await Promise.all([
// @ts-ignore
resolve(options, config.TOKEN),
// @ts-ignore
resolve(options, config.USERNAME),
// @ts-ignore
resolve(options, config.PASSWORD),
// @ts-ignore
resolve(options, config.HEADERS),
])
@@ -187,7 +193,7 @@ export const getRequestBody = (options: ApiRequestOptions): unknown => {
export const sendRequest = async <T>(
config: OpenAPIConfig,
options: ApiRequestOptions,
options: ApiRequestOptions<T>,
url: string,
body: unknown,
formData: FormData | undefined,
@@ -325,7 +331,7 @@ export const catchErrorCodes = (
*/
export const request = <T>(
config: OpenAPIConfig,
options: ApiRequestOptions,
options: ApiRequestOptions<T>,
axiosClient: AxiosInstance = axios,
): CancelablePromise<T> => {
return new CancelablePromise(async (resolve, reject, onCancel) => {
@@ -357,12 +363,17 @@ export const request = <T>(
options.responseHeader,
)
let transformedBody = responseBody
if (options.responseTransformer && isSuccess(response.status)) {
transformedBody = await options.responseTransformer(responseBody)
}
const result: ApiResult = {
url,
ok: isSuccess(response.status),
status: response.status,
statusText: response.statusText,
body: responseHeader ?? responseBody,
body: responseHeader ?? transformedBody,
}
catchErrorCodes(options, result)

View File

@@ -1,14 +0,0 @@
import type { ApiResult } from "./ApiResult"
export type TResult = "body" | "raw"
export type TApiResponse<T extends TResult, TData> = Exclude<
T,
"raw"
> extends never
? ApiResult<TData>
: ApiResult<TData>["body"]
export type TConfig<T extends TResult> = {
_result?: T
}