import { EventEmitter } from 'events' import { NextFunction, HookContext as BaseHookContext } from '@feathersjs/hooks' type SelfOrArray = S | S[] type OptionalPick = Pick> type Entries = { [K in keyof T]: [K, T[K]] }[keyof T][] type GetKeyByValue = Extract[number], [PropertyKey, Value]>[0] export type { NextFunction } /** * The object returned from `.find` call by standard database adapters */ export interface Paginated { total: number limit: number skip: number data: T[] } /** * Options that can be passed when registering a service via `app.use(name, service, options)` */ export interface ServiceOptions { /** * A list of custom events that this service emits to clients */ events?: string[] | readonly string[] /** * A list of service methods that should be available __externally__ to clients */ methods?: MethodTypes[] | readonly MethodTypes[] /** * Provide a full list of events that this service should emit to clients. * Unlike the `events` option, this will not be merged with the default events. */ serviceEvents?: string[] | readonly string[] /** * Initial data to always add as route params to this service. */ routeParams?: { [key: string]: any } } export interface ClientService< Result = any, Data = Partial, PatchData = Data, FindResult = Paginated, P = Params > { find(params?: P): Promise get(id: Id, params?: P): Promise create(data: Data[], params?: P): Promise create(data: Data, params?: P): Promise update(id: Id, data: Data, params?: P): Promise update(id: NullableId, data: Data, params?: P): Promise update(id: null, data: Data, params?: P): Promise patch(id: NullableId, data: PatchData, params?: P): Promise patch(id: Id, data: PatchData, params?: P): Promise patch(id: null, data: PatchData, params?: P): Promise remove(id: NullableId, params?: P): Promise remove(id: Id, params?: P): Promise remove(id: null, params?: P): Promise } export interface ServiceMethods< Result = any, Data = Partial, ServiceParams = Params, PatchData = Partial > { find(params?: ServiceParams & { paginate?: PaginationParams }): Promise get(id: Id, params?: ServiceParams): Promise create(data: Data, params?: ServiceParams): Promise update(id: NullableId, data: Data, params?: ServiceParams): Promise patch(id: NullableId, data: PatchData, params?: ServiceParams): Promise remove(id: NullableId, params?: ServiceParams): Promise setup?(app: Application, path: string): Promise teardown?(app: Application, path: string): Promise } export interface ServiceOverloads< Result = any, Data = Partial, ServiceParams = Params, PatchData = Partial > { create?(data: Data[], params?: ServiceParams): Promise update?(id: Id, data: Data, params?: ServiceParams): Promise update?(id: null, data: Data, params?: ServiceParams): Promise patch?(id: Id, data: PatchData, params?: ServiceParams): Promise patch?(id: null, data: PatchData, params?: ServiceParams): Promise remove?(id: Id, params?: ServiceParams): Promise remove?(id: null, params?: ServiceParams): Promise } /** * A complete service interface. The `ServiceInterface` type should be preferred for customs service * implementations */ export type Service< Result = any, Data = Partial, ServiceParams = Params, PatchData = Partial > = ServiceMethods & ServiceOverloads /** * The `Service` service interface but with none of the methods required. */ export type ServiceInterface< Result = any, Data = Partial, ServiceParams = Params, PatchData = Partial > = Partial> export interface ServiceAddons extends EventEmitter { id?: string hooks(options: HookOptions): this } export interface ServiceHookOverloads { find(params: P & { paginate?: PaginationParams }, context: HookContext): Promise get(id: Id, params: P, context: HookContext): Promise create( data: ServiceGenericData | ServiceGenericData[], params: P, context: HookContext ): Promise update(id: NullableId, data: ServiceGenericData, params: P, context: HookContext): Promise patch(id: NullableId, data: ServiceGenericData, params: P, context: HookContext): Promise remove(id: NullableId, params: P, context: HookContext): Promise } export type FeathersService = S & ServiceAddons & OptionalPick, keyof S> export type CustomMethods = { [K in keyof T]: (data: T[K][0], params?: Params) => Promise } /** * An interface usually use by transport clients that represents a e.g. HTTP or websocket * connection that can be configured on the application. */ export type TransportConnection = { (app: Application): void Service: any service: ( name: L ) => keyof any extends keyof Services ? ServiceInterface : Services[L] } /** * A real-time connection object */ export interface RealTimeConnection { [key: string]: any } /** * The interface for a custom service method. Can e.g. be used to type client side services. */ export type CustomMethod = (data: T, params?: P) => Promise export type ServiceMixin = (service: FeathersService, path: string, options: ServiceOptions) => void export type ServiceGenericType = S extends ServiceInterface ? T : any export type ServiceGenericData = S extends ServiceInterface ? D : any export type ServiceGenericParams = S extends ServiceInterface ? P : any export interface FeathersApplication { /** * The Feathers application version */ version: string /** * A list of callbacks that run when a new service is registered */ mixins: ServiceMixin>[] /** * The index of all services keyed by their path. * * __Important:__ Services should always be retrieved via `app.service('name')` * not via `app.services`. */ services: Services /** * The application settings that can be used via * `app.get` and `app.set` */ settings: Settings /** * A private-ish indicator if `app.setup()` has been called already */ _isSetup: boolean /** * Retrieve an application setting by name * * @param name The setting name */ get(name: L): Settings[L] /** * Set an application setting * * @param name The setting name * @param value The setting value */ set(name: L, value: Settings[L]): this /** * Runs a callback configure function with the current application instance. * * @param callback The callback `(app: Application) => {}` to run */ configure(callback: (this: this, app: this) => void): this /** * Returns a fallback service instance that will be registered * when no service was found. Usually throws a `NotFound` error * but also used to instantiate client side services. * * @param location The path of the service */ defaultService(location: string): ServiceInterface /** * Register a new service or a sub-app. When passed another * Feathers application, all its services will be re-registered * with the `path` prefix. * * @param path The path for the service to register * @param service The service object to register or another * Feathers application to use a sub-app under the `path` prefix. * @param options The options for this service */ use( path: L, service: keyof any extends keyof Services ? ServiceInterface | Application : Services[L], options?: ServiceOptions ): this /** * Unregister an existing service. * * @param path The name of the service to unregister */ unuse( path: L ): Promise> /** * Get the Feathers service instance for a path. This will * be the service originally registered with Feathers functionality * like hooks and events added. * * @param path The name of the service. */ service( path: L ): FeathersService /** * Set up the application and call all services `.setup` method if available. * * @param server A server instance (optional) */ setup(server?: any): Promise /** * Tear down the application and call all services `.teardown` method if available. * * @param server A server instance (optional) */ teardown(server?: any): Promise /** * Register application level hooks. * * @param map The application hook settings. */ hooks(map: ApplicationHookOptions): this } // This needs to be an interface instead of a type // so that the declaration can be extended by other modules export interface Application extends FeathersApplication, EventEmitter {} export type Id = number | string export type NullableId = Id | null export interface Query { [key: string]: any } export interface Params { query?: Q provider?: string route?: { [key: string]: any } headers?: { [key: string]: any } } export interface PaginationOptions { default?: number max?: number } export type PaginationParams = false | PaginationOptions export interface Http { /** * A writeable, optional property with status code override. */ status?: number /** * A writeable, optional property with headers. */ headers?: { [key: string]: string | string[] } /** * A writeable, optional property with `Location` header's value. */ location?: string } export type HookType = 'before' | 'after' | 'error' | 'around' type Serv = FA extends Application ? S : never export interface HookContext extends BaseHookContext> { /** * A read only property that contains the Feathers application object. This can be used to * retrieve other services (via context.app.service('name')) or configuration values. */ readonly app: A /** * A read only property with the name of the service method (one of find, get, * create, update, patch, remove). */ readonly method: string /** * A read only property and contains the service name (or path) without leading or * trailing slashes. */ path: 0 extends 1 & S ? keyof Serv & string : GetKeyByValue, S> & string /** * A read only property and contains the service this hook currently runs on. */ readonly service: S /** * A read only property with the hook type (one of 'around', 'before', 'after' or 'error'). */ readonly type: HookType /** * The list of method arguments. Should not be modified, modify the * `params`, `data` and `id` properties instead. */ readonly arguments: any[] /** * A writeable property containing the data of a create, update and patch service * method call. */ data?: ServiceGenericData /** * A writeable property with the error object that was thrown in a failed method call. * It is only available in error hooks. */ error?: any /** * A writeable property and the id for a get, remove, update and patch service * method call. For remove, update and patch context.id can also be null when * modifying multiple entries. In all other cases it will be undefined. */ id?: Id /** * A writeable property that contains the service method parameters (including * params.query). */ params: ServiceGenericParams /** * A writeable property containing the result of the successful service method call. * It is only available in after hooks. * * `context.result` can also be set in * * - A before hook to skip the actual service method (database) call * - An error hook to swallow the error and return a result instead */ result?: ServiceGenericType /** * A writeable, optional property and contains a 'safe' version of the data that * should be sent to any client. If context.dispatch has not been set context.result * will be sent to the client instead. */ dispatch?: ServiceGenericType /** * A writeable, optional property that allows to override the standard HTTP status * code that should be returned. * * @deprecated Use `http.status` instead. */ statusCode?: number /** * A writeable, optional property with options specific to HTTP transports. */ http?: Http /** * The event emitted by this method. Can be set to `null` to skip event emitting. */ event: string | null } // Regular hook typings export type HookFunction = ( this: S, context: HookContext ) => Promise | void> | HookContext | void export type Hook = HookFunction type HookMethodMap = { [L in keyof S]?: SelfOrArray> } & { all?: SelfOrArray> } type HookTypeMap = SelfOrArray> | HookMethodMap // New @feathersjs/hook typings export type AroundHookFunction = ( context: HookContext, next: NextFunction ) => Promise export type AroundHookMap = { [L in keyof S]?: AroundHookFunction[] } & { all?: AroundHookFunction[] } export type HookMap = { around?: AroundHookMap before?: HookTypeMap after?: HookTypeMap error?: HookTypeMap } export type HookOptions = AroundHookMap | AroundHookFunction[] | HookMap export interface ApplicationHookContext extends BaseHookContext { app: A server: any } export type ApplicationHookFunction = ( context: ApplicationHookContext, next: NextFunction ) => Promise export type ApplicationHookMap = { setup?: ApplicationHookFunction[] teardown?: ApplicationHookFunction[] } export type ApplicationHookOptions = HookOptions | ApplicationHookMap