UNPKG

15.6 kBTypeScriptView Raw
1import { EventEmitter } from 'events';
2import { NextFunction, HookContext as BaseHookContext } from '@feathersjs/hooks';
3type SelfOrArray<S> = S | S[];
4type OptionalPick<T, K extends PropertyKey> = Pick<T, Extract<keyof T, K>>;
5type Entries<T> = {
6 [K in keyof T]: [K, T[K]];
7}[keyof T][];
8type GetKeyByValue<Obj, Value> = Extract<Entries<Obj>[number], [PropertyKey, Value]>[0];
9export type { NextFunction };
10/**
11 * The object returned from `.find` call by standard database adapters
12 */
13export interface Paginated<T> {
14 total: number;
15 limit: number;
16 skip: number;
17 data: T[];
18}
19/**
20 * Options that can be passed when registering a service via `app.use(name, service, options)`
21 */
22export interface ServiceOptions<MethodTypes = string> {
23 /**
24 * A list of custom events that this service emits to clients
25 */
26 events?: string[] | readonly string[];
27 /**
28 * A list of service methods that should be available __externally__ to clients
29 */
30 methods?: MethodTypes[] | readonly MethodTypes[];
31 /**
32 * Provide a full list of events that this service should emit to clients.
33 * Unlike the `events` option, this will not be merged with the default events.
34 */
35 serviceEvents?: string[] | readonly string[];
36 /**
37 * Initial data to always add as route params to this service.
38 */
39 routeParams?: {
40 [key: string]: any;
41 };
42}
43export interface ClientService<Result = any, Data = Partial<Result>, PatchData = Data, FindResult = Paginated<Result>, P = Params> {
44 find(params?: P): Promise<FindResult>;
45 get(id: Id, params?: P): Promise<Result>;
46 create(data: Data[], params?: P): Promise<Result[]>;
47 create(data: Data, params?: P): Promise<Result>;
48 update(id: Id, data: Data, params?: P): Promise<Result>;
49 update(id: NullableId, data: Data, params?: P): Promise<Result | Result[]>;
50 update(id: null, data: Data, params?: P): Promise<Result[]>;
51 patch(id: NullableId, data: PatchData, params?: P): Promise<Result | Result[]>;
52 patch(id: Id, data: PatchData, params?: P): Promise<Result>;
53 patch(id: null, data: PatchData, params?: P): Promise<Result[]>;
54 remove(id: NullableId, params?: P): Promise<Result | Result[]>;
55 remove(id: Id, params?: P): Promise<Result>;
56 remove(id: null, params?: P): Promise<Result[]>;
57}
58export interface ServiceMethods<Result = any, Data = Partial<Result>, ServiceParams = Params, PatchData = Partial<Data>> {
59 find(params?: ServiceParams & {
60 paginate?: PaginationParams;
61 }): Promise<Result | Result[]>;
62 get(id: Id, params?: ServiceParams): Promise<Result>;
63 create(data: Data, params?: ServiceParams): Promise<Result>;
64 update(id: NullableId, data: Data, params?: ServiceParams): Promise<Result | Result[]>;
65 patch(id: NullableId, data: PatchData, params?: ServiceParams): Promise<Result | Result[]>;
66 remove(id: NullableId, params?: ServiceParams): Promise<Result | Result[]>;
67 setup?(app: Application, path: string): Promise<void>;
68 teardown?(app: Application, path: string): Promise<void>;
69}
70export interface ServiceOverloads<Result = any, Data = Partial<Result>, ServiceParams = Params, PatchData = Partial<Data>> {
71 create?(data: Data[], params?: ServiceParams): Promise<Result[]>;
72 update?(id: Id, data: Data, params?: ServiceParams): Promise<Result>;
73 update?(id: null, data: Data, params?: ServiceParams): Promise<Result[]>;
74 patch?(id: Id, data: PatchData, params?: ServiceParams): Promise<Result>;
75 patch?(id: null, data: PatchData, params?: ServiceParams): Promise<Result[]>;
76 remove?(id: Id, params?: ServiceParams): Promise<Result>;
77 remove?(id: null, params?: ServiceParams): Promise<Result[]>;
78}
79/**
80 * A complete service interface. The `ServiceInterface` type should be preferred for customs service
81 * implementations
82 */
83export type Service<Result = any, Data = Partial<Result>, ServiceParams = Params, PatchData = Partial<Data>> = ServiceMethods<Result, Data, ServiceParams> & ServiceOverloads<Result, Data, ServiceParams, PatchData>;
84/**
85 * The `Service` service interface but with none of the methods required.
86 */
87export type ServiceInterface<Result = any, Data = Partial<Result>, ServiceParams = Params, PatchData = Partial<Data>> = Partial<ServiceMethods<Result, Data, ServiceParams, PatchData>>;
88export interface ServiceAddons<A = Application, S = Service> extends EventEmitter {
89 id?: string;
90 hooks(options: HookOptions<A, S>): this;
91}
92export interface ServiceHookOverloads<S, P = Params> {
93 find(params: P & {
94 paginate?: PaginationParams;
95 }, context: HookContext): Promise<HookContext>;
96 get(id: Id, params: P, context: HookContext): Promise<HookContext>;
97 create(data: ServiceGenericData<S> | ServiceGenericData<S>[], params: P, context: HookContext): Promise<HookContext>;
98 update(id: NullableId, data: ServiceGenericData<S>, params: P, context: HookContext): Promise<HookContext>;
99 patch(id: NullableId, data: ServiceGenericData<S>, params: P, context: HookContext): Promise<HookContext>;
100 remove(id: NullableId, params: P, context: HookContext): Promise<HookContext>;
101}
102export type FeathersService<A = FeathersApplication, S = Service> = S & ServiceAddons<A, S> & OptionalPick<ServiceHookOverloads<S>, keyof S>;
103export type CustomMethods<T extends {
104 [key: string]: [any, any];
105}> = {
106 [K in keyof T]: (data: T[K][0], params?: Params) => Promise<T[K][1]>;
107};
108/**
109 * An interface usually use by transport clients that represents a e.g. HTTP or websocket
110 * connection that can be configured on the application.
111 */
112export type TransportConnection<Services = any> = {
113 (app: Application<Services>): void;
114 Service: any;
115 service: <L extends keyof Services & string>(name: L) => keyof any extends keyof Services ? ServiceInterface : Services[L];
116};
117/**
118 * A real-time connection object
119 */
120export interface RealTimeConnection {
121 [key: string]: any;
122}
123/**
124 * The interface for a custom service method. Can e.g. be used to type client side services.
125 */
126export type CustomMethod<T = any, R = T, P extends Params = Params> = (data: T, params?: P) => Promise<R>;
127export type ServiceMixin<A> = (service: FeathersService<A>, path: string, options: ServiceOptions) => void;
128export type ServiceGenericType<S> = S extends ServiceInterface<infer T> ? T : any;
129export type ServiceGenericData<S> = S extends ServiceInterface<infer _T, infer D> ? D : any;
130export type ServiceGenericParams<S> = S extends ServiceInterface<infer _T, infer _D, infer P> ? P : any;
131export interface FeathersApplication<Services = any, Settings = any> {
132 /**
133 * The Feathers application version
134 */
135 version: string;
136 /**
137 * A list of callbacks that run when a new service is registered
138 */
139 mixins: ServiceMixin<Application<Services, Settings>>[];
140 /**
141 * The index of all services keyed by their path.
142 *
143 * __Important:__ Services should always be retrieved via `app.service('name')`
144 * not via `app.services`.
145 */
146 services: Services;
147 /**
148 * The application settings that can be used via
149 * `app.get` and `app.set`
150 */
151 settings: Settings;
152 /**
153 * A private-ish indicator if `app.setup()` has been called already
154 */
155 _isSetup: boolean;
156 /**
157 * Retrieve an application setting by name
158 *
159 * @param name The setting name
160 */
161 get<L extends keyof Settings & string>(name: L): Settings[L];
162 /**
163 * Set an application setting
164 *
165 * @param name The setting name
166 * @param value The setting value
167 */
168 set<L extends keyof Settings & string>(name: L, value: Settings[L]): this;
169 /**
170 * Runs a callback configure function with the current application instance.
171 *
172 * @param callback The callback `(app: Application) => {}` to run
173 */
174 configure(callback: (this: this, app: this) => void): this;
175 /**
176 * Returns a fallback service instance that will be registered
177 * when no service was found. Usually throws a `NotFound` error
178 * but also used to instantiate client side services.
179 *
180 * @param location The path of the service
181 */
182 defaultService(location: string): ServiceInterface;
183 /**
184 * Register a new service or a sub-app. When passed another
185 * Feathers application, all its services will be re-registered
186 * with the `path` prefix.
187 *
188 * @param path The path for the service to register
189 * @param service The service object to register or another
190 * Feathers application to use a sub-app under the `path` prefix.
191 * @param options The options for this service
192 */
193 use<L extends keyof Services & string>(path: L, service: keyof any extends keyof Services ? ServiceInterface | Application : Services[L], options?: ServiceOptions<keyof any extends keyof Services ? string : keyof Services[L]>): this;
194 /**
195 * Unregister an existing service.
196 *
197 * @param path The name of the service to unregister
198 */
199 unuse<L extends keyof Services & string>(path: L): Promise<FeathersService<this, keyof any extends keyof Services ? Service : Services[L]>>;
200 /**
201 * Get the Feathers service instance for a path. This will
202 * be the service originally registered with Feathers functionality
203 * like hooks and events added.
204 *
205 * @param path The name of the service.
206 */
207 service<L extends keyof Services & string>(path: L): FeathersService<this, keyof any extends keyof Services ? Service : Services[L]>;
208 /**
209 * Set up the application and call all services `.setup` method if available.
210 *
211 * @param server A server instance (optional)
212 */
213 setup(server?: any): Promise<this>;
214 /**
215 * Tear down the application and call all services `.teardown` method if available.
216 *
217 * @param server A server instance (optional)
218 */
219 teardown(server?: any): Promise<this>;
220 /**
221 * Register application level hooks.
222 *
223 * @param map The application hook settings.
224 */
225 hooks(map: ApplicationHookOptions<this>): this;
226}
227export interface Application<Services = any, Settings = any> extends FeathersApplication<Services, Settings>, EventEmitter {
228}
229export type Id = number | string;
230export type NullableId = Id | null;
231export interface Query {
232 [key: string]: any;
233}
234export interface Params<Q = Query> {
235 query?: Q;
236 provider?: string;
237 route?: {
238 [key: string]: any;
239 };
240 headers?: {
241 [key: string]: any;
242 };
243}
244export interface PaginationOptions {
245 default?: number;
246 max?: number;
247}
248export type PaginationParams = false | PaginationOptions;
249export interface Http {
250 /**
251 * A writeable, optional property with status code override.
252 */
253 status?: number;
254 /**
255 * A writeable, optional property with headers.
256 */
257 headers?: {
258 [key: string]: string | string[];
259 };
260 /**
261 * A writeable, optional property with `Location` header's value.
262 */
263 location?: string;
264}
265export type HookType = 'before' | 'after' | 'error' | 'around';
266type Serv<FA> = FA extends Application<infer S> ? S : never;
267export interface HookContext<A = Application, S = any> extends BaseHookContext<ServiceGenericType<S>> {
268 /**
269 * A read only property that contains the Feathers application object. This can be used to
270 * retrieve other services (via context.app.service('name')) or configuration values.
271 */
272 readonly app: A;
273 /**
274 * A read only property with the name of the service method (one of find, get,
275 * create, update, patch, remove).
276 */
277 readonly method: string;
278 /**
279 * A read only property and contains the service name (or path) without leading or
280 * trailing slashes.
281 */
282 path: 0 extends 1 & S ? keyof Serv<A> & string : GetKeyByValue<Serv<A>, S> & string;
283 /**
284 * A read only property and contains the service this hook currently runs on.
285 */
286 readonly service: S;
287 /**
288 * A read only property with the hook type (one of 'around', 'before', 'after' or 'error').
289 */
290 readonly type: HookType;
291 /**
292 * The list of method arguments. Should not be modified, modify the
293 * `params`, `data` and `id` properties instead.
294 */
295 readonly arguments: any[];
296 /**
297 * A writeable property containing the data of a create, update and patch service
298 * method call.
299 */
300 data?: ServiceGenericData<S>;
301 /**
302 * A writeable property with the error object that was thrown in a failed method call.
303 * It is only available in error hooks.
304 */
305 error?: any;
306 /**
307 * A writeable property and the id for a get, remove, update and patch service
308 * method call. For remove, update and patch context.id can also be null when
309 * modifying multiple entries. In all other cases it will be undefined.
310 */
311 id?: Id;
312 /**
313 * A writeable property that contains the service method parameters (including
314 * params.query).
315 */
316 params: ServiceGenericParams<S>;
317 /**
318 * A writeable property containing the result of the successful service method call.
319 * It is only available in after hooks.
320 *
321 * `context.result` can also be set in
322 *
323 * - A before hook to skip the actual service method (database) call
324 * - An error hook to swallow the error and return a result instead
325 */
326 result?: ServiceGenericType<S>;
327 /**
328 * A writeable, optional property and contains a 'safe' version of the data that
329 * should be sent to any client. If context.dispatch has not been set context.result
330 * will be sent to the client instead.
331 */
332 dispatch?: ServiceGenericType<S>;
333 /**
334 * A writeable, optional property that allows to override the standard HTTP status
335 * code that should be returned.
336 *
337 * @deprecated Use `http.status` instead.
338 */
339 statusCode?: number;
340 /**
341 * A writeable, optional property with options specific to HTTP transports.
342 */
343 http?: Http;
344 /**
345 * The event emitted by this method. Can be set to `null` to skip event emitting.
346 */
347 event: string | null;
348}
349export type HookFunction<A = Application, S = Service> = (this: S, context: HookContext<A, S>) => Promise<HookContext<Application, S> | void> | HookContext<Application, S> | void;
350export type Hook<A = Application, S = Service> = HookFunction<A, S>;
351type HookMethodMap<A, S> = {
352 [L in keyof S]?: SelfOrArray<HookFunction<A, S>>;
353} & {
354 all?: SelfOrArray<HookFunction<A, S>>;
355};
356type HookTypeMap<A, S> = SelfOrArray<HookFunction<A, S>> | HookMethodMap<A, S>;
357export type AroundHookFunction<A = Application, S = Service> = (context: HookContext<A, S>, next: NextFunction) => Promise<void>;
358export type AroundHookMap<A, S> = {
359 [L in keyof S]?: AroundHookFunction<A, S>[];
360} & {
361 all?: AroundHookFunction<A, S>[];
362};
363export type HookMap<A, S> = {
364 around?: AroundHookMap<A, S>;
365 before?: HookTypeMap<A, S>;
366 after?: HookTypeMap<A, S>;
367 error?: HookTypeMap<A, S>;
368};
369export type HookOptions<A, S> = AroundHookMap<A, S> | AroundHookFunction<A, S>[] | HookMap<A, S>;
370export interface ApplicationHookContext<A = Application> extends BaseHookContext {
371 app: A;
372 server: any;
373}
374export type ApplicationHookFunction<A> = (context: ApplicationHookContext<A>, next: NextFunction) => Promise<void>;
375export type ApplicationHookMap<A> = {
376 setup?: ApplicationHookFunction<A>[];
377 teardown?: ApplicationHookFunction<A>[];
378};
379export type ApplicationHookOptions<A> = HookOptions<A, any> | ApplicationHookMap<A>;