@feathersjs/feathers 5.0.0-pre.6 → 5.0.0
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.
- package/CHANGELOG.md +265 -212
- package/LICENSE +1 -1
- package/{readme.md → README.md} +7 -12
- package/lib/application.d.ts +20 -15
- package/lib/application.js +83 -44
- package/lib/application.js.map +1 -1
- package/lib/declarations.d.ts +193 -78
- package/lib/events.d.ts +2 -2
- package/lib/events.js +5 -6
- package/lib/events.js.map +1 -1
- package/lib/hooks.d.ts +42 -0
- package/lib/hooks.js +176 -0
- package/lib/hooks.js.map +1 -0
- package/lib/index.d.ts +2 -2
- package/lib/index.js +8 -4
- package/lib/index.js.map +1 -1
- package/lib/service.d.ts +3 -1
- package/lib/service.js +27 -26
- package/lib/service.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/version.js.map +1 -1
- package/package.json +17 -16
- package/src/application.ts +162 -101
- package/src/declarations.ts +281 -147
- package/src/events.ts +15 -15
- package/src/hooks.ts +234 -0
- package/src/index.ts +13 -12
- package/src/service.ts +38 -50
- package/src/version.ts +1 -1
- package/lib/dependencies.d.ts +0 -4
- package/lib/dependencies.js +0 -18
- package/lib/dependencies.js.map +0 -1
- package/lib/hooks/index.d.ts +0 -14
- package/lib/hooks/index.js +0 -84
- package/lib/hooks/index.js.map +0 -1
- package/lib/hooks/legacy.d.ts +0 -7
- package/lib/hooks/legacy.js +0 -114
- package/lib/hooks/legacy.js.map +0 -1
- package/src/dependencies.ts +0 -5
- package/src/hooks/index.ts +0 -109
- package/src/hooks/legacy.ts +0 -138
package/src/application.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import version from './version'
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
} from '
|
|
5
|
-
import { eventHook, eventMixin } from './events'
|
|
6
|
-
import { hookMixin } from './hooks
|
|
7
|
-
import { wrapService, getServiceOptions, protectedMethods } from './service'
|
|
1
|
+
import version from './version'
|
|
2
|
+
import { EventEmitter } from 'events'
|
|
3
|
+
import { stripSlashes, createDebug } from '@feathersjs/commons'
|
|
4
|
+
import { HOOKS, hooks, middleware } from '@feathersjs/hooks'
|
|
5
|
+
import { eventHook, eventMixin } from './events'
|
|
6
|
+
import { hookMixin } from './hooks'
|
|
7
|
+
import { wrapService, getServiceOptions, protectedMethods } from './service'
|
|
8
8
|
import {
|
|
9
9
|
FeathersApplication,
|
|
10
10
|
ServiceMixin,
|
|
@@ -12,152 +12,213 @@ import {
|
|
|
12
12
|
ServiceOptions,
|
|
13
13
|
ServiceInterface,
|
|
14
14
|
Application,
|
|
15
|
-
HookOptions,
|
|
16
15
|
FeathersService,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
} from './
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
this.
|
|
16
|
+
ApplicationHookOptions
|
|
17
|
+
} from './declarations'
|
|
18
|
+
import { enableHooks } from './hooks'
|
|
19
|
+
|
|
20
|
+
const debug = createDebug('@feathersjs/feathers')
|
|
21
|
+
|
|
22
|
+
export class Feathers<Services, Settings>
|
|
23
|
+
extends EventEmitter
|
|
24
|
+
implements FeathersApplication<Services, Settings>
|
|
25
|
+
{
|
|
26
|
+
services: Services = {} as Services
|
|
27
|
+
settings: Settings = {} as Settings
|
|
28
|
+
mixins: ServiceMixin<Application<Services, Settings>>[] = [hookMixin, eventMixin]
|
|
29
|
+
version: string = version
|
|
30
|
+
_isSetup = false
|
|
31
|
+
|
|
32
|
+
protected registerHooks: (this: any, allHooks: any) => any
|
|
33
|
+
|
|
34
|
+
constructor() {
|
|
35
|
+
super()
|
|
36
|
+
this.registerHooks = enableHooks(this)
|
|
37
|
+
this.registerHooks({
|
|
38
|
+
around: [eventHook]
|
|
39
|
+
})
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
get<L extends keyof
|
|
42
|
-
return this.settings[name]
|
|
42
|
+
get<L extends keyof Settings & string>(name: L): Settings[L] {
|
|
43
|
+
return this.settings[name]
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
set<L extends keyof
|
|
46
|
-
this.settings[name] = value
|
|
47
|
-
return this
|
|
46
|
+
set<L extends keyof Settings & string>(name: L, value: Settings[L]) {
|
|
47
|
+
this.settings[name] = value
|
|
48
|
+
return this
|
|
48
49
|
}
|
|
49
50
|
|
|
50
|
-
configure
|
|
51
|
-
callback.call(this, this)
|
|
51
|
+
configure(callback: (this: this, app: this) => void) {
|
|
52
|
+
callback.call(this, this)
|
|
52
53
|
|
|
53
|
-
return this
|
|
54
|
+
return this
|
|
54
55
|
}
|
|
55
56
|
|
|
56
|
-
defaultService
|
|
57
|
-
throw new Error(`Can not find service '${location}'`)
|
|
57
|
+
defaultService(location: string): ServiceInterface {
|
|
58
|
+
throw new Error(`Can not find service '${location}'`)
|
|
58
59
|
}
|
|
59
60
|
|
|
60
|
-
service<L extends keyof
|
|
61
|
+
service<L extends keyof Services & string>(
|
|
61
62
|
location: L
|
|
62
|
-
): FeathersService<this, keyof any extends keyof
|
|
63
|
-
const path = (stripSlashes(location) || '/') as L
|
|
64
|
-
const current = this.services[path]
|
|
63
|
+
): FeathersService<this, keyof any extends keyof Services ? Service : Services[L]> {
|
|
64
|
+
const path = (stripSlashes(location) || '/') as L
|
|
65
|
+
const current = this.services[path]
|
|
65
66
|
|
|
66
67
|
if (typeof current === 'undefined') {
|
|
67
|
-
this.use(path, this.defaultService(path) as any)
|
|
68
|
-
return this.service(path)
|
|
68
|
+
this.use(path, this.defaultService(path) as any)
|
|
69
|
+
return this.service(path)
|
|
69
70
|
}
|
|
70
71
|
|
|
71
|
-
return current as any
|
|
72
|
+
return current as any
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
protected _setup() {
|
|
76
|
+
this._isSetup = true
|
|
77
|
+
|
|
78
|
+
return Object.keys(this.services)
|
|
79
|
+
.reduce(
|
|
80
|
+
(current, path) =>
|
|
81
|
+
current.then(() => {
|
|
82
|
+
const service: any = this.service(path as any)
|
|
83
|
+
|
|
84
|
+
if (typeof service.setup === 'function') {
|
|
85
|
+
debug(`Setting up service for \`${path}\``)
|
|
86
|
+
|
|
87
|
+
return service.setup(this, path)
|
|
88
|
+
}
|
|
89
|
+
}),
|
|
90
|
+
Promise.resolve()
|
|
91
|
+
)
|
|
92
|
+
.then(() => this)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
get setup() {
|
|
96
|
+
return this._setup
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
set setup(value) {
|
|
100
|
+
this._setup = (value as any)[HOOKS]
|
|
101
|
+
? value
|
|
102
|
+
: hooks(
|
|
103
|
+
value,
|
|
104
|
+
middleware().params('server').props({
|
|
105
|
+
app: this
|
|
106
|
+
})
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
protected _teardown() {
|
|
111
|
+
this._isSetup = false
|
|
112
|
+
|
|
113
|
+
return Object.keys(this.services)
|
|
114
|
+
.reduce(
|
|
115
|
+
(current, path) =>
|
|
116
|
+
current.then(() => {
|
|
117
|
+
const service: any = this.service(path as any)
|
|
118
|
+
|
|
119
|
+
if (typeof service.teardown === 'function') {
|
|
120
|
+
debug(`Tearing down service for \`${path}\``)
|
|
121
|
+
|
|
122
|
+
return service.teardown(this, path)
|
|
123
|
+
}
|
|
124
|
+
}),
|
|
125
|
+
Promise.resolve()
|
|
126
|
+
)
|
|
127
|
+
.then(() => this)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
get teardown() {
|
|
131
|
+
return this._teardown
|
|
72
132
|
}
|
|
73
133
|
|
|
74
|
-
|
|
134
|
+
set teardown(value) {
|
|
135
|
+
this._teardown = (value as any)[HOOKS]
|
|
136
|
+
? value
|
|
137
|
+
: hooks(
|
|
138
|
+
value,
|
|
139
|
+
middleware().params('server').props({
|
|
140
|
+
app: this
|
|
141
|
+
})
|
|
142
|
+
)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
use<L extends keyof Services & string>(
|
|
75
146
|
path: L,
|
|
76
|
-
service: keyof any extends keyof
|
|
77
|
-
options?: ServiceOptions
|
|
147
|
+
service: keyof any extends keyof Services ? ServiceInterface | Application : Services[L],
|
|
148
|
+
options?: ServiceOptions<keyof any extends keyof Services ? string : keyof Services[L]>
|
|
78
149
|
): this {
|
|
79
150
|
if (typeof path !== 'string') {
|
|
80
|
-
throw new Error(`'${path}' is not a valid service path.`)
|
|
151
|
+
throw new Error(`'${path}' is not a valid service path.`)
|
|
81
152
|
}
|
|
82
153
|
|
|
83
|
-
const location = (stripSlashes(path) || '/') as L
|
|
84
|
-
const subApp = service as Application
|
|
85
|
-
const isSubApp = typeof subApp.service === 'function' && subApp.services
|
|
154
|
+
const location = (stripSlashes(path) || '/') as L
|
|
155
|
+
const subApp = service as Application
|
|
156
|
+
const isSubApp = typeof subApp.service === 'function' && subApp.services
|
|
86
157
|
|
|
87
158
|
if (isSubApp) {
|
|
88
|
-
Object.keys(subApp.services).forEach(subPath =>
|
|
159
|
+
Object.keys(subApp.services).forEach((subPath) =>
|
|
89
160
|
this.use(`${location}/${subPath}` as any, subApp.service(subPath) as any)
|
|
90
|
-
)
|
|
161
|
+
)
|
|
91
162
|
|
|
92
|
-
return this
|
|
163
|
+
return this
|
|
93
164
|
}
|
|
94
165
|
|
|
95
|
-
const protoService = wrapService(location, service, options)
|
|
96
|
-
const serviceOptions = getServiceOptions(
|
|
166
|
+
const protoService = wrapService(location, service, options as ServiceOptions)
|
|
167
|
+
const serviceOptions = getServiceOptions(protoService)
|
|
97
168
|
|
|
98
169
|
for (const name of protectedMethods) {
|
|
99
170
|
if (serviceOptions.methods.includes(name)) {
|
|
100
|
-
throw new Error(`'${name}' on service '${location}' is not allowed as a custom method name`)
|
|
171
|
+
throw new Error(`'${name}' on service '${location}' is not allowed as a custom method name`)
|
|
101
172
|
}
|
|
102
173
|
}
|
|
103
174
|
|
|
104
|
-
debug(`Registering new service at \`${location}\``)
|
|
175
|
+
debug(`Registering new service at \`${location}\``)
|
|
105
176
|
|
|
106
177
|
// Add all the mixins
|
|
107
|
-
this.mixins.forEach(fn => fn.call(this, protoService, location, serviceOptions))
|
|
178
|
+
this.mixins.forEach((fn) => fn.call(this, protoService, location, serviceOptions))
|
|
179
|
+
|
|
180
|
+
this.services[location] = protoService
|
|
108
181
|
|
|
109
182
|
// If we ran setup already, set this service up explicitly, this will not `await`
|
|
110
183
|
if (this._isSetup && typeof protoService.setup === 'function') {
|
|
111
|
-
debug(`Setting up service for \`${location}\``)
|
|
112
|
-
protoService.setup(this, location)
|
|
184
|
+
debug(`Setting up service for \`${location}\``)
|
|
185
|
+
protoService.setup(this, location)
|
|
113
186
|
}
|
|
114
187
|
|
|
115
|
-
this
|
|
116
|
-
|
|
117
|
-
return this;
|
|
188
|
+
return this
|
|
118
189
|
}
|
|
119
190
|
|
|
120
|
-
|
|
121
|
-
|
|
191
|
+
async unuse<L extends keyof Services & string>(
|
|
192
|
+
location: L
|
|
193
|
+
): Promise<FeathersService<this, keyof any extends keyof Services ? Service : Services[L]>> {
|
|
194
|
+
const path = (stripSlashes(location) || '/') as L
|
|
195
|
+
const service = this.services[path] as Service
|
|
122
196
|
|
|
123
|
-
if (
|
|
124
|
-
|
|
197
|
+
if (service && typeof service.teardown === 'function') {
|
|
198
|
+
await service.teardown(this as any, path)
|
|
125
199
|
}
|
|
126
200
|
|
|
127
|
-
|
|
128
|
-
this.appHooks[HOOKS].push(...hookMap as any);
|
|
129
|
-
} else {
|
|
130
|
-
const methodHookMap = hookMap as HookMap<Application<ServiceTypes, AppSettings>, any>;
|
|
131
|
-
|
|
132
|
-
Object.keys(methodHookMap).forEach(key => {
|
|
133
|
-
const methodHooks = this.appHooks[key] || [];
|
|
201
|
+
delete this.services[path]
|
|
134
202
|
|
|
135
|
-
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return this;
|
|
203
|
+
return service as any
|
|
140
204
|
}
|
|
141
205
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
})
|
|
206
|
+
hooks(hookMap: ApplicationHookOptions<this>) {
|
|
207
|
+
const untypedMap = hookMap as any
|
|
208
|
+
|
|
209
|
+
if (untypedMap.before || untypedMap.after || untypedMap.error || untypedMap.around) {
|
|
210
|
+
// regular hooks for all service methods
|
|
211
|
+
this.registerHooks(untypedMap)
|
|
212
|
+
} else if (untypedMap.setup || untypedMap.teardown) {
|
|
213
|
+
// .setup and .teardown application hooks
|
|
214
|
+
hooks(this, untypedMap)
|
|
215
|
+
} else {
|
|
216
|
+
// Other registration formats are just `around` hooks
|
|
217
|
+
this.registerHooks({
|
|
218
|
+
around: untypedMap
|
|
219
|
+
})
|
|
156
220
|
}
|
|
157
221
|
|
|
158
|
-
return
|
|
159
|
-
this._isSetup = true;
|
|
160
|
-
return this;
|
|
161
|
-
});
|
|
222
|
+
return this
|
|
162
223
|
}
|
|
163
224
|
}
|