@feathersjs/feathers 5.0.0-pre.1 → 5.0.0-pre.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +182 -0
  2. package/LICENSE +1 -1
  3. package/lib/application.d.ts +19 -8
  4. package/lib/application.js +80 -78
  5. package/lib/application.js.map +1 -1
  6. package/lib/declarations.d.ts +207 -106
  7. package/lib/dependencies.d.ts +4 -0
  8. package/lib/dependencies.js +18 -0
  9. package/lib/dependencies.js.map +1 -0
  10. package/lib/events.d.ts +4 -4
  11. package/lib/events.js +16 -69
  12. package/lib/events.js.map +1 -1
  13. package/lib/hooks/index.d.ts +13 -2
  14. package/lib/hooks/index.js +84 -146
  15. package/lib/hooks/index.js.map +1 -1
  16. package/lib/hooks/regular.d.ts +12 -0
  17. package/lib/hooks/regular.js +169 -0
  18. package/lib/hooks/regular.js.map +1 -0
  19. package/lib/index.d.ts +9 -4
  20. package/lib/index.js +9 -12
  21. package/lib/index.js.map +1 -1
  22. package/lib/service.d.ts +21 -0
  23. package/lib/service.js +68 -0
  24. package/lib/service.js.map +1 -0
  25. package/lib/version.d.ts +1 -1
  26. package/lib/version.js +1 -1
  27. package/lib/version.js.map +1 -1
  28. package/package.json +12 -13
  29. package/readme.md +1 -77
  30. package/src/application.ts +115 -105
  31. package/src/declarations.ts +274 -121
  32. package/src/dependencies.ts +5 -0
  33. package/src/events.ts +18 -75
  34. package/src/hooks/index.ts +95 -150
  35. package/src/hooks/regular.ts +207 -0
  36. package/src/index.ts +10 -17
  37. package/src/service.ts +91 -0
  38. package/src/version.ts +1 -1
  39. package/lib/hooks/base.d.ts +0 -3
  40. package/lib/hooks/base.js +0 -29
  41. package/lib/hooks/base.js.map +0 -1
  42. package/lib/hooks/commons.d.ts +0 -20
  43. package/lib/hooks/commons.js +0 -298
  44. package/lib/hooks/commons.js.map +0 -1
  45. package/src/hooks/base.ts +0 -32
  46. package/src/hooks/commons.ts +0 -336
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":";;AAAA,kBAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":";;AAAA,kBAAe,cAAc,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@feathersjs/feathers",
3
3
  "description": "A framework for real-time applications and REST API with JavaScript and TypeScript",
4
- "version": "5.0.0-pre.1",
4
+ "version": "5.0.0-pre.15",
5
5
  "homepage": "http://feathersjs.com",
6
6
  "repository": {
7
7
  "type": "git",
@@ -47,7 +47,8 @@
47
47
  "version": "npm run write-version",
48
48
  "publish": "npm run reset-version",
49
49
  "compile": "shx rm -rf lib/ && tsc",
50
- "test": "npm run compile && mocha --config ../../.mocharc.json --recursive test/**.test.ts test/**/*.test.ts"
50
+ "test": "npm run compile && npm run mocha",
51
+ "mocha": "mocha --config ../../.mocharc.json --recursive test/"
51
52
  },
52
53
  "engines": {
53
54
  "node": ">= 12"
@@ -56,19 +57,17 @@
56
57
  "access": "public"
57
58
  },
58
59
  "dependencies": {
59
- "@feathersjs/commons": "^5.0.0-pre.1",
60
- "@feathersjs/hooks": "^0.6.1",
61
- "debug": "^4.3.1",
62
- "events": "^3.2.0",
63
- "uberproto": "^2.0.6"
60
+ "@feathersjs/commons": "^5.0.0-pre.15",
61
+ "@feathersjs/hooks": "^0.6.5",
62
+ "events": "^3.3.0"
64
63
  },
