-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathAppConfigLoader.coffee
More file actions
109 lines (90 loc) · 3.61 KB
/
AppConfigLoader.coffee
File metadata and controls
109 lines (90 loc) · 3.61 KB
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
define [
'app/application'
'cord!isBrowser'
'cord!utils/Future'
'underscore'
], (application, isBrowser, Future, _) ->
class AppConfigLoader
###
Application configuration loader
Purpose of this class is to load and merge all enabled bundles configurations, including routes and service
definitions for the service container (DI).
This is static class. Loading starts immediately after it's required anywhere. Usage:
```
require ['cord!AppConfigLoader], (AppConfigLoader) ->
AppConfigLoader.ready().done (appConfig) ->
appConfig.routes
appConfig.services
```
###
@_promise: Future.single('AppConfigLoader')
@ready: ->
###
Returns future with merged configuration which is completed asynchronously when all configs are loaded and merged
@return Future(Object)
###
@_promise
@_load: ->
application.unshift('cord/core') # core is always enabled
configs = ("cord!/#{ bundle }/config" for i, bundle of application)
require configs, (args...) ->
routes = {}
services = {}
fallbackRoutes = {}
fallbackApiErrors = {}
proxyRoutes = []
processRoutes = (source, destination, bundle) ->
for route, params of source
# expanding widget path to fully-qualified canonical name if short path is given
if params.widget and params.widget.substr(0, 2) is '//'
params.widget = "/#{ bundle }#{ params.widget }"
# eliminating duplicate routes here
# todo: may be it should be reported when there are duplicate routes?
_.extend(destination, source)
fatalErrorPageFile = undefined
for config, i in args
if config.proxyRoutes
if _.isArray(config.proxyRoutes)
proxyRoutes = proxyRoutes.concat(config.proxyRoutes)
else
proxyRoutes.push(config.proxyRoutes)
if config.fallbackRoutes?
processRoutes config.fallbackRoutes, fallbackRoutes, application[i]
if config.routes?
processRoutes config.routes, routes, application[i]
if config.services?
# flatten services configuration (excluding server-only or browser-only configuration)
srv = _.clone(config.services)
flatSrv = {}
if srv[':browser']?
_.extend(flatSrv, srv[':browser']) if isBrowser
delete srv[':browser']
if srv[':server']?
_.extend(flatSrv, srv[':server']) if not isBrowser
delete srv[':server']
_.extend(flatSrv, srv)
# normalize services configuration
for name, def of flatSrv
services[name] =
if _.isFunction(def)
deps: []
factory: def
else
deps: def.deps
factory: def.factory
autoStart: def.autoStart
if config.fallbackApiErrors?
for error, fallback of config.fallbackApiErrors
fallbackApiErrors[error] = fallback
fatalErrorPageFile = config.fatalErrorPageFile if config.fatalErrorPageFile
errorWidget = config.errorWidget if config.errorWidget
AppConfigLoader._promise.resolve
routes: routes
services: services
fallbackRoutes: fallbackRoutes
fallbackApiErrors: fallbackApiErrors
fatalErrorPageFile: fatalErrorPageFile
errorWidget: errorWidget
proxyRoutes: proxyRoutes
# start loading immediately on class loading
@_load()