import { EventEmitter, NextFunction, HookContext as BaseHookContext} from './dependencies.ts';
type SelfOrArray<S> = S | S[];type OptionalPick<T, K extends PropertyKey> = Pick<T, Extract<keyof T, K>>
export type { NextFunction };
export interface ServiceOptions { events?: string[]; methods?: string[]; serviceEvents?: string[];}
export interface ServiceMethods<T, D = Partial<T>> { find (params?: Params): Promise<T | T[]>;
get (id: Id, params?: Params): Promise<T>;
create (data: D, params?: Params): Promise<T>;
update (id: NullableId, data: D, params?: Params): Promise<T | T[]>;
patch (id: NullableId, data: D, params?: Params): Promise<T | T[]>;
remove (id: NullableId, params?: Params): Promise<T | T[]>;
setup (app: Application, path: string): Promise<void>;}
export interface ServiceOverloads<T, D> { create? (data: D[], params?: Params): Promise<T[]>;
update? (id: Id, data: D, params?: Params): Promise<T>;
update? (id: null, data: D, params?: Params): Promise<T[]>;
patch? (id: Id, data: D, params?: Params): Promise<T>;
patch? (id: null, data: D, params?: Params): Promise<T[]>;
remove? (id: Id, params?: Params): Promise<T>;
remove? (id: null, params?: Params): Promise<T[]>;}
export type Service<T, D = Partial<T>> = ServiceMethods<T, D> & ServiceOverloads<T, D>;
export type ServiceInterface<T, D = Partial<T>> = Partial<ServiceMethods<T, D>>;
export interface ServiceAddons<A = Application, S = Service<any, any>> extends EventEmitter { id?: string; hooks (options: HookOptions<A, S>): this;}
export interface ServiceHookOverloads<S> { find ( params: Params, context: HookContext ): Promise<HookContext>;
get ( id: Id, params: Params, context: HookContext ): Promise<HookContext>;
create ( data: ServiceGenericData<S> | ServiceGenericData<S>[], params: Params, context: HookContext ): Promise<HookContext>;
update ( id: NullableId, data: ServiceGenericData<S>, params: Params, context: HookContext ): Promise<HookContext>;
patch ( id: NullableId, data: ServiceGenericData<S>, params: Params, context: HookContext ): Promise<HookContext>;
remove ( id: NullableId, params: Params, context: HookContext ): Promise<HookContext>;}
export type FeathersService<A = FeathersApplication, S = Service<any>> = S & ServiceAddons<A, S> & OptionalPick<ServiceHookOverloads<S>, keyof S>;
export type CustomMethod<Methods extends string> = { [k in Methods]: <X = any> (data: any, params?: Params) => Promise<X>;}
export type ServiceMixin<A> = (service: FeathersService<A>, path: string, options?: ServiceOptions) => void;
export type ServiceGenericType<S> = S extends ServiceInterface<infer T> ? T : any;export type ServiceGenericData<S> = S extends ServiceInterface<infer _T, infer D> ? D : any;
export interface FeathersApplication<ServiceTypes = any, AppSettings = any> { version: string;
mixins: ServiceMixin<Application<ServiceTypes, AppSettings>>[];
services: ServiceTypes;
settings: AppSettings;
_isSetup: boolean;
appHooks: HookMap<Application<ServiceTypes, AppSettings>, any>;
get<L extends keyof AppSettings & string> (name: L): AppSettings[L];
set<L extends keyof AppSettings & string> (name: L, value: AppSettings[L]): this;
configure (callback: (this: this, app: this) => void): this;
defaultService (location: string): ServiceInterface<any>;
use<L extends keyof ServiceTypes & string> ( path: L, service: keyof any extends keyof ServiceTypes ? ServiceInterface<any> | Application : ServiceTypes[L], options?: ServiceOptions ): this;
service<L extends keyof ServiceTypes & string> ( path: L ): FeathersService<this, keyof any extends keyof ServiceTypes ? Service<any> : ServiceTypes[L]>;
setup (server?: any): Promise<this>;
hooks (map: HookOptions<this, any>): this;}
export interface Application<ServiceTypes = any, AppSettings = any> extends FeathersApplication<ServiceTypes, AppSettings>, EventEmitter {
}
export type Id = number | string;export type NullableId = Id | null;
export interface Query { [key: string]: any;}
export interface Params { query?: Query; provider?: string; route?: { [key: string]: string }; headers?: { [key: string]: any }; [key: string]: any; }
export interface HookContext<A = Application, S = any> extends BaseHookContext<ServiceGenericType<S>> { readonly app: A; readonly method: string; readonly path: string; readonly service: S; readonly type: null | 'before' | 'after' | 'error'; readonly arguments: any[]; data?: ServiceGenericData<S>; error?: any; id?: Id; params: Params; result?: ServiceGenericType<S>; dispatch?: ServiceGenericType<S>; statusCode?: number; event: string|null;}
export type LegacyHookFunction<A = Application, S = Service<any, any>> = (this: S, context: HookContext<A, S>) => (Promise<HookContext<Application, S> | void> | HookContext<Application, S> | void);
export type Hook<A = Application, S = Service<any, any>> = LegacyHookFunction<A, S>;
type LegacyHookMethodMap<A, S> = { [L in keyof S]?: SelfOrArray<LegacyHookFunction<A, S>>; } & { all?: SelfOrArray<LegacyHookFunction<A, S>> };
type LegacyHookTypeMap<A, S> = SelfOrArray<LegacyHookFunction<A, S>> | LegacyHookMethodMap<A, S>;
export type LegacyHookMap<A, S> = { before?: LegacyHookTypeMap<A, S>, after?: LegacyHookTypeMap<A, S>, error?: LegacyHookTypeMap<A, S>}
export type HookFunction<A = Application, S = Service<any, any>> = (context: HookContext<A, S>, next: NextFunction) => Promise<void>;
export type HookMap<A, S> = { [L in keyof S]?: HookFunction<A, S>[];};
export type HookOptions<A, S> = HookMap<A, S> | HookFunction<A, S>[] | LegacyHookMap<A, S>;