65
64
  "devDependencies": {
66
- "@types/mocha": "^8.0.4",
67
- "@types/node": "^14.14.10",
68
- "mocha": "^8.2.1",
65
+ "@types/mocha": "^9.0.0",
66
+ "@types/node": "^16.11.6",
67
+ "mocha": "^9.1.3",
69
68
  "shx": "^0.3.3",
70
- "ts-node": "^9.1.0",
71
- "typescript": "^4.1.2"
69
+ "ts-node": "^10.4.0",
70
+ "typescript": "^4.4.4"
72
71
  },
73
- "gitHead": "3756506935c520fc50d4be416ff649c2158afdac"
72
+ "gitHead": "8008bf4f8529a2a40b6a2f976c1f43ae13675693"
74
73
  }
package/readme.md CHANGED
@@ -2,15 +2,11 @@
2
2
 
3
3
  ## A framework for real-time applications and REST APIs with JavaScript and TypeScript
4
4
 
5
- [![Greenkeeper badge](https://badges.greenkeeper.io/feathersjs/feathers.svg)](https://greenkeeper.io/)
6
5
  [![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI)
7
6
  [![Maintainability](https://api.codeclimate.com/v1/badges/cb5ec42a2d0cc1a47a02/maintainability)](https://codeclimate.com/github/feathersjs/feathers/maintainability)
8
7
  [![Test Coverage](https://api.codeclimate.com/v1/badges/cb5ec42a2d0cc1a47a02/test_coverage)](https://codeclimate.com/github/feathersjs/feathers/test_coverage)
9
8
  [![Download Status](https://img.shields.io/npm/dm/@feathersjs/feathers.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/feathers)
10
9
 
11
- [![Slack Status](http://slack.feathersjs.com/badge.svg)](http://slack.feathersjs.com)
12
- [![Telegram Status](https://img.shields.io/badge/Telegram_RU_chat:-Feathers-216bc1.svg?style=flat)](https://t.me/featherjs)
13
-
14
10
  Feathers is a lightweight web-framework for creating real-time applications and REST APIs using JavaScript or TypeScript.
15
11
 
16
12
  Feathers can interact with any backend technology, supports over a dozen databases and works with any frontend technology like React, VueJS, Angular, React Native, Android or iOS.
@@ -29,84 +25,12 @@ $ npm start
29
25
 
30
26
  To learn more about Feathers visit the website at [feathersjs.com](http://feathersjs.com) or jump right into [the Feathers guides](http://docs.feathersjs.com/guides).
31
27
 
32
- ## Support
33
-
34
- ### Sponsors
35
-
36
- Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/feathers#sponsor)]
37
-
38
- <a href="https://opencollective.com/feathers/sponsor/0/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/0/avatar.svg"></a>
39
- <a href="https://opencollective.com/feathers/sponsor/1/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/1/avatar.svg"></a>
40
- <a href="https://opencollective.com/feathers/sponsor/2/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/2/avatar.svg"></a>
41
- <a href="https://opencollective.com/feathers/sponsor/3/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/3/avatar.svg"></a>
42
- <a href="https://opencollective.com/feathers/sponsor/4/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/4/avatar.svg"></a>
43
- <a href="https://opencollective.com/feathers/sponsor/5/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/5/avatar.svg"></a>
44
- <a href="https://opencollective.com/feathers/sponsor/6/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/6/avatar.svg"></a>
45
- <a href="https://opencollective.com/feathers/sponsor/7/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/7/avatar.svg"></a>
46
- <a href="https://opencollective.com/feathers/sponsor/8/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/8/avatar.svg"></a>
47
- <a href="https://opencollective.com/feathers/sponsor/9/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/9/avatar.svg"></a>
48
- <a href="https://opencollective.com/feathers/sponsor/10/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/10/avatar.svg"></a>
49
- <a href="https://opencollective.com/feathers/sponsor/11/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/11/avatar.svg"></a>
50
- <a href="https://opencollective.com/feathers/sponsor/12/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/12/avatar.svg"></a>
51
- <a href="https://opencollective.com/feathers/sponsor/13/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/13/avatar.svg"></a>
52
- <a href="https://opencollective.com/feathers/sponsor/14/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/14/avatar.svg"></a>
53
- <a href="https://opencollective.com/feathers/sponsor/15/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/15/avatar.svg"></a>
54
- <a href="https://opencollective.com/feathers/sponsor/16/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/16/avatar.svg"></a>
55
- <a href="https://opencollective.com/feathers/sponsor/17/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/17/avatar.svg"></a>
56
- <a href="https://opencollective.com/feathers/sponsor/18/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/18/avatar.svg"></a>
57
- <a href="https://opencollective.com/feathers/sponsor/19/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/19/avatar.svg"></a>
58
- <a href="https://opencollective.com/feathers/sponsor/20/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/20/avatar.svg"></a>
59
- <a href="https://opencollective.com/feathers/sponsor/21/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/21/avatar.svg"></a>
60
- <a href="https://opencollective.com/feathers/sponsor/22/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/22/avatar.svg"></a>
61
- <a href="https://opencollective.com/feathers/sponsor/23/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/23/avatar.svg"></a>
62
- <a href="https://opencollective.com/feathers/sponsor/24/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/24/avatar.svg"></a>
63
- <a href="https://opencollective.com/feathers/sponsor/25/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/25/avatar.svg"></a>
64
- <a href="https://opencollective.com/feathers/sponsor/26/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/26/avatar.svg"></a>
65
- <a href="https://opencollective.com/feathers/sponsor/27/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/27/avatar.svg"></a>
66
- <a href="https://opencollective.com/feathers/sponsor/28/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/28/avatar.svg"></a>
67
- <a href="https://opencollective.com/feathers/sponsor/29/website" target="_blank"><img src="https://opencollective.com/feathers/sponsor/29/avatar.svg"></a>
68
-
69
- ### Backers
70
-
71
- Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/feathers#backer)]
72
-
73
- <a href="https://opencollective.com/feathers/backer/0/website" target="_blank"><img src="https://opencollective.com/feathers/backer/0/avatar.svg"></a>
74
- <a href="https://opencollective.com/feathers/backer/1/website" target="_blank"><img src="https://opencollective.com/feathers/backer/1/avatar.svg"></a>
75
- <a href="https://opencollective.com/feathers/backer/2/website" target="_blank"><img src="https://opencollective.com/feathers/backer/2/avatar.svg"></a>
76
- <a href="https://opencollective.com/feathers/backer/3/website" target="_blank"><img src="https://opencollective.com/feathers/backer/3/avatar.svg"></a>
77
- <a href="https://opencollective.com/feathers/backer/4/website" target="_blank"><img src="https://opencollective.com/feathers/backer/4/avatar.svg"></a>
78
- <a href="https://opencollective.com/feathers/backer/5/website" target="_blank"><img src="https://opencollective.com/feathers/backer/5/avatar.svg"></a>
79
- <a href="https://opencollective.com/feathers/backer/6/website" target="_blank"><img src="https://opencollective.com/feathers/backer/6/avatar.svg"></a>
80
- <a href="https://opencollective.com/feathers/backer/7/website" target="_blank"><img src="https://opencollective.com/feathers/backer/7/avatar.svg"></a>
81
- <a href="https://opencollective.com/feathers/backer/8/website" target="_blank"><img src="https://opencollective.com/feathers/backer/8/avatar.svg"></a>
82
- <a href="https://opencollective.com/feathers/backer/9/website" target="_blank"><img src="https://opencollective.com/feathers/backer/9/avatar.svg"></a>
83
- <a href="https://opencollective.com/feathers/backer/10/website" target="_blank"><img src="https://opencollective.com/feathers/backer/10/avatar.svg"></a>
84
- <a href="https://opencollective.com/feathers/backer/11/website" target="_blank"><img src="https://opencollective.com/feathers/backer/11/avatar.svg"></a>
85
- <a href="https://opencollective.com/feathers/backer/12/website" target="_blank"><img src="https://opencollective.com/feathers/backer/12/avatar.svg"></a>
86
- <a href="https://opencollective.com/feathers/backer/13/website" target="_blank"><img src="https://opencollective.com/feathers/backer/13/avatar.svg"></a>
87
- <a href="https://opencollective.com/feathers/backer/14/website" target="_blank"><img src="https://opencollective.com/feathers/backer/14/avatar.svg"></a>
88
- <a href="https://opencollective.com/feathers/backer/15/website" target="_blank"><img src="https://opencollective.com/feathers/backer/15/avatar.svg"></a>
89
- <a href="https://opencollective.com/feathers/backer/16/website" target="_blank"><img src="https://opencollective.com/feathers/backer/16/avatar.svg"></a>
90
- <a href="https://opencollective.com/feathers/backer/17/website" target="_blank"><img src="https://opencollective.com/feathers/backer/17/avatar.svg"></a>
91
- <a href="https://opencollective.com/feathers/backer/18/website" target="_blank"><img src="https://opencollective.com/feathers/backer/18/avatar.svg"></a>
92
- <a href="https://opencollective.com/feathers/backer/19/website" target="_blank"><img src="https://opencollective.com/feathers/backer/19/avatar.svg"></a>
93
- <a href="https://opencollective.com/feathers/backer/20/website" target="_blank"><img src="https://opencollective.com/feathers/backer/20/avatar.svg"></a>
94
- <a href="https://opencollective.com/feathers/backer/21/website" target="_blank"><img src="https://opencollective.com/feathers/backer/21/avatar.svg"></a>
95
- <a href="https://opencollective.com/feathers/backer/22/website" target="_blank"><img src="https://opencollective.com/feathers/backer/22/avatar.svg"></a>
96
- <a href="https://opencollective.com/feathers/backer/23/website" target="_blank"><img src="https://opencollective.com/feathers/backer/23/avatar.svg"></a>
97
- <a href="https://opencollective.com/feathers/backer/24/website" target="_blank"><img src="https://opencollective.com/feathers/backer/24/avatar.svg"></a>
98
- <a href="https://opencollective.com/feathers/backer/25/website" target="_blank"><img src="https://opencollective.com/feathers/backer/25/avatar.svg"></a>
99
- <a href="https://opencollective.com/feathers/backer/26/website" target="_blank"><img src="https://opencollective.com/feathers/backer/26/avatar.svg"></a>
100
- <a href="https://opencollective.com/feathers/backer/27/website" target="_blank"><img src="https://opencollective.com/feathers/backer/27/avatar.svg"></a>
101
- <a href="https://opencollective.com/feathers/backer/28/website" target="_blank"><img src="https://opencollective.com/feathers/backer/28/avatar.svg"></a>
102
- <a href="https://opencollective.com/feathers/backer/29/website" target="_blank"><img src="https://opencollective.com/feathers/backer/29/avatar.svg"></a>
103
-
104
28
  ## Documentation
105
29
 
106
30
  The [Feathers docs](http://docs.feathersjs.com) are loaded with awesome stuff and tell you every thing you need to know about using and configuring Feathers.
107
31
 
108
32
  ## License
109
33
 
110
- Copyright (c) 2019 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors)
34
+ Copyright (c) 2021 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors)
111
35
 
112
36
  Licensed under the [MIT license](LICENSE).
@@ -1,129 +1,112 @@
1
- import Debug from 'debug';
2
- import { stripSlashes } from '@feathersjs/commons';
3
-
4
- // @ts-ignore
5
- import Uberproto from 'uberproto';
6
- import events from './events';
7
- import hooks from './hooks';
8
1
  import version from './version';
9
- import { BaseApplication, Service } from './declarations';
10
-
11
- const debug = Debug('feathers:application');
12
-
13
- const Proto = Uberproto.extend({
14
- create: null
15
- });
16
-
17
- interface AppExtensions {
18
- _isSetup: boolean;
19
- init (): void;
20
- services: { [key: string]: Service<any> };
21
- }
22
-
23
- export default {
24
- init () {
25
- Object.assign(this, {
26
- version,
27
- methods: [
28
- 'find', 'get', 'create', 'update', 'patch', 'remove'
29
- ],
30
- mixins: [],
31
- services: {},
32
- providers: [],
33
- _setup: false,
34
- settings: {}
35
- });
36
-
37
- this.configure(hooks());
38
- this.configure(events());
39
- },
2
+ import {
3
+ EventEmitter, stripSlashes, createDebug, HOOKS
4
+ } from './dependencies';
5
+ import { eventHook, eventMixin } from './events';
6
+ import { hookMixin } from './hooks/index';
7
+ import { wrapService, getServiceOptions, protectedMethods } from './service';
8
+ import {
9
+ FeathersApplication,
10
+ ServiceMixin,
11
+ Service,
12
+ ServiceOptions,
13
+ ServiceInterface,
14
+ Application,
15
+ HookOptions,
16
+ FeathersService,
17
+ HookMap,
18
+ RegularHookMap
19
+ } from './declarations';
20
+ import { enableRegularHooks } from './hooks/regular';
21
+
22
+ const debug = createDebug('@feathersjs/feathers');
23
+
24
+ export class Feathers<Services, Settings> extends EventEmitter implements FeathersApplication<Services, Settings> {
25
+ services: Services = ({} as Services);
26
+ settings: Settings = ({} as Settings);
27
+ mixins: ServiceMixin<Application<Services, Settings>>[] = [ hookMixin, eventMixin ];
28
+ version: string = version;
29
+ _isSetup = false;
30
+ appHooks: HookMap<Application<Services, Settings>, any> = {
31
+ [HOOKS]: [ (eventHook as any) ]
32
+ };
33
+
34
+ private regularHooks: (this: any, allHooks: any) => any;
35
+
36
+ constructor () {
37
+ super();
38
+ this.regularHooks = enableRegularHooks(this);
39
+ }
40
40
 
41
- get (name) {
41
+ get<L extends keyof Settings & string> (name: L): Settings[L] {
42
42
  return this.settings[name];
43
- },
43
+ }
44
44
 
45
- set (name, value) {
45
+ set<L extends keyof Settings & string> (name: L, value: Settings[L]) {
46
46
  this.settings[name] = value;
47
47
  return this;
48
- },
49
-
50
- disable (name) {
51
- this.settings[name] = false;
52
- return this;
53
- },
48
+ }
54
49
 
55
- disabled (name) {
56
- return !this.settings[name];
57
- },
50
+ configure (callback: (this: this, app: this) => void) {
51
+ callback.call(this, this);
58
52
 
59
- enable (name) {
60
- this.settings[name] = true;
61
53
  return this;
62
- },
63
-
64
- enabled (name) {
65
- return !!this.settings[name];
66
- },
67
-
68
- configure (fn) {
69
- fn.call(this, this);
54
+ }
70
55
 
71
- return this;
72
- },
56
+ defaultService (location: string): ServiceInterface {
57
+ throw new Error(`Can not find service '${location}'`);
58
+ }
73
59
 
74
- service (path: string) {
75
- const location = stripSlashes(path) || '/';
76
- const current = this.services[location];
60
+ service<L extends keyof Services & string> (
61
+ location: L
62
+ ): FeathersService<this, keyof any extends keyof Services ? Service : Services[L]> {
63
+ const path = (stripSlashes(location) || '/') as L;
64
+ const current = this.services[path];
77
65
 
78
- if (typeof current === 'undefined' && typeof this.defaultService === 'function') {
79
- return this.use(location, this.defaultService(location))
80
- .service(location);
66
+ if (typeof current === 'undefined') {
67
+ this.use(path, this.defaultService(path) as any);
68
+ return this.service(path);
81
69
  }
82
70
 
83
- return current;
84
- },
71
+ return current as any;
72
+ }
85
73
 
86
- use (path, service, options: any = {}) {
74
+ use<L extends keyof Services & string> (
75
+ path: L,
76
+ service: keyof any extends keyof Services ? ServiceInterface | Application : Services[L],
77
+ options?: ServiceOptions
78
+ ): this {
87
79
  if (typeof path !== 'string') {
88
80
  throw new Error(`'${path}' is not a valid service path.`);
89
81
  }
90
82
 
91
- const location = stripSlashes(path) || '/';
92
- const isSubApp = typeof service.service === 'function' && service.services;
93
- const isService = this.methods.concat('setup').some(name => typeof (service as any)[name] === 'function');
83
+ const location = (stripSlashes(path) || '/') as L;
84
+ const subApp = service as Application;
85
+ const isSubApp = typeof subApp.service === 'function' && subApp.services;
94
86
 
95
87
  if (isSubApp) {
96
- const subApp = service;
97
-
98
88
  Object.keys(subApp.services).forEach(subPath =>
99
- this.use(`${location}/${subPath}`, subApp.service(subPath))
89
+ this.use(`${location}/${subPath}` as any, subApp.service(subPath) as any)
100
90
  );
101
91
 
102
92
  return this;
103
93
  }
104
94
 
105
- if (!isService) {
106
- throw new Error(`Invalid service object passed for path \`${location}\``);
107
- }
95
+ const protoService = wrapService(location, service, options);
96
+ const serviceOptions = getServiceOptions(service, options);
108
97
 
109
- // If the service is already Uberproto'd use it directly
110
- const protoService = Proto.isPrototypeOf(service) ? service : Proto.extend(service);
98
+ for (const name of protectedMethods) {
99
+ if (serviceOptions.methods.includes(name)) {
100
+ throw new Error(`'${name}' on service '${location}' is not allowed as a custom method name`);
101
+ }
102
+ }
111
103
 
112
104
  debug(`Registering new service at \`${location}\``);
113
105
 
114
106
  // Add all the mixins
115
- this.mixins.forEach(fn => fn.call(this, protoService, location, options));
107
+ this.mixins.forEach(fn => fn.call(this, protoService, location, serviceOptions));
116
108
 
117
- if (typeof protoService._setup === 'function') {
118
- protoService._setup(this, location);
119
- }
120
-
121
- // Run the provider functions to register the service
122
- this.providers.forEach(provider =>
123
- provider.call(this, protoService, location, options)
124
- );
125
-
126
- // If we ran setup already, set this service up explicitly
109
+ // If we ran setup already, set this service up explicitly, this will not `await`
127
110
  if (this._isSetup && typeof protoService.setup === 'function') {
128
111
  debug(`Setting up service for \`${location}\``);
129
112
  protoService.setup(this, location);
@@ -132,22 +115,49 @@ export default {
132
115
  this.services[location] = protoService;
133
116
 
134
117
  return this;
135
- },
118
+ }
136
119
 
137
- setup () {
138
- // Setup each service (pass the app so that they can look up other services etc.)
139
- Object.keys(this.services).forEach(path => {
140
- const service = this.services[path];
120
+ hooks (hookMap: HookOptions<this, any>) {
121
+ const regularMap = hookMap as RegularHookMap<this, any>;
141
122
 
142
- debug(`Setting up service for \`${path}\``);
123
+ if (regularMap.before || regularMap.after || regularMap.error) {
124
+ return this.regularHooks(regularMap);
125
+ }
143
126
 
144
- if (typeof service.setup === 'function') {
145
- service.setup(this, path);
146
- }
147
- });
127
+ if (Array.isArray(hookMap)) {
128
+ this.appHooks[HOOKS].push(...hookMap as any);
129
+ } else {
130
+ const methodHookMap = hookMap as HookMap<Application<Services, Settings>, any>;
148
131
 
149
- this._isSetup = true;
132
+ Object.keys(methodHookMap).forEach(key => {
133
+ const methodHooks = this.appHooks[key] || [];
134
+
135
+ this.appHooks[key] = methodHooks.concat(methodHookMap[key]);
136
+ });
137
+ }
150
138
 
151
139
  return this;
152
140
  }
153
- } as BaseApplication & AppExtensions;
141
+
142
+ setup () {
143
+ let promise = Promise.resolve();
144
+
145
+ // Setup each service (pass the app so that they can look up other services etc.)
146
+ for (const path of Object.keys(this.services)) {
147
+ promise = promise.then(() => {
148
+ const service: any = this.service(path as any);
149
+
150
+ if (typeof service.setup === 'function') {
151
+ debug(`Setting up service for \`${path}\``);
152
+
153
+ return service.setup(this, path);
154
+ }
155
+ });
156
+ }
157
+
158
+ return promise.then(() => {
159
+ this._isSetup = true;
160
+ return this;
161
+ });
162
+ }
163
+ }