UNPKG

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