alchemymvc 1.4.0-alpha.2 → 1.4.0-alpha.3
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/lib/app/assets/stylesheets/{alchemy-info.less → alchemy-info.scss} +2 -0
- package/lib/app/conduit/loopback_conduit.js +23 -8
- package/lib/app/helper/enum_values.js +29 -10
- package/lib/app/helper/router_helper.js +19 -11
- package/lib/app/helper_field/enum_field.js +13 -0
- package/lib/app/helper_model/document.js +7 -6
- package/lib/app/model/system_task_model.js +13 -4
- package/lib/bootstrap.js +5 -0
- package/lib/class/element.js +16 -0
- package/lib/core/middleware.js +383 -59
- package/lib/scripts/create_shared_constants.js +26 -11
- package/lib/scripts/preload_modules.js +0 -1
- package/package.json +3 -3
|
@@ -89,7 +89,7 @@ LoopConduit.setMethod(function copyParentProperties(conduit) {
|
|
|
89
89
|
*
|
|
90
90
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
91
91
|
* @since 1.1.3
|
|
92
|
-
* @version 1.
|
|
92
|
+
* @version 1.4.0
|
|
93
93
|
*
|
|
94
94
|
* @param {Object} options
|
|
95
95
|
* @param {Function} callback
|
|
@@ -108,17 +108,20 @@ LoopConduit.setMethod(function setOptions(options, callback) {
|
|
|
108
108
|
options = JSON.clone(options);
|
|
109
109
|
|
|
110
110
|
for (key in options) {
|
|
111
|
-
|
|
111
|
+
|
|
112
|
+
// Keep track if a request method has been set
|
|
113
|
+
let got_method = false;
|
|
112
114
|
|
|
113
115
|
info = Classes.Develry.Request.getMethodInfo(key);
|
|
114
116
|
|
|
115
117
|
if (info && options[key]) {
|
|
116
118
|
|
|
117
|
-
if (info.method == 'get' &&
|
|
118
|
-
//
|
|
119
|
+
if (info.method == 'get' && got_method) {
|
|
120
|
+
// If a request method has already been set,
|
|
121
|
+
// do not let `get` options overwrite it!
|
|
119
122
|
} else {
|
|
120
123
|
this.method = key;
|
|
121
|
-
|
|
124
|
+
got_method = true;
|
|
122
125
|
}
|
|
123
126
|
|
|
124
127
|
if (info.has_body && typeof options[key] == 'object') {
|
|
@@ -131,6 +134,8 @@ LoopConduit.setMethod(function setOptions(options, callback) {
|
|
|
131
134
|
this.method = options.method;
|
|
132
135
|
}
|
|
133
136
|
|
|
137
|
+
let route_params = options.params;
|
|
138
|
+
|
|
134
139
|
if (options.name) {
|
|
135
140
|
// @TODO: what about path sections?
|
|
136
141
|
route = this.getRouteByName(options.name);
|
|
@@ -147,7 +152,7 @@ LoopConduit.setMethod(function setOptions(options, callback) {
|
|
|
147
152
|
|
|
148
153
|
// @WARNING: It's best to just generate the URL
|
|
149
154
|
// and let it parse all the information that way
|
|
150
|
-
options.href = this.routeUrl(options.name,
|
|
155
|
+
options.href = this.routeUrl(options.name, route_params, {extra_get_parameters: false});
|
|
151
156
|
}
|
|
152
157
|
|
|
153
158
|
if (!this.method) {
|
|
@@ -158,6 +163,10 @@ LoopConduit.setMethod(function setOptions(options, callback) {
|
|
|
158
163
|
|
|
159
164
|
this.original_url = RURL.parse(options.href);
|
|
160
165
|
|
|
166
|
+
if (options.get && typeof options.get == 'object') {
|
|
167
|
+
this.original_url.addQuery(options.get);
|
|
168
|
+
}
|
|
169
|
+
|
|
161
170
|
this.url = this.original_url;
|
|
162
171
|
this.original_path = this.url.path;
|
|
163
172
|
this.original_pathname = this.url.pathname;
|
|
@@ -169,14 +178,20 @@ LoopConduit.setMethod(function setOptions(options, callback) {
|
|
|
169
178
|
this.parseSection();
|
|
170
179
|
|
|
171
180
|
promise = this.parseRoute();
|
|
181
|
+
} else if (options.get && typeof options.get == 'object') {
|
|
182
|
+
if (!this.params) {
|
|
183
|
+
this.params = {};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
Object.assign(this.params, options.get);
|
|
172
187
|
}
|
|
173
188
|
|
|
174
189
|
if (options.body) {
|
|
175
190
|
this.body = options.body;
|
|
176
191
|
}
|
|
177
192
|
|
|
178
|
-
if (
|
|
179
|
-
this.setRouteParameters(
|
|
193
|
+
if (route_params) {
|
|
194
|
+
this.setRouteParameters(route_params);
|
|
180
195
|
}
|
|
181
196
|
|
|
182
197
|
if (options.arguments) {
|
|
@@ -40,7 +40,7 @@ EnumMap.setMethod(function get(name) {
|
|
|
40
40
|
*
|
|
41
41
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
42
42
|
* @since 1.2.1
|
|
43
|
-
* @version 1.
|
|
43
|
+
* @version 1.4.0
|
|
44
44
|
*
|
|
45
45
|
* @param {string} name
|
|
46
46
|
* @param {*} value
|
|
@@ -65,18 +65,37 @@ EnumMap.setMethod(function set(name, value) {
|
|
|
65
65
|
name : value,
|
|
66
66
|
title : value,
|
|
67
67
|
};
|
|
68
|
-
} else if (typeof value == 'function') {
|
|
69
|
-
result = {
|
|
70
|
-
name : value.name,
|
|
71
|
-
title : value.title,
|
|
72
|
-
};
|
|
73
68
|
} else {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
69
|
+
if (typeof value == 'function') {
|
|
70
|
+
result = {
|
|
71
|
+
name : value.name,
|
|
72
|
+
title : value.title,
|
|
73
|
+
};
|
|
74
|
+
} else {
|
|
75
|
+
result = {
|
|
76
|
+
name : value.name,
|
|
77
|
+
title : value.title || value.name,
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
if (value.icon) {
|
|
81
|
+
result.icon = value.icon;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (value.color) {
|
|
85
|
+
result.color = value.color;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (value.text_color) {
|
|
89
|
+
result.text_color = value.text_color;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (value.enum_info) {
|
|
94
|
+
Object.assign(result, value.enum_info);
|
|
95
|
+
}
|
|
78
96
|
}
|
|
79
97
|
|
|
98
|
+
result.number = this.local.size + 1;
|
|
80
99
|
result.value = value;
|
|
81
100
|
result.is_enumified = true;
|
|
82
101
|
|
|
@@ -112,7 +112,7 @@ Router.setMethod(function isLocalUrl(url) {
|
|
|
112
112
|
*
|
|
113
113
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
114
114
|
* @since 1.1.0
|
|
115
|
-
* @version 1.
|
|
115
|
+
* @version 1.4.0
|
|
116
116
|
*
|
|
117
117
|
* @param {Element} element The element to apply to
|
|
118
118
|
* @param {string} name The route name
|
|
@@ -225,6 +225,8 @@ Router.setMethod(function applyDirective(element, name, options) {
|
|
|
225
225
|
disable_ajax = true;
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
+
let method_attribute = false;
|
|
229
|
+
|
|
228
230
|
if (element.role == 'link') {
|
|
229
231
|
attribute_name = 'href';
|
|
230
232
|
} else {
|
|
@@ -232,6 +234,7 @@ Router.setMethod(function applyDirective(element, name, options) {
|
|
|
232
234
|
switch (element.nodeName) {
|
|
233
235
|
case 'FORM':
|
|
234
236
|
attribute_name = 'action';
|
|
237
|
+
method_attribute = 'method';
|
|
235
238
|
break;
|
|
236
239
|
|
|
237
240
|
case 'AREA':
|
|
@@ -260,6 +263,10 @@ Router.setMethod(function applyDirective(element, name, options) {
|
|
|
260
263
|
}
|
|
261
264
|
}
|
|
262
265
|
|
|
266
|
+
if (method_attribute && config.methods?.[0]) {
|
|
267
|
+
element.setAttribute(method_attribute, config.methods[0]);
|
|
268
|
+
}
|
|
269
|
+
|
|
263
270
|
if (disable_ajax) {
|
|
264
271
|
element.setAttribute('data-he-link', 'false');
|
|
265
272
|
}
|
|
@@ -384,19 +391,13 @@ Router.setMethod(function routeConfig(name, socket_route) {
|
|
|
384
391
|
*/
|
|
385
392
|
Router.setMethod(function routeUrl(name, parameters, options) {
|
|
386
393
|
|
|
387
|
-
var base_url,
|
|
388
|
-
locales,
|
|
389
|
-
config,
|
|
390
|
-
url,
|
|
391
|
-
key,
|
|
392
|
-
i;
|
|
393
|
-
|
|
394
394
|
if (!options) {
|
|
395
395
|
options = {};
|
|
396
396
|
}
|
|
397
397
|
|
|
398
|
-
|
|
399
|
-
|
|
398
|
+
let locales,
|
|
399
|
+
config = options.config || this.routeConfig(name),
|
|
400
|
+
url = '';
|
|
400
401
|
|
|
401
402
|
if (options.locale || options.prefix) {
|
|
402
403
|
locales = [options.prefix || options.locale];
|
|
@@ -417,11 +418,15 @@ Router.setMethod(function routeUrl(name, parameters, options) {
|
|
|
417
418
|
// (in case it's a special parameters object, like a Document)
|
|
418
419
|
parameters = Object.create(parameters);
|
|
419
420
|
}
|
|
421
|
+
} else {
|
|
422
|
+
parameters = {};
|
|
420
423
|
}
|
|
421
424
|
|
|
422
425
|
let chosen_prefix;
|
|
423
426
|
|
|
424
427
|
if (config != null) {
|
|
428
|
+
let i;
|
|
429
|
+
|
|
425
430
|
for (i = 0; i < locales.length; i++) {
|
|
426
431
|
if (config.paths && config.paths[locales[i]]) {
|
|
427
432
|
chosen_prefix = locales[i];
|
|
@@ -435,7 +440,7 @@ Router.setMethod(function routeUrl(name, parameters, options) {
|
|
|
435
440
|
}
|
|
436
441
|
|
|
437
442
|
if (!url && config.paths) {
|
|
438
|
-
key = Object.keys(config.paths).first();
|
|
443
|
+
let key = Object.keys(config.paths).first();
|
|
439
444
|
|
|
440
445
|
if (key) {
|
|
441
446
|
url = '/' + key + config.paths[key];
|
|
@@ -520,6 +525,9 @@ Router.setMethod(function routeUrl(name, parameters, options) {
|
|
|
520
525
|
}
|
|
521
526
|
|
|
522
527
|
if (options.full || options.absolute) {
|
|
528
|
+
|
|
529
|
+
let base_url;
|
|
530
|
+
|
|
523
531
|
if (this.view) {
|
|
524
532
|
base_url = this.view.internal('url');
|
|
525
533
|
}
|
|
@@ -83,4 +83,17 @@ Enum.setMethod(function getClientConfigOptions(wm) {
|
|
|
83
83
|
let options = JSON.clone(this.options, 'toHawkejs', wm);
|
|
84
84
|
|
|
85
85
|
return options;
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Get the configuration entry for the given value
|
|
90
|
+
*
|
|
91
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
92
|
+
* @since 1.4.0
|
|
93
|
+
* @version 1.4.0
|
|
94
|
+
*
|
|
95
|
+
* @return {Object}
|
|
96
|
+
*/
|
|
97
|
+
Enum.setMethod(function getValueConfiguration(value) {
|
|
98
|
+
return this.getValues()?.get?.(value);
|
|
86
99
|
});
|
|
@@ -1002,7 +1002,7 @@ Document.setMethod(function recomputeFieldIfNecessary(name, force = false) {
|
|
|
1002
1002
|
*
|
|
1003
1003
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
1004
1004
|
* @since 1.3.21
|
|
1005
|
-
* @version 1.
|
|
1005
|
+
* @version 1.4.0
|
|
1006
1006
|
*
|
|
1007
1007
|
* @param {string|Alchemy.Field} name
|
|
1008
1008
|
* @param {*} value
|
|
@@ -1018,9 +1018,7 @@ Document.setMethod(function _setComputedFieldValue(name, value) {
|
|
|
1018
1018
|
}
|
|
1019
1019
|
|
|
1020
1020
|
if (Pledge.isThenable(value)) {
|
|
1021
|
-
value.then(value =>
|
|
1022
|
-
this.$main[name] = value;
|
|
1023
|
-
});
|
|
1021
|
+
value = value.then(value => this.$main[name] = value);
|
|
1024
1022
|
} else {
|
|
1025
1023
|
this.$main[name] = value;
|
|
1026
1024
|
}
|
|
@@ -1034,7 +1032,7 @@ Document.setMethod(function _setComputedFieldValue(name, value) {
|
|
|
1034
1032
|
*
|
|
1035
1033
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
1036
1034
|
* @since 1.3.21
|
|
1037
|
-
* @version 1.
|
|
1035
|
+
* @version 1.4.0
|
|
1038
1036
|
*
|
|
1039
1037
|
* @return {Pledge|undefined}
|
|
1040
1038
|
*/
|
|
@@ -1089,8 +1087,11 @@ Document.setMethod(function recomputeValues() {
|
|
|
1089
1087
|
}
|
|
1090
1088
|
|
|
1091
1089
|
let result = compute_method.call(this, this, field);
|
|
1090
|
+
result = this._setComputedFieldValue(key, result);
|
|
1092
1091
|
|
|
1093
|
-
|
|
1092
|
+
if (Pledge.isThenable(result)) {
|
|
1093
|
+
promises.push(result);
|
|
1094
|
+
}
|
|
1094
1095
|
}
|
|
1095
1096
|
|
|
1096
1097
|
if (promises.length) {
|
|
@@ -15,7 +15,7 @@ const SystemTask = Function.inherits('Alchemy.Model.System', 'Task');
|
|
|
15
15
|
*
|
|
16
16
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
17
17
|
* @since 1.3.17
|
|
18
|
-
* @version 1.
|
|
18
|
+
* @version 1.4.0
|
|
19
19
|
*/
|
|
20
20
|
SystemTask.constitute(function addTaskFields() {
|
|
21
21
|
|
|
@@ -48,9 +48,18 @@ SystemTask.constitute(function addTaskFields() {
|
|
|
48
48
|
|
|
49
49
|
this.addField('schedule_type', 'Enum', {
|
|
50
50
|
values: {
|
|
51
|
-
user :
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
user : {
|
|
52
|
+
title : 'User',
|
|
53
|
+
icon : 'user',
|
|
54
|
+
},
|
|
55
|
+
system_forced : {
|
|
56
|
+
title: 'System (forced)',
|
|
57
|
+
icon : 'shield-keyhole',
|
|
58
|
+
},
|
|
59
|
+
system_fallback : {
|
|
60
|
+
title: 'System (fallback)',
|
|
61
|
+
icon : 'shield-halved',
|
|
62
|
+
}
|
|
54
63
|
},
|
|
55
64
|
default: 'user',
|
|
56
65
|
});
|
package/lib/bootstrap.js
CHANGED
package/lib/class/element.js
CHANGED
|
@@ -7,6 +7,22 @@
|
|
|
7
7
|
*/
|
|
8
8
|
const Element = Function.inherits('Hawkejs.Element', 'Alchemy.Element', 'Element');
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Let Alchemy handle the stylesheets of custom elements
|
|
12
|
+
*
|
|
13
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
14
|
+
* @since 1.4.0
|
|
15
|
+
* @version 1.4.0
|
|
16
|
+
*/
|
|
17
|
+
Classes.Hawkejs.Element.Element.setStylesheetHandler(function handleStylesheet(path) {
|
|
18
|
+
|
|
19
|
+
if (!path || Blast.isBrowser) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
alchemy.registerRequiredStylesheet(path);
|
|
24
|
+
});
|
|
25
|
+
|
|
10
26
|
/**
|
|
11
27
|
* The default element prefix (when element contains no hyphen) is "al"
|
|
12
28
|
*
|
package/lib/core/middleware.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
let publicDirs = alchemy.shared('public.directories', new Deck()),
|
|
2
2
|
scriptDirs = alchemy.shared('script.directories', new Deck()),
|
|
3
3
|
assetDirs = alchemy.shared('asset.directories', new Deck()),
|
|
4
4
|
styleDirs = alchemy.shared('stylesheet.directories', new Deck()),
|
|
@@ -11,9 +11,10 @@ var publicDirs = alchemy.shared('public.directories', new Deck()),
|
|
|
11
11
|
Nodent = alchemy.use('nodent-compiler'),
|
|
12
12
|
Terser = alchemy.use('terser'),
|
|
13
13
|
libpath = alchemy.use('path'),
|
|
14
|
+
required_stylesheets = new Set(),
|
|
14
15
|
nodent_compiler,
|
|
15
16
|
regenerator_runtime,
|
|
16
|
-
|
|
17
|
+
sass_functions,
|
|
17
18
|
babel_polyfill,
|
|
18
19
|
babel_preset,
|
|
19
20
|
babel_async,
|
|
@@ -122,7 +123,7 @@ function getMiddlePaths(paths, ext, new_ext) {
|
|
|
122
123
|
}
|
|
123
124
|
|
|
124
125
|
/**
|
|
125
|
-
*
|
|
126
|
+
* Stylesheet middleware
|
|
126
127
|
*
|
|
127
128
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
128
129
|
* @since 0.2.0
|
|
@@ -130,17 +131,11 @@ function getMiddlePaths(paths, ext, new_ext) {
|
|
|
130
131
|
*/
|
|
131
132
|
Alchemy.setMethod(function styleMiddleware(req, res, nextMiddleware) {
|
|
132
133
|
|
|
133
|
-
var warnings,
|
|
134
|
-
compiled,
|
|
135
|
-
o_stats,
|
|
136
|
-
path,
|
|
137
|
-
url;
|
|
138
|
-
|
|
139
134
|
// Get the URL object
|
|
140
|
-
url = req.conduit.url;
|
|
135
|
+
let url = req.conduit.url;
|
|
141
136
|
|
|
142
137
|
// Get the path, including the query
|
|
143
|
-
path = url.path;
|
|
138
|
+
let path = url.path;
|
|
144
139
|
|
|
145
140
|
// If this file has already been found & compiled, serve it to the user
|
|
146
141
|
if (asset_cache.has(path)) {
|
|
@@ -151,41 +146,106 @@ Alchemy.setMethod(function styleMiddleware(req, res, nextMiddleware) {
|
|
|
151
146
|
}});
|
|
152
147
|
}
|
|
153
148
|
|
|
154
|
-
|
|
155
|
-
|
|
149
|
+
let css_path = req.middlePath;
|
|
150
|
+
|
|
151
|
+
findStylesheet(css_path, {compile: true}).done((err, result) => {
|
|
152
|
+
|
|
153
|
+
if (err) {
|
|
154
|
+
return req.conduit.error(err);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
let compiled_path = result?.compiled?.path;
|
|
158
|
+
|
|
159
|
+
if (!compiled_path) {
|
|
160
|
+
return nextMiddleware();
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return req.conduit.serveFile(compiled_path, {
|
|
164
|
+
mimetype: 'text/css',
|
|
165
|
+
onError: function onError(err) {
|
|
166
|
+
if (fileCache[compiled_path]) {
|
|
167
|
+
fileCache[compiled_path] = null;
|
|
168
|
+
|
|
169
|
+
let source_path = result.source?.path;
|
|
170
|
+
|
|
171
|
+
if (stats && fileCache[source_path]) {
|
|
172
|
+
fileCache[source_path] = null;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
alchemy.styleMiddleware(req, res, nextMiddleware);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Find a stylesheet
|
|
184
|
+
*
|
|
185
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
186
|
+
* @since 1.4.0
|
|
187
|
+
* @version 1.4.0
|
|
188
|
+
*
|
|
189
|
+
* @param {string} css_path Relative path to the CSS source file
|
|
190
|
+
* @param {Object} options
|
|
191
|
+
*
|
|
192
|
+
* @return {Pledge<Object>}
|
|
193
|
+
*/
|
|
194
|
+
function findStylesheet(css_path, options) {
|
|
195
|
+
|
|
196
|
+
let source_stats,
|
|
197
|
+
compiled,
|
|
198
|
+
warnings = [];
|
|
199
|
+
|
|
200
|
+
if (css_path[0] != '/') {
|
|
201
|
+
css_path = '/' + css_path;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (!options) {
|
|
205
|
+
options = {};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
let do_compile = options.compile === true;
|
|
209
|
+
|
|
210
|
+
if (!css_path.endsWith('.css')) {
|
|
211
|
+
return Pledge.reject(new Error('Not a .css file'));
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return Function.series(function getCssPath(next) {
|
|
156
215
|
|
|
157
|
-
Function.series(function getCssPath(next) {
|
|
158
216
|
// Look for a regular .css file
|
|
159
|
-
alchemy.findAssetPath(
|
|
217
|
+
alchemy.findAssetPath(css_path, styleDirs.getSorted(), function gotAssetPath(err, stats) {
|
|
160
218
|
|
|
161
219
|
if (err || !stats || !stats.path) {
|
|
162
220
|
return next();
|
|
163
221
|
}
|
|
164
222
|
|
|
165
|
-
compiled = stats;
|
|
223
|
+
source_stats = compiled = stats;
|
|
166
224
|
next();
|
|
167
225
|
});
|
|
168
226
|
}, function getLessPath(next) {
|
|
169
227
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if (compiled || !less) {
|
|
228
|
+
if (source_stats || !less) {
|
|
173
229
|
return next();
|
|
174
230
|
}
|
|
175
231
|
|
|
176
|
-
|
|
232
|
+
let less_path = getMiddlePaths(css_path, /\.css$/, '.less');
|
|
177
233
|
|
|
178
234
|
// Look through all the asset folders for the less style file
|
|
179
|
-
alchemy.findAssetPath(
|
|
235
|
+
alchemy.findAssetPath(less_path, styleDirs.getSorted(), function gotAssetPath(err, stats) {
|
|
180
236
|
|
|
181
237
|
if (err || !stats || !stats.path) {
|
|
182
238
|
return next();
|
|
183
239
|
}
|
|
184
240
|
|
|
185
|
-
|
|
241
|
+
source_stats = stats;
|
|
242
|
+
|
|
243
|
+
if (!do_compile) {
|
|
244
|
+
return next();
|
|
245
|
+
}
|
|
186
246
|
|
|
187
247
|
// Compile this less file
|
|
188
|
-
alchemy.getCompiledLessPath(stats.path,
|
|
248
|
+
alchemy.getCompiledLessPath(stats.path, options, function gotLessPath(err, cssInfo) {
|
|
189
249
|
|
|
190
250
|
if (err) {
|
|
191
251
|
warnings.push(err);
|
|
@@ -199,25 +259,27 @@ Alchemy.setMethod(function styleMiddleware(req, res, nextMiddleware) {
|
|
|
199
259
|
|
|
200
260
|
}, function getScssPath(next) {
|
|
201
261
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
if (compiled || !sass) {
|
|
262
|
+
if (source_stats || !sass) {
|
|
205
263
|
return next();
|
|
206
264
|
}
|
|
207
265
|
|
|
208
|
-
|
|
266
|
+
let scss_path = getMiddlePaths(css_path, /\.css$/, '.scss');
|
|
209
267
|
|
|
210
268
|
// Look through all the asset folders for the scss style file
|
|
211
|
-
alchemy.findAssetPath(
|
|
269
|
+
alchemy.findAssetPath(scss_path, styleDirs.getSorted(), function gotAssetPath(err, stats) {
|
|
212
270
|
|
|
213
271
|
if (err || !stats || !stats.path) {
|
|
214
272
|
return next();
|
|
215
273
|
}
|
|
216
274
|
|
|
217
|
-
|
|
275
|
+
source_stats = stats;
|
|
276
|
+
|
|
277
|
+
if (!do_compile) {
|
|
278
|
+
return next();
|
|
279
|
+
}
|
|
218
280
|
|
|
219
281
|
// Compile this less file
|
|
220
|
-
alchemy.getCompiledSassPath(stats.path,
|
|
282
|
+
alchemy.getCompiledSassPath(stats.path, options, function gotSassPath(err, cssInfo) {
|
|
221
283
|
|
|
222
284
|
if (err) {
|
|
223
285
|
warnings.push(err);
|
|
@@ -232,34 +294,28 @@ Alchemy.setMethod(function styleMiddleware(req, res, nextMiddleware) {
|
|
|
232
294
|
}, function done(err) {
|
|
233
295
|
|
|
234
296
|
if (err) {
|
|
235
|
-
|
|
297
|
+
throw err;
|
|
236
298
|
}
|
|
237
299
|
|
|
238
300
|
// If there are warnings, use the first one
|
|
239
301
|
if (warnings.length) {
|
|
240
|
-
|
|
302
|
+
throw warnings[0];
|
|
241
303
|
}
|
|
242
304
|
|
|
243
|
-
if (
|
|
244
|
-
return
|
|
305
|
+
if (options?.post_css_only) {
|
|
306
|
+
return compiled;
|
|
245
307
|
}
|
|
246
308
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
if (fileCache[compiled.path]) {
|
|
251
|
-
fileCache[compiled.path] = null;
|
|
252
|
-
|
|
253
|
-
if (o_stats && fileCache[o_stats.path]) {
|
|
254
|
-
fileCache[o_stats.path] = null;
|
|
255
|
-
}
|
|
309
|
+
if (do_compile && (!compiled || !compiled.path)) {
|
|
310
|
+
return false;
|
|
311
|
+
}
|
|
256
312
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
}
|
|
313
|
+
return {
|
|
314
|
+
compiled : compiled,
|
|
315
|
+
source : source_stats,
|
|
316
|
+
};
|
|
261
317
|
});
|
|
262
|
-
}
|
|
318
|
+
}
|
|
263
319
|
|
|
264
320
|
/**
|
|
265
321
|
* Sourcemap middleware:
|
|
@@ -807,7 +863,8 @@ Alchemy.setMethod(function findImagePath(image_path, callback) {
|
|
|
807
863
|
*/
|
|
808
864
|
Alchemy.setMethod(function findAssetPath(assetFile, directories, callback) {
|
|
809
865
|
|
|
810
|
-
|
|
866
|
+
let found_asset_dir,
|
|
867
|
+
sub_path,
|
|
811
868
|
found,
|
|
812
869
|
iter;
|
|
813
870
|
|
|
@@ -888,6 +945,7 @@ Alchemy.setMethod(function findAssetPath(assetFile, directories, callback) {
|
|
|
888
945
|
if (err == null && stats.isFile()) {
|
|
889
946
|
stats.path = path;
|
|
890
947
|
found = stats;
|
|
948
|
+
found_asset_dir = dir;
|
|
891
949
|
}
|
|
892
950
|
|
|
893
951
|
nextc();
|
|
@@ -910,6 +968,7 @@ Alchemy.setMethod(function findAssetPath(assetFile, directories, callback) {
|
|
|
910
968
|
stats.servepath = cpath;
|
|
911
969
|
stats.path = cpath;
|
|
912
970
|
found = stats;
|
|
971
|
+
found_asset_dir = dir;
|
|
913
972
|
}
|
|
914
973
|
|
|
915
974
|
nextc();
|
|
@@ -927,6 +986,10 @@ Alchemy.setMethod(function findAssetPath(assetFile, directories, callback) {
|
|
|
927
986
|
found = {};
|
|
928
987
|
}
|
|
929
988
|
|
|
989
|
+
if (found_asset_dir) {
|
|
990
|
+
found.relative_path = libpath.relative(found_asset_dir, found.path);
|
|
991
|
+
}
|
|
992
|
+
|
|
930
993
|
callback(null, found);
|
|
931
994
|
});
|
|
932
995
|
});
|
|
@@ -936,13 +999,19 @@ Alchemy.setMethod(function findAssetPath(assetFile, directories, callback) {
|
|
|
936
999
|
*
|
|
937
1000
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
938
1001
|
* @since 0.5.0
|
|
939
|
-
* @version 1.0
|
|
1002
|
+
* @version 1.4.0
|
|
940
1003
|
*
|
|
941
1004
|
* @param {string} css
|
|
1005
|
+
* @param {Object} options
|
|
942
1006
|
* @param {Function} callback
|
|
943
1007
|
*/
|
|
944
|
-
function doPostCss(css, callback) {
|
|
1008
|
+
function doPostCss(css, options, callback) {
|
|
945
1009
|
postcss([autoprefixer]).process(css, {from: undefined}).then(function gotCssResult(result) {
|
|
1010
|
+
|
|
1011
|
+
if (options?.post_css_only) {
|
|
1012
|
+
return callback(null, result);
|
|
1013
|
+
}
|
|
1014
|
+
|
|
946
1015
|
callback(null, result.css);
|
|
947
1016
|
}).catch(function gotError(err) {
|
|
948
1017
|
callback(err);
|
|
@@ -958,14 +1027,16 @@ function doPostCss(css, callback) {
|
|
|
958
1027
|
*/
|
|
959
1028
|
Alchemy.setMethod(function getCompiledLessPath(lessPath, options, callback) {
|
|
960
1029
|
|
|
1030
|
+
let check_cache = !options?.post_css_only && options?.cache !== false && alchemy.settings.performance.cache;
|
|
1031
|
+
|
|
961
1032
|
// If it has been compiled before, return that
|
|
962
1033
|
// @todo: check timestamps on dev. Not-founds are not cached
|
|
963
|
-
if (
|
|
964
|
-
return setImmediate(
|
|
1034
|
+
if (check_cache && fileCache[lessPath]) {
|
|
1035
|
+
return setImmediate(() => callback(null, fileCache[lessPath]));
|
|
965
1036
|
}
|
|
966
1037
|
|
|
967
1038
|
if (!lessPath || typeof lessPath != 'string') {
|
|
968
|
-
return setImmediate(
|
|
1039
|
+
return setImmediate(() => callback(new Error('Invalid path given')));
|
|
969
1040
|
}
|
|
970
1041
|
|
|
971
1042
|
fs.readFile(lessPath, {encoding: 'utf8'}, function gotLessCode(err, source) {
|
|
@@ -1005,6 +1076,10 @@ Alchemy.setMethod(function getCompiledLessPath(lessPath, options, callback) {
|
|
|
1005
1076
|
// @todo: add minify options
|
|
1006
1077
|
css = cssTree.css;
|
|
1007
1078
|
|
|
1079
|
+
if (options.post_css_only) {
|
|
1080
|
+
return doPostCss(css, options, callback);
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1008
1083
|
Blast.openTempFile({suffix: '.css'}, function getTempFile(err, info) {
|
|
1009
1084
|
|
|
1010
1085
|
var cssBuffer;
|
|
@@ -1021,7 +1096,7 @@ Alchemy.setMethod(function getCompiledLessPath(lessPath, options, callback) {
|
|
|
1021
1096
|
return callback(new Error('LESS file failed to compile'));
|
|
1022
1097
|
}
|
|
1023
1098
|
|
|
1024
|
-
doPostCss(css, function gotResult(err, css) {
|
|
1099
|
+
doPostCss(css, options, function gotResult(err, css) {
|
|
1025
1100
|
|
|
1026
1101
|
if (err) {
|
|
1027
1102
|
return callback(err);
|
|
@@ -1049,18 +1124,143 @@ Alchemy.setMethod(function getCompiledLessPath(lessPath, options, callback) {
|
|
|
1049
1124
|
});
|
|
1050
1125
|
});
|
|
1051
1126
|
|
|
1127
|
+
/**
|
|
1128
|
+
* Create the alchemy.scss content
|
|
1129
|
+
*
|
|
1130
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
1131
|
+
* @since 1.4.0
|
|
1132
|
+
* @version 1.4.0
|
|
1133
|
+
*/
|
|
1134
|
+
async function createAlchemyScss() {
|
|
1135
|
+
|
|
1136
|
+
let contents = '';
|
|
1137
|
+
|
|
1138
|
+
for (let css_name of required_stylesheets) {
|
|
1139
|
+
if (!css_name.endsWith('.scss') && !css_name.endsWith('.css') && !css_name.endsWith('.less')) {
|
|
1140
|
+
css_name += '.css';
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
let result = await findStylesheet(css_name);
|
|
1144
|
+
|
|
1145
|
+
if (!result?.source?.relative_path) {
|
|
1146
|
+
throw new Error('Could not find ' + css_name);
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
contents += '@use "' + result.source.relative_path + '";\n';
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
return {contents};
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
/**
|
|
1156
|
+
* Custom SCSS import logic
|
|
1157
|
+
*
|
|
1158
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
1159
|
+
* @since 1.4.0
|
|
1160
|
+
* @version 1.4.0
|
|
1161
|
+
*
|
|
1162
|
+
* @param {string} path_to_import The requested path to import
|
|
1163
|
+
* @param {string} current_file_path The path to the current file
|
|
1164
|
+
*/
|
|
1165
|
+
async function customScssImporter(path_to_import, current_file_path) {
|
|
1166
|
+
|
|
1167
|
+
// The alchemy.scss file is a special case
|
|
1168
|
+
if (path_to_import === 'alchemy.scss' || path_to_import === 'alchemy') {
|
|
1169
|
+
return createAlchemyScss();
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
// Get the current directory this SCSS file is in
|
|
1173
|
+
let current_dir = libpath.dirname(current_file_path);
|
|
1174
|
+
|
|
1175
|
+
// Get the dirname to import
|
|
1176
|
+
let dir_to_import = libpath.dirname(path_to_import);
|
|
1177
|
+
|
|
1178
|
+
// Get the filename
|
|
1179
|
+
let filename_to_import = libpath.basename(path_to_import);
|
|
1180
|
+
|
|
1181
|
+
// Get all the style dirs
|
|
1182
|
+
let style_dirs = styleDirs.getSorted();
|
|
1183
|
+
|
|
1184
|
+
// Get the source style dir (the one this file is in)
|
|
1185
|
+
let source_style_dir;
|
|
1186
|
+
|
|
1187
|
+
for (let style_dir of style_dirs) {
|
|
1188
|
+
if (current_dir.startsWith(style_dir)) {
|
|
1189
|
+
source_style_dir = style_dir;
|
|
1190
|
+
break;
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
let include_paths = [
|
|
1195
|
+
current_dir,
|
|
1196
|
+
...style_dirs,
|
|
1197
|
+
];
|
|
1198
|
+
|
|
1199
|
+
// If the dir this file was in is from one of the allowed style dirs,
|
|
1200
|
+
// we have to add possible overrides to the include paths
|
|
1201
|
+
if (source_style_dir) {
|
|
1202
|
+
let extra_path = current_dir.after(source_style_dir);
|
|
1203
|
+
|
|
1204
|
+
if (extra_path.length > 2) {
|
|
1205
|
+
extra_path = libpath.resolve('/', extra_path);
|
|
1206
|
+
let new_path = libpath.join(PATH_APP, 'assets', 'stylesheets', extra_path);
|
|
1207
|
+
include_paths.unshift(new_path);
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
for (let include_path of include_paths) {
|
|
1212
|
+
let test_path = libpath.join(include_path, path_to_import);
|
|
1213
|
+
|
|
1214
|
+
let file = new Classes.Alchemy.Inode.File(test_path);
|
|
1215
|
+
|
|
1216
|
+
if (await file.exists()) {
|
|
1217
|
+
return {file: test_path};
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
// Look for files starting with an underscore
|
|
1222
|
+
if (filename_to_import[0] != '_') {
|
|
1223
|
+
let dashed_filename_to_import = '_' + filename_to_import;
|
|
1224
|
+
return customScssImporter(libpath.join(dir_to_import, dashed_filename_to_import), current_file_path);
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
let extension = libpath.extname(filename_to_import);
|
|
1228
|
+
|
|
1229
|
+
// If no extension was given, look for that too
|
|
1230
|
+
if (!extension) {
|
|
1231
|
+
filename_to_import += '.scss';
|
|
1232
|
+
return customScssImporter(libpath.join(dir_to_import, filename_to_import), current_file_path);
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
if (path_to_import.startsWith('/overrides/')) {
|
|
1236
|
+
return {contents: '// Failed to find ' + path_to_import};
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
throw new Error('SCSS file not found');
|
|
1240
|
+
};
|
|
1241
|
+
|
|
1242
|
+
function logSassWarning(message, options) {
|
|
1243
|
+
console.warn('Sass warning:', message, options);
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
function logSassDebug(message, options) {
|
|
1247
|
+
console.log('Sass debug:', message, options);
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1052
1250
|
/**
|
|
1053
1251
|
* Callback with the compiled CSS filepath
|
|
1054
1252
|
*
|
|
1055
1253
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
1056
1254
|
* @since 0.2.0
|
|
1057
|
-
* @version 1.
|
|
1255
|
+
* @version 1.4.0
|
|
1058
1256
|
*/
|
|
1059
1257
|
Alchemy.setMethod(function getCompiledSassPath(sassPath, options, callback) {
|
|
1060
1258
|
|
|
1259
|
+
let check_cache = !options?.post_css_only && options?.cache !== false && alchemy.settings.performance.cache;
|
|
1260
|
+
|
|
1061
1261
|
// If it has been compiled before, return that
|
|
1062
1262
|
// @todo: check timestamps on dev. Not-founds are not cached
|
|
1063
|
-
if (
|
|
1263
|
+
if (check_cache && fileCache[sassPath]) {
|
|
1064
1264
|
return setImmediate(function lessCache(){callback(null, fileCache[sassPath])});
|
|
1065
1265
|
}
|
|
1066
1266
|
|
|
@@ -1079,8 +1279,13 @@ Alchemy.setMethod(function getCompiledSassPath(sassPath, options, callback) {
|
|
|
1079
1279
|
}
|
|
1080
1280
|
|
|
1081
1281
|
const render_options = {
|
|
1082
|
-
includePaths :
|
|
1282
|
+
includePaths : styleDirs.getSorted(),
|
|
1083
1283
|
functions : sass_functions,
|
|
1284
|
+
importer : customScssImporter,
|
|
1285
|
+
logger : {
|
|
1286
|
+
warn : logSassWarning,
|
|
1287
|
+
debug : logSassDebug,
|
|
1288
|
+
},
|
|
1084
1289
|
};
|
|
1085
1290
|
|
|
1086
1291
|
if (alchemy.settings.debugging.debug) {
|
|
@@ -1104,6 +1309,11 @@ Alchemy.setMethod(function getCompiledSassPath(sassPath, options, callback) {
|
|
|
1104
1309
|
});
|
|
1105
1310
|
|
|
1106
1311
|
function writeToTemp(content) {
|
|
1312
|
+
|
|
1313
|
+
if (options?.post_css_only) {
|
|
1314
|
+
return doPostCss(content, options, callback);
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1107
1317
|
Blast.openTempFile({suffix: '.css'}, function getTempFile(err, info) {
|
|
1108
1318
|
|
|
1109
1319
|
if (err) {
|
|
@@ -1118,7 +1328,7 @@ Alchemy.setMethod(function getCompiledSassPath(sassPath, options, callback) {
|
|
|
1118
1328
|
return writeToFile(info, content);
|
|
1119
1329
|
}
|
|
1120
1330
|
|
|
1121
|
-
doPostCss(content, function gotPostCss(err, css) {
|
|
1331
|
+
doPostCss(content, options, function gotPostCss(err, css) {
|
|
1122
1332
|
|
|
1123
1333
|
if (err) {
|
|
1124
1334
|
return callback(err);
|
|
@@ -1147,7 +1357,121 @@ Alchemy.setMethod(function getCompiledSassPath(sassPath, options, callback) {
|
|
|
1147
1357
|
callback(null, file);
|
|
1148
1358
|
});
|
|
1149
1359
|
});
|
|
1360
|
+
}
|
|
1361
|
+
});
|
|
1362
|
+
});
|
|
1363
|
+
|
|
1364
|
+
/**
|
|
1365
|
+
* Register a style that should always be included in the output
|
|
1366
|
+
*
|
|
1367
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
1368
|
+
* @since 1.4.0
|
|
1369
|
+
* @version 1.4.0
|
|
1370
|
+
*
|
|
1371
|
+
* @param {string} css_path Could be a path, could be a name
|
|
1372
|
+
*/
|
|
1373
|
+
Alchemy.setMethod(function registerRequiredStylesheet(css_path) {
|
|
1374
|
+
required_stylesheets.add(css_path);
|
|
1375
|
+
});
|
|
1376
|
+
|
|
1377
|
+
/**
|
|
1378
|
+
* Extract CSS exports from a PostCSS result object
|
|
1379
|
+
*
|
|
1380
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
1381
|
+
* @since 1.4.0
|
|
1382
|
+
* @version 1.4.0
|
|
1383
|
+
*
|
|
1384
|
+
* @param {Object} postcss_result
|
|
1385
|
+
*/
|
|
1386
|
+
function extractPostCSSExports(postcss_result) {
|
|
1387
|
+
|
|
1388
|
+
const icss_import_rx = /^:import\(("[^"]*"|'[^']*'|[^"']+)\)$/;
|
|
1389
|
+
const icss_balanced_quotes = /^("[^"]*"|'[^']*'|[^"']+)$/;
|
|
1390
|
+
const remove_rules = true;
|
|
1391
|
+
const mode = 'auto';
|
|
1392
|
+
|
|
1393
|
+
const getDeclsObject = (rule) => {
|
|
1394
|
+
const object = {};
|
|
1395
|
+
|
|
1396
|
+
rule.walkDecls((decl) => {
|
|
1397
|
+
const before = decl.raws.before ? decl.raws.before.trim() : "";
|
|
1398
|
+
object[before + decl.prop] = decl.value;
|
|
1399
|
+
});
|
|
1400
|
+
|
|
1401
|
+
return object;
|
|
1402
|
+
};
|
|
1403
|
+
|
|
1404
|
+
const icss_imports = {};
|
|
1405
|
+
const icss_exports = {};
|
|
1406
|
+
|
|
1407
|
+
function addImports(node, path) {
|
|
1408
|
+
const unquoted = path.replace(/'|"/g, "");
|
|
1409
|
+
icss_imports[unquoted] = Object.assign(
|
|
1410
|
+
icss_imports[unquoted] || {},
|
|
1411
|
+
getDeclsObject(node)
|
|
1412
|
+
);
|
|
1413
|
+
|
|
1414
|
+
if (remove_rules) {
|
|
1415
|
+
node.remove();
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1150
1418
|
|
|
1419
|
+
function addExports(node) {
|
|
1420
|
+
Object.assign(icss_exports, getDeclsObject(node));
|
|
1421
|
+
if (remove_rules) {
|
|
1422
|
+
node.remove();
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
|
|
1426
|
+
postcss_result.root.each((node) => {
|
|
1427
|
+
if (node.type === 'rule' && mode !== 'at-rule') {
|
|
1428
|
+
if (node.selector.slice(0, 7) === ':import') {
|
|
1429
|
+
const matches = icss_import_rx.exec(node.selector);
|
|
1430
|
+
|
|
1431
|
+
if (matches) {
|
|
1432
|
+
addImports(node, matches[1]);
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1436
|
+
if (node.selector === ':export') {
|
|
1437
|
+
addExports(node);
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
if (node.type === 'atrule' && mode !== 'rule') {
|
|
1442
|
+
if (node.name === 'icss-import') {
|
|
1443
|
+
const matches = icss_balanced_quotes.exec(node.params);
|
|
1444
|
+
|
|
1445
|
+
if (matches) {
|
|
1446
|
+
addImports(node, matches[1]);
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
if (node.name === 'icss-export') {
|
|
1450
|
+
addExports(node);
|
|
1451
|
+
}
|
|
1151
1452
|
}
|
|
1152
1453
|
});
|
|
1454
|
+
|
|
1455
|
+
return {
|
|
1456
|
+
imports : icss_imports,
|
|
1457
|
+
exports : icss_exports,
|
|
1458
|
+
};
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1461
|
+
/**
|
|
1462
|
+
* Extract CSS exports from a CSS file path
|
|
1463
|
+
*
|
|
1464
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
1465
|
+
* @since 1.4.0
|
|
1466
|
+
* @version 1.4.0
|
|
1467
|
+
*
|
|
1468
|
+
* @param {string} css_path
|
|
1469
|
+
*/
|
|
1470
|
+
Alchemy.setMethod(async function extractCSSExports(css_path) {
|
|
1471
|
+
|
|
1472
|
+
let result = await findStylesheet(css_path, {post_css_only: true, compile: true});
|
|
1473
|
+
|
|
1474
|
+
result = extractPostCSSExports(result);
|
|
1475
|
+
|
|
1476
|
+
return result?.exports;
|
|
1153
1477
|
});
|
|
@@ -17,6 +17,21 @@ function DEFINE(name, value) {
|
|
|
17
17
|
Object.defineProperty(globalThis, name, {value: value});
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Function to define global constants
|
|
22
|
+
* and have them inside Hawkejs views too
|
|
23
|
+
*
|
|
24
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
25
|
+
* @since 1.4.0
|
|
26
|
+
* @version 1.4.0
|
|
27
|
+
*
|
|
28
|
+
* @type {Function}
|
|
29
|
+
*/
|
|
30
|
+
function DEFINE_CLIENT(name, value) {
|
|
31
|
+
DEFINE(name, value);
|
|
32
|
+
Classes.Hawkejs.setGlobal(name, value);
|
|
33
|
+
}
|
|
34
|
+
|
|
20
35
|
/**
|
|
21
36
|
* Use DEFINE for itself
|
|
22
37
|
*
|
|
@@ -37,7 +52,7 @@ DEFINE('DEFINE', DEFINE);
|
|
|
37
52
|
*
|
|
38
53
|
* @type {Informer}
|
|
39
54
|
*/
|
|
40
|
-
|
|
55
|
+
DEFINE_CLIENT('Blast', __Protoblast);
|
|
41
56
|
|
|
42
57
|
/**
|
|
43
58
|
* All classes will be collected here
|
|
@@ -48,7 +63,7 @@ DEFINE('Blast', __Protoblast);
|
|
|
48
63
|
*
|
|
49
64
|
* @type {Object}
|
|
50
65
|
*/
|
|
51
|
-
|
|
66
|
+
DEFINE_CLIENT('Classes', Blast.Classes);
|
|
52
67
|
|
|
53
68
|
/**
|
|
54
69
|
* Available types
|
|
@@ -59,7 +74,7 @@ DEFINE('Classes', Blast.Classes);
|
|
|
59
74
|
*
|
|
60
75
|
* @type {Object}
|
|
61
76
|
*/
|
|
62
|
-
|
|
77
|
+
DEFINE_CLIENT('Types', Blast.Types);
|
|
63
78
|
|
|
64
79
|
/**
|
|
65
80
|
* The new Local Date/Time classes
|
|
@@ -68,9 +83,9 @@ DEFINE('Types', Blast.Types);
|
|
|
68
83
|
* @since 1.3.20
|
|
69
84
|
* @version 1.3.20
|
|
70
85
|
*/
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
86
|
+
DEFINE_CLIENT('LocalDateTime', Classes.Develry.LocalDateTime);
|
|
87
|
+
DEFINE_CLIENT('LocalDate', Classes.Develry.LocalDate);
|
|
88
|
+
DEFINE_CLIENT('LocalTime', Classes.Develry.LocalTime);
|
|
74
89
|
|
|
75
90
|
/**
|
|
76
91
|
* The new Decimal classes
|
|
@@ -79,10 +94,10 @@ DEFINE('LocalTime', Classes.Develry.LocalTime);
|
|
|
79
94
|
* @since 1.3.20
|
|
80
95
|
* @version 1.3.20
|
|
81
96
|
*/
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
97
|
+
DEFINE_CLIENT('Decimal', Classes.Develry.Decimal);
|
|
98
|
+
DEFINE_CLIENT('MutableDecimal', Classes.Develry.MutableDecimal);
|
|
99
|
+
DEFINE_CLIENT('FixedDecimal', Classes.Develry.FixedDecimal);
|
|
100
|
+
DEFINE_CLIENT('MutableFixedDecimal', Classes.Develry.MutableFixedDecimal);
|
|
86
101
|
|
|
87
102
|
/**
|
|
88
103
|
* The Trail class:
|
|
@@ -92,4 +107,4 @@ DEFINE('MutableFixedDecimal', Classes.Develry.MutableFixedDecimal);
|
|
|
92
107
|
* @since 1.4.0
|
|
93
108
|
* @version 1.4.0
|
|
94
109
|
*/
|
|
95
|
-
|
|
110
|
+
DEFINE_CLIENT('Trail', Classes.Develry.Trail);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "alchemymvc",
|
|
3
3
|
"description": "MVC framework for Node.js",
|
|
4
|
-
"version": "1.4.0-alpha.
|
|
4
|
+
"version": "1.4.0-alpha.3",
|
|
5
5
|
"author": "Jelle De Loecker <jelle@elevenways.be>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"alchemy",
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"optionalDependencies": {
|
|
47
47
|
"janeway" : "~0.4.4",
|
|
48
48
|
"less" : "~4.2.0",
|
|
49
|
-
"sass" : "~1.
|
|
50
|
-
"sass-embedded" : "~1.
|
|
49
|
+
"sass" : "~1.71.1",
|
|
50
|
+
"sass-embedded" : "~1.71.1",
|
|
51
51
|
"nodent-compiler" : "~3.2.13",
|
|
52
52
|
"socket.io-client" : "~4.7.2",
|
|
53
53
|
"socket.io-msgpack-parser": "~3.0.2"
|