alchemymvc 1.3.21 → 1.4.0-alpha.1
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/LICENSE +1 -1
- package/README.md +3 -3
- package/lib/app/behaviour/publishable_behaviour.js +5 -5
- package/lib/app/behaviour/revision_behaviour.js +10 -10
- package/lib/app/behaviour/sluggable_behaviour.js +14 -14
- package/lib/app/conduit/electron_conduit.js +9 -9
- package/lib/app/conduit/http_conduit.js +13 -13
- package/lib/app/conduit/loopback_conduit.js +15 -15
- package/lib/app/conduit/socket_conduit.js +43 -43
- package/lib/app/config/routes.js +26 -0
- package/lib/app/controller/00-default_app_controller.js +21 -0
- package/lib/app/controller/alchemy_info_controller.js +12 -12
- package/lib/app/datasource/mongo_datasource.js +16 -16
- package/lib/app/element/00-default_app_element.js +19 -0
- package/lib/app/element/time_ago.js +5 -5
- package/lib/app/helper/00-default_app_helper.js +11 -0
- package/lib/app/helper/alchemy_helper.js +22 -22
- package/lib/app/helper/backed_map.js +1 -1
- package/lib/app/helper/breadcrumb.js +10 -10
- package/lib/app/helper/client_collection.js +3 -3
- package/lib/app/helper/cron.js +29 -29
- package/lib/app/helper/enum_values.js +6 -6
- package/lib/app/helper/pagination_helper.js +36 -36
- package/lib/app/helper/router_helper.js +35 -35
- package/lib/app/helper/socket_helper.js +57 -57
- package/lib/app/helper/syncable.js +84 -59
- package/lib/app/helper_component/paginate_component.js +9 -9
- package/lib/app/helper_controller/component.js +1 -1
- package/lib/app/helper_controller/conduit.js +31 -31
- package/lib/app/helper_controller/controller.js +54 -39
- package/lib/app/helper_datasource/00-nosql_datasource.js +624 -70
- package/lib/app/helper_datasource/05-fallback_datasource.js +10 -10
- package/lib/app/helper_datasource/idb_datasource.js +6 -6
- package/lib/app/helper_datasource/indexed_db.js +22 -22
- package/lib/app/helper_datasource/remote_datasource.js +5 -5
- package/lib/app/helper_error/http_error.js +4 -4
- package/lib/app/helper_error/model_error.js +2 -2
- package/lib/app/helper_error/validation_error.js +12 -12
- package/lib/app/helper_field/00-objectid_field.js +7 -7
- package/lib/app/helper_field/05-string_field.js +16 -12
- package/lib/app/helper_field/06-text_field.js +2 -4
- package/lib/app/helper_field/10-number_field.js +9 -12
- package/lib/app/helper_field/11-date_field.js +15 -15
- package/lib/app/helper_field/15-local_temporal_field.js +10 -10
- package/lib/app/helper_field/20-decimal_field.js +8 -9
- package/lib/app/helper_field/belongsto_field.js +1 -1
- package/lib/app/helper_field/big_int_field.js +8 -8
- package/lib/app/helper_field/boolean_field.js +9 -11
- package/lib/app/helper_field/datetime_field.js +3 -3
- package/lib/app/helper_field/enum_field.js +13 -8
- package/lib/app/helper_field/fixed_decimal_field.js +6 -7
- package/lib/app/helper_field/geopoint_field.js +9 -10
- package/lib/app/helper_field/habtm_field.js +3 -3
- package/lib/app/helper_field/hasoneparent_field.js +1 -1
- package/lib/app/helper_field/html_field.js +2 -4
- package/lib/app/helper_field/integer_field.js +8 -11
- package/lib/app/helper_field/local_date_field.js +5 -5
- package/lib/app/helper_field/local_date_time_field.js +5 -5
- package/lib/app/helper_field/local_time_field.js +5 -5
- package/lib/app/helper_field/mixed_field.js +5 -5
- package/lib/app/helper_field/object_field.js +8 -8
- package/lib/app/helper_field/password_field.js +3 -3
- package/lib/app/helper_field/regexp_field.js +7 -9
- package/lib/app/helper_field/schema_field.js +91 -88
- package/lib/app/helper_field/settings_field.js +92 -0
- package/lib/app/helper_field/time_field.js +6 -6
- package/lib/app/helper_field/url_field.js +2 -4
- package/lib/app/helper_model/00-base_criteria.js +662 -0
- package/lib/app/helper_model/05-criteria_expressions.js +605 -0
- package/lib/app/helper_model/10-model_criteria.js +1182 -0
- package/lib/app/helper_model/data_provider.js +2 -2
- package/lib/app/helper_model/document.js +103 -92
- package/lib/app/helper_model/document_list.js +14 -14
- package/lib/app/helper_model/field_config.js +11 -11
- package/lib/app/helper_model/field_set.js +17 -17
- package/lib/app/helper_model/model.js +203 -124
- package/lib/app/helper_model/remote_data_provider.js +2 -2
- package/lib/app/helper_validator/00_validator.js +16 -16
- package/lib/app/helper_validator/not_empty_validator.js +9 -9
- package/lib/app/model/00-default_app_model.js +18 -0
- package/lib/app/model/05-system_model.js +27 -0
- package/lib/app/model/{alchemy_migration_model.js → system_migration_model.js} +4 -4
- package/lib/app/model/system_setting_model.js +154 -0
- package/lib/app/model/{alchemy_task_history_model.js → system_task_history_model.js} +7 -7
- package/lib/app/model/{alchemy_task_model.js → system_task_model.js} +11 -11
- package/lib/bootstrap.js +22 -312
- package/lib/class/accumulator.js +5 -5
- package/lib/class/behaviour.js +5 -5
- package/lib/class/component.js +3 -3
- package/lib/class/conduit.js +203 -163
- package/lib/class/controller.js +42 -42
- package/lib/class/datasource.js +74 -79
- package/lib/class/document.js +74 -95
- package/lib/class/document_list.js +5 -5
- package/lib/class/element.js +17 -17
- package/lib/class/error.js +3 -3
- package/lib/class/field.js +169 -91
- package/lib/class/field_value.js +6 -6
- package/lib/class/helper.js +3 -3
- package/lib/class/inode.js +17 -17
- package/lib/class/inode_dir.js +12 -12
- package/lib/class/inode_file.js +50 -25
- package/lib/class/inode_list.js +4 -4
- package/lib/class/migration.js +4 -4
- package/lib/class/model.js +182 -168
- package/lib/class/path_definition.js +22 -22
- package/lib/class/path_evaluator.js +5 -5
- package/lib/class/path_param_definition.js +7 -7
- package/lib/class/plugin.js +312 -0
- package/lib/class/postponement.js +29 -29
- package/lib/class/reciprocal.js +8 -8
- package/lib/class/route.js +33 -33
- package/lib/class/router.js +73 -73
- package/lib/class/schema.js +21 -21
- package/lib/class/schema_client.js +73 -67
- package/lib/class/session.js +63 -29
- package/lib/class/session_scene.js +4 -4
- package/lib/class/sitemap.js +16 -16
- package/lib/class/task.js +39 -39
- package/lib/class/task_service.js +43 -47
- package/lib/{init → core}/alchemy.js +413 -374
- package/lib/{init/functions.js → core/alchemy_functions.js} +171 -108
- package/lib/core/alchemy_load_functions.js +715 -0
- package/lib/core/base.js +50 -62
- package/lib/core/client_alchemy.js +144 -152
- package/lib/core/client_base.js +39 -52
- package/lib/core/discovery.js +16 -18
- package/lib/core/middleware.js +54 -43
- package/lib/core/{routing.js → prefix.js} +14 -16
- package/lib/core/setting.js +1684 -0
- package/lib/core/stage.js +758 -0
- package/lib/scripts/create_constants.js +119 -0
- package/lib/{init/languages.js → scripts/create_languages.js} +5 -5
- package/lib/scripts/create_settings.js +449 -0
- package/lib/scripts/create_shared_constants.js +95 -0
- package/lib/scripts/create_stages.js +55 -0
- package/lib/scripts/init_alchemy.js +51 -0
- package/lib/{init/requirements.js → scripts/preload_modules.js} +15 -2
- package/lib/scripts/setup_devwatch.js +238 -0
- package/lib/stages/00-load_core.js +342 -0
- package/lib/stages/05-load_app.js +57 -0
- package/lib/stages/10-datasource.js +61 -0
- package/lib/stages/15-tasks.js +27 -0
- package/lib/stages/20-settings.js +68 -0
- package/lib/stages/50-routes.js +218 -0
- package/lib/stages/90-server.js +347 -0
- package/package.json +5 -7
- package/lib/app/helper_model/criteria.js +0 -2294
- package/lib/app/helper_model/db_query.js +0 -1488
- package/lib/app/routes.js +0 -11
- package/lib/core/socket.js +0 -171
- package/lib/init/constants.js +0 -158
- package/lib/init/devwatch.js +0 -238
- package/lib/init/load_functions.js +0 -973
- package/lib/stages.js +0 -513
package/lib/stages.js
DELETED
|
@@ -1,513 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This file is loaded after the main 'init' & 'core' folder files.
|
|
3
|
-
* Its main purpose is to launch the server in several stages and
|
|
4
|
-
* allow the app-specific logic to hook into them.
|
|
5
|
-
*
|
|
6
|
-
* Alchemy: Node.js MVC Framework
|
|
7
|
-
* Copyright 2013-2018
|
|
8
|
-
*
|
|
9
|
-
* Licensed under The MIT License
|
|
10
|
-
* Redistributions of files must retain the above copyright notice.
|
|
11
|
-
*
|
|
12
|
-
* @copyright Copyright 2013-2018
|
|
13
|
-
* @since 0.0.1
|
|
14
|
-
* @version 1.1.0
|
|
15
|
-
*/
|
|
16
|
-
let path = alchemy.modules.path,
|
|
17
|
-
settings = alchemy.settings,
|
|
18
|
-
http = alchemy.modules.http,
|
|
19
|
-
hawkejs = alchemy.hawkejs,
|
|
20
|
-
fs = alchemy.use('fs'),
|
|
21
|
-
total_http_requests = 0;
|
|
22
|
-
|
|
23
|
-
if (alchemy.settings.debug) {
|
|
24
|
-
alchemy.sputnik.on('launching', function onLaunch(stage) {
|
|
25
|
-
|
|
26
|
-
let colored_name = alchemy.colors.fg.getRgb(0, 5, 5) + stage.name + alchemy.colors.reset;
|
|
27
|
-
|
|
28
|
-
let args = ['Launching', colored_name, 'stage…'];
|
|
29
|
-
|
|
30
|
-
let line = alchemy.printLog(alchemy.INFO, args, {level: 1});
|
|
31
|
-
|
|
32
|
-
if (line && line.args) {
|
|
33
|
-
stage.pledge.then(function finished() {
|
|
34
|
-
line.args.push('Done in', stage.ended - stage.started, 'ms');
|
|
35
|
-
line.dissect();
|
|
36
|
-
line.render();
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Add a getter for the total amount of http requests
|
|
44
|
-
*
|
|
45
|
-
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
46
|
-
* @since 1.3.1
|
|
47
|
-
* @version 1.3.1
|
|
48
|
-
*
|
|
49
|
-
* @type {Number}
|
|
50
|
-
*/
|
|
51
|
-
Alchemy.setProperty(function http_request_counter() {
|
|
52
|
-
return total_http_requests;
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* The "http" stage:
|
|
57
|
-
* Create the server and listen to requests
|
|
58
|
-
*
|
|
59
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
60
|
-
* @since 0.0.1
|
|
61
|
-
* @version 1.3.1
|
|
62
|
-
*/
|
|
63
|
-
alchemy.sputnik.add(function http() {
|
|
64
|
-
|
|
65
|
-
// Create the server
|
|
66
|
-
alchemy.server = alchemy.modules.http.createServer();
|
|
67
|
-
|
|
68
|
-
// Listen for requests
|
|
69
|
-
alchemy.server.on('request', function onRequest(request, response) {
|
|
70
|
-
Router.resolve(request, response);
|
|
71
|
-
total_http_requests++;
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* The "coreApp" stage:
|
|
77
|
-
* Load in Alchemy's main 'app' folder.
|
|
78
|
-
*
|
|
79
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
80
|
-
* @since 0.0.1
|
|
81
|
-
* @version 1.1.0
|
|
82
|
-
*/
|
|
83
|
-
alchemy.sputnik.add(function core_app() {
|
|
84
|
-
alchemy.usePath(path.resolve(PATH_CORE, 'app'), {weight: 1});
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* The "datasources" stage:
|
|
89
|
-
* Make a connection to all the datasources.
|
|
90
|
-
*
|
|
91
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
92
|
-
* @since 0.0.1
|
|
93
|
-
* @version 1.1.0
|
|
94
|
-
*/
|
|
95
|
-
alchemy.sputnik.add(function datasources() {
|
|
96
|
-
|
|
97
|
-
var tasks = [];
|
|
98
|
-
|
|
99
|
-
// Force Blast to load
|
|
100
|
-
try {
|
|
101
|
-
Blast.doLoaded();
|
|
102
|
-
} catch (err) {
|
|
103
|
-
alchemy.printLog('error', ['Failed to load application:', err.message], {err: err, level: 1});
|
|
104
|
-
return
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// Require the environment datasources configuration
|
|
108
|
-
try {
|
|
109
|
-
require(path.resolve(PATH_ROOT, 'app', 'config', settings.environment, 'database'));
|
|
110
|
-
} catch (err) {
|
|
111
|
-
|
|
112
|
-
if (err.code == 'MODULE_NOT_FOUND') {
|
|
113
|
-
if (!alchemy.settings.client_mode) {
|
|
114
|
-
// Only output a warning when not in client mode
|
|
115
|
-
log.warn('Could not find ' + settings.environment + ' database settings');
|
|
116
|
-
}
|
|
117
|
-
} else {
|
|
118
|
-
log.warn('Could not load ' + settings.environment + ' database settings:', err);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// Get all available datasources
|
|
125
|
-
Object.each(Datasource.get(), function eachDatasource(datasource, key) {
|
|
126
|
-
tasks.push(datasource.setup());
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
return Function.parallel(tasks);
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* The "plugins" stage:
|
|
134
|
-
* Initialize the defined plugins.
|
|
135
|
-
*
|
|
136
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
137
|
-
* @since 0.0.1
|
|
138
|
-
* @version 1.2.7
|
|
139
|
-
*/
|
|
140
|
-
alchemy.sputnik.add(function plugins() {
|
|
141
|
-
// Load in the plugins
|
|
142
|
-
try {
|
|
143
|
-
alchemy.startPlugins();
|
|
144
|
-
} catch (err) {
|
|
145
|
-
// Constitutors sometimes throw errors during this stage.
|
|
146
|
-
// Not sure yet why they don't get caught by sputnik
|
|
147
|
-
// @TODO: refactor!
|
|
148
|
-
log.error('Caught error during "plugins" stage:', err);
|
|
149
|
-
throw err;
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* The "baseApp" stage:
|
|
155
|
-
* Load all the files in the user-defined 'app' folder
|
|
156
|
-
*
|
|
157
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
158
|
-
* @since 0.0.1
|
|
159
|
-
* @version 0.0.1
|
|
160
|
-
*/
|
|
161
|
-
alchemy.sputnik.add(function base_app() {
|
|
162
|
-
// Load in the app
|
|
163
|
-
alchemy.usePath(PATH_APP, {weight: 20});
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* The "defineDebug" stage:
|
|
168
|
-
* Setup some debug settings
|
|
169
|
-
*
|
|
170
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
171
|
-
* @since 0.0.1
|
|
172
|
-
* @version 1.1.0
|
|
173
|
-
*/
|
|
174
|
-
alchemy.sputnik.add(function define_debug() {
|
|
175
|
-
// See if we want to enable debugging
|
|
176
|
-
if (settings.debug) {
|
|
177
|
-
log.info('Hawkejs debugging has been ENABLED');
|
|
178
|
-
alchemy.hawkejs._debug = true;
|
|
179
|
-
}
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* The "hawkejsSetup" stage:
|
|
184
|
-
* Initialize Hawkejs
|
|
185
|
-
*
|
|
186
|
-
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
187
|
-
* @since 0.0.1
|
|
188
|
-
* @version 1.3.3
|
|
189
|
-
*/
|
|
190
|
-
alchemy.sputnik.add(function hawkejs_setup() {
|
|
191
|
-
|
|
192
|
-
// Set the correct asset paths
|
|
193
|
-
alchemy.hawkejs.style_path = 'stylesheets/';
|
|
194
|
-
alchemy.hawkejs.script_path = 'scripts/';
|
|
195
|
-
|
|
196
|
-
// Serve the hawkejs file
|
|
197
|
-
Router.use('/hawkejs/hawkejs-client.js', function getHawkejs(req, res, next) {
|
|
198
|
-
|
|
199
|
-
var retries = 0;
|
|
200
|
-
|
|
201
|
-
Blast.getClientPath({
|
|
202
|
-
modify_prototypes : true,
|
|
203
|
-
ua : req.conduit.headers.useragent,
|
|
204
|
-
create_source_map : alchemy.settings.source_map,
|
|
205
|
-
enable_coverage : !!global.__coverage__
|
|
206
|
-
}).done(gotClientFile);
|
|
207
|
-
|
|
208
|
-
function gotClientFile(err, path) {
|
|
209
|
-
|
|
210
|
-
if (err) {
|
|
211
|
-
return retryFnc(err);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
let options = {};
|
|
215
|
-
|
|
216
|
-
if (req.conduit && req.conduit.supports('async') === false) {
|
|
217
|
-
options.add_async_support = true;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
alchemy.minifyScript(path, options, function gotMinifiedPath(err, mpath) {
|
|
221
|
-
|
|
222
|
-
var options;
|
|
223
|
-
|
|
224
|
-
if (!retries) {
|
|
225
|
-
options = {
|
|
226
|
-
onError: retryFnc
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
req.conduit.serveFile(mpath || path, options);
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
function retryFnc(err) {
|
|
235
|
-
|
|
236
|
-
if (retries > 0) {
|
|
237
|
-
return req.conduit.error(new Error('Failed to serve client file'));
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
retries++;
|
|
241
|
-
|
|
242
|
-
Blast.getClientPath({
|
|
243
|
-
refresh : true,
|
|
244
|
-
modify_prototypes : true,
|
|
245
|
-
ua : req.conduit.headers.useragent,
|
|
246
|
-
create_source_map : alchemy.settings.source_map,
|
|
247
|
-
}).done(gotClientFile);
|
|
248
|
-
}
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
// Serve the static file with exposed variables
|
|
252
|
-
Router.use('/hawkejs/static.js', function getHawkejs(req, res, next) {
|
|
253
|
-
alchemy.hawkejs.getStaticExposedPath((err, path) => {
|
|
254
|
-
|
|
255
|
-
if (err) {
|
|
256
|
-
return req.conduit.error(err);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
req.conduit.serveFile(path);
|
|
260
|
-
});
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
// Serve multiple template files
|
|
264
|
-
Router.use('/hawkejs/templates', function onGetTemplates(req, res) {
|
|
265
|
-
|
|
266
|
-
var names = req.conduit.param('name');
|
|
267
|
-
|
|
268
|
-
if (!names) {
|
|
269
|
-
return req.conduit.error(new Error('No template names have been given'));
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
alchemy.hawkejs.getFirstAvailableSource(names, function gotResult(err, result) {
|
|
273
|
-
|
|
274
|
-
if (err) {
|
|
275
|
-
return req.conduit.error(err);
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
if (!result || !result.name) {
|
|
279
|
-
return req.conduit.notFound('Could not find any of the given templates');
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
req.conduit.setHeader('cache-control', 'public, max-age=3600, must-revalidate');
|
|
283
|
-
|
|
284
|
-
// Don't use json dry, hawkejs expects regular json
|
|
285
|
-
req.conduit.json_dry = false;
|
|
286
|
-
|
|
287
|
-
req.conduit.end(result);
|
|
288
|
-
});
|
|
289
|
-
}, {methods: ['get'], weight: 19});
|
|
290
|
-
|
|
291
|
-
// Serve single template files
|
|
292
|
-
Router.use('/hawkejs/template', function onGetTemplate(req, res) {
|
|
293
|
-
|
|
294
|
-
var name = req.conduit.param('name');
|
|
295
|
-
|
|
296
|
-
if (!name) {
|
|
297
|
-
return req.conduit.error(new Error('No template name has been given'));
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
alchemy.hawkejs.getTemplatePath(name, function gotTemplate(err, path) {
|
|
301
|
-
|
|
302
|
-
if (err) {
|
|
303
|
-
return req.conduit.error(err);
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
if (!path) {
|
|
307
|
-
req.conduit.notFound('Could not find ' + name);
|
|
308
|
-
} else {
|
|
309
|
-
req.conduit.serveFile(path);
|
|
310
|
-
}
|
|
311
|
-
});
|
|
312
|
-
}, {methods: ['get'], weight: 19});
|
|
313
|
-
});
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* The "middleware" stage:
|
|
317
|
-
* Setup middleware
|
|
318
|
-
*
|
|
319
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
320
|
-
* @since 0.0.1
|
|
321
|
-
* @version 1.1.3
|
|
322
|
-
*/
|
|
323
|
-
alchemy.sputnik.add(function middleware() {
|
|
324
|
-
|
|
325
|
-
// Serve public files
|
|
326
|
-
Router.use('/public/', alchemy.publicMiddleware, 50);
|
|
327
|
-
|
|
328
|
-
// Serve stylesheets
|
|
329
|
-
Router.use('/stylesheets/', alchemy.styleMiddleware, 50);
|
|
330
|
-
|
|
331
|
-
// Serve scripts
|
|
332
|
-
Router.use('/scripts/', alchemy.scriptMiddleware, 50);
|
|
333
|
-
|
|
334
|
-
// Serve fonts
|
|
335
|
-
Router.use('/fonts/', alchemy.fontMiddleware, 50);
|
|
336
|
-
|
|
337
|
-
// Serve root files
|
|
338
|
-
Router.use('/', alchemy.rootMiddleware, 49);
|
|
339
|
-
|
|
340
|
-
if (alchemy.settings.debug) {
|
|
341
|
-
// Serve sourcemap files
|
|
342
|
-
Router.use('/_sourcemaps/', alchemy.sourcemapMiddleware, 50);
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
// Parse body (form-data & json, no multipart)
|
|
346
|
-
// @todo: not all routes require body parsing
|
|
347
|
-
Router.use(function parseBody(req, res, next) {
|
|
348
|
-
|
|
349
|
-
// Don't re-check internal redirects, they always should have a body set
|
|
350
|
-
if (req.original.body != null || (req.conduit && req.conduit instanceof Classes.Alchemy.Conduit.Loopback)) {
|
|
351
|
-
return next();
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
alchemy.parseRequestBody(req, res, next);
|
|
355
|
-
|
|
356
|
-
}, {methods: ['post'], weight: 99999});
|
|
357
|
-
});
|
|
358
|
-
|
|
359
|
-
/**
|
|
360
|
-
* The "routes" stage:
|
|
361
|
-
* Initialize all the routes
|
|
362
|
-
*
|
|
363
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
364
|
-
* @since 0.0.1
|
|
365
|
-
* @version 0.4.0
|
|
366
|
-
*/
|
|
367
|
-
alchemy.sputnik.add(function routes() {
|
|
368
|
-
try {
|
|
369
|
-
alchemy.useOnce(path.resolve(PATH_APP, 'config', 'routes'));
|
|
370
|
-
} catch (err) {
|
|
371
|
-
// Only output warning when not in client mode
|
|
372
|
-
if (!alchemy.settings.client_mode) {
|
|
373
|
-
log.warn('No route config was found');
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
});
|
|
377
|
-
|
|
378
|
-
/**
|
|
379
|
-
* The "startServer" stage:
|
|
380
|
-
* Actually start the server
|
|
381
|
-
*
|
|
382
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
383
|
-
* @since 0.0.1
|
|
384
|
-
* @version 1.3.5
|
|
385
|
-
*/
|
|
386
|
-
alchemy.sputnik.add(function start_server() {
|
|
387
|
-
|
|
388
|
-
if (process.send) {
|
|
389
|
-
// Create a connection to the hohenheim parent
|
|
390
|
-
alchemy.hohenheim = new Classes.Alchemy.Reciprocal(process, 'hohenheim');
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
if (alchemy.settings.client_mode) {
|
|
394
|
-
return alchemy.sputnik.launch('listening');
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
alchemy.exposeDefaultStaticVariables();
|
|
398
|
-
|
|
399
|
-
// If a falsy (non-null) port is given (and no socket file), do nothing
|
|
400
|
-
if (!settings.port && settings.port !== null && !settings.socket) {
|
|
401
|
-
return;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
let listen_target;
|
|
405
|
-
|
|
406
|
-
// Are we using a socket file?
|
|
407
|
-
if (typeof settings.socket == 'string') {
|
|
408
|
-
let stat;
|
|
409
|
-
|
|
410
|
-
try {
|
|
411
|
-
stat = fs.statSync(settings.socket);
|
|
412
|
-
} catch (err) {
|
|
413
|
-
// File not found, so it's safe to use
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
if (stat) {
|
|
417
|
-
log.info('Found existing socketfile at', settings.socket, ', need to remove it');
|
|
418
|
-
fs.unlinkSync(settings.socket);
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
listen_target = settings.socket;
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
if (!listen_target && settings.port) {
|
|
425
|
-
listen_target = settings.port;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
// Start listening on the given port
|
|
429
|
-
// The actual `requests` listener is defined in the 'http' stage
|
|
430
|
-
alchemy.server.listen(listen_target, function areListening(){
|
|
431
|
-
|
|
432
|
-
let address = alchemy.server.address();
|
|
433
|
-
let url = alchemy.settings.url;
|
|
434
|
-
|
|
435
|
-
if (typeof address == 'string') {
|
|
436
|
-
settings.socket = address;
|
|
437
|
-
log.info('HTTP server listening on socket file', address);
|
|
438
|
-
|
|
439
|
-
// Make readable by everyone
|
|
440
|
-
if (settings.socketfile_chmod) {
|
|
441
|
-
fs.chmodSync(address, settings.socketfile_chmod);
|
|
442
|
-
}
|
|
443
|
-
} else {
|
|
444
|
-
// Get the actual server port
|
|
445
|
-
settings.port = address.port;
|
|
446
|
-
log.info('HTTP server listening on port', settings.port);
|
|
447
|
-
|
|
448
|
-
if (!url) {
|
|
449
|
-
url = 'http://localhost:' + address.port;
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
if (url) {
|
|
454
|
-
let pretty_url = alchemy.colors.bg.getRgb(1, 0, 1) + alchemy.colors.fg.getRgb(5, 3, 0) + ' ' + url + ' ' + alchemy.colors.reset;
|
|
455
|
-
log.info('Served at »»', pretty_url, '««');
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
// If this process is a child, tell the parent we're ready
|
|
459
|
-
if (process.send) {
|
|
460
|
-
log.info('Letting the parent know we\'re ready!');
|
|
461
|
-
process.send({alchemy: {ready: true}});
|
|
462
|
-
|
|
463
|
-
process.on('disconnect', function onParentExit() {
|
|
464
|
-
log.info('Parent exited, closing down');
|
|
465
|
-
process.exit();
|
|
466
|
-
});
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
alchemy.sputnik.launch('listening');
|
|
470
|
-
});
|
|
471
|
-
|
|
472
|
-
// Listen for errors (like EADDRINUSE)
|
|
473
|
-
alchemy.server.on('error', function onError(err) {
|
|
474
|
-
|
|
475
|
-
if (process.send) {
|
|
476
|
-
process.send({alchemy: {error: err}});
|
|
477
|
-
return process.exit();
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
throw err;
|
|
481
|
-
});
|
|
482
|
-
});
|
|
483
|
-
|
|
484
|
-
/**
|
|
485
|
-
* Launch the "startServer" stage after datasources & socket
|
|
486
|
-
*
|
|
487
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
488
|
-
* @since 0.0.1
|
|
489
|
-
* @version 0.5.0
|
|
490
|
-
*/
|
|
491
|
-
alchemy.sputnik.after(['datasources', 'socket'], function scheduleServerStart() {
|
|
492
|
-
|
|
493
|
-
// Need to wait for all classes to load
|
|
494
|
-
Blast.loaded(function hasLoaded() {
|
|
495
|
-
|
|
496
|
-
alchemy.sputnik.launch('start_server');
|
|
497
|
-
|
|
498
|
-
// Indicate the server has started
|
|
499
|
-
alchemy.started = true;
|
|
500
|
-
});
|
|
501
|
-
});
|
|
502
|
-
|
|
503
|
-
alchemy.sputnik.launch([
|
|
504
|
-
'http',
|
|
505
|
-
'core_app',
|
|
506
|
-
'plugins',
|
|
507
|
-
'base_app',
|
|
508
|
-
'middleware',
|
|
509
|
-
'datasources',
|
|
510
|
-
'define_debug',
|
|
511
|
-
'socket',
|
|
512
|
-
'hawkejs_setup',
|
|
513
|
-
'routes']);
|