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
|
@@ -0,0 +1,715 @@
|
|
|
1
|
+
let fs = alchemy.use('fs'),
|
|
2
|
+
libpath = alchemy.use('path'),
|
|
3
|
+
LOADED = Symbol('LOADED'),
|
|
4
|
+
_duplicateCheck = {};
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Require the given path.
|
|
8
|
+
* The path follows an app structure.
|
|
9
|
+
*
|
|
10
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
11
|
+
* @since 1.4.0
|
|
12
|
+
* @version 1.4.0
|
|
13
|
+
*
|
|
14
|
+
* @param {string} dir_path
|
|
15
|
+
* @param {Object} options
|
|
16
|
+
*
|
|
17
|
+
* @return {boolean}
|
|
18
|
+
*/
|
|
19
|
+
Alchemy.setMethod(function useAppPath(dir_path, options) {
|
|
20
|
+
|
|
21
|
+
if (!fs.existsSync(dir_path)) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (!options) {
|
|
26
|
+
options = {};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (options.plugin && options.weight == null) {
|
|
30
|
+
options.weight = 15;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let context = options?.plugin || this;
|
|
34
|
+
|
|
35
|
+
let server_directories = new Map(),
|
|
36
|
+
helper_directories = new Map(),
|
|
37
|
+
files = new Map();
|
|
38
|
+
|
|
39
|
+
let config_directory,
|
|
40
|
+
asset_directory,
|
|
41
|
+
view_directory,
|
|
42
|
+
public_path,
|
|
43
|
+
root_path;
|
|
44
|
+
|
|
45
|
+
// Loop over all the entries in the app directory
|
|
46
|
+
eachDirectoryEntryStats(dir_path, (file_path, name, stat) => {
|
|
47
|
+
|
|
48
|
+
if (stat.isDirectory()) {
|
|
49
|
+
let corrected_name,
|
|
50
|
+
is_helper = false;
|
|
51
|
+
|
|
52
|
+
if (name == 'helper' || name == 'element') {
|
|
53
|
+
corrected_name = name;
|
|
54
|
+
is_helper = true;
|
|
55
|
+
} else if (name.startsWith('helper_')) {
|
|
56
|
+
corrected_name = name.slice(7);
|
|
57
|
+
is_helper = true;
|
|
58
|
+
} else if (name == 'assets') {
|
|
59
|
+
asset_directory = file_path;
|
|
60
|
+
return;
|
|
61
|
+
} else if (name == 'view') {
|
|
62
|
+
view_directory = file_path;
|
|
63
|
+
return;
|
|
64
|
+
} else if (name == 'public') {
|
|
65
|
+
public_path = file_path;
|
|
66
|
+
return;
|
|
67
|
+
} else if (name == 'root') {
|
|
68
|
+
root_path = file_path;
|
|
69
|
+
return;
|
|
70
|
+
} else if (name == 'config') {
|
|
71
|
+
config_directory = file_path;
|
|
72
|
+
return;
|
|
73
|
+
} else if (name == 'source') {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (is_helper) {
|
|
78
|
+
helper_directories.set(corrected_name, file_path);
|
|
79
|
+
} else {
|
|
80
|
+
server_directories.set(name, file_path);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
files.set(name, file_path);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// Load the bootstrap file first
|
|
88
|
+
if (files.get('bootstrap.js')) {
|
|
89
|
+
|
|
90
|
+
if (!options.plugin) {
|
|
91
|
+
context.useOnce(files.get('bootstrap.js'));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
files.delete('bootstrap.js');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (config_directory) {
|
|
98
|
+
context.usePath(config_directory, options);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (options.helpers !== false) {
|
|
102
|
+
|
|
103
|
+
if (helper_directories.get('error')) {
|
|
104
|
+
this.useHelperPath(helper_directories.get('error'));
|
|
105
|
+
helper_directories.delete('error');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (helper_directories.get('datasource')) {
|
|
109
|
+
this.useHelperPath(helper_directories.get('datasource'));
|
|
110
|
+
helper_directories.delete('datasource');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (helper_directories.get('field')) {
|
|
114
|
+
this.useHelperPath(helper_directories.get('field'));
|
|
115
|
+
helper_directories.delete('field');
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (helper_directories.get('helper')) {
|
|
119
|
+
this.useHelperPath(helper_directories.get('helper'));
|
|
120
|
+
helper_directories.delete('helper');
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Load the server-side code next
|
|
125
|
+
for (let [name, file_path] of server_directories) {
|
|
126
|
+
context.usePath(file_path);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (options.helpers !== false) {
|
|
130
|
+
|
|
131
|
+
if (helper_directories.get('element')) {
|
|
132
|
+
this.useHelperPath(helper_directories.get('element'));
|
|
133
|
+
helper_directories.delete('element');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (helper_directories.get('model')) {
|
|
137
|
+
this.useHelperPath(helper_directories.get('model'));
|
|
138
|
+
helper_directories.delete('model');
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (helper_directories.get('document')) {
|
|
142
|
+
this.useHelperPath(helper_directories.get('document'));
|
|
143
|
+
helper_directories.delete('document');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (helper_directories.get('controller')) {
|
|
147
|
+
this.useHelperPath(helper_directories.get('controller'));
|
|
148
|
+
helper_directories.delete('controller');
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (helper_directories.get('component')) {
|
|
152
|
+
this.useHelperPath(helper_directories.get('component'));
|
|
153
|
+
helper_directories.delete('component');
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (helper_directories.get('validator')) {
|
|
157
|
+
this.useHelperPath(helper_directories.get('validator'));
|
|
158
|
+
helper_directories.delete('validator');
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
for (let [name, file_path] of helper_directories) {
|
|
162
|
+
this.useHelperPath(file_path);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (view_directory && options.views !== false) {
|
|
167
|
+
alchemy.addViewDirectory(view_directory, options.weight);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (asset_directory) {
|
|
171
|
+
// Add the main asset directory
|
|
172
|
+
alchemy.addAssetDirectory(asset_directory, options.weight);
|
|
173
|
+
|
|
174
|
+
if (options.scripts !== false) {
|
|
175
|
+
alchemy.addScriptDirectory(libpath.resolve(asset_directory, 'scripts'), options.weight);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (options.stylesheets !== false) {
|
|
179
|
+
alchemy.addStylesheetDirectory(libpath.resolve(asset_directory, 'stylesheets'), options.weight);
|
|
180
|
+
|
|
181
|
+
// Also add the public folder, so less files in there can also be compiled
|
|
182
|
+
alchemy.addStylesheetDirectory(libpath.resolve(dir_path, 'public'), options.weight);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (options.fonts !== false) {
|
|
186
|
+
alchemy.addFontDirectory(libpath.resolve(asset_directory, 'fonts'), options.weight);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (options.images !== false) {
|
|
190
|
+
alchemy.addImageDirectory(libpath.resolve(asset_directory, 'images'), options.weight);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (public_path && options.public !== false) {
|
|
195
|
+
alchemy.addPublicDirectory(public_path, options.weight);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (root_path && options.root !== false) {
|
|
199
|
+
alchemy.addRootDirectory(root_path, options.weight);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Require the given helper path
|
|
205
|
+
*
|
|
206
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
207
|
+
* @since 1.4.0
|
|
208
|
+
* @version 1.4.0
|
|
209
|
+
*
|
|
210
|
+
* @param {string} dir_path
|
|
211
|
+
* @param {Object} options
|
|
212
|
+
*
|
|
213
|
+
* @return {boolean}
|
|
214
|
+
*/
|
|
215
|
+
Alchemy.setMethod(function useHelperPath(dir_path, options) {
|
|
216
|
+
|
|
217
|
+
let sub_directories = [];
|
|
218
|
+
|
|
219
|
+
eachDirectoryEntryStats(dir_path, (file_path, name, stat) => {
|
|
220
|
+
|
|
221
|
+
if (stat.isDirectory()) {
|
|
222
|
+
sub_directories.push(file_path);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
try {
|
|
227
|
+
alchemy.hawkejs.load(file_path, {
|
|
228
|
+
arguments : 'hawkejs'
|
|
229
|
+
});
|
|
230
|
+
} catch (err) {
|
|
231
|
+
alchemy.printLog('warning', ['Unable to add helper file ' + name + '\n' + String(err), err], {err: err, level: -2});
|
|
232
|
+
alchemy.printLog('warning', ['File was at', file_path], {err: err, level: -2});
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
for (let dir of sub_directories) {
|
|
237
|
+
this.useHelperPath(dir, options);
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Require all the files in the given path.
|
|
243
|
+
*
|
|
244
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
245
|
+
* @since 1.4.0
|
|
246
|
+
* @version 1.4.0
|
|
247
|
+
*
|
|
248
|
+
* @param {string} dir_path
|
|
249
|
+
* @param {Object} options
|
|
250
|
+
*
|
|
251
|
+
* @return {boolean}
|
|
252
|
+
*/
|
|
253
|
+
Alchemy.setMethod(function usePath(dir_path, options) {
|
|
254
|
+
|
|
255
|
+
let recursive = options?.recursive !== false,
|
|
256
|
+
sub_directories = [];
|
|
257
|
+
|
|
258
|
+
let context = options?.plugin || this;
|
|
259
|
+
|
|
260
|
+
eachDirectoryEntryStats(dir_path, (file_path, name, stat) => {
|
|
261
|
+
|
|
262
|
+
if (stat.isDirectory()) {
|
|
263
|
+
if (recursive) {
|
|
264
|
+
sub_directories.push(file_path);
|
|
265
|
+
}
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
context.useOnce(file_path);
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
if (recursive && sub_directories.length) {
|
|
273
|
+
for (let dir of sub_directories) {
|
|
274
|
+
context.usePath(dir, options);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Iterate over a directory's content, but only
|
|
281
|
+
*
|
|
282
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
283
|
+
* @since 1.4.0
|
|
284
|
+
* @version 1.4.0
|
|
285
|
+
*
|
|
286
|
+
* @param {string} path
|
|
287
|
+
* @param {Function} callback
|
|
288
|
+
*/
|
|
289
|
+
function eachDirectoryEntryStats(path, callback) {
|
|
290
|
+
|
|
291
|
+
let extension,
|
|
292
|
+
file_path,
|
|
293
|
+
files = fs.readdirSync(path),
|
|
294
|
+
stat;
|
|
295
|
+
|
|
296
|
+
for (let file of files) {
|
|
297
|
+
|
|
298
|
+
// Ignore all the hidden files
|
|
299
|
+
if (file[0] == '.') {
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
switch (file) {
|
|
304
|
+
case 'node_modules':
|
|
305
|
+
case 'test':
|
|
306
|
+
case 'empty':
|
|
307
|
+
case 'migrations':
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Ignore manual files
|
|
312
|
+
if (file.includes('.manual.')) {
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
extension = libpath.extname(file).toLowerCase();
|
|
317
|
+
|
|
318
|
+
switch (extension) {
|
|
319
|
+
case '.md':
|
|
320
|
+
case '.json':
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
file_path = libpath.resolve(path, file);
|
|
325
|
+
stat = fs.lstatSync(file_path);
|
|
326
|
+
|
|
327
|
+
callback(file_path, file, stat);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Default _usePath options
|
|
333
|
+
*
|
|
334
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
335
|
+
* @since 0.5.0
|
|
336
|
+
* @version 0.5.0
|
|
337
|
+
*
|
|
338
|
+
* @type {Object}
|
|
339
|
+
*/
|
|
340
|
+
Alchemy.setProperty('default_use_path_options', {
|
|
341
|
+
ignore : false,
|
|
342
|
+
recursive : -1,
|
|
343
|
+
_level : -1,
|
|
344
|
+
|
|
345
|
+
// Load the bootstrap.js file first
|
|
346
|
+
bootstrap : true,
|
|
347
|
+
|
|
348
|
+
// Load the app_ file afterwards
|
|
349
|
+
app : true
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Add an asset directory
|
|
354
|
+
*
|
|
355
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
356
|
+
* @since 0.2.0
|
|
357
|
+
* @version 0.4.0
|
|
358
|
+
*
|
|
359
|
+
* @param {string} dirPath The path to load
|
|
360
|
+
* @param {number} weight The weighted importance [10]
|
|
361
|
+
*/
|
|
362
|
+
Alchemy.setMethod(function addAssetDirectory(dirPath, weight) {
|
|
363
|
+
|
|
364
|
+
if (typeof weight !== 'number') {
|
|
365
|
+
weight = 10;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
alchemy.shared('asset.directories').push(dirPath, weight);
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Add a scripts directory
|
|
373
|
+
*
|
|
374
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
375
|
+
* @since 0.2.0
|
|
376
|
+
* @version 0.4.0
|
|
377
|
+
*
|
|
378
|
+
* @param {string} dirPath The path to load
|
|
379
|
+
* @param {number} weight The weighted importance [10]
|
|
380
|
+
*/
|
|
381
|
+
Alchemy.setMethod(function addScriptDirectory(dirPath, weight) {
|
|
382
|
+
|
|
383
|
+
if (typeof weight !== 'number') {
|
|
384
|
+
weight = 10;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
alchemy.shared('script.directories').push(dirPath, weight);
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Add a stylesheets directory
|
|
392
|
+
*
|
|
393
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
394
|
+
* @since 0.2.0
|
|
395
|
+
* @version 0.4.0
|
|
396
|
+
*
|
|
397
|
+
* @param {string} dirPath The path to load
|
|
398
|
+
* @param {number} weight The weighted importance [10]
|
|
399
|
+
*/
|
|
400
|
+
Alchemy.setMethod(function addStylesheetDirectory(dirPath, weight) {
|
|
401
|
+
|
|
402
|
+
if (typeof weight !== 'number') {
|
|
403
|
+
weight = 10;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
alchemy.shared('stylesheet.directories').push(dirPath, weight);
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Add a font directory
|
|
411
|
+
*
|
|
412
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
413
|
+
* @since 1.1.3
|
|
414
|
+
* @version 1.1.3
|
|
415
|
+
*
|
|
416
|
+
* @param {string} dirPath The path to load
|
|
417
|
+
* @param {number} weight The weighted importance [10]
|
|
418
|
+
*/
|
|
419
|
+
Alchemy.setMethod(function addFontDirectory(dirPath, weight) {
|
|
420
|
+
|
|
421
|
+
if (typeof weight !== 'number') {
|
|
422
|
+
weight = 10;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
alchemy.shared('font.directories').push(dirPath, weight);
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Add an image directory
|
|
430
|
+
*
|
|
431
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
432
|
+
* @since 0.2.0
|
|
433
|
+
* @version 0.4.0
|
|
434
|
+
*
|
|
435
|
+
* @param {string} dirPath The path to load
|
|
436
|
+
* @param {number} weight The weighted importance [10]
|
|
437
|
+
*/
|
|
438
|
+
Alchemy.setMethod(function addImageDirectory(dirPath, weight) {
|
|
439
|
+
|
|
440
|
+
if (typeof weight !== 'number') {
|
|
441
|
+
weight = 10;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
alchemy.shared('images.directories').push(dirPath, weight);
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Add a public directory
|
|
449
|
+
*
|
|
450
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
451
|
+
* @since 0.2.0
|
|
452
|
+
* @version 0.4.0
|
|
453
|
+
*
|
|
454
|
+
* @param {string} dirPath The path to load
|
|
455
|
+
* @param {number} weight The weighted importance [10]
|
|
456
|
+
*/
|
|
457
|
+
Alchemy.setMethod(function addPublicDirectory(dirPath, weight) {
|
|
458
|
+
|
|
459
|
+
if (typeof weight !== 'number') {
|
|
460
|
+
weight = 10;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
alchemy.shared('public.directories').push(dirPath, weight);
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Add a root directory
|
|
468
|
+
*
|
|
469
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
470
|
+
* @since 0.2.0
|
|
471
|
+
* @version 0.4.0
|
|
472
|
+
*
|
|
473
|
+
* @param {string} dirPath The path to load
|
|
474
|
+
* @param {number} weight The weighted importance [10]
|
|
475
|
+
*/
|
|
476
|
+
Alchemy.setMethod(function addRootDirectory(dirPath, weight) {
|
|
477
|
+
|
|
478
|
+
if (typeof weight !== 'number') {
|
|
479
|
+
weight = 10;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
alchemy.shared('root.directories').push(dirPath, weight);
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Tell hawkejs to use this path to look for views.
|
|
487
|
+
*
|
|
488
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
489
|
+
* @since 0.0.1
|
|
490
|
+
* @version 0.4.0
|
|
491
|
+
*
|
|
492
|
+
* @param {string} dirPath The path to load
|
|
493
|
+
* @param {number} weight The weighted importance [10]
|
|
494
|
+
*/
|
|
495
|
+
Alchemy.setMethod(function addViewDirectory(dirPath, weight) {
|
|
496
|
+
|
|
497
|
+
if (typeof weight !== 'number') {
|
|
498
|
+
weight = 10;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
alchemy.hawkejs.addViewDirectory(dirPath, weight);
|
|
502
|
+
});
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* Prepare a plugin for use.
|
|
506
|
+
* This immediately executes the plugin's bootstrap.js file,
|
|
507
|
+
* but the loading of the app tree happens later.
|
|
508
|
+
*
|
|
509
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
510
|
+
* @since 0.0.1
|
|
511
|
+
* @version 1.4.0
|
|
512
|
+
*
|
|
513
|
+
* @param {string} name The name of the plugin (which is its path)
|
|
514
|
+
* @param {Object} options Options to pass to the plugin
|
|
515
|
+
*
|
|
516
|
+
* @return {Alchemy.Plugin}
|
|
517
|
+
*/
|
|
518
|
+
Alchemy.setMethod(function usePlugin(name, options) {
|
|
519
|
+
|
|
520
|
+
let full_name;
|
|
521
|
+
|
|
522
|
+
// Strip of the "alchemy-" from the name, should it be given
|
|
523
|
+
if (name.startsWith('alchemy-')) {
|
|
524
|
+
full_name = name;
|
|
525
|
+
name = name.slice(8);
|
|
526
|
+
} else {
|
|
527
|
+
// The "full" name starts with "alchemy-"
|
|
528
|
+
full_name = 'alchemy-' + name;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
// Make sure the plugin hasn't been loaded already
|
|
532
|
+
if (alchemy.plugins[name] != null) {
|
|
533
|
+
|
|
534
|
+
if (options) {
|
|
535
|
+
log.warn('Tried to load plugin "' + name + '" with options twice!');
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
return true;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
if (options == null) {
|
|
542
|
+
options = {};
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// Create the possible paths to this plugin
|
|
546
|
+
let possible_paths = [];
|
|
547
|
+
|
|
548
|
+
if (options.path_to_plugin) {
|
|
549
|
+
possible_paths.push(options.path_to_plugin);
|
|
550
|
+
} else {
|
|
551
|
+
// Look for the "alchemy-" path first
|
|
552
|
+
possible_paths.push(alchemy.pathResolve(PATH_ROOT, 'node_modules', full_name));
|
|
553
|
+
possible_paths.push(alchemy.pathResolve(PATH_ROOT, 'node_modules', name));
|
|
554
|
+
|
|
555
|
+
// It's also allowed to be inside the app/plugins folder
|
|
556
|
+
possible_paths.push(alchemy.pathResolve(PATH_APP, 'plugins', full_name));
|
|
557
|
+
possible_paths.push(alchemy.pathResolve(PATH_APP, 'plugins', name));
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
let path_to_plugin,
|
|
561
|
+
is_dir = false;
|
|
562
|
+
|
|
563
|
+
for (let path of possible_paths) {
|
|
564
|
+
try {
|
|
565
|
+
let plugin_stat = fs.lstatSync(path);
|
|
566
|
+
is_dir = plugin_stat.isDirectory() || plugin_stat.isSymbolicLink();
|
|
567
|
+
path_to_plugin = path;
|
|
568
|
+
break;
|
|
569
|
+
} catch (err) {
|
|
570
|
+
// Ignore
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
if (!is_dir) {
|
|
575
|
+
log.error('Could not find ' + JSON.stringify(name) + ' plugin directory');
|
|
576
|
+
return false;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
let instance = new Classes.Alchemy.Plugin(name, path_to_plugin, options);
|
|
580
|
+
|
|
581
|
+
// Set the given options
|
|
582
|
+
alchemy.plugins[name] = instance;
|
|
583
|
+
|
|
584
|
+
instance.doPreload();
|
|
585
|
+
|
|
586
|
+
return instance;
|
|
587
|
+
});
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* If a plugin hasn't been loaded yet, but it is required, die
|
|
591
|
+
*
|
|
592
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
593
|
+
* @since 0.0.1
|
|
594
|
+
* @version 1.4.0
|
|
595
|
+
*
|
|
596
|
+
* @param {string|Array} names
|
|
597
|
+
* @param {boolean} attempt_require
|
|
598
|
+
*/
|
|
599
|
+
Alchemy.setMethod(function requirePlugin(names, attempt_require) {
|
|
600
|
+
|
|
601
|
+
var message,
|
|
602
|
+
missing = '',
|
|
603
|
+
name,
|
|
604
|
+
temp,
|
|
605
|
+
i;
|
|
606
|
+
|
|
607
|
+
if (attempt_require == null) {
|
|
608
|
+
attempt_require = true;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
if (!Array.isArray(names)) {
|
|
612
|
+
names = [names];
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
for (i = 0; i < names.length; i++) {
|
|
616
|
+
|
|
617
|
+
name = names[i];
|
|
618
|
+
|
|
619
|
+
if (typeof alchemy.plugins[name] === 'undefined') {
|
|
620
|
+
|
|
621
|
+
if (attempt_require) {
|
|
622
|
+
temp = alchemy.usePlugin(name);
|
|
623
|
+
|
|
624
|
+
if (temp) {
|
|
625
|
+
let plugin_stage = STAGES.getStage('load_app.plugins');
|
|
626
|
+
|
|
627
|
+
if (!plugin_stage || plugin_stage.started) {
|
|
628
|
+
// If the plugin stage has already started,
|
|
629
|
+
// manually start this plugin now
|
|
630
|
+
alchemy.startPlugins(name);
|
|
631
|
+
}
|
|
632
|
+
continue;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
if (missing) {
|
|
637
|
+
missing += ', ';
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
missing += name;
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
if (missing) {
|
|
645
|
+
message = 'These required plugin(s) are missing: ' + missing;
|
|
646
|
+
die(message, {level: 2});
|
|
647
|
+
}
|
|
648
|
+
});
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* Load in a file only once
|
|
652
|
+
*
|
|
653
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
654
|
+
* @since 0.0.1
|
|
655
|
+
* @version 1.1.0
|
|
656
|
+
*/
|
|
657
|
+
Alchemy.setMethod(function useOnce(dirPath, options) {
|
|
658
|
+
|
|
659
|
+
if (typeof options == 'undefined') {
|
|
660
|
+
options = {};
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
dirPath = alchemy.pathResolve.apply(null, arguments);
|
|
664
|
+
|
|
665
|
+
if (typeof _duplicateCheck[dirPath] === 'undefined') {
|
|
666
|
+
|
|
667
|
+
// Mainly used for tidying up the unit tests
|
|
668
|
+
if (process.env.NO_ALCHEMY_LOAD_WARNING == 1) {
|
|
669
|
+
options.throwError = false;
|
|
670
|
+
options.silent = true;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
if (options.client == null) {
|
|
674
|
+
options.client = false;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
try {
|
|
678
|
+
Blast.require(dirPath, options);
|
|
679
|
+
_duplicateCheck[dirPath] = true;
|
|
680
|
+
//log.verbose('Used file once: ' + dirPath, {level: 1});
|
|
681
|
+
} catch (err) {
|
|
682
|
+
|
|
683
|
+
// Add the path to the file that failed to load,
|
|
684
|
+
// this can be used when it's a syntax error
|
|
685
|
+
// (It's hard to find the cause otherwise)
|
|
686
|
+
err.file_path = dirPath;
|
|
687
|
+
|
|
688
|
+
_duplicateCheck[dirPath] = false;
|
|
689
|
+
|
|
690
|
+
if (options.throwError !== false) {
|
|
691
|
+
|
|
692
|
+
if (options.throwError !== true) {
|
|
693
|
+
let yellow = __Janeway.esc('103;91');
|
|
694
|
+
alchemy.printLog('error', [yellow + '========================='], {err: err, level: -2});
|
|
695
|
+
alchemy.printLog('error', [yellow + ' Failed to load file: '], {err: err, level: -2});
|
|
696
|
+
alchemy.printLog('error', [yellow + ' »', dirPath.split(libpath.sep).last()], {err: err, level: -2});
|
|
697
|
+
alchemy.printLog('error', [yellow + ' In directory: '], {err: err, level: -2});
|
|
698
|
+
alchemy.printLog('error', [yellow + ' »', dirPath.split(libpath.sep).slice(0, -1).join(libpath.sep)], {err: err, level: -2});
|
|
699
|
+
alchemy.printLog('error', [yellow + ' With error: '], {err: err, level: -2});
|
|
700
|
+
alchemy.printLog('error', [yellow + ' »', err], {err: err, level: -2});
|
|
701
|
+
alchemy.printLog('error', [yellow + '========================='], {err: err, level: -2});
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
throw err;
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
if (!options.silent) {
|
|
708
|
+
// @todo: "Failed to use file once..." message doesn't get displayed
|
|
709
|
+
log.error('Failed to use file once: ' + dirPath, {level: 5, err: err, extra: true});
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
} else {
|
|
713
|
+
//log.verbose('File not loaded, already used once: ' + dirPath, {level: 1});
|
|
714
|
+
}
|
|
715
|
+
});
|