This is an automated email from the ASF dual-hosted git repository. rahulvats pushed a commit to branch ci/v3-2-test/fix-ui-static-check in repository https://gitbox.apache.org/repos/asf/airflow.git
commit 3011105dcce7b28aa118fbd1f1bab23c55255323 Author: vatsrahul1001 <[email protected]> AuthorDate: Mon Mar 30 16:45:40 2026 +0530 Regenerate simple auth manager UI OpenAPI client --- .../simple/ui/openapi-gen/queries/common.ts | 11 +- .../ui/openapi-gen/queries/ensureQueryData.ts | 21 +- .../simple/ui/openapi-gen/queries/index.ts | 2 +- .../ui/openapi-gen/queries/infiniteQueries.ts | 2 +- .../simple/ui/openapi-gen/queries/prefetch.ts | 21 +- .../simple/ui/openapi-gen/queries/queries.ts | 33 +- .../simple/ui/openapi-gen/queries/suspense.ts | 27 +- .../simple/ui/openapi-gen/requests/client.gen.ts | 16 + .../ui/openapi-gen/requests/client/client.gen.ts | 156 +++++++++ .../simple/ui/openapi-gen/requests/client/index.ts | 23 ++ .../ui/openapi-gen/requests/client/types.gen.ts | 160 +++++++++ .../ui/openapi-gen/requests/client/utils.gen.ts | 208 ++++++++++++ .../ui/openapi-gen/requests/core/ApiError.ts | 21 -- .../openapi-gen/requests/core/ApiRequestOptions.ts | 14 - .../ui/openapi-gen/requests/core/ApiResult.ts | 7 - .../openapi-gen/requests/core/CancelablePromise.ts | 126 ------- .../simple/ui/openapi-gen/requests/core/OpenAPI.ts | 58 ---- .../ui/openapi-gen/requests/core/auth.gen.ts | 41 +++ .../requests/core/bodySerializer.gen.ts | 84 +++++ .../ui/openapi-gen/requests/core/params.gen.ts | 169 ++++++++++ .../requests/core/pathSerializer.gen.ts | 171 ++++++++++ .../requests/core/queryKeySerializer.gen.ts | 117 +++++++ .../simple/ui/openapi-gen/requests/core/request.ts | 374 --------------------- .../requests/core/serverSentEvents.gen.ts | 243 +++++++++++++ .../ui/openapi-gen/requests/core/types.gen.ts | 104 ++++++ .../ui/openapi-gen/requests/core/utils.gen.ts | 140 ++++++++ .../simple/ui/openapi-gen/requests/index.ts | 6 +- .../simple/ui/openapi-gen/requests/schemas.gen.ts | 177 +++++----- .../simple/ui/openapi-gen/requests/sdk.gen.ts | 67 ++++ .../simple/ui/openapi-gen/requests/services.gen.ts | 74 +--- .../simple/ui/openapi-gen/requests/types.gen.ts | 195 +++++++++-- 31 files changed, 2054 insertions(+), 814 deletions(-) diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/common.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/common.ts index cefec2d009b..17f37daa8cc 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/common.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/common.ts @@ -1,8 +1,9 @@ -// generated with @7nohe/[email protected] -import { type Options } from "@hey-api/client-axios"; +// generated with @7nohe/[email protected] import { UseQueryResult } from "@tanstack/react-query"; -import { createToken, createTokenAllAdmins, createTokenCli, loginAllAdmins } from "../requests/services.gen"; +import type { Options } from "../requests/sdk.gen"; +import { createToken, createTokenAllAdmins, createTokenCli, loginAllAdmins } from "../requests/sdk.gen"; +import { CreateTokenAllAdminsData, LoginAllAdminsData } from "../requests/types.gen"; export type CreateTokenAllAdminsDefaultResponse = Awaited<ReturnType<typeof createTokenAllAdmins>>["data"]; export type CreateTokenAllAdminsQueryResult< @@ -11,7 +12,7 @@ export type CreateTokenAllAdminsQueryResult< > = UseQueryResult<TData, TError>; export const useCreateTokenAllAdminsKey = "CreateTokenAllAdmins"; export const UseCreateTokenAllAdminsKeyFn = ( - clientOptions: Options<unknown, true> = {}, + clientOptions: Options<CreateTokenAllAdminsData, true> = {}, queryKey?: Array<unknown>, ) => [useCreateTokenAllAdminsKey, ...(queryKey ?? [clientOptions])]; export type LoginAllAdminsDefaultResponse = Awaited<ReturnType<typeof loginAllAdmins>>["data"]; @@ -21,7 +22,7 @@ export type LoginAllAdminsQueryResult< > = UseQueryResult<TData, TError>; export const useLoginAllAdminsKey = "LoginAllAdmins"; export const UseLoginAllAdminsKeyFn = ( - clientOptions: Options<unknown, true> = {}, + clientOptions: Options<LoginAllAdminsData, true> = {}, queryKey?: Array<unknown>, ) => [useLoginAllAdminsKey, ...(queryKey ?? [clientOptions])]; export type CreateTokenMutationResult = Awaited<ReturnType<typeof createToken>>; diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/ensureQueryData.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/ensureQueryData.ts index 2ef7bd14a69..a0f3de25dde 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/ensureQueryData.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/ensureQueryData.ts @@ -1,21 +1,32 @@ -// generated with @7nohe/[email protected] -import { type Options } from "@hey-api/client-axios"; +// generated with @7nohe/[email protected] import { type QueryClient } from "@tanstack/react-query"; -import { createTokenAllAdmins, loginAllAdmins } from "../requests/services.gen"; +import type { Options } from "../requests/sdk.gen"; +import { createTokenAllAdmins, loginAllAdmins } from "../requests/sdk.gen"; +import { CreateTokenAllAdminsData, LoginAllAdminsData } from "../requests/types.gen"; import * as Common from "./common"; +/** + * Create Token All Admins + * + * Create a token with no credentials only if ``simple_auth_manager_all_admins`` is True. + */ export const ensureUseCreateTokenAllAdminsData = ( queryClient: QueryClient, - clientOptions: Options<unknown, true> = {}, + clientOptions: Options<CreateTokenAllAdminsData, true> = {}, ) => queryClient.ensureQueryData({ queryKey: Common.UseCreateTokenAllAdminsKeyFn(clientOptions), queryFn: () => createTokenAllAdmins({ ...clientOptions }).then((response) => response.data), }); +/** + * Login All Admins + * + * Login the user with no credentials. + */ export const ensureUseLoginAllAdminsData = ( queryClient: QueryClient, - clientOptions: Options<unknown, true> = {}, + clientOptions: Options<LoginAllAdminsData, true> = {}, ) => queryClient.ensureQueryData({ queryKey: Common.UseLoginAllAdminsKeyFn(clientOptions), diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/index.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/index.ts index 1fecbe2b0d2..fd344d39ed4 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/index.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/index.ts @@ -1,4 +1,4 @@ -// generated with @7nohe/[email protected] +// generated with @7nohe/[email protected] export * from "./common"; export * from "./queries"; diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/infiniteQueries.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/infiniteQueries.ts index 9d70f5ba83f..eb9895b02c2 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/infiniteQueries.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/infiniteQueries.ts @@ -1 +1 @@ -// generated with @7nohe/[email protected] +// generated with @7nohe/[email protected] diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/prefetch.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/prefetch.ts index 26121c74967..9d3156f311a 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/prefetch.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/prefetch.ts @@ -1,21 +1,32 @@ -// generated with @7nohe/[email protected] -import { type Options } from "@hey-api/client-axios"; +// generated with @7nohe/[email protected] import { type QueryClient } from "@tanstack/react-query"; -import { createTokenAllAdmins, loginAllAdmins } from "../requests/services.gen"; +import type { Options } from "../requests/sdk.gen"; +import { createTokenAllAdmins, loginAllAdmins } from "../requests/sdk.gen"; +import { CreateTokenAllAdminsData, LoginAllAdminsData } from "../requests/types.gen"; import * as Common from "./common"; +/** + * Create Token All Admins + * + * Create a token with no credentials only if ``simple_auth_manager_all_admins`` is True. + */ export const prefetchUseCreateTokenAllAdmins = ( queryClient: QueryClient, - clientOptions: Options<unknown, true> = {}, + clientOptions: Options<CreateTokenAllAdminsData, true> = {}, ) => queryClient.prefetchQuery({ queryKey: Common.UseCreateTokenAllAdminsKeyFn(clientOptions), queryFn: () => createTokenAllAdmins({ ...clientOptions }).then((response) => response.data), }); +/** + * Login All Admins + * + * Login the user with no credentials. + */ export const prefetchUseLoginAllAdmins = ( queryClient: QueryClient, - clientOptions: Options<unknown, true> = {}, + clientOptions: Options<LoginAllAdminsData, true> = {}, ) => queryClient.prefetchQuery({ queryKey: Common.UseLoginAllAdminsKeyFn(clientOptions), diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/queries.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/queries.ts index 5e1ad9acc52..461248cf6bc 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/queries.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/queries.ts @@ -1,24 +1,32 @@ -// generated with @7nohe/[email protected] -import { type Options } from "@hey-api/client-axios"; +// generated with @7nohe/[email protected] import { useMutation, UseMutationOptions, useQuery, UseQueryOptions } from "@tanstack/react-query"; import { AxiosError } from "axios"; -import { createToken, createTokenAllAdmins, createTokenCli, loginAllAdmins } from "../requests/services.gen"; +import type { Options } from "../requests/sdk.gen"; +import { createToken, createTokenAllAdmins, createTokenCli, loginAllAdmins } from "../requests/sdk.gen"; import { + CreateTokenAllAdminsData, CreateTokenAllAdminsError, CreateTokenCliData, CreateTokenCliError, CreateTokenData, CreateTokenError, + LoginAllAdminsData, + LoginAllAdminsError, } from "../requests/types.gen"; import * as Common from "./common"; +/** + * Create Token All Admins + * + * Create a token with no credentials only if ``simple_auth_manager_all_admins`` is True. + */ export const useCreateTokenAllAdmins = < TData = Common.CreateTokenAllAdminsDefaultResponse, TError = AxiosError<CreateTokenAllAdminsError>, TQueryKey extends Array<unknown> = unknown[], >( - clientOptions: Options<unknown, true> = {}, + clientOptions: Options<CreateTokenAllAdminsData, true> = {}, queryKey?: TQueryKey, options?: Omit<UseQueryOptions<TData, TError>, "queryKey" | "queryFn">, ) => @@ -28,12 +36,17 @@ export const useCreateTokenAllAdmins = < createTokenAllAdmins({ ...clientOptions }).then((response) => response.data as TData) as TData, ...options, }); +/** + * Login All Admins + * + * Login the user with no credentials. + */ export const useLoginAllAdmins = < TData = Common.LoginAllAdminsDefaultResponse, TError = AxiosError<LoginAllAdminsError>, TQueryKey extends Array<unknown> = unknown[], >( - clientOptions: Options<unknown, true> = {}, + clientOptions: Options<LoginAllAdminsData, true> = {}, queryKey?: TQueryKey, options?: Omit<UseQueryOptions<TData, TError>, "queryKey" | "queryFn">, ) => @@ -42,6 +55,11 @@ export const useLoginAllAdmins = < queryFn: () => loginAllAdmins({ ...clientOptions }).then((response) => response.data as TData) as TData, ...options, }); +/** + * Create Token + * + * Authenticate the user. + */ export const useCreateToken = < TData = Common.CreateTokenMutationResult, TError = AxiosError<CreateTokenError>, @@ -59,6 +77,11 @@ export const useCreateToken = < mutationFn: (clientOptions) => createToken(clientOptions) as unknown as Promise<TData>, ...options, }); +/** + * Create Token Cli + * + * Authenticate the user for the CLI. + */ export const useCreateTokenCli = < TData = Common.CreateTokenCliMutationResult, TError = AxiosError<CreateTokenCliError>, diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/suspense.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/suspense.ts index 91f54777bf1..f34840b4496 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/suspense.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/queries/suspense.ts @@ -1,18 +1,28 @@ -// generated with @7nohe/[email protected] -import { type Options } from "@hey-api/client-axios"; +// generated with @7nohe/[email protected] import { useSuspenseQuery, UseSuspenseQueryOptions } from "@tanstack/react-query"; import { AxiosError } from "axios"; -import { createTokenAllAdmins, loginAllAdmins } from "../requests/services.gen"; -import { CreateTokenAllAdminsError } from "../requests/types.gen"; +import type { Options } from "../requests/sdk.gen"; +import { createTokenAllAdmins, loginAllAdmins } from "../requests/sdk.gen"; +import { + CreateTokenAllAdminsData, + CreateTokenAllAdminsError, + LoginAllAdminsData, + LoginAllAdminsError, +} from "../requests/types.gen"; import * as Common from "./common"; +/** + * Create Token All Admins + * + * Create a token with no credentials only if ``simple_auth_manager_all_admins`` is True. + */ export const useCreateTokenAllAdminsSuspense = < TData = NonNullable<Common.CreateTokenAllAdminsDefaultResponse>, TError = AxiosError<CreateTokenAllAdminsError>, TQueryKey extends Array<unknown> = unknown[], >( - clientOptions: Options<unknown, true> = {}, + clientOptions: Options<CreateTokenAllAdminsData, true> = {}, queryKey?: TQueryKey, options?: Omit<UseSuspenseQueryOptions<TData, TError>, "queryKey" | "queryFn">, ) => @@ -22,12 +32,17 @@ export const useCreateTokenAllAdminsSuspense = < createTokenAllAdmins({ ...clientOptions }).then((response) => response.data as TData) as TData, ...options, }); +/** + * Login All Admins + * + * Login the user with no credentials. + */ export const useLoginAllAdminsSuspense = < TData = NonNullable<Common.LoginAllAdminsDefaultResponse>, TError = AxiosError<LoginAllAdminsError>, TQueryKey extends Array<unknown> = unknown[], >( - clientOptions: Options<unknown, true> = {}, + clientOptions: Options<LoginAllAdminsData, true> = {}, queryKey?: TQueryKey, options?: Omit<UseSuspenseQueryOptions<TData, TError>, "queryKey" | "queryFn">, ) => diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client.gen.ts new file mode 100644 index 00000000000..cab3c70195b --- /dev/null +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client.gen.ts @@ -0,0 +1,16 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { type ClientOptions, type Config, createClient, createConfig } from './client'; +import type { ClientOptions as ClientOptions2 } from './types.gen'; + +/** + * The `createClientConfig()` function will be called on client initialization + * and the returned object will become the client's initial configuration. + * + * You may want to initialize your client this way instead of calling + * `setConfig()`. This is useful for example if you're using Next.js + * to ensure your client always has the correct values. + */ +export type CreateClientConfig<T extends ClientOptions = ClientOptions2> = (override?: Config<ClientOptions & T>) => Config<Required<ClientOptions> & T>; + +export const client = createClient(createConfig<ClientOptions2>()); diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/client.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/client.gen.ts new file mode 100644 index 00000000000..9b3b2fa6a0e --- /dev/null +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/client.gen.ts @@ -0,0 +1,156 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { AxiosError, AxiosInstance, RawAxiosRequestHeaders } from 'axios'; +import axios from 'axios'; + +import { createSseClient } from '../core/serverSentEvents.gen'; +import type { HttpMethod } from '../core/types.gen'; +import { getValidRequestBody } from '../core/utils.gen'; +import type { Client, Config, RequestOptions } from './types.gen'; +import { buildUrl, createConfig, mergeConfigs, mergeHeaders, setAuthParams } from './utils.gen'; + +export const createClient = (config: Config = {}): Client => { + let _config = mergeConfigs(createConfig(), config); + + let instance: AxiosInstance; + + if (_config.axios && !('Axios' in _config.axios)) { + instance = _config.axios; + } else { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { auth, ...configWithoutAuth } = _config; + instance = axios.create(configWithoutAuth); + } + + const getConfig = (): Config => ({ ..._config }); + + const setConfig = (config: Config): Config => { + _config = mergeConfigs(_config, config); + instance.defaults = { + ...instance.defaults, + ..._config, + // @ts-expect-error + headers: mergeHeaders(instance.defaults.headers, _config.headers), + }; + return getConfig(); + }; + + const beforeRequest = async (options: RequestOptions) => { + const opts = { + ..._config, + ...options, + axios: options.axios ?? _config.axios ?? instance, + headers: mergeHeaders(_config.headers, options.headers), + }; + + if (opts.security) { + await setAuthParams({ + ...opts, + security: opts.security, + }); + } + + if (opts.requestValidator) { + await opts.requestValidator(opts); + } + + if (opts.body !== undefined && opts.bodySerializer) { + opts.body = opts.bodySerializer(opts.body); + } + + const url = buildUrl(opts); + + return { opts, url }; + }; + + // @ts-expect-error + const request: Client['request'] = async (options) => { + // @ts-expect-error + const { opts, url } = await beforeRequest(options); + try { + // assign Axios here for consistency with fetch + const _axios = opts.axios!; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { auth, ...optsWithoutAuth } = opts; + const response = await _axios({ + ...optsWithoutAuth, + baseURL: '', // the baseURL is already included in `url` + data: getValidRequestBody(opts), + headers: opts.headers as RawAxiosRequestHeaders, + // let `paramsSerializer()` handle query params if it exists + params: opts.paramsSerializer ? opts.query : undefined, + url, + }); + + let { data } = response; + + if (opts.responseType === 'json') { + if (opts.responseValidator) { + await opts.responseValidator(data); + } + + if (opts.responseTransformer) { + data = await opts.responseTransformer(data); + } + } + + return { + ...response, + data: data ?? {}, + }; + } catch (error) { + const e = error as AxiosError; + if (opts.throwOnError) { + throw e; + } + // @ts-expect-error + e.error = e.response?.data ?? {}; + return e; + } + }; + + const makeMethodFn = (method: Uppercase<HttpMethod>) => (options: RequestOptions) => + request({ ...options, method }); + + const makeSseFn = (method: Uppercase<HttpMethod>) => async (options: RequestOptions) => { + const { opts, url } = await beforeRequest(options); + return createSseClient({ + ...opts, + body: opts.body as BodyInit | null | undefined, + headers: opts.headers as Record<string, string>, + method, + serializedBody: getValidRequestBody(opts) as BodyInit | null | undefined, + // @ts-expect-error + signal: opts.signal, + url, + }); + }; + + return { + buildUrl, + connect: makeMethodFn('CONNECT'), + delete: makeMethodFn('DELETE'), + get: makeMethodFn('GET'), + getConfig, + head: makeMethodFn('HEAD'), + instance, + options: makeMethodFn('OPTIONS'), + patch: makeMethodFn('PATCH'), + post: makeMethodFn('POST'), + put: makeMethodFn('PUT'), + request, + setConfig, + sse: { + connect: makeSseFn('CONNECT'), + delete: makeSseFn('DELETE'), + get: makeSseFn('GET'), + head: makeSseFn('HEAD'), + options: makeSseFn('OPTIONS'), + patch: makeSseFn('PATCH'), + post: makeSseFn('POST'), + put: makeSseFn('PUT'), + trace: makeSseFn('TRACE'), + }, + trace: makeMethodFn('TRACE'), + } as Client; +}; diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/index.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/index.ts new file mode 100644 index 00000000000..7bd7b98807a --- /dev/null +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/index.ts @@ -0,0 +1,23 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type { Auth } from '../core/auth.gen'; +export type { QuerySerializerOptions } from '../core/bodySerializer.gen'; +export { + formDataBodySerializer, + jsonBodySerializer, + urlSearchParamsBodySerializer, +} from '../core/bodySerializer.gen'; +export { buildClientParams } from '../core/params.gen'; +export { serializeQueryKeyValue } from '../core/queryKeySerializer.gen'; +export { createClient } from './client.gen'; +export type { + Client, + ClientOptions, + Config, + CreateClientConfig, + Options, + RequestOptions, + RequestResult, + TDataShape, +} from './types.gen'; +export { createConfig } from './utils.gen'; diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/types.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/types.gen.ts new file mode 100644 index 00000000000..3a6f9244287 --- /dev/null +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/types.gen.ts @@ -0,0 +1,160 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { + AxiosError, + AxiosInstance, + AxiosRequestHeaders, + AxiosResponse, + AxiosStatic, + CreateAxiosDefaults, +} from 'axios'; + +import type { Auth } from '../core/auth.gen'; +import type { + ServerSentEventsOptions, + ServerSentEventsResult, +} from '../core/serverSentEvents.gen'; +import type { Client as CoreClient, Config as CoreConfig } from '../core/types.gen'; + +export interface Config<T extends ClientOptions = ClientOptions> + extends Omit<CreateAxiosDefaults, 'auth' | 'baseURL' | 'headers' | 'method'>, CoreConfig { + /** + * Axios implementation. You can use this option to provide either an + * `AxiosStatic` or an `AxiosInstance`. + * + * @default axios + */ + axios?: AxiosStatic | AxiosInstance; + /** + * Base URL for all requests made by this client. + */ + baseURL?: T['baseURL']; + /** + * An object containing any HTTP headers that you want to pre-populate your + * `Headers` object with. + * + * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more} + */ + headers?: + | AxiosRequestHeaders + | Record< + string, + string | number | boolean | (string | number | boolean)[] | null | undefined | unknown + >; + /** + * Throw an error instead of returning it in the response? + * + * @default false + */ + throwOnError?: T['throwOnError']; +} + +export interface RequestOptions< + TData = unknown, + ThrowOnError extends boolean = boolean, + Url extends string = string, +> + extends + Config<{ + throwOnError: ThrowOnError; + }>, + Pick< + ServerSentEventsOptions<TData>, + | 'onSseError' + | 'onSseEvent' + | 'sseDefaultRetryDelay' + | 'sseMaxRetryAttempts' + | 'sseMaxRetryDelay' + > { + /** + * Any body that you want to add to your request. + * + * {@link https://developer.mozilla.org/docs/Web/API/fetch#body} + */ + body?: unknown; + path?: Record<string, unknown>; + query?: Record<string, unknown>; + /** + * Security mechanism(s) to use for the request. + */ + security?: ReadonlyArray<Auth>; + url: Url; +} + +export interface ClientOptions { + baseURL?: string; + throwOnError?: boolean; +} + +export type RequestResult< + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = boolean, +> = ThrowOnError extends true + ? Promise<AxiosResponse<TData extends Record<string, unknown> ? TData[keyof TData] : TData>> + : Promise< + | (AxiosResponse<TData extends Record<string, unknown> ? TData[keyof TData] : TData> & { + error: undefined; + }) + | (AxiosError<TError extends Record<string, unknown> ? TError[keyof TError] : TError> & { + data: undefined; + error: TError extends Record<string, unknown> ? TError[keyof TError] : TError; + }) + >; + +type MethodFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false>( + options: Omit<RequestOptions<TData, ThrowOnError>, 'method'>, +) => RequestResult<TData, TError, ThrowOnError>; + +type SseFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false>( + options: Omit<RequestOptions<TData, ThrowOnError>, 'method'>, +) => Promise<ServerSentEventsResult<TData, TError>>; + +type RequestFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false>( + options: Omit<RequestOptions<TData, ThrowOnError>, 'method'> & + Pick<Required<RequestOptions<TData, ThrowOnError>>, 'method'>, +) => RequestResult<TData, TError, ThrowOnError>; + +type BuildUrlFn = < + TData extends { + body?: unknown; + path?: Record<string, unknown>; + query?: Record<string, unknown>; + url: string; + }, +>( + options: TData & Options<TData>, +) => string; + +export type Client = CoreClient<RequestFn, Config, MethodFn, BuildUrlFn, SseFn> & { + instance: AxiosInstance; +}; + +/** + * The `createClientConfig()` function will be called on client initialization + * and the returned object will become the client's initial configuration. + * + * You may want to initialize your client this way instead of calling + * `setConfig()`. This is useful for example if you're using Next.js + * to ensure your client always has the correct values. + */ +export type CreateClientConfig<T extends ClientOptions = ClientOptions> = ( + override?: Config<ClientOptions & T>, +) => Config<Required<ClientOptions> & T>; + +export interface TDataShape { + body?: unknown; + headers?: unknown; + path?: unknown; + query?: unknown; + url: string; +} + +type OmitKeys<T, K> = Pick<T, Exclude<keyof T, K>>; + +export type Options< + TData extends TDataShape = TDataShape, + ThrowOnError extends boolean = boolean, + TResponse = unknown, +> = OmitKeys<RequestOptions<TResponse, ThrowOnError>, 'body' | 'path' | 'query' | 'url'> & + ([TData] extends [never] ? unknown : Omit<TData, 'url'>); diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/utils.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/utils.gen.ts new file mode 100644 index 00000000000..1b4600f7687 --- /dev/null +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/client/utils.gen.ts @@ -0,0 +1,208 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { getAuthToken } from '../core/auth.gen'; +import type { QuerySerializerOptions } from '../core/bodySerializer.gen'; +import { + serializeArrayParam, + serializeObjectParam, + serializePrimitiveParam, +} from '../core/pathSerializer.gen'; +import { getUrl } from '../core/utils.gen'; +import type { Client, ClientOptions, Config, RequestOptions } from './types.gen'; + +export const createQuerySerializer = <T = unknown>({ + parameters = {}, + ...args +}: QuerySerializerOptions = {}) => { + const querySerializer = (queryParams: T) => { + const search: string[] = []; + if (queryParams && typeof queryParams === 'object') { + for (const name in queryParams) { + const value = queryParams[name]; + + if (value === undefined || value === null) { + continue; + } + + const options = parameters[name] || args; + + if (Array.isArray(value)) { + const serializedArray = serializeArrayParam({ + allowReserved: options.allowReserved, + explode: true, + name, + style: 'form', + value, + ...options.array, + }); + if (serializedArray) search.push(serializedArray); + } else if (typeof value === 'object') { + const serializedObject = serializeObjectParam({ + allowReserved: options.allowReserved, + explode: true, + name, + style: 'deepObject', + value: value as Record<string, unknown>, + ...options.object, + }); + if (serializedObject) search.push(serializedObject); + } else { + const serializedPrimitive = serializePrimitiveParam({ + allowReserved: options.allowReserved, + name, + value: value as string, + }); + if (serializedPrimitive) search.push(serializedPrimitive); + } + } + } + return search.join('&'); + }; + return querySerializer; +}; + +const checkForExistence = ( + options: Pick<RequestOptions, 'auth' | 'query'> & { + headers: Record<any, unknown>; + }, + name?: string, +): boolean => { + if (!name) { + return false; + } + if (name in options.headers || options.query?.[name]) { + return true; + } + if ( + 'Cookie' in options.headers && + options.headers['Cookie'] && + typeof options.headers['Cookie'] === 'string' + ) { + return options.headers['Cookie'].includes(`${name}=`); + } + return false; +}; + +export const setAuthParams = async ({ + security, + ...options +}: Pick<Required<RequestOptions>, 'security'> & + Pick<RequestOptions, 'auth' | 'query'> & { + headers: Record<any, unknown>; + }) => { + for (const auth of security) { + if (checkForExistence(options, auth.name)) { + continue; + } + const token = await getAuthToken(auth, options.auth); + + if (!token) { + continue; + } + + const name = auth.name ?? 'Authorization'; + + switch (auth.in) { + case 'query': + if (!options.query) { + options.query = {}; + } + options.query[name] = token; + break; + case 'cookie': { + const value = `${name}=${token}`; + if ('Cookie' in options.headers && options.headers['Cookie']) { + options.headers['Cookie'] = `${options.headers['Cookie']}; ${value}`; + } else { + options.headers['Cookie'] = value; + } + break; + } + case 'header': + default: + options.headers[name] = token; + break; + } + } +}; + +export const buildUrl: Client['buildUrl'] = (options) => { + const instanceBaseUrl = options.axios?.defaults?.baseURL; + + const baseUrl = + !!options.baseURL && typeof options.baseURL === 'string' ? options.baseURL : instanceBaseUrl; + + return getUrl({ + baseUrl: baseUrl as string, + path: options.path, + // let `paramsSerializer()` handle query params if it exists + query: !options.paramsSerializer ? options.query : undefined, + querySerializer: + typeof options.querySerializer === 'function' + ? options.querySerializer + : createQuerySerializer(options.querySerializer), + url: options.url, + }); +}; + +export const mergeConfigs = (a: Config, b: Config): Config => { + const config = { ...a, ...b }; + config.headers = mergeHeaders(a.headers, b.headers); + return config; +}; + +/** + * Special Axios headers keywords allowing to set headers by request method. + */ +export const axiosHeadersKeywords = [ + 'common', + 'delete', + 'get', + 'head', + 'patch', + 'post', + 'put', +] as const; + +export const mergeHeaders = ( + ...headers: Array<Required<Config>['headers'] | undefined> +): Record<any, unknown> => { + const mergedHeaders: Record<any, unknown> = {}; + for (const header of headers) { + if (!header || typeof header !== 'object') { + continue; + } + + const iterator = Object.entries(header); + + for (const [key, value] of iterator) { + if ( + axiosHeadersKeywords.includes(key as (typeof axiosHeadersKeywords)[number]) && + typeof value === 'object' + ) { + mergedHeaders[key] = { + ...(mergedHeaders[key] as Record<any, unknown>), + ...value, + }; + } else if (value === null) { + delete mergedHeaders[key]; + } else if (Array.isArray(value)) { + for (const v of value) { + // @ts-expect-error + mergedHeaders[key] = [...(mergedHeaders[key] ?? []), v as string]; + } + } else if (value !== undefined) { + // assume object headers are meant to be JSON stringified, i.e. their + // content value in OpenAPI specification is 'application/json' + mergedHeaders[key] = typeof value === 'object' ? JSON.stringify(value) : (value as string); + } + } + } + return mergedHeaders; +}; + +export const createConfig = <T extends ClientOptions = ClientOptions>( + override: Config<Omit<ClientOptions, keyof T> & T> = {}, +): Config<Omit<ClientOptions, keyof T> & T> => ({ + ...override, +}); diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/ApiError.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/ApiError.ts deleted file mode 100644 index fc85c6d1888..00000000000 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/ApiError.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { ApiRequestOptions } from "./ApiRequestOptions"; -import type { ApiResult } from "./ApiResult"; - -export class ApiError extends Error { - public readonly url: string; - public readonly status: number; - public readonly statusText: string; - public readonly body: unknown; - public readonly request: ApiRequestOptions; - - constructor(request: ApiRequestOptions, response: ApiResult, message: string) { - super(message); - - this.name = "ApiError"; - this.url = response.url; - this.status = response.status; - this.statusText = response.statusText; - this.body = response.body; - this.request = request; - } -} diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/ApiRequestOptions.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/ApiRequestOptions.ts deleted file mode 100644 index a74f880c89a..00000000000 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/ApiRequestOptions.ts +++ /dev/null @@ -1,14 +0,0 @@ -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 responseTransformer?: (data: unknown) => Promise<T>; - readonly url: string; -}; diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/ApiResult.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/ApiResult.ts deleted file mode 100644 index 05040ba8167..00000000000 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/ApiResult.ts +++ /dev/null @@ -1,7 +0,0 @@ -export type ApiResult<TData = any> = { - readonly body: TData; - readonly ok: boolean; - readonly status: number; - readonly statusText: string; - readonly url: string; -}; diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/CancelablePromise.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/CancelablePromise.ts deleted file mode 100644 index 0640e989760..00000000000 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/CancelablePromise.ts +++ /dev/null @@ -1,126 +0,0 @@ -export class CancelError extends Error { - constructor(message: string) { - super(message); - this.name = "CancelError"; - } - - public get isCancelled(): boolean { - return true; - } -} - -export interface OnCancel { - readonly isResolved: boolean; - readonly isRejected: boolean; - readonly isCancelled: boolean; - - (cancelHandler: () => void): void; -} - -export class CancelablePromise<T> implements Promise<T> { - private _isResolved: boolean; - private _isRejected: boolean; - private _isCancelled: boolean; - readonly cancelHandlers: (() => void)[]; - readonly promise: Promise<T>; - private _resolve?: (value: T | PromiseLike<T>) => void; - private _reject?: (reason?: unknown) => void; - - constructor( - executor: ( - resolve: (value: T | PromiseLike<T>) => void, - reject: (reason?: unknown) => void, - onCancel: OnCancel, - ) => void, - ) { - this._isResolved = false; - this._isRejected = false; - this._isCancelled = false; - this.cancelHandlers = []; - this.promise = new Promise<T>((resolve, reject) => { - this._resolve = resolve; - this._reject = reject; - - const onResolve = (value: T | PromiseLike<T>): void => { - if (this._isResolved || this._isRejected || this._isCancelled) { - return; - } - this._isResolved = true; - if (this._resolve) this._resolve(value); - }; - - const onReject = (reason?: unknown): void => { - if (this._isResolved || this._isRejected || this._isCancelled) { - return; - } - this._isRejected = true; - if (this._reject) this._reject(reason); - }; - - const onCancel = (cancelHandler: () => void): void => { - if (this._isResolved || this._isRejected || this._isCancelled) { - return; - } - this.cancelHandlers.push(cancelHandler); - }; - - Object.defineProperty(onCancel, "isResolved", { - get: (): boolean => this._isResolved, - }); - - Object.defineProperty(onCancel, "isRejected", { - get: (): boolean => this._isRejected, - }); - - Object.defineProperty(onCancel, "isCancelled", { - get: (): boolean => this._isCancelled, - }); - - return executor(onResolve, onReject, onCancel as OnCancel); - }); - } - - get [Symbol.toStringTag]() { - return "Cancellable Promise"; - } - - public then<TResult1 = T, TResult2 = never>( - onFulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null, - onRejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null, - ): Promise<TResult1 | TResult2> { - return this.promise.then(onFulfilled, onRejected); - } - - public catch<TResult = never>( - onRejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null, - ): Promise<T | TResult> { - return this.promise.catch(onRejected); - } - - public finally(onFinally?: (() => void) | null): Promise<T> { - return this.promise.finally(onFinally); - } - - public cancel(): void { - if (this._isResolved || this._isRejected || this._isCancelled) { - return; - } - this._isCancelled = true; - if (this.cancelHandlers.length) { - try { - for (const cancelHandler of this.cancelHandlers) { - cancelHandler(); - } - } catch (error) { - console.warn("Cancellation threw an error", error); - return; - } - } - this.cancelHandlers.length = 0; - if (this._reject) this._reject(new CancelError("Request aborted")); - } - - public get isCancelled(): boolean { - return this._isCancelled; - } -} diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/OpenAPI.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/OpenAPI.ts deleted file mode 100644 index dddf78f069e..00000000000 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/OpenAPI.ts +++ /dev/null @@ -1,58 +0,0 @@ -import type { AxiosRequestConfig, AxiosResponse } from "axios"; - -import type { ApiRequestOptions } from "./ApiRequestOptions"; - -type Headers = Record<string, string>; -type Middleware<T> = (value: T) => T | Promise<T>; -type Resolver<T> = (options: ApiRequestOptions<T>) => Promise<T>; - -export class Interceptors<T> { - _fns: Middleware<T>[]; - - constructor() { - this._fns = []; - } - - 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>): void { - this._fns = [...this._fns, fn]; - } -} - -export type OpenAPIConfig = { - BASE: string; - CREDENTIALS: "include" | "omit" | "same-origin"; - ENCODE_PATH?: ((path: string) => string) | undefined; - HEADERS?: Headers | Resolver<Headers> | undefined; - PASSWORD?: string | Resolver<string> | undefined; - TOKEN?: string | Resolver<string> | undefined; - USERNAME?: string | Resolver<string> | undefined; - VERSION: string; - WITH_CREDENTIALS: boolean; - interceptors: { - request: Interceptors<AxiosRequestConfig>; - response: Interceptors<AxiosResponse>; - }; -}; - -export const OpenAPI: OpenAPIConfig = { - BASE: "", - CREDENTIALS: "include", - ENCODE_PATH: undefined, - HEADERS: undefined, - PASSWORD: undefined, - TOKEN: undefined, - USERNAME: undefined, - VERSION: "0.1.0", - WITH_CREDENTIALS: false, - interceptors: { - request: new Interceptors(), - response: new Interceptors(), - }, -}; diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/auth.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/auth.gen.ts new file mode 100644 index 00000000000..3ebf9947883 --- /dev/null +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/auth.gen.ts @@ -0,0 +1,41 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type AuthToken = string | undefined; + +export interface Auth { + /** + * Which part of the request do we use to send the auth? + * + * @default 'header' + */ + in?: 'header' | 'query' | 'cookie'; + /** + * Header or query parameter name. + * + * @default 'Authorization' + */ + name?: string; + scheme?: 'basic' | 'bearer'; + type: 'apiKey' | 'http'; +} + +export const getAuthToken = async ( + auth: Auth, + callback: ((auth: Auth) => Promise<AuthToken> | AuthToken) | AuthToken, +): Promise<string | undefined> => { + const token = typeof callback === 'function' ? await callback(auth) : callback; + + if (!token) { + return; + } + + if (auth.scheme === 'bearer') { + return `Bearer ${token}`; + } + + if (auth.scheme === 'basic') { + return `Basic ${btoa(token)}`; + } + + return token; +}; diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/bodySerializer.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/bodySerializer.gen.ts new file mode 100644 index 00000000000..8ad92c9ffd6 --- /dev/null +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/bodySerializer.gen.ts @@ -0,0 +1,84 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { ArrayStyle, ObjectStyle, SerializerOptions } from './pathSerializer.gen'; + +export type QuerySerializer = (query: Record<string, unknown>) => string; + +export type BodySerializer = (body: any) => any; + +type QuerySerializerOptionsObject = { + allowReserved?: boolean; + array?: Partial<SerializerOptions<ArrayStyle>>; + object?: Partial<SerializerOptions<ObjectStyle>>; +}; + +export type QuerySerializerOptions = QuerySerializerOptionsObject & { + /** + * Per-parameter serialization overrides. When provided, these settings + * override the global array/object settings for specific parameter names. + */ + parameters?: Record<string, QuerySerializerOptionsObject>; +}; + +const serializeFormDataPair = (data: FormData, key: string, value: unknown): void => { + if (typeof value === 'string' || value instanceof Blob) { + data.append(key, value); + } else if (value instanceof Date) { + data.append(key, value.toISOString()); + } else { + data.append(key, JSON.stringify(value)); + } +}; + +const serializeUrlSearchParamsPair = (data: URLSearchParams, key: string, value: unknown): void => { + if (typeof value === 'string') { + data.append(key, value); + } else { + data.append(key, JSON.stringify(value)); + } +}; + +export const formDataBodySerializer = { + bodySerializer: <T extends Record<string, any> | Array<Record<string, any>>>( + body: T, + ): FormData => { + const data = new FormData(); + + Object.entries(body).forEach(([key, value]) => { + if (value === undefined || value === null) { + return; + } + if (Array.isArray(value)) { + value.forEach((v) => serializeFormDataPair(data, key, v)); + } else { + serializeFormDataPair(data, key, value); + } + }); + + return data; + }, +}; + +export const jsonBodySerializer = { + bodySerializer: <T>(body: T): string => + JSON.stringify(body, (_key, value) => (typeof value === 'bigint' ? value.toString() : value)), +}; + +export const urlSearchParamsBodySerializer = { + bodySerializer: <T extends Record<string, any> | Array<Record<string, any>>>(body: T): string => { + const data = new URLSearchParams(); + + Object.entries(body).forEach(([key, value]) => { + if (value === undefined || value === null) { + return; + } + if (Array.isArray(value)) { + value.forEach((v) => serializeUrlSearchParamsPair(data, key, v)); + } else { + serializeUrlSearchParamsPair(data, key, value); + } + }); + + return data.toString(); + }, +}; diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/params.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/params.gen.ts new file mode 100644 index 00000000000..6099cab1b42 --- /dev/null +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/params.gen.ts @@ -0,0 +1,169 @@ +// This file is auto-generated by @hey-api/openapi-ts + +type Slot = 'body' | 'headers' | 'path' | 'query'; + +export type Field = + | { + in: Exclude<Slot, 'body'>; + /** + * Field name. This is the name we want the user to see and use. + */ + key: string; + /** + * Field mapped name. This is the name we want to use in the request. + * If omitted, we use the same value as `key`. + */ + map?: string; + } + | { + in: Extract<Slot, 'body'>; + /** + * Key isn't required for bodies. + */ + key?: string; + map?: string; + } + | { + /** + * Field name. This is the name we want the user to see and use. + */ + key: string; + /** + * Field mapped name. This is the name we want to use in the request. + * If `in` is omitted, `map` aliases `key` to the transport layer. + */ + map: Slot; + }; + +export interface Fields { + allowExtra?: Partial<Record<Slot, boolean>>; + args?: ReadonlyArray<Field>; +} + +export type FieldsConfig = ReadonlyArray<Field | Fields>; + +const extraPrefixesMap: Record<string, Slot> = { + $body_: 'body', + $headers_: 'headers', + $path_: 'path', + $query_: 'query', +}; +const extraPrefixes = Object.entries(extraPrefixesMap); + +type KeyMap = Map< + string, + | { + in: Slot; + map?: string; + } + | { + in?: never; + map: Slot; + } +>; + +const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => { + if (!map) { + map = new Map(); + } + + for (const config of fields) { + if ('in' in config) { + if (config.key) { + map.set(config.key, { + in: config.in, + map: config.map, + }); + } + } else if ('key' in config) { + map.set(config.key, { + map: config.map, + }); + } else if (config.args) { + buildKeyMap(config.args, map); + } + } + + return map; +}; + +interface Params { + body: unknown; + headers: Record<string, unknown>; + path: Record<string, unknown>; + query: Record<string, unknown>; +} + +const stripEmptySlots = (params: Params) => { + for (const [slot, value] of Object.entries(params)) { + if (value && typeof value === 'object' && !Object.keys(value).length) { + delete params[slot as Slot]; + } + } +}; + +export const buildClientParams = (args: ReadonlyArray<unknown>, fields: FieldsConfig) => { + const params: Params = { + body: {}, + headers: {}, + path: {}, + query: {}, + }; + + const map = buildKeyMap(fields); + + let config: FieldsConfig[number] | undefined; + + for (const [index, arg] of args.entries()) { + if (fields[index]) { + config = fields[index]; + } + + if (!config) { + continue; + } + + if ('in' in config) { + if (config.key) { + const field = map.get(config.key)!; + const name = field.map || config.key; + if (field.in) { + (params[field.in] as Record<string, unknown>)[name] = arg; + } + } else { + params.body = arg; + } + } else { + for (const [key, value] of Object.entries(arg ?? {})) { + const field = map.get(key); + + if (field) { + if (field.in) { + const name = field.map || key; + (params[field.in] as Record<string, unknown>)[name] = value; + } else { + params[field.map] = value; + } + } else { + const extra = extraPrefixes.find(([prefix]) => key.startsWith(prefix)); + + if (extra) { + const [prefix, slot] = extra; + (params[slot] as Record<string, unknown>)[key.slice(prefix.length)] = value; + } else if ('allowExtra' in config && config.allowExtra) { + for (const [slot, allowed] of Object.entries(config.allowExtra)) { + if (allowed) { + (params[slot as Slot] as Record<string, unknown>)[key] = value; + break; + } + } + } + } + } + } + } + + stripEmptySlots(params); + + return params; +}; diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/pathSerializer.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/pathSerializer.gen.ts new file mode 100644 index 00000000000..c714ee015b2 --- /dev/null +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/pathSerializer.gen.ts @@ -0,0 +1,171 @@ +// This file is auto-generated by @hey-api/openapi-ts + +interface SerializeOptions<T> extends SerializePrimitiveOptions, SerializerOptions<T> {} + +interface SerializePrimitiveOptions { + allowReserved?: boolean; + name: string; +} + +export interface SerializerOptions<T> { + /** + * @default true + */ + explode: boolean; + style: T; +} + +export type ArrayStyle = 'form' | 'spaceDelimited' | 'pipeDelimited'; +export type ArraySeparatorStyle = ArrayStyle | MatrixStyle; +type MatrixStyle = 'label' | 'matrix' | 'simple'; +export type ObjectStyle = 'form' | 'deepObject'; +type ObjectSeparatorStyle = ObjectStyle | MatrixStyle; + +interface SerializePrimitiveParam extends SerializePrimitiveOptions { + value: string; +} + +export const separatorArrayExplode = (style: ArraySeparatorStyle) => { + switch (style) { + case 'label': + return '.'; + case 'matrix': + return ';'; + case 'simple': + return ','; + default: + return '&'; + } +}; + +export const separatorArrayNoExplode = (style: ArraySeparatorStyle) => { + switch (style) { + case 'form': + return ','; + case 'pipeDelimited': + return '|'; + case 'spaceDelimited': + return '%20'; + default: + return ','; + } +}; + +export const separatorObjectExplode = (style: ObjectSeparatorStyle) => { + switch (style) { + case 'label': + return '.'; + case 'matrix': + return ';'; + case 'simple': + return ','; + default: + return '&'; + } +}; + +export const serializeArrayParam = ({ + allowReserved, + explode, + name, + style, + value, +}: SerializeOptions<ArraySeparatorStyle> & { + value: unknown[]; +}) => { + if (!explode) { + const joinedValues = ( + allowReserved ? value : value.map((v) => encodeURIComponent(v as string)) + ).join(separatorArrayNoExplode(style)); + switch (style) { + case 'label': + return `.${joinedValues}`; + case 'matrix': + return `;${name}=${joinedValues}`; + case 'simple': + return joinedValues; + default: + return `${name}=${joinedValues}`; + } + } + + const separator = separatorArrayExplode(style); + const joinedValues = value + .map((v) => { + if (style === 'label' || style === 'simple') { + return allowReserved ? v : encodeURIComponent(v as string); + } + + return serializePrimitiveParam({ + allowReserved, + name, + value: v as string, + }); + }) + .join(separator); + return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues; +}; + +export const serializePrimitiveParam = ({ + allowReserved, + name, + value, +}: SerializePrimitiveParam) => { + if (value === undefined || value === null) { + return ''; + } + + if (typeof value === 'object') { + throw new Error( + 'Deeply-nested arrays/objects aren't supported. Provide your own `querySerializer()` to handle these.', + ); + } + + return `${name}=${allowReserved ? value : encodeURIComponent(value)}`; +}; + +export const serializeObjectParam = ({ + allowReserved, + explode, + name, + style, + value, + valueOnly, +}: SerializeOptions<ObjectSeparatorStyle> & { + value: Record<string, unknown> | Date; + valueOnly?: boolean; +}) => { + if (value instanceof Date) { + return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`; + } + + if (style !== 'deepObject' && !explode) { + let values: string[] = []; + Object.entries(value).forEach(([key, v]) => { + values = [...values, key, allowReserved ? (v as string) : encodeURIComponent(v as string)]; + }); + const joinedValues = values.join(','); + switch (style) { + case 'form': + return `${name}=${joinedValues}`; + case 'label': + return `.${joinedValues}`; + case 'matrix': + return `;${name}=${joinedValues}`; + default: + return joinedValues; + } + } + + const separator = separatorObjectExplode(style); + const joinedValues = Object.entries(value) + .map(([key, v]) => + serializePrimitiveParam({ + allowReserved, + name: style === 'deepObject' ? `${name}[${key}]` : key, + value: v as string, + }), + ) + .join(separator); + return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues; +}; diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/queryKeySerializer.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/queryKeySerializer.gen.ts new file mode 100644 index 00000000000..5000df606f3 --- /dev/null +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/queryKeySerializer.gen.ts @@ -0,0 +1,117 @@ +// This file is auto-generated by @hey-api/openapi-ts + +/** + * JSON-friendly union that mirrors what Pinia Colada can hash. + */ +export type JsonValue = + | null + | string + | number + | boolean + | JsonValue[] + | { [key: string]: JsonValue }; + +/** + * Replacer that converts non-JSON values (bigint, Date, etc.) to safe substitutes. + */ +export const queryKeyJsonReplacer = (_key: string, value: unknown) => { + if (value === undefined || typeof value === 'function' || typeof value === 'symbol') { + return undefined; + } + if (typeof value === 'bigint') { + return value.toString(); + } + if (value instanceof Date) { + return value.toISOString(); + } + return value; +}; + +/** + * Safely stringifies a value and parses it back into a JsonValue. + */ +export const stringifyToJsonValue = (input: unknown): JsonValue | undefined => { + try { + const json = JSON.stringify(input, queryKeyJsonReplacer); + if (json === undefined) { + return undefined; + } + return JSON.parse(json) as JsonValue; + } catch { + return undefined; + } +}; + +/** + * Detects plain objects (including objects with a null prototype). + */ +const isPlainObject = (value: unknown): value is Record<string, unknown> => { + if (value === null || typeof value !== 'object') { + return false; + } + const prototype = Object.getPrototypeOf(value as object); + return prototype === Object.prototype || prototype === null; +}; + +/** + * Turns URLSearchParams into a sorted JSON object for deterministic keys. + */ +const serializeSearchParams = (params: URLSearchParams): JsonValue => { + const entries = Array.from(params.entries()).sort(([a], [b]) => a.localeCompare(b)); + const result: Record<string, JsonValue> = {}; + + for (const [key, value] of entries) { + const existing = result[key]; + if (existing === undefined) { + result[key] = value; + continue; + } + + if (Array.isArray(existing)) { + (existing as string[]).push(value); + } else { + result[key] = [existing, value]; + } + } + + return result; +}; + +/** + * Normalizes any accepted value into a JSON-friendly shape for query keys. + */ +export const serializeQueryKeyValue = (value: unknown): JsonValue | undefined => { + if (value === null) { + return null; + } + + if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') { + return value; + } + + if (value === undefined || typeof value === 'function' || typeof value === 'symbol') { + return undefined; + } + + if (typeof value === 'bigint') { + return value.toString(); + } + + if (value instanceof Date) { + return value.toISOString(); + } + + if (Array.isArray(value)) { + return stringifyToJsonValue(value); + } + + if (typeof URLSearchParams !== 'undefined' && value instanceof URLSearchParams) { + return serializeSearchParams(value); + } + + if (isPlainObject(value)) { + return stringifyToJsonValue(value); + } + + return undefined; +}; diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/request.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/request.ts deleted file mode 100644 index 319b8c47df5..00000000000 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/request.ts +++ /dev/null @@ -1,374 +0,0 @@ -import axios from "axios"; -import type { AxiosError, AxiosRequestConfig, AxiosResponse, AxiosInstance } from "axios"; - -import { ApiError } from "./ApiError"; -import type { ApiRequestOptions } from "./ApiRequestOptions"; -import type { ApiResult } from "./ApiResult"; -import { CancelablePromise } from "./CancelablePromise"; -import type { OnCancel } from "./CancelablePromise"; -import type { OpenAPIConfig } from "./OpenAPI"; - -export const isString = (value: unknown): value is string => { - return typeof value === "string"; -}; - -export const isStringWithValue = (value: unknown): value is string => { - return isString(value) && value !== ""; -}; - -export const isBlob = (value: any): value is Blob => { - return value instanceof Blob; -}; - -export const isFormData = (value: unknown): value is FormData => { - return value instanceof FormData; -}; - -export const isSuccess = (status: number): boolean => { - return status >= 200 && status < 300; -}; - -export const base64 = (str: string): string => { - try { - return btoa(str); - } catch (err) { - // @ts-ignore - return Buffer.from(str).toString("base64"); - } -}; - -export const getQueryString = (params: Record<string, unknown>): string => { - const qs: string[] = []; - - const append = (key: string, value: unknown) => { - qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`); - }; - - const encodePair = (key: string, value: unknown) => { - if (value === undefined || value === null) { - return; - } - - 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)); - } else { - append(key, value); - } - }; - - Object.entries(params).forEach(([key, value]) => encodePair(key, value)); - - return qs.length ? `?${qs.join("&")}` : ""; -}; - -const getUrl = (config: OpenAPIConfig, options: ApiRequestOptions): string => { - const encoder = config.ENCODE_PATH || encodeURI; - - const path = options.url - .replace("{api-version}", config.VERSION) - .replace(/{(.*?)}/g, (substring: string, group: string) => { - if (options.path?.hasOwnProperty(group)) { - return encoder(String(options.path[group])); - } - return substring; - }); - - const url = config.BASE + path; - return options.query ? url + getQueryString(options.query) : url; -}; - -export const getFormData = (options: ApiRequestOptions): FormData | undefined => { - if (options.formData) { - const formData = new FormData(); - - const process = (key: string, value: unknown) => { - if (isString(value) || isBlob(value)) { - formData.append(key, value); - } else { - formData.append(key, JSON.stringify(value)); - } - }; - - Object.entries(options.formData) - .filter(([, value]) => value !== undefined && value !== null) - .forEach(([key, value]) => { - if (Array.isArray(value)) { - value.forEach((v) => process(key, v)); - } else { - process(key, value); - } - }); - - return formData; - } - return undefined; -}; - -type Resolver<T> = (options: ApiRequestOptions<T>) => Promise<T>; - -export const resolve = async <T>( - options: ApiRequestOptions<T>, - resolver?: T | Resolver<T>, -): Promise<T | undefined> => { - if (typeof resolver === "function") { - return (resolver as Resolver<T>)(options); - } - return resolver; -}; - -export const getHeaders = async <T>( - config: OpenAPIConfig, - 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), - ]); - - const headers = Object.entries({ - Accept: "application/json", - ...additionalHeaders, - ...options.headers, - }) - .filter(([, value]) => value !== undefined && value !== null) - .reduce( - (headers, [key, value]) => ({ - ...headers, - [key]: String(value), - }), - {} as Record<string, string>, - ); - - if (isStringWithValue(token)) { - headers["Authorization"] = `Bearer ${token}`; - } - - if (isStringWithValue(username) && isStringWithValue(password)) { - const credentials = base64(`${username}:${password}`); - headers["Authorization"] = `Basic ${credentials}`; - } - - if (options.body !== undefined) { - if (options.mediaType) { - headers["Content-Type"] = options.mediaType; - } else if (isBlob(options.body)) { - headers["Content-Type"] = options.body.type || "application/octet-stream"; - } else if (isString(options.body)) { - headers["Content-Type"] = "text/plain"; - } else if (!isFormData(options.body)) { - headers["Content-Type"] = "application/json"; - } - } else if (options.formData !== undefined) { - if (options.mediaType) { - headers["Content-Type"] = options.mediaType; - } - } - - return headers; -}; - -export const getRequestBody = (options: ApiRequestOptions): unknown => { - if (options.body) { - return options.body; - } - return undefined; -}; - -export const sendRequest = async <T>( - config: OpenAPIConfig, - options: ApiRequestOptions<T>, - url: string, - body: unknown, - formData: FormData | undefined, - headers: Record<string, string>, - onCancel: OnCancel, - axiosClient: AxiosInstance, -): Promise<AxiosResponse<T>> => { - const controller = new AbortController(); - - let requestConfig: AxiosRequestConfig = { - data: body ?? formData, - headers, - method: options.method, - signal: controller.signal, - url, - withCredentials: config.WITH_CREDENTIALS, - }; - - onCancel(() => controller.abort()); - - for (const fn of config.interceptors.request._fns) { - requestConfig = await fn(requestConfig); - } - - try { - return await axiosClient.request(requestConfig); - } catch (error) { - const axiosError = error as AxiosError<T>; - if (axiosError.response) { - return axiosError.response; - } - throw error; - } -}; - -export const getResponseHeader = ( - response: AxiosResponse<unknown>, - responseHeader?: string, -): string | undefined => { - if (responseHeader) { - const content = response.headers[responseHeader]; - if (isString(content)) { - return content; - } - } - return undefined; -}; - -export const getResponseBody = (response: AxiosResponse<unknown>): unknown => { - if (response.status !== 204) { - return response.data; - } - return undefined; -}; - -export const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult): void => { - const errors: Record<number, string> = { - 400: "Bad Request", - 401: "Unauthorized", - 402: "Payment Required", - 403: "Forbidden", - 404: "Not Found", - 405: "Method Not Allowed", - 406: "Not Acceptable", - 407: "Proxy Authentication Required", - 408: "Request Timeout", - 409: "Conflict", - 410: "Gone", - 411: "Length Required", - 412: "Precondition Failed", - 413: "Payload Too Large", - 414: "URI Too Long", - 415: "Unsupported Media Type", - 416: "Range Not Satisfiable", - 417: "Expectation Failed", - 418: "Im a teapot", - 421: "Misdirected Request", - 422: "Unprocessable Content", - 423: "Locked", - 424: "Failed Dependency", - 425: "Too Early", - 426: "Upgrade Required", - 428: "Precondition Required", - 429: "Too Many Requests", - 431: "Request Header Fields Too Large", - 451: "Unavailable For Legal Reasons", - 500: "Internal Server Error", - 501: "Not Implemented", - 502: "Bad Gateway", - 503: "Service Unavailable", - 504: "Gateway Timeout", - 505: "HTTP Version Not Supported", - 506: "Variant Also Negotiates", - 507: "Insufficient Storage", - 508: "Loop Detected", - 510: "Not Extended", - 511: "Network Authentication Required", - ...options.errors, - }; - - const error = errors[result.status]; - if (error) { - throw new ApiError(options, result, error); - } - - if (!result.ok) { - const errorStatus = result.status ?? "unknown"; - const errorStatusText = result.statusText ?? "unknown"; - const errorBody = (() => { - try { - return JSON.stringify(result.body, null, 2); - } catch (e) { - return undefined; - } - })(); - - throw new ApiError( - options, - result, - `Generic Error: status: ${errorStatus}; status text: ${errorStatusText}; body: ${errorBody}`, - ); - } -}; - -/** - * Request method - * @param config The OpenAPI configuration object - * @param options The request options from the service - * @param axiosClient The axios client instance to use - * @returns CancelablePromise<T> - * @throws ApiError - */ -export const request = <T>( - config: OpenAPIConfig, - options: ApiRequestOptions<T>, - axiosClient: AxiosInstance = axios, -): CancelablePromise<T> => { - return new CancelablePromise(async (resolve, reject, onCancel) => { - try { - const url = getUrl(config, options); - const formData = getFormData(options); - const body = getRequestBody(options); - const headers = await getHeaders(config, options); - - if (!onCancel.isCancelled) { - let response = await sendRequest<T>( - config, - options, - url, - body, - formData, - headers, - onCancel, - axiosClient, - ); - - for (const fn of config.interceptors.response._fns) { - response = await fn(response); - } - - const responseBody = getResponseBody(response); - const responseHeader = getResponseHeader(response, 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 ?? transformedBody, - }; - - catchErrorCodes(options, result); - - resolve(result.body); - } - } catch (error) { - reject(error); - } - }); -}; diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/serverSentEvents.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/serverSentEvents.gen.ts new file mode 100644 index 00000000000..6aa6cf02a4f --- /dev/null +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/serverSentEvents.gen.ts @@ -0,0 +1,243 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Config } from './types.gen'; + +export type ServerSentEventsOptions<TData = unknown> = Omit<RequestInit, 'method'> & + Pick<Config, 'method' | 'responseTransformer' | 'responseValidator'> & { + /** + * Fetch API implementation. You can use this option to provide a custom + * fetch instance. + * + * @default globalThis.fetch + */ + fetch?: typeof fetch; + /** + * Implementing clients can call request interceptors inside this hook. + */ + onRequest?: (url: string, init: RequestInit) => Promise<Request>; + /** + * Callback invoked when a network or parsing error occurs during streaming. + * + * This option applies only if the endpoint returns a stream of events. + * + * @param error The error that occurred. + */ + onSseError?: (error: unknown) => void; + /** + * Callback invoked when an event is streamed from the server. + * + * This option applies only if the endpoint returns a stream of events. + * + * @param event Event streamed from the server. + * @returns Nothing (void). + */ + onSseEvent?: (event: StreamEvent<TData>) => void; + serializedBody?: RequestInit['body']; + /** + * Default retry delay in milliseconds. + * + * This option applies only if the endpoint returns a stream of events. + * + * @default 3000 + */ + sseDefaultRetryDelay?: number; + /** + * Maximum number of retry attempts before giving up. + */ + sseMaxRetryAttempts?: number; + /** + * Maximum retry delay in milliseconds. + * + * Applies only when exponential backoff is used. + * + * This option applies only if the endpoint returns a stream of events. + * + * @default 30000 + */ + sseMaxRetryDelay?: number; + /** + * Optional sleep function for retry backoff. + * + * Defaults to using `setTimeout`. + */ + sseSleepFn?: (ms: number) => Promise<void>; + url: string; + }; + +export interface StreamEvent<TData = unknown> { + data: TData; + event?: string; + id?: string; + retry?: number; +} + +export type ServerSentEventsResult<TData = unknown, TReturn = void, TNext = unknown> = { + stream: AsyncGenerator< + TData extends Record<string, unknown> ? TData[keyof TData] : TData, + TReturn, + TNext + >; +}; + +export const createSseClient = <TData = unknown>({ + onRequest, + onSseError, + onSseEvent, + responseTransformer, + responseValidator, + sseDefaultRetryDelay, + sseMaxRetryAttempts, + sseMaxRetryDelay, + sseSleepFn, + url, + ...options +}: ServerSentEventsOptions): ServerSentEventsResult<TData> => { + let lastEventId: string | undefined; + + const sleep = sseSleepFn ?? ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms))); + + const createStream = async function* () { + let retryDelay: number = sseDefaultRetryDelay ?? 3000; + let attempt = 0; + const signal = options.signal ?? new AbortController().signal; + + while (true) { + if (signal.aborted) break; + + attempt++; + + const headers = + options.headers instanceof Headers + ? options.headers + : new Headers(options.headers as Record<string, string> | undefined); + + if (lastEventId !== undefined) { + headers.set('Last-Event-ID', lastEventId); + } + + try { + const requestInit: RequestInit = { + redirect: 'follow', + ...options, + body: options.serializedBody, + headers, + signal, + }; + let request = new Request(url, requestInit); + if (onRequest) { + request = await onRequest(url, requestInit); + } + // fetch must be assigned here, otherwise it would throw the error: + // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation + const _fetch = options.fetch ?? globalThis.fetch; + const response = await _fetch(request); + + if (!response.ok) throw new Error(`SSE failed: ${response.status} ${response.statusText}`); + + if (!response.body) throw new Error('No body in SSE response'); + + const reader = response.body.pipeThrough(new TextDecoderStream()).getReader(); + + let buffer = ''; + + const abortHandler = () => { + try { + reader.cancel(); + } catch { + // noop + } + }; + + signal.addEventListener('abort', abortHandler); + + try { + while (true) { + const { done, value } = await reader.read(); + if (done) break; + buffer += value; + // Normalize line endings: CRLF -> LF, then CR -> LF + buffer = buffer.replace(/\r\n/g, '\n').replace(/\r/g, '\n'); + + const chunks = buffer.split('\n\n'); + buffer = chunks.pop() ?? ''; + + for (const chunk of chunks) { + const lines = chunk.split('\n'); + const dataLines: Array<string> = []; + let eventName: string | undefined; + + for (const line of lines) { + if (line.startsWith('data:')) { + dataLines.push(line.replace(/^data:\s*/, '')); + } else if (line.startsWith('event:')) { + eventName = line.replace(/^event:\s*/, ''); + } else if (line.startsWith('id:')) { + lastEventId = line.replace(/^id:\s*/, ''); + } else if (line.startsWith('retry:')) { + const parsed = Number.parseInt(line.replace(/^retry:\s*/, ''), 10); + if (!Number.isNaN(parsed)) { + retryDelay = parsed; + } + } + } + + let data: unknown; + let parsedJson = false; + + if (dataLines.length) { + const rawData = dataLines.join('\n'); + try { + data = JSON.parse(rawData); + parsedJson = true; + } catch { + data = rawData; + } + } + + if (parsedJson) { + if (responseValidator) { + await responseValidator(data); + } + + if (responseTransformer) { + data = await responseTransformer(data); + } + } + + onSseEvent?.({ + data, + event: eventName, + id: lastEventId, + retry: retryDelay, + }); + + if (dataLines.length) { + yield data as any; + } + } + } + } finally { + signal.removeEventListener('abort', abortHandler); + reader.releaseLock(); + } + + break; // exit loop on normal completion + } catch (error) { + // connection failed or aborted; retry after delay + onSseError?.(error); + + if (sseMaxRetryAttempts !== undefined && attempt >= sseMaxRetryAttempts) { + break; // stop after firing error + } + + // exponential backoff: double retry each attempt, cap at 30s + const backoff = Math.min(retryDelay * 2 ** (attempt - 1), sseMaxRetryDelay ?? 30000); + await sleep(backoff); + } + } + }; + + const stream = createStream(); + + return { stream }; +}; diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/types.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/types.gen.ts new file mode 100644 index 00000000000..97463257e43 --- /dev/null +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/types.gen.ts @@ -0,0 +1,104 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Auth, AuthToken } from './auth.gen'; +import type { BodySerializer, QuerySerializer, QuerySerializerOptions } from './bodySerializer.gen'; + +export type HttpMethod = + | 'connect' + | 'delete' + | 'get' + | 'head' + | 'options' + | 'patch' + | 'post' + | 'put' + | 'trace'; + +export type Client< + RequestFn = never, + Config = unknown, + MethodFn = never, + BuildUrlFn = never, + SseFn = never, +> = { + /** + * Returns the final request URL. + */ + buildUrl: BuildUrlFn; + getConfig: () => Config; + request: RequestFn; + setConfig: (config: Config) => Config; +} & { + [K in HttpMethod]: MethodFn; +} & ([SseFn] extends [never] ? { sse?: never } : { sse: { [K in HttpMethod]: SseFn } }); + +export interface Config { + /** + * Auth token or a function returning auth token. The resolved value will be + * added to the request payload as defined by its `security` array. + */ + auth?: ((auth: Auth) => Promise<AuthToken> | AuthToken) | AuthToken; + /** + * A function for serializing request body parameter. By default, + * {@link JSON.stringify()} will be used. + */ + bodySerializer?: BodySerializer | null; + /** + * An object containing any HTTP headers that you want to pre-populate your + * `Headers` object with. + * + * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more} + */ + headers?: + | RequestInit['headers'] + | Record< + string, + string | number | boolean | (string | number | boolean)[] | null | undefined | unknown + >; + /** + * The request method. + * + * {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more} + */ + method?: Uppercase<HttpMethod>; + /** + * A function for serializing request query parameters. By default, arrays + * will be exploded in form style, objects will be exploded in deepObject + * style, and reserved characters are percent-encoded. + * + * This method will have no effect if the native `paramsSerializer()` Axios + * API function is used. + * + * {@link https://swagger.io/docs/specification/serialization/#query View examples} + */ + querySerializer?: QuerySerializer | QuerySerializerOptions; + /** + * A function validating request data. This is useful if you want to ensure + * the request conforms to the desired shape, so it can be safely sent to + * the server. + */ + requestValidator?: (data: unknown) => Promise<unknown>; + /** + * A function transforming response data before it's returned. This is useful + * for post-processing data, e.g. converting ISO strings into Date objects. + */ + responseTransformer?: (data: unknown) => Promise<unknown>; + /** + * A function validating response data. This is useful if you want to ensure + * the response conforms to the desired shape, so it can be safely passed to + * the transformers and returned to the user. + */ + responseValidator?: (data: unknown) => Promise<unknown>; +} + +type IsExactlyNeverOrNeverUndefined<T> = [T] extends [never] + ? true + : [T] extends [never | undefined] + ? [undefined] extends [T] + ? false + : true + : false; + +export type OmitNever<T extends Record<string, unknown>> = { + [K in keyof T as IsExactlyNeverOrNeverUndefined<T[K]> extends true ? never : K]: T[K]; +}; diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/utils.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/utils.gen.ts new file mode 100644 index 00000000000..e7ddbe35411 --- /dev/null +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/core/utils.gen.ts @@ -0,0 +1,140 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { BodySerializer, QuerySerializer } from './bodySerializer.gen'; +import { + type ArraySeparatorStyle, + serializeArrayParam, + serializeObjectParam, + serializePrimitiveParam, +} from './pathSerializer.gen'; + +export interface PathSerializer { + path: Record<string, unknown>; + url: string; +} + +export const PATH_PARAM_RE = /\{[^{}]+\}/g; + +export const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => { + let url = _url; + const matches = _url.match(PATH_PARAM_RE); + if (matches) { + for (const match of matches) { + let explode = false; + let name = match.substring(1, match.length - 1); + let style: ArraySeparatorStyle = 'simple'; + + if (name.endsWith('*')) { + explode = true; + name = name.substring(0, name.length - 1); + } + + if (name.startsWith('.')) { + name = name.substring(1); + style = 'label'; + } else if (name.startsWith(';')) { + name = name.substring(1); + style = 'matrix'; + } + + const value = path[name]; + + if (value === undefined || value === null) { + continue; + } + + if (Array.isArray(value)) { + url = url.replace(match, serializeArrayParam({ explode, name, style, value })); + continue; + } + + if (typeof value === 'object') { + url = url.replace( + match, + serializeObjectParam({ + explode, + name, + style, + value: value as Record<string, unknown>, + valueOnly: true, + }), + ); + continue; + } + + if (style === 'matrix') { + url = url.replace( + match, + `;${serializePrimitiveParam({ + name, + value: value as string, + })}`, + ); + continue; + } + + const replaceValue = encodeURIComponent( + style === 'label' ? `.${value as string}` : (value as string), + ); + url = url.replace(match, replaceValue); + } + } + return url; +}; + +export const getUrl = ({ + baseUrl, + path, + query, + querySerializer, + url: _url, +}: { + baseUrl?: string; + path?: Record<string, unknown>; + query?: Record<string, unknown>; + querySerializer: QuerySerializer; + url: string; +}) => { + const pathUrl = _url.startsWith('/') ? _url : `/${_url}`; + let url = (baseUrl ?? '') + pathUrl; + if (path) { + url = defaultPathSerializer({ path, url }); + } + let search = query ? querySerializer(query) : ''; + if (search.startsWith('?')) { + search = search.substring(1); + } + if (search) { + url += `?${search}`; + } + return url; +}; + +export function getValidRequestBody(options: { + body?: unknown; + bodySerializer?: BodySerializer | null; + serializedBody?: unknown; +}) { + const hasBody = options.body !== undefined; + const isSerializedBody = hasBody && options.bodySerializer; + + if (isSerializedBody) { + if ('serializedBody' in options) { + const hasSerializedBody = + options.serializedBody !== undefined && options.serializedBody !== ''; + + return hasSerializedBody ? options.serializedBody : null; + } + + // not all clients implement a serializedBody property (i.e. client-axios) + return options.body !== '' ? options.body : null; + } + + // plain/text body + if (hasBody) { + return options.body; + } + + // no body was provided + return undefined; +} diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/index.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/index.ts index 1cb041de5c9..4d874426a85 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/index.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/index.ts @@ -1,4 +1,4 @@ // This file is auto-generated by @hey-api/openapi-ts -export * from "./schemas.gen"; -export * from "./services.gen"; -export * from "./types.gen"; + +export { createToken, createTokenAllAdmins, createTokenCli, loginAllAdmins, type Options } from './sdk.gen'; +export type { ClientOptions, CreateTokenAllAdminsData, CreateTokenAllAdminsError, CreateTokenAllAdminsErrors, CreateTokenAllAdminsResponse, CreateTokenAllAdminsResponses, CreateTokenCliData, CreateTokenCliError, CreateTokenCliErrors, CreateTokenCliResponse, CreateTokenCliResponses, CreateTokenData, CreateTokenError, CreateTokenErrors, CreateTokenResponse, CreateTokenResponses, HttpExceptionResponse, HttpValidationError, LoginAllAdminsData, LoginAllAdminsError, LoginAllAdminsErrors, Login [...] diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/schemas.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/schemas.gen.ts index a95410436ad..25b02375ff8 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/schemas.gen.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/schemas.gen.ts @@ -1,104 +1,115 @@ // This file is auto-generated by @hey-api/openapi-ts export const HTTPExceptionResponseSchema = { - properties: { - detail: { - anyOf: [ - { - type: "string", - }, - { - additionalProperties: true, - type: "object", - }, - ], - title: "Detail", + properties: { + detail: { + anyOf: [ + { + type: 'string' + }, + { + additionalProperties: true, + type: 'object' + } + ], + title: 'Detail' + } }, - }, - type: "object", - required: ["detail"], - title: "HTTPExceptionResponse", - description: "HTTPException Model used for error response.", + type: 'object', + required: [ + 'detail' + ], + title: 'HTTPExceptionResponse', + description: 'HTTPException Model used for error response.' } as const; export const HTTPValidationErrorSchema = { - properties: { - detail: { - items: { - $ref: "#/components/schemas/ValidationError", - }, - type: "array", - title: "Detail", + properties: { + detail: { + items: { + $ref: '#/components/schemas/ValidationError' + }, + type: 'array', + title: 'Detail' + } }, - }, - type: "object", - title: "HTTPValidationError", + type: 'object', + title: 'HTTPValidationError' } as const; export const LoginBodySchema = { - properties: { - username: { - type: "string", - title: "Username", - }, - password: { - type: "string", - title: "Password", + properties: { + username: { + type: 'string', + title: 'Username' + }, + password: { + type: 'string', + title: 'Password' + } }, - }, - additionalProperties: false, - type: "object", - required: ["username", "password"], - title: "LoginBody", - description: "Login serializer for post bodies.", + additionalProperties: false, + type: 'object', + required: [ + 'username', + 'password' + ], + title: 'LoginBody', + description: 'Login serializer for post bodies.' } as const; export const LoginResponseSchema = { - properties: { - access_token: { - type: "string", - title: "Access Token", + properties: { + access_token: { + type: 'string', + title: 'Access Token' + } }, - }, - type: "object", - required: ["access_token"], - title: "LoginResponse", - description: "Login serializer for responses.", + type: 'object', + required: [ + 'access_token' + ], + title: 'LoginResponse', + description: 'Login serializer for responses.' } as const; export const ValidationErrorSchema = { - properties: { - loc: { - items: { - anyOf: [ - { - type: "string", - }, - { - type: "integer", - }, - ], - }, - type: "array", - title: "Location", - }, - msg: { - type: "string", - title: "Message", - }, - type: { - type: "string", - title: "Error Type", - }, - input: { - title: "Input", - }, - ctx: { - type: "object", - title: "Context", + properties: { + loc: { + items: { + anyOf: [ + { + type: 'string' + }, + { + type: 'integer' + } + ] + }, + type: 'array', + title: 'Location' + }, + msg: { + type: 'string', + title: 'Message' + }, + type: { + type: 'string', + title: 'Error Type' + }, + input: { + title: 'Input' + }, + ctx: { + type: 'object', + title: 'Context' + } }, - }, - type: "object", - required: ["loc", "msg", "type"], - title: "ValidationError", + type: 'object', + required: [ + 'loc', + 'msg', + 'type' + ], + title: 'ValidationError' } as const; diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/sdk.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/sdk.gen.ts new file mode 100644 index 00000000000..d34e29be6ae --- /dev/null +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/sdk.gen.ts @@ -0,0 +1,67 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Client, Options as Options2, TDataShape } from './client'; +import { client } from './client.gen'; +import type { CreateTokenAllAdminsData, CreateTokenAllAdminsErrors, CreateTokenAllAdminsResponses, CreateTokenCliData, CreateTokenCliErrors, CreateTokenCliResponses, CreateTokenData, CreateTokenErrors, CreateTokenResponses, LoginAllAdminsData, LoginAllAdminsErrors } from './types.gen'; + +export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean> = Options2<TData, ThrowOnError> & { + /** + * You can provide a client instance returned by `createClient()` instead of + * individual options. This might be also useful if you want to implement a + * custom client. + */ + client?: Client; + /** + * You can pass arbitrary values through the `meta` object. This can be + * used to access values that aren't defined as part of the SDK function. + */ + meta?: Record<string, unknown>; +}; + +/** + * Create Token All Admins + * + * Create a token with no credentials only if ``simple_auth_manager_all_admins`` is True. + */ +export const createTokenAllAdmins = <ThrowOnError extends boolean = false>(options?: Options<CreateTokenAllAdminsData, ThrowOnError>) => (options?.client ?? client).get<CreateTokenAllAdminsResponses, CreateTokenAllAdminsErrors, ThrowOnError>({ + responseType: 'json', + url: '/auth/token', + ...options +}); + +/** + * Create Token + * + * Authenticate the user. + */ +export const createToken = <ThrowOnError extends boolean = false>(options: Options<CreateTokenData, ThrowOnError>) => (options.client ?? client).post<CreateTokenResponses, CreateTokenErrors, ThrowOnError>({ + responseType: 'json', + url: '/auth/token', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Login All Admins + * + * Login the user with no credentials. + */ +export const loginAllAdmins = <ThrowOnError extends boolean = false>(options?: Options<LoginAllAdminsData, ThrowOnError>) => (options?.client ?? client).get<unknown, LoginAllAdminsErrors, ThrowOnError>({ url: '/auth/token/login', ...options }); + +/** + * Create Token Cli + * + * Authenticate the user for the CLI. + */ +export const createTokenCli = <ThrowOnError extends boolean = false>(options: Options<CreateTokenCliData, ThrowOnError>) => (options.client ?? client).post<CreateTokenCliResponses, CreateTokenCliErrors, ThrowOnError>({ + responseType: 'json', + url: '/auth/token/cli', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/services.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/services.gen.ts index 24bf06e5487..fbae39c7afb 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/services.gen.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/services.gen.ts @@ -1,71 +1,3 @@ -// This file is auto-generated by @hey-api/openapi-ts -import { createClient, createConfig, type Options } from "@hey-api/client-axios"; - -import type { - CreateTokenData, - CreateTokenError, - CreateTokenResponse, - CreateTokenAllAdminsError, - CreateTokenAllAdminsResponse, - CreateTokenCliData, - CreateTokenCliError, - CreateTokenCliResponse, -} from "./types.gen"; - -export const client = createClient(createConfig()); - -/** - * Create Token - * Authenticate the user. - */ -export const createToken = <ThrowOnError extends boolean = false>( - options: Options<CreateTokenData, ThrowOnError>, -) => { - return (options?.client ?? client).post<CreateTokenResponse, CreateTokenError, ThrowOnError>({ - ...options, - url: "/auth/token", - }); -}; - -/** - * Create Token All Admins - * Create a token with no credentials only if ``simple_auth_manager_all_admins`` is True. - */ -export const createTokenAllAdmins = <ThrowOnError extends boolean = false>( - options?: Options<unknown, ThrowOnError>, -) => { - return (options?.client ?? client).get< - CreateTokenAllAdminsResponse, - CreateTokenAllAdminsError, - ThrowOnError - >({ - ...options, - url: "/auth/token", - }); -}; - -/** - * Login All Admins - * Login the user with no credentials. - */ -export const loginAllAdmins = <ThrowOnError extends boolean = false>( - options?: Options<unknown, ThrowOnError>, -) => { - return (options?.client ?? client).get<void, unknown, ThrowOnError>({ - ...options, - url: "/auth/token/login", - }); -}; - -/** - * Create Token Cli - * Authenticate the user for the CLI. - */ -export const createTokenCli = <ThrowOnError extends boolean = false>( - options: Options<CreateTokenCliData, ThrowOnError>, -) => { - return (options?.client ?? client).post<CreateTokenCliResponse, CreateTokenCliError, ThrowOnError>({ - ...options, - url: "/auth/token/cli", - }); -}; +// This file is auto-generated for backward compatibility +export * from './client.gen.js'; +export * from './sdk.gen.js'; diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/types.gen.ts b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/types.gen.ts index 81e0f48ffbc..2497945807a 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/types.gen.ts +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/requests/types.gen.ts @@ -1,67 +1,204 @@ // This file is auto-generated by @hey-api/openapi-ts +export type ClientOptions = { + baseURL: `${string}://${string}` | (string & {}); +}; + /** + * HTTPExceptionResponse + * * HTTPException Model used for error response. */ -export type HTTPExceptionResponse = { - detail: - | string - | { +export type HttpExceptionResponse = { + /** + * Detail + */ + detail: string | { [key: string]: unknown; - }; + }; }; -export type HTTPValidationError = { - detail?: Array<ValidationError>; +/** + * HTTPValidationError + */ +export type HttpValidationError = { + /** + * Detail + */ + detail?: Array<ValidationError>; }; /** + * LoginBody + * * Login serializer for post bodies. */ export type LoginBody = { - username: string; - password: string; + /** + * Username + */ + username: string; + /** + * Password + */ + password: string; }; /** + * LoginResponse + * * Login serializer for responses. */ export type LoginResponse = { - access_token: string; + /** + * Access Token + */ + access_token: string; }; +/** + * ValidationError + */ export type ValidationError = { - loc: Array<string | number>; - msg: string; - type: string; - input?: unknown; - ctx?: { - [key: string]: unknown; - }; + /** + * Location + */ + loc: Array<string | number>; + /** + * Message + */ + msg: string; + /** + * Error Type + */ + type: string; + /** + * Input + */ + input?: unknown; + /** + * Context + */ + ctx?: { + [key: string]: unknown; + }; +}; + +export type CreateTokenAllAdminsData = { + body?: never; + path?: never; + query?: never; + url: '/auth/token'; +}; + +export type CreateTokenAllAdminsErrors = { + /** + * Forbidden + */ + 403: HttpExceptionResponse; +}; + +export type CreateTokenAllAdminsError = CreateTokenAllAdminsErrors[keyof CreateTokenAllAdminsErrors]; + +export type CreateTokenAllAdminsResponses = { + /** + * Successful Response + */ + 201: LoginResponse; }; +export type CreateTokenAllAdminsResponse = CreateTokenAllAdminsResponses[keyof CreateTokenAllAdminsResponses]; + export type CreateTokenData = { - body: LoginBody; - headers?: { + body: LoginBody; + headers?: { + /** + * Content-Type + * + * Content-Type of the request body + */ + 'Content-Type'?: 'application/json' | 'application/x-www-form-urlencoded'; + }; + path?: never; + query?: never; + url: '/auth/token'; +}; + +export type CreateTokenErrors = { + /** + * Bad Request + */ + 400: HttpExceptionResponse; + /** + * Unauthorized + */ + 401: HttpExceptionResponse; + /** + * Unsupported Media Type + */ + 415: HttpExceptionResponse; + /** + * Validation Error + */ + 422: HttpValidationError; +}; + +export type CreateTokenError = CreateTokenErrors[keyof CreateTokenErrors]; + +export type CreateTokenResponses = { /** - * Content-Type of the request body + * Successful Response */ - "Content-Type"?: "application/json" | "application/x-www-form-urlencoded"; - }; + 201: LoginResponse; }; -export type CreateTokenResponse = LoginResponse; +export type CreateTokenResponse = CreateTokenResponses[keyof CreateTokenResponses]; -export type CreateTokenError = HTTPExceptionResponse | HTTPValidationError; +export type LoginAllAdminsData = { + body?: never; + path?: never; + query?: never; + url: '/auth/token/login'; +}; -export type CreateTokenAllAdminsResponse = LoginResponse; +export type LoginAllAdminsErrors = { + /** + * Forbidden + */ + 403: HttpExceptionResponse; +}; -export type CreateTokenAllAdminsError = HTTPExceptionResponse; +export type LoginAllAdminsError = LoginAllAdminsErrors[keyof LoginAllAdminsErrors]; export type CreateTokenCliData = { - body: LoginBody; + body: LoginBody; + path?: never; + query?: never; + url: '/auth/token/cli'; }; -export type CreateTokenCliResponse = LoginResponse; +export type CreateTokenCliErrors = { + /** + * Bad Request + */ + 400: HttpExceptionResponse; + /** + * Unauthorized + */ + 401: HttpExceptionResponse; + /** + * Validation Error + */ + 422: HttpValidationError; +}; + +export type CreateTokenCliError = CreateTokenCliErrors[keyof CreateTokenCliErrors]; + +export type CreateTokenCliResponses = { + /** + * Successful Response + */ + 201: LoginResponse; +}; -export type CreateTokenCliError = HTTPExceptionResponse | HTTPValidationError; +export type CreateTokenCliResponse = CreateTokenCliResponses[keyof CreateTokenCliResponses];
