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
|
@@ -1,973 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// Get some modules from the cache
|
|
4
|
-
var fs = alchemy.use('fs'),
|
|
5
|
-
path = alchemy.use('path'),
|
|
6
|
-
LOADED = Symbol('LOADED'),
|
|
7
|
-
module = require('module'),
|
|
8
|
-
original_wrap = module.wrap,
|
|
9
|
-
original_wrapper = module.wrapper.slice(0),
|
|
10
|
-
original_resolve = module._resolveFilename,
|
|
11
|
-
strict_wrapper = original_wrapper[0] + '"use strict";',
|
|
12
|
-
prive = {},
|
|
13
|
-
_duplicateCheck = {},
|
|
14
|
-
cwd = process.cwd();
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Require all files in a certain directory.
|
|
18
|
-
* Does not cache the files.
|
|
19
|
-
*
|
|
20
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
21
|
-
* @since 0.0.1
|
|
22
|
-
* @version 1.1.5
|
|
23
|
-
*
|
|
24
|
-
* @param {String} dirPath The path to load
|
|
25
|
-
* @param {Object} options
|
|
26
|
-
* .modular Treat certain kinds of subdirectories different
|
|
27
|
-
* .bootstrap Load the bootstrap.js file first
|
|
28
|
-
* .app Load an app_ file second
|
|
29
|
-
* .weight The weight, including views & less
|
|
30
|
-
*
|
|
31
|
-
* @returns {Boolean} If we were able to load in the directory
|
|
32
|
-
*/
|
|
33
|
-
Alchemy.setMethod(function usePath(dirPath, options) {
|
|
34
|
-
|
|
35
|
-
var modularRegex = [],
|
|
36
|
-
useOptions = {};
|
|
37
|
-
|
|
38
|
-
if (typeof options === 'undefined') options = {};
|
|
39
|
-
|
|
40
|
-
// Use different functions for different directories by default
|
|
41
|
-
if (typeof options.modular === 'undefined') options.modular = true;
|
|
42
|
-
if (typeof options._level === 'undefined') options._level = -1;
|
|
43
|
-
if (typeof options.weight !== 'number') options.weight = 10;
|
|
44
|
-
|
|
45
|
-
options._level++;
|
|
46
|
-
useOptions._level = options._level;
|
|
47
|
-
|
|
48
|
-
// Always ignore .git directories
|
|
49
|
-
modularRegex.push(/^.git$/);
|
|
50
|
-
|
|
51
|
-
// Ignore bootstrap file if it's a plugin, because it's already loaded
|
|
52
|
-
if (options.plugin) {
|
|
53
|
-
useOptions.bootstrap = false;
|
|
54
|
-
modularRegex.push({regex: /bootstrap.js/, level: 0});
|
|
55
|
-
|
|
56
|
-
// Plugins have a higher weight
|
|
57
|
-
// They're more important than the core, but less than the root
|
|
58
|
-
if (typeof options.weight !== 'number') {
|
|
59
|
-
options.weight = 15;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (options.modular && options._level == 0) {
|
|
64
|
-
|
|
65
|
-
// Load Hawkejs view helper classes
|
|
66
|
-
if (options.helpers !== false) {
|
|
67
|
-
prive.loadHelpers(dirPath, 'helper_datasource');
|
|
68
|
-
prive.loadHelpers(dirPath, 'helper_field');
|
|
69
|
-
prive.loadHelpers(dirPath, 'helper');
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Load the custom element folder as helpers, too
|
|
73
|
-
if (options.elements !== false) {
|
|
74
|
-
prive.loadHelpers(dirPath, 'element');
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Let Hawkejs now about this view directory
|
|
78
|
-
if (options.views !== false) {
|
|
79
|
-
alchemy.addViewDirectory(path.resolve(dirPath, 'view'), options.weight);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Main asset directory
|
|
83
|
-
alchemy.addAssetDirectory(path.resolve(dirPath, 'assets'), options.weight);
|
|
84
|
-
|
|
85
|
-
// Asset scripts
|
|
86
|
-
if (options.scripts !== false) {
|
|
87
|
-
alchemy.addScriptDirectory(path.resolve(dirPath, 'assets', 'scripts'), options.weight);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Asset stylesheets
|
|
91
|
-
if (options.less !== false) {
|
|
92
|
-
alchemy.addStylesheetDirectory(path.resolve(dirPath, 'assets', 'stylesheets'), options.weight);
|
|
93
|
-
|
|
94
|
-
// Also add the public folder, so less files in there can also be compiled
|
|
95
|
-
alchemy.addStylesheetDirectory(path.resolve(dirPath, 'public'), options.weight);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Fonts
|
|
99
|
-
if (options.fonts !== false) {
|
|
100
|
-
alchemy.addFontDirectory(path.resolve(dirPath, 'assets', 'fonts'), options.weight);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Images
|
|
104
|
-
if (options.images !== false) {
|
|
105
|
-
alchemy.addImageDirectory(path.resolve(dirPath, 'assets', 'images'), options.weight);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// public folders (going to /public/)
|
|
109
|
-
if (options.public !== false) {
|
|
110
|
-
alchemy.addPublicDirectory(path.resolve(dirPath, 'public'), options.weight);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Root folders (/)
|
|
114
|
-
if (options.root !== false) {
|
|
115
|
-
alchemy.addRootDirectory(path.resolve(dirPath, 'root'), options.weight);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
modularRegex.push(/^view$|^helper$|^helper_datasource$|^helper_error$|^helper_field$|^helper_document$|^helper_model$|^helper_controller$|^helper_component$|^helper_validator$|^element$|^plugins$|^assets$/);
|
|
119
|
-
|
|
120
|
-
useOptions.modular = true;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Do not load /config subdirectories
|
|
124
|
-
if (/\/config$/.exec(dirPath)) useOptions.recursive = false;
|
|
125
|
-
|
|
126
|
-
useOptions.ignore = modularRegex;
|
|
127
|
-
|
|
128
|
-
this._usePath(dirPath, useOptions);
|
|
129
|
-
|
|
130
|
-
// Load record-related helpers, but only after loading the models
|
|
131
|
-
if (options.modular && options._level == 0) {
|
|
132
|
-
if (options.helpers !== false) {
|
|
133
|
-
prive.loadHelpers(dirPath, 'helper_error');
|
|
134
|
-
prive.loadHelpers(dirPath, 'helper_model');
|
|
135
|
-
prive.loadHelpers(dirPath, 'helper_document');
|
|
136
|
-
prive.loadHelpers(dirPath, 'helper_controller');
|
|
137
|
-
prive.loadHelpers(dirPath, 'helper_component');
|
|
138
|
-
prive.loadHelpers(dirPath, 'helper_validator');
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Default _usePath options
|
|
145
|
-
*
|
|
146
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
147
|
-
* @since 0.5.0
|
|
148
|
-
* @version 0.5.0
|
|
149
|
-
*
|
|
150
|
-
* @type {Object}
|
|
151
|
-
*/
|
|
152
|
-
Alchemy.setProperty('default_use_path_options', {
|
|
153
|
-
ignore : false,
|
|
154
|
-
recursive : -1,
|
|
155
|
-
_level : -1,
|
|
156
|
-
|
|
157
|
-
// Load the bootstrap.js file first
|
|
158
|
-
bootstrap : true,
|
|
159
|
-
|
|
160
|
-
// Load the app_ file afterwards
|
|
161
|
-
app : true
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Require all files in a certain directory.
|
|
166
|
-
*
|
|
167
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
168
|
-
* @since 0.0.1
|
|
169
|
-
* @version 1.2.0
|
|
170
|
-
*
|
|
171
|
-
* @param {String} dir_path
|
|
172
|
-
* @param {Object} options
|
|
173
|
-
*
|
|
174
|
-
* @returns {Boolean} If we were able to load in the directory
|
|
175
|
-
*/
|
|
176
|
-
Alchemy.setMethod(function _usePath(dir_path, options) {
|
|
177
|
-
|
|
178
|
-
var files;
|
|
179
|
-
|
|
180
|
-
options = Object.assign({}, this.default_use_path_options, options);
|
|
181
|
-
|
|
182
|
-
// Load the bootstrap file
|
|
183
|
-
if (options.bootstrap) {
|
|
184
|
-
prive.loadBootstrap(dir_path);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// Load the app_ file
|
|
188
|
-
if (options.app) {
|
|
189
|
-
prive.loadRegexFile(dir_path, /^app_/);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
if (options.modularParent == null) {
|
|
193
|
-
options.modularParent = options.modular;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
// Up the recursive level by 1. Starting points are 0.
|
|
197
|
-
options._level++;
|
|
198
|
-
|
|
199
|
-
// Read in the directory file listing
|
|
200
|
-
try {
|
|
201
|
-
files = fs.readdirSync(dir_path);
|
|
202
|
-
} catch (err) {
|
|
203
|
-
return false;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
let directories = [],
|
|
207
|
-
file_name,
|
|
208
|
-
file_path,
|
|
209
|
-
file_stat,
|
|
210
|
-
entry,
|
|
211
|
-
i;
|
|
212
|
-
|
|
213
|
-
// Iterate over the directorie entries
|
|
214
|
-
for (i = 0; i < files.length; i++) {
|
|
215
|
-
file_name = files[i];
|
|
216
|
-
|
|
217
|
-
// Skip hidden files or the "empty" file
|
|
218
|
-
if (file_name[0] == '.' || file_name == 'empty') {
|
|
219
|
-
continue;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// Skip bootstrap & app files if already loaded
|
|
223
|
-
if (options.bootstrap && file_name === 'bootstrap.js') {
|
|
224
|
-
continue;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
if (options.app && file_name.startsWith('app_')) {
|
|
228
|
-
continue;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// Always ignore public or node_modules paths
|
|
232
|
-
if (file_name == 'node_modules' || file_name == 'public' || file_name == 'test') {
|
|
233
|
-
continue;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// Ignore files that contain .manual.
|
|
237
|
-
if (file_name.indexOf('.manual.') > -1) {
|
|
238
|
-
continue;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
// See if this is in the options.ignore property
|
|
242
|
-
if (prive.checkRegex(file_name, options.ignore, options._level)) {
|
|
243
|
-
continue;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
// Resolve the entire path
|
|
247
|
-
file_path = path.resolve(dir_path, file_name);
|
|
248
|
-
|
|
249
|
-
// Get information on this entry
|
|
250
|
-
file_stat = fs.lstatSync(file_path);
|
|
251
|
-
|
|
252
|
-
// Save directories for later, files come first
|
|
253
|
-
if (file_stat.isDirectory()) {
|
|
254
|
-
directories.push({
|
|
255
|
-
parent_path : dir_path,
|
|
256
|
-
name : file_name,
|
|
257
|
-
path : file_path,
|
|
258
|
-
stat : file_stat,
|
|
259
|
-
local_path : file_path.slice(PATH_APP.length),
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
continue;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
alchemy.useOnce(file_path);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
// Exit early if we don't have to recursively add directories
|
|
269
|
-
if (!options.recursive) {
|
|
270
|
-
return true;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// Now do the directories
|
|
274
|
-
for (i = 0; i < directories.length; i++) {
|
|
275
|
-
entry = directories[i];
|
|
276
|
-
|
|
277
|
-
// Don't load migrations
|
|
278
|
-
if (entry.local_path == '/migrations') {
|
|
279
|
-
continue;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
// Do not include subfolders of the "config" directory
|
|
283
|
-
// if it's a modular load
|
|
284
|
-
if (options.modularParent && /\/config$/.exec(entry.parent_path)) {
|
|
285
|
-
continue;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
this._usePath(entry.path, {
|
|
289
|
-
ignore : options.ignore,
|
|
290
|
-
recursive : options.recursive - 1,
|
|
291
|
-
_level : options._level,
|
|
292
|
-
modularParent : options.modularParent
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
return true;
|
|
297
|
-
});
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
* Add an asset directory
|
|
301
|
-
*
|
|
302
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
303
|
-
* @since 0.2.0
|
|
304
|
-
* @version 0.4.0
|
|
305
|
-
*
|
|
306
|
-
* @param {String} dirPath The path to load
|
|
307
|
-
* @param {Number} weight The weighted importance [10]
|
|
308
|
-
*/
|
|
309
|
-
Alchemy.setMethod(function addAssetDirectory(dirPath, weight) {
|
|
310
|
-
|
|
311
|
-
if (typeof weight !== 'number') {
|
|
312
|
-
weight = 10;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
alchemy.shared('asset.directories').push(dirPath, weight);
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
/**
|
|
319
|
-
* Add a scripts directory
|
|
320
|
-
*
|
|
321
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
322
|
-
* @since 0.2.0
|
|
323
|
-
* @version 0.4.0
|
|
324
|
-
*
|
|
325
|
-
* @param {String} dirPath The path to load
|
|
326
|
-
* @param {Number} weight The weighted importance [10]
|
|
327
|
-
*/
|
|
328
|
-
Alchemy.setMethod(function addScriptDirectory(dirPath, weight) {
|
|
329
|
-
|
|
330
|
-
if (typeof weight !== 'number') {
|
|
331
|
-
weight = 10;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
alchemy.shared('script.directories').push(dirPath, weight);
|
|
335
|
-
});
|
|
336
|
-
|
|
337
|
-
/**
|
|
338
|
-
* Add a stylesheets directory
|
|
339
|
-
*
|
|
340
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
341
|
-
* @since 0.2.0
|
|
342
|
-
* @version 0.4.0
|
|
343
|
-
*
|
|
344
|
-
* @param {String} dirPath The path to load
|
|
345
|
-
* @param {Number} weight The weighted importance [10]
|
|
346
|
-
*/
|
|
347
|
-
Alchemy.setMethod(function addStylesheetDirectory(dirPath, weight) {
|
|
348
|
-
|
|
349
|
-
if (typeof weight !== 'number') {
|
|
350
|
-
weight = 10;
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
alchemy.shared('stylesheet.directories').push(dirPath, weight);
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
/**
|
|
357
|
-
* Add a font directory
|
|
358
|
-
*
|
|
359
|
-
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
360
|
-
* @since 1.1.3
|
|
361
|
-
* @version 1.1.3
|
|
362
|
-
*
|
|
363
|
-
* @param {String} dirPath The path to load
|
|
364
|
-
* @param {Number} weight The weighted importance [10]
|
|
365
|
-
*/
|
|
366
|
-
Alchemy.setMethod(function addFontDirectory(dirPath, weight) {
|
|
367
|
-
|
|
368
|
-
if (typeof weight !== 'number') {
|
|
369
|
-
weight = 10;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
alchemy.shared('font.directories').push(dirPath, weight);
|
|
373
|
-
});
|
|
374
|
-
|
|
375
|
-
/**
|
|
376
|
-
* Add an image directory
|
|
377
|
-
*
|
|
378
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
379
|
-
* @since 0.2.0
|
|
380
|
-
* @version 0.4.0
|
|
381
|
-
*
|
|
382
|
-
* @param {String} dirPath The path to load
|
|
383
|
-
* @param {Number} weight The weighted importance [10]
|
|
384
|
-
*/
|
|
385
|
-
Alchemy.setMethod(function addImageDirectory(dirPath, weight) {
|
|
386
|
-
|
|
387
|
-
if (typeof weight !== 'number') {
|
|
388
|
-
weight = 10;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
alchemy.shared('images.directories').push(dirPath, weight);
|
|
392
|
-
});
|
|
393
|
-
|
|
394
|
-
/**
|
|
395
|
-
* Add a public directory
|
|
396
|
-
*
|
|
397
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
398
|
-
* @since 0.2.0
|
|
399
|
-
* @version 0.4.0
|
|
400
|
-
*
|
|
401
|
-
* @param {String} dirPath The path to load
|
|
402
|
-
* @param {Number} weight The weighted importance [10]
|
|
403
|
-
*/
|
|
404
|
-
Alchemy.setMethod(function addPublicDirectory(dirPath, weight) {
|
|
405
|
-
|
|
406
|
-
if (typeof weight !== 'number') {
|
|
407
|
-
weight = 10;
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
alchemy.shared('public.directories').push(dirPath, weight);
|
|
411
|
-
});
|
|
412
|
-
|
|
413
|
-
/**
|
|
414
|
-
* Add a root directory
|
|
415
|
-
*
|
|
416
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
417
|
-
* @since 0.2.0
|
|
418
|
-
* @version 0.4.0
|
|
419
|
-
*
|
|
420
|
-
* @param {String} dirPath The path to load
|
|
421
|
-
* @param {Number} weight The weighted importance [10]
|
|
422
|
-
*/
|
|
423
|
-
Alchemy.setMethod(function addRootDirectory(dirPath, weight) {
|
|
424
|
-
|
|
425
|
-
if (typeof weight !== 'number') {
|
|
426
|
-
weight = 10;
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
alchemy.shared('root.directories').push(dirPath, weight);
|
|
430
|
-
});
|
|
431
|
-
|
|
432
|
-
/**
|
|
433
|
-
* Tell hawkejs to use this path to look for views.
|
|
434
|
-
*
|
|
435
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
436
|
-
* @since 0.0.1
|
|
437
|
-
* @version 0.4.0
|
|
438
|
-
*
|
|
439
|
-
* @param {String} dirPath The path to load
|
|
440
|
-
* @param {Number} weight The weighted importance [10]
|
|
441
|
-
*/
|
|
442
|
-
Alchemy.setMethod(function addViewDirectory(dirPath, weight) {
|
|
443
|
-
|
|
444
|
-
if (typeof weight !== 'number') {
|
|
445
|
-
weight = 10;
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
alchemy.hawkejs.addViewDirectory(dirPath, weight);
|
|
449
|
-
});
|
|
450
|
-
|
|
451
|
-
/**
|
|
452
|
-
* Load in the bootstrap file.
|
|
453
|
-
*
|
|
454
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
455
|
-
* @since 0.0.1
|
|
456
|
-
* @version 0.4.0
|
|
457
|
-
*
|
|
458
|
-
* @param {String} dirPath The path to load
|
|
459
|
-
*
|
|
460
|
-
* @returns {Boolean} If we were able to load in the file
|
|
461
|
-
*/
|
|
462
|
-
prive.loadBootstrap = function loadBootstrap(dirPath) {
|
|
463
|
-
|
|
464
|
-
// If a bootstrap.js file exists inside the directory, load it first
|
|
465
|
-
var bootstrapPath = path.resolve(dirPath, 'bootstrap.js');
|
|
466
|
-
|
|
467
|
-
if (typeof _duplicateCheck[bootstrapPath] == 'undefined') {
|
|
468
|
-
|
|
469
|
-
if (fs.existsSync(bootstrapPath)) {
|
|
470
|
-
alchemy.makeNextRequireStrict();
|
|
471
|
-
require(bootstrapPath);
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
_duplicateCheck[bootstrapPath] = true;
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
return _duplicateCheck[bootstrapPath];
|
|
478
|
-
};
|
|
479
|
-
|
|
480
|
-
/**
|
|
481
|
-
* Load in a file by regex.
|
|
482
|
-
*
|
|
483
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
484
|
-
* @since 0.0.1
|
|
485
|
-
* @version 0.0.1
|
|
486
|
-
*
|
|
487
|
-
* @param {String} dirPath The path to load
|
|
488
|
-
* @param {RegExp} pattern The pattern to match
|
|
489
|
-
* @param {Boolean} multiple Keep looking after finding one? (false)
|
|
490
|
-
*
|
|
491
|
-
* @returns {Boolean} If we were able to load in the file
|
|
492
|
-
*/
|
|
493
|
-
prive.loadRegexFile = function loadRegexFile (dirPath, pattern, multiple) {
|
|
494
|
-
|
|
495
|
-
var files, fileCount, fileName, filePath, fileStat, result = false;
|
|
496
|
-
|
|
497
|
-
if (!(pattern instanceof RegExp)) {
|
|
498
|
-
log.error('Tried to load a file by passing invalid regex', {level: 1});
|
|
499
|
-
return false;
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
try {
|
|
503
|
-
files = fs.readdirSync(dirPath);
|
|
504
|
-
} catch (err) {
|
|
505
|
-
return false;
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
for (fileCount in files) {
|
|
509
|
-
|
|
510
|
-
fileName = files[fileCount];
|
|
511
|
-
|
|
512
|
-
// Continue to the next file if the patternd ooesn't match
|
|
513
|
-
if (!pattern.exec(fileName)) continue;
|
|
514
|
-
|
|
515
|
-
filePath = path.resolve(dirPath, fileName);
|
|
516
|
-
fileStat = fs.lstatSync(filePath);
|
|
517
|
-
|
|
518
|
-
// Skip directories
|
|
519
|
-
if (fileStat.isDirectory()) continue;
|
|
520
|
-
|
|
521
|
-
alchemy.useOnce(filePath);
|
|
522
|
-
|
|
523
|
-
result = true;
|
|
524
|
-
|
|
525
|
-
// Stop looking for more matches if multiple is false/undefined
|
|
526
|
-
if (!multiple) break;
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
return result;
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
/**
|
|
533
|
-
* Load in a directory containing helpers.
|
|
534
|
-
* These helpers will be added to the main Hawkejs instance.
|
|
535
|
-
*
|
|
536
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
537
|
-
* @since 0.0.1
|
|
538
|
-
* @version 1.1.0
|
|
539
|
-
*
|
|
540
|
-
* @param {String} dir_path The path to load
|
|
541
|
-
*/
|
|
542
|
-
prive.loadHelpers = function loadHelpers(...path_pieces) {
|
|
543
|
-
|
|
544
|
-
var dir_path,
|
|
545
|
-
helperFiles,
|
|
546
|
-
fileCount,
|
|
547
|
-
filePath,
|
|
548
|
-
dirs,
|
|
549
|
-
name;
|
|
550
|
-
|
|
551
|
-
// Make a path out of all the arguments
|
|
552
|
-
dir_path = alchemy.pathResolve.apply(null, path_pieces);
|
|
553
|
-
|
|
554
|
-
if (typeof _duplicateCheck[dir_path] != 'undefined') return false;
|
|
555
|
-
|
|
556
|
-
if (!fs.existsSync(dir_path)) {
|
|
557
|
-
_duplicateCheck[dir_path] = false;
|
|
558
|
-
return false;
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
// Possible sub dirs
|
|
562
|
-
dirs = [];
|
|
563
|
-
|
|
564
|
-
try {
|
|
565
|
-
helperFiles = fs.readdirSync(dir_path);
|
|
566
|
-
|
|
567
|
-
for (fileCount in helperFiles) {
|
|
568
|
-
name = helperFiles[fileCount];
|
|
569
|
-
|
|
570
|
-
// Don't require the "empty" file or any hidden files
|
|
571
|
-
if (name == 'empty' || name[0] == '.') {
|
|
572
|
-
continue;
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
try {
|
|
576
|
-
filePath = path.resolve(dir_path, name);
|
|
577
|
-
|
|
578
|
-
if (fs.lstatSync(filePath).isDirectory()) {
|
|
579
|
-
dirs.push(filePath);
|
|
580
|
-
} else {
|
|
581
|
-
alchemy.hawkejs.load(filePath, {
|
|
582
|
-
arguments : 'hawkejs'
|
|
583
|
-
});
|
|
584
|
-
}
|
|
585
|
-
} catch (err) {
|
|
586
|
-
alchemy.printLog('warning', ['Unable to add helper file ' + name + '\n' + String(err), err], {err: err, level: -2});
|
|
587
|
-
alchemy.printLog('warning', ['File was at', filePath], {err: err, level: -2});
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
_duplicateCheck[dir_path] = true;
|
|
592
|
-
|
|
593
|
-
for (let i = 0; i < dirs.length; i++) {
|
|
594
|
-
loadHelpers(dirs[i]);
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
return true;
|
|
598
|
-
} catch (err) {
|
|
599
|
-
|
|
600
|
-
_duplicateCheck[dir_path] = false;
|
|
601
|
-
log.warn('Was unable to read in helper directory ' + dir_path);
|
|
602
|
-
|
|
603
|
-
return false;
|
|
604
|
-
}
|
|
605
|
-
};
|
|
606
|
-
|
|
607
|
-
/**
|
|
608
|
-
* Check haystack for a regex
|
|
609
|
-
*
|
|
610
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
611
|
-
* @since 0.0.1
|
|
612
|
-
* @version 0.4.0
|
|
613
|
-
*
|
|
614
|
-
* @param {String} haystack The string to compare to
|
|
615
|
-
* @param {Array} needles An array of regexes
|
|
616
|
-
* @param {Number} currentLevel The current level we're on
|
|
617
|
-
*
|
|
618
|
-
* @returns {boolean} False if no match was found, true if any matched
|
|
619
|
-
*/
|
|
620
|
-
prive.checkRegex = function checkRegex(haystack, needles, currentLevel) {
|
|
621
|
-
|
|
622
|
-
var rexCount,
|
|
623
|
-
rex;
|
|
624
|
-
|
|
625
|
-
if (typeof currentLevel == 'undefined') {
|
|
626
|
-
currentLevel = -1;
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
// See if we need to ignore this file according to the given regex
|
|
630
|
-
if (needles instanceof RegExp && needles.exec(haystack)) {
|
|
631
|
-
return true;
|
|
632
|
-
} else if (needles instanceof Array) {
|
|
633
|
-
|
|
634
|
-
for (rexCount = 0; rexCount < needles.length; rexCount++) {
|
|
635
|
-
|
|
636
|
-
rex = needles[rexCount];
|
|
637
|
-
|
|
638
|
-
if (rex instanceof RegExp) {
|
|
639
|
-
if (rex.exec(haystack)) return true;
|
|
640
|
-
} else {
|
|
641
|
-
if (rex.constructor.name == 'Object' && rex.regex instanceof RegExp) {
|
|
642
|
-
if (rex.level < 0 || rex.level == currentLevel) {
|
|
643
|
-
if (rex.regex.exec(haystack)) {
|
|
644
|
-
return true;
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
return false;
|
|
653
|
-
};
|
|
654
|
-
|
|
655
|
-
/**
|
|
656
|
-
* Prepare a plugin for use.
|
|
657
|
-
* This immediately executes the plugin's bootstrap.js file,
|
|
658
|
-
* but the loading of the app tree happens later.
|
|
659
|
-
*
|
|
660
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
661
|
-
* @since 0.0.1
|
|
662
|
-
* @version 1.1.0
|
|
663
|
-
*
|
|
664
|
-
* @param {String} name The name of the plugin (which is its path)
|
|
665
|
-
* @param {Object} options Options to pass to the plugin
|
|
666
|
-
*/
|
|
667
|
-
Alchemy.setMethod(function usePlugin(name, options) {
|
|
668
|
-
|
|
669
|
-
var possible_paths,
|
|
670
|
-
path_to_plugin,
|
|
671
|
-
plugin_stat,
|
|
672
|
-
full_name,
|
|
673
|
-
is_dir = false;
|
|
674
|
-
|
|
675
|
-
// Strip of the "alchemy-" from the name, should it be given
|
|
676
|
-
if (name.startsWith('alchemy-')) {
|
|
677
|
-
name = name.slice(8);
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
// The "full" name starts with "alchemy-"
|
|
681
|
-
full_name = 'alchemy-' + name;
|
|
682
|
-
|
|
683
|
-
if (alchemy.plugins[name] != null) {
|
|
684
|
-
|
|
685
|
-
if (options) {
|
|
686
|
-
log.warn('Tried to load plugin "' + name + '" with options twice!');
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
return true;
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
if (options == null) {
|
|
693
|
-
options = {};
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
// Create the possible paths to this plugin
|
|
697
|
-
possible_paths = [];
|
|
698
|
-
|
|
699
|
-
if (options.path_to_plugin) {
|
|
700
|
-
possible_paths.push(options.path_to_plugin);
|
|
701
|
-
} else {
|
|
702
|
-
|
|
703
|
-
let temp,
|
|
704
|
-
key;
|
|
705
|
-
|
|
706
|
-
// Look for the "alchemy-" path first
|
|
707
|
-
possible_paths.push(alchemy.pathResolve(PATH_ROOT, 'node_modules', full_name));
|
|
708
|
-
possible_paths.push(alchemy.pathResolve(PATH_ROOT, 'node_modules', name));
|
|
709
|
-
|
|
710
|
-
// It's also allowed to be inside the app/plugins folder
|
|
711
|
-
possible_paths.push(alchemy.pathResolve(PATH_APP, 'plugins', full_name));
|
|
712
|
-
possible_paths.push(alchemy.pathResolve(PATH_APP, 'plugins', name));
|
|
713
|
-
|
|
714
|
-
// And even in other plugins
|
|
715
|
-
for (key in alchemy.plugins) {
|
|
716
|
-
temp = alchemy.plugins[key];
|
|
717
|
-
possible_paths.push(alchemy.pathResolve(temp.__path, 'node_modules', full_name));
|
|
718
|
-
possible_paths.push(alchemy.pathResolve(temp.__path, 'node_modules', name));
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
// Look for the plugin in every possible path
|
|
723
|
-
possible_paths.some(function eachPath(value) {
|
|
724
|
-
|
|
725
|
-
try {
|
|
726
|
-
path_to_plugin = value;
|
|
727
|
-
plugin_stat = fs.lstatSync(path_to_plugin);
|
|
728
|
-
is_dir = plugin_stat.isDirectory() || plugin_stat.isSymbolicLink();
|
|
729
|
-
|
|
730
|
-
// Stop the loop, path has been found
|
|
731
|
-
return true;
|
|
732
|
-
} catch (err) {
|
|
733
|
-
// Try the next value
|
|
734
|
-
return false;
|
|
735
|
-
}
|
|
736
|
-
});
|
|
737
|
-
|
|
738
|
-
if (is_dir) {
|
|
739
|
-
|
|
740
|
-
// Pass along the path the plugin is in
|
|
741
|
-
options.__path = path_to_plugin;
|
|
742
|
-
|
|
743
|
-
// Set the given options
|
|
744
|
-
alchemy.plugins[name] = options;
|
|
745
|
-
|
|
746
|
-
try {
|
|
747
|
-
// Require the bootstrap.js file now, if it exists
|
|
748
|
-
alchemy.useOnce(alchemy.pathResolve(path_to_plugin, 'bootstrap.js'), {throwError: true});
|
|
749
|
-
} catch (err) {
|
|
750
|
-
// Only throw an error when loading failed
|
|
751
|
-
// because bootstrap files are not required
|
|
752
|
-
if (err.message.indexOf('Cannot find') === -1) {
|
|
753
|
-
throw err;
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
|
|
757
|
-
return true;
|
|
758
|
-
} else {
|
|
759
|
-
log.error('Could not find ' + JSON.stringify(name) + ' plugin directory');
|
|
760
|
-
return false;
|
|
761
|
-
}
|
|
762
|
-
});
|
|
763
|
-
|
|
764
|
-
/**
|
|
765
|
-
* Start all the loaded plugins
|
|
766
|
-
*
|
|
767
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
768
|
-
* @since 0.0.1
|
|
769
|
-
* @version 1.1.0
|
|
770
|
-
*
|
|
771
|
-
* @param {String|Array} names Names of plugins to start
|
|
772
|
-
*/
|
|
773
|
-
Alchemy.setMethod(function startPlugins(names) {
|
|
774
|
-
|
|
775
|
-
var plugin,
|
|
776
|
-
path,
|
|
777
|
-
name,
|
|
778
|
-
all;
|
|
779
|
-
|
|
780
|
-
if (!names) {
|
|
781
|
-
all = true;
|
|
782
|
-
|
|
783
|
-
// Make sure all the constitutions of the core classes are loaded
|
|
784
|
-
Blast.doLoaded();
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
if (typeof names == 'string') {
|
|
788
|
-
names = [names];
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
for (name in alchemy.plugins) {
|
|
792
|
-
|
|
793
|
-
if (!all && names.indexOf(name) == -1) {
|
|
794
|
-
continue;
|
|
795
|
-
}
|
|
796
|
-
|
|
797
|
-
plugin = alchemy.plugins[name];
|
|
798
|
-
path = plugin.__path;
|
|
799
|
-
|
|
800
|
-
if (path) {
|
|
801
|
-
if (!plugin[LOADED]) {
|
|
802
|
-
alchemy.usePath(path, {plugin: true});
|
|
803
|
-
plugin[LOADED] = true;
|
|
804
|
-
}
|
|
805
|
-
} else {
|
|
806
|
-
log.error('Plugin path was undefined: ' + name);
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
});
|
|
810
|
-
|
|
811
|
-
/**
|
|
812
|
-
* If a plugin hasn't been loaded yet, but it is required, die
|
|
813
|
-
*
|
|
814
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
815
|
-
* @since 0.0.1
|
|
816
|
-
* @version 1.2.2
|
|
817
|
-
*
|
|
818
|
-
* @param {String|Array} names
|
|
819
|
-
* @param {Boolean} attempt_require
|
|
820
|
-
*/
|
|
821
|
-
Alchemy.setMethod(function requirePlugin(names, attempt_require) {
|
|
822
|
-
|
|
823
|
-
var message,
|
|
824
|
-
missing = '',
|
|
825
|
-
name,
|
|
826
|
-
temp,
|
|
827
|
-
i;
|
|
828
|
-
|
|
829
|
-
if (attempt_require == null) {
|
|
830
|
-
attempt_require = true;
|
|
831
|
-
}
|
|
832
|
-
|
|
833
|
-
if (!Array.isArray(names)) {
|
|
834
|
-
names = [names];
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
for (i = 0; i < names.length; i++) {
|
|
838
|
-
|
|
839
|
-
name = names[i];
|
|
840
|
-
|
|
841
|
-
if (typeof alchemy.plugins[name] === 'undefined') {
|
|
842
|
-
|
|
843
|
-
if (attempt_require) {
|
|
844
|
-
temp = alchemy.usePlugin(name);
|
|
845
|
-
|
|
846
|
-
if (temp) {
|
|
847
|
-
let plugin_stage = alchemy.sputnik.get('plugins');
|
|
848
|
-
|
|
849
|
-
if (!plugin_stage || plugin_stage.started) {
|
|
850
|
-
// If the plugin stage has already started,
|
|
851
|
-
// manually start this plugin now
|
|
852
|
-
alchemy.startPlugins(name);
|
|
853
|
-
}
|
|
854
|
-
continue;
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
if (missing) {
|
|
859
|
-
missing += ', ';
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
missing += name;
|
|
863
|
-
}
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
if (missing) {
|
|
867
|
-
message = 'These required plugin(s) are missing: ' + missing;
|
|
868
|
-
die(message, {level: 2});
|
|
869
|
-
}
|
|
870
|
-
});
|
|
871
|
-
|
|
872
|
-
/**
|
|
873
|
-
* Load in a file only once
|
|
874
|
-
*
|
|
875
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
876
|
-
* @since 0.0.1
|
|
877
|
-
* @version 1.1.0
|
|
878
|
-
*/
|
|
879
|
-
Alchemy.setMethod(function useOnce(dirPath, options) {
|
|
880
|
-
|
|
881
|
-
if (typeof options == 'undefined') {
|
|
882
|
-
options = {};
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
dirPath = alchemy.pathResolve.apply(null, arguments);
|
|
886
|
-
|
|
887
|
-
if (dirPath.indexOf('.js') === -1) {
|
|
888
|
-
//log.verbose('Skipped non JS file: ' + dirPath.split('/').pop());
|
|
889
|
-
return false;
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
if (typeof _duplicateCheck[dirPath] === 'undefined') {
|
|
893
|
-
|
|
894
|
-
// Mainly used for tidying up the unit tests
|
|
895
|
-
if (process.env.NO_ALCHEMY_LOAD_WARNING == 1) {
|
|
896
|
-
options.throwError = false;
|
|
897
|
-
options.silent = true;
|
|
898
|
-
}
|
|
899
|
-
|
|
900
|
-
// Make sure the next requirement uses strict
|
|
901
|
-
alchemy.makeNextRequireStrict();
|
|
902
|
-
|
|
903
|
-
try {
|
|
904
|
-
require(dirPath);
|
|
905
|
-
_duplicateCheck[dirPath] = true;
|
|
906
|
-
//log.verbose('Used file once: ' + dirPath, {level: 1});
|
|
907
|
-
} catch (err) {
|
|
908
|
-
|
|
909
|
-
// Add the path to the file that failed to load,
|
|
910
|
-
// this can be used when it's a syntax error
|
|
911
|
-
// (It's hard to find the cause otherwise)
|
|
912
|
-
err.file_path = dirPath;
|
|
913
|
-
|
|
914
|
-
_duplicateCheck[dirPath] = false;
|
|
915
|
-
|
|
916
|
-
if (options.throwError !== false) {
|
|
917
|
-
|
|
918
|
-
if (options.throwError !== true) {
|
|
919
|
-
let yellow = __Janeway.esc('103;91');
|
|
920
|
-
alchemy.printLog('error', [yellow + '========================='], {err: err, level: -2});
|
|
921
|
-
alchemy.printLog('error', [yellow + ' Failed to load file: '], {err: err, level: -2});
|
|
922
|
-
alchemy.printLog('error', [yellow + ' »', dirPath.split(path.sep).last()], {err: err, level: -2});
|
|
923
|
-
alchemy.printLog('error', [yellow + ' In directory: '], {err: err, level: -2});
|
|
924
|
-
alchemy.printLog('error', [yellow + ' »', dirPath.split(path.sep).slice(0, -1).join(path.sep)], {err: err, level: -2});
|
|
925
|
-
alchemy.printLog('error', [yellow + ' With error: '], {err: err, level: -2});
|
|
926
|
-
alchemy.printLog('error', [yellow + ' »', err], {err: err, level: -2});
|
|
927
|
-
alchemy.printLog('error', [yellow + '========================='], {err: err, level: -2});
|
|
928
|
-
}
|
|
929
|
-
|
|
930
|
-
throw err;
|
|
931
|
-
}
|
|
932
|
-
|
|
933
|
-
if (!options.silent) {
|
|
934
|
-
// @todo: "Failed to use file once..." message doesn't get displayed
|
|
935
|
-
log.error('Failed to use file once: ' + dirPath, {level: 5, err: err, extra: true});
|
|
936
|
-
}
|
|
937
|
-
}
|
|
938
|
-
} else {
|
|
939
|
-
//log.verbose('File not loaded, already used once: ' + dirPath, {level: 1});
|
|
940
|
-
}
|
|
941
|
-
});
|
|
942
|
-
|
|
943
|
-
/**
|
|
944
|
-
* Make the next `require` call strict
|
|
945
|
-
*
|
|
946
|
-
* @author Jelle De Loecker <jelle@develry.be>
|
|
947
|
-
* @since 0.4.0
|
|
948
|
-
* @version 0.4.0
|
|
949
|
-
*/
|
|
950
|
-
Alchemy.setMethod(function makeNextRequireStrict() {
|
|
951
|
-
// Overwrite the original wrap method
|
|
952
|
-
module.wrap = function wrap(script) {
|
|
953
|
-
|
|
954
|
-
// Restore the original functions
|
|
955
|
-
module.wrap = original_wrap;
|
|
956
|
-
module._resolveFilename = original_resolve;
|
|
957
|
-
|
|
958
|
-
// Add the strict wrapper for this requirement
|
|
959
|
-
return strict_wrapper + script + module.wrapper[1];
|
|
960
|
-
};
|
|
961
|
-
|
|
962
|
-
// Overwrite the original _resolveFilename method
|
|
963
|
-
module._resolveFilename = function _resolveFilename(request, parent, isMain) {
|
|
964
|
-
try {
|
|
965
|
-
return original_resolve(request, parent, isMain);
|
|
966
|
-
} catch (err) {
|
|
967
|
-
module.wrap = original_wrap;
|
|
968
|
-
module._resolveFilename = original_resolve;
|
|
969
|
-
throw err;
|
|
970
|
-
}
|
|
971
|
-
};
|
|
972
|
-
|
|
973
|
-
});
|