declare global {
    /**
     * Типы, используемые Api клиентом для работы со схемой расширения
     *
     * В схеме указываться только `POST` запросы в формате `application/json`, мотивация: схема не должна быть перегруженной
     *
     * При этом API обязано поддерживать те же запросы:
     *
     * - с HTTP методом GET: для поддержки кеширования
     * - в формате `multipart/form-data`: для поддержки работы с файлами
     *
     * @see Api.Ext
     */
    namespace Api {
        /**
         * Параметры запроса метода API
         *
         * @template Path Путь метода API
         */
        type Params<RequestContext extends Api.ClientRequestContext<any, any, any>, FieldsNarrow extends Api.ParamsFields<RequestContext> | undefined = undefined, Model extends RequestContext['Model'] = RequestContext['Model'], ParamsOriginal extends Api.ParamsOriginal<RequestContext> = Api.ParamsOriginal<RequestContext>> = Omit<ParamsOriginal, 'fields' | 'filters' | 'orders' | 'fetch_style'> & Api.PickAndRetype<ParamsOriginal, 'fields', FieldsNarrow extends Api.Ext.Schemas['Fields'] ? Api.ArrowNarrow<Api.ParamsFields<RequestContext>, FieldsNarrow> : Api.ParamsFields<RequestContext>> & Api.PickAndRetype<ParamsOriginal, 'filters', [Model] extends [never] ? never : Api.Field.Filter<Model>[]> & Api.PickAndRetype<ParamsOriginal, 'orders', [Model] extends [never] ? never : Api.Field.Order<Model>[]>;
        /**
         * Получить параметр списка полей с учетом дженериков модели
         *
         * Если в схеме не указан конкретный тип `fields`, он будет заменен типом из модели
         */
        type ParamsFields<RequestContext extends Api.ClientRequestContext<any, any, any>, ParamsOriginalFields extends Api.ParamsOriginalFields<RequestContext> = Api.ParamsOriginalFields<RequestContext>> = [RequestContext['Model']] extends [never] ? ParamsOriginalFields : ParamsOriginalFields extends Api.Ext.Schemas['Fields'] ? Api.ModelFields<RequestContext['Model']> : ParamsOriginalFields;
        /**
         * Параметры запроса метода API, классический OpenAPI без дженериков
         *
         * @template Path Путь метода API
         * @template T Интерфейс `paths` в схеме openAPI
         *
         * @see PathsAbstract
         */
        type ParamsOriginal<RequestContext extends Api.ClientRequestContext<any, any, any>> = RequestContext['Schema']['post'] extends {
            requestBody: {
                content: {
                    'application/json': infer P extends Record<string, any>;
                };
            };
        } ? P : Record<string, any>;
        type ParamsOriginalByPath<Paths extends Api.PathsAbstract, Path extends Api.Path<Paths>> = Paths[Path]['post'] extends {
            requestBody: {
                content: {
                    'application/json': infer P extends Record<string, any>;
                };
            };
        } ? P : Record<string, any>;
        /**
         * Получить параметр списка полей без учета дженериков модели и преобразовать его в базовый тип `fields`
         */
        type ParamsOriginalFields<RequestContext extends Api.ClientRequestContext<any, any, any>> = Api.ParamsOriginal<RequestContext> extends {
            fields?: infer Fields extends any[];
        } ? unknown[] extends Fields ? Api.Ext.Schemas['Fields'] : Fields : never;
        /**
         * Тип ответа метода API с расширением дженериков для TV Open API
         *
         * Расширение классического `ResponseOriginal`
         *
         * @template RequestContext Контекст запроса
         * @template Fields Имена полей для выборки, так как это массив, подстановка типа тут работать не будет, подстановка реализуется в js утилите
         * @template FetchStyle Способ получения данных, влияет на тип получения результата, по умолчанию `null` - определяется автоматически
         *
         * @see Api.Ext.FetchStyle
         * @see `ResponseOriginal`
         */
        type Response<RequestContext extends Api.ClientRequestContext<any, any, any>, Fields extends Api.ParamsFields<RequestContext> | undefined = undefined, FetchStyle extends RequestContext['ParamsFetchStyle'] | null = null, Result extends Api.Result<RequestContext, Fields, FetchStyle> = Api.Result<RequestContext, Fields, FetchStyle>> = Api.ResponseSuccess<Result, RequestContext['Oper']> | Api.ResponseError<Result>;
        /**
         * Тип ответа метода API с произвольной типизацией
         *
         * Для случаев, когда тип не описан в Open API
         *
         * Расширение классического `ResponseOriginal`
         *
         * @see ResponseOriginal
         */
        type ResponseCustom<Result = any> = Api.ResponseSuccess<Result, any> | Api.ResponseError<Result>;
        /**
         * Тип ответа метода API, классический OpenAPI без дженериков
         *
         * @template Path Путь метода API
         * @template T Интерфейс `paths` в схеме openAPI
         *
         * @see PathsAbstract
         */
        type ResponseOriginal<RequestContext extends Api.ClientRequestContext<any, any, any>> = RequestContext['Schema']['post']['responses'][200]['content'] extends {
            'application/json': infer R extends Record<string, any>;
        } ? R : never;
        /**
         * Тип `result` в ответе метода API
         *
         * Для методов API без модели и fetchStyle
         *
         * @template Path Путь метода API
         * @template T Интерфейс `paths` в схеме openAPI
         *
         * @see `ResponseOriginal`
         * @see PathsAbstract
         */
        type ResponseOriginalResult<RequestContext extends Api.ClientRequestContext<any, any, any>> = Exclude<Api.ResponseOriginal<RequestContext>, Api.Ext.Schemas['ResponseError']> extends {
            result?: infer R;
        } ? R : never;
        /**
         * Результат в ответе метода API
         *
         * Не путайте с ответом API `Response`, который помимо результата содержит дополнительную информацию о выполнении метода
         *
         * @see Api.Response
         */
        type Result<RequestContext extends Api.ClientRequestContext<any, any, any>, Fields extends Api.ParamsFields<RequestContext> | undefined = undefined, FetchStyle extends RequestContext['ParamsFetchStyle'] | null = null, Model extends RequestContext['Model'] = RequestContext['Model'], ResponseOriginalResult extends Api.ResponseOriginalResult<RequestContext> = Api.ResponseOriginalResult<RequestContext>> = [Model] extends [never] ? ResponseOriginalResult : null extends FetchStyle ? RequestContext['Oper'] extends 'get' ? ResultModel<Fields, 'fetchAll', Model> : ResponseOriginalResult : ResultModel<Fields, NonNullable<FetchStyle>, Model>;
        /**
         * Результат в ответе метода API для модели
         *
         * @see Api.Result
         */
        type ResultModel<Fields extends Api.ModelFields<Model> | undefined, FetchStyle extends Api.Ext.Schemas['FetchStyle'], Model extends Api.Ext.Schemas['Model']> = Fields extends Api.ModelFields<Model> ? ResultByModelFetchStyle<Fields, Model>[FetchStyle] : never;
        /**
         * Преобразование модели в зависимости от `fetchStyle`
         */
        type ResultByModelFetchStyle<Fields extends Api.ModelFields<Model>, Model extends Api.Ext.Schemas['Model']> = {
            fetchAll: ModelSelected<Fields, Model>[];
            fetchAllNum: number[][];
            fetchAllColumn: Fields[0] extends keyof Model ? Model[Fields[0]][] : never;
            fetch: ModelSelected<Fields, Model>;
            fetchColumn: Fields[0] extends keyof Model ? Model[Fields[0]] : never;
            fetchGroup: Record<string, ModelSelected<Fields, Model>[]>;
            fetchGroupColumn: Fields[0] extends keyof Model ? Record<string, Model[Fields[0]][]> : never;
            fetchUnique: Record<string, ModelSelected<Fields, Model>>;
            fetchUniqueNum: Fields extends [] ? never : Record<string, SelectedModelNum<Fields, Model>>;
            fetchUniqueColumn: Fields[0] extends keyof Model ? Record<string, Model[Fields[0]]> : never;
        };
        /**
         * Модель только с нужными полями
         */
        type ModelSelected<Fields extends Api.ModelFields<Model>, Model extends Api.Ext.Schemas['Model']> = Fields extends [] ? never : Omit<Model, Exclude<keyof Model, Fields[number]>>;
        /**
         * Модель только с нужными полями без имен
         */
        type SelectedModelNum<Fields extends Api.ModelFields<Model>, Model extends Api.Ext.Schemas['Model']> = Fields extends [] ? never : {
            [K in keyof Fields]: Fields[K] extends keyof Model ? Model[Fields[K]] : never;
        };
    }
}
export {};
