/
application.js
147 lines (112 loc) · 3.48 KB
/
application.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
const debug = require('debug')('feathers:application');
const { stripSlashes } = require('@feathersjs/commons');
const Uberproto = require('uberproto');
const events = require('./events');
const hooks = require('./hooks');
const version = require('./version');
const Proto = Uberproto.extend({
create: null
});
const application = {
init () {
Object.assign(this, {
version,
methods: [
'find', 'get', 'create', 'update', 'patch', 'remove'
],
mixins: [],
services: {},
providers: [],
_setup: false,
settings: {}
});
this.configure(hooks());
this.configure(events());
},
get (name) {
return this.settings[name];
},
set (name, value) {
this.settings[name] = value;
return this;
},
disable (name) {
this.settings[name] = false;
return this;
},
disabled (name) {
return !this.settings[name];
},
enable (name) {
this.settings[name] = true;
return this;
},
enabled (name) {
return !!this.settings[name];
},
configure (fn) {
fn.call(this, this);
return this;
},
service (path, service) {
if (typeof service !== 'undefined') {
throw new Error('Registering a new service with `app.service(path, service)` is no longer supported. Use `app.use(path, service)` instead.');
}
const location = stripSlashes(path);
const current = this.services[location];
if (typeof current === 'undefined' && typeof this.defaultService === 'function') {
return this.use(`/${location}`, this.defaultService(location))
.service(location);
}
return current;
},
use (path, service, options = {}) {
const location = stripSlashes(path);
const isSubApp = typeof service.service === 'function' && service.services;
const isService = this.methods.concat('setup').some(name =>
(service && typeof service[name] === 'function')
);
if (isSubApp) {
const subApp = service;
Object.keys(subApp.services).forEach(subPath =>
this.use(`${location}/${subPath}`, subApp.service(subPath))
);
return this;
}
if (!isService) {
throw new Error(`Invalid service object passed for path \`${location}\``);
}
// If the service is already Uberproto'd use it directly
const protoService = Proto.isPrototypeOf(service) ? service : Proto.extend(service);
debug(`Registering new service at \`${location}\``);
// Add all the mixins
this.mixins.forEach(fn => fn.call(this, protoService, location, options));
if (typeof protoService._setup === 'function') {
protoService._setup(this, location);
}
// Run the provider functions to register the service
this.providers.forEach(provider =>
provider.call(this, protoService, location, options)
);
// If we ran setup already, set this service up explicitly
if (this._isSetup && typeof protoService.setup === 'function') {
debug(`Setting up service for \`${location}\``);
protoService.setup(this, location);
}
this.services[location] = protoService;
return this;
},
setup () {
// Setup each service (pass the app so that they can look up other services etc.)
Object.keys(this.services).forEach(path => {
const service = this.services[path];
debug(`Setting up service for \`${path}\``);
if (typeof service.setup === 'function') {
service.setup(this, path);
}
});
this._isSetup = true;
return this;
}
};
module.exports = application;