total5 0.0.13-9 → 0.0.13
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/builders.js +17 -8
- package/changelog.txt +14 -0
- package/controller.js +12 -9
- package/htmlparser.js +58 -14
- package/index.js +38 -8
- package/package.json +1 -1
- package/routing.js +24 -3
- package/test.js +4 -1
- package/viewengine.js +24 -22
package/builders.js
CHANGED
|
@@ -171,6 +171,7 @@ Options.prototype.publish = function(value) {
|
|
|
171
171
|
F.stats.performance.publish++;
|
|
172
172
|
F.TTMS.cache.socket.send({ type: 'publish', id: name, data: tmp }, client => client.tmsready && client.$subscribers[name]);
|
|
173
173
|
}
|
|
174
|
+
|
|
174
175
|
return self;
|
|
175
176
|
};
|
|
176
177
|
|
|
@@ -1237,7 +1238,7 @@ exports.newaction = function(name, obj) {
|
|
|
1237
1238
|
name = obj.id || obj.name;
|
|
1238
1239
|
}
|
|
1239
1240
|
|
|
1240
|
-
|
|
1241
|
+
let url = name;
|
|
1241
1242
|
|
|
1242
1243
|
if (F.actions[name])
|
|
1243
1244
|
F.actions[name].remove();
|
|
@@ -1254,6 +1255,8 @@ exports.newaction = function(name, obj) {
|
|
|
1254
1255
|
obj.options.csrf = obj.csrf;
|
|
1255
1256
|
obj.options.encrypt = obj.encrypt;
|
|
1256
1257
|
obj.options.compress = obj.compress;
|
|
1258
|
+
obj.audit = obj.audit === true ? NOOP : (obj.audit ? Tangular.compile(obj.audit) : null);
|
|
1259
|
+
obj.called = 0;
|
|
1257
1260
|
|
|
1258
1261
|
if (obj.cache)
|
|
1259
1262
|
obj.cache = parseactioncache(obj, obj.cache);
|
|
@@ -1284,16 +1287,16 @@ exports.newaction = function(name, obj) {
|
|
|
1284
1287
|
|
|
1285
1288
|
if (obj.publish) {
|
|
1286
1289
|
|
|
1287
|
-
|
|
1290
|
+
let tmsschema = obj.publish == true ? (obj.input || obj.output) : obj.publish;
|
|
1288
1291
|
|
|
1289
1292
|
if (typeof(tmsschema) === 'string') {
|
|
1290
1293
|
if (tmsschema[0] === '+')
|
|
1291
1294
|
tmsschema = (obj.input || obj.output) + ',' + tmsschema.substring(1);
|
|
1292
1295
|
|
|
1293
|
-
|
|
1296
|
+
let keys = tmsschema.split(',');
|
|
1294
1297
|
obj.$publish = [];
|
|
1295
|
-
for (
|
|
1296
|
-
|
|
1298
|
+
for (let key of keys) {
|
|
1299
|
+
let index = key.indexOf(':');
|
|
1297
1300
|
obj.$publish.push(index === -1 ? key : key.substring(0, index));
|
|
1298
1301
|
}
|
|
1299
1302
|
}
|
|
@@ -1382,14 +1385,14 @@ ActionCaller.prototype.exec = function() {
|
|
|
1382
1385
|
$.id = action.id;
|
|
1383
1386
|
$.error = self.error;
|
|
1384
1387
|
$.controller = self.controller;
|
|
1385
|
-
$.fields = action.fields;
|
|
1386
1388
|
$.user = self.options.user;
|
|
1387
1389
|
$.config = action.config || EMPTYOBJECT;
|
|
1388
1390
|
|
|
1391
|
+
action.called++;
|
|
1392
|
+
|
|
1389
1393
|
$.$callback = function(err, response) {
|
|
1390
1394
|
|
|
1391
1395
|
if (!err) {
|
|
1392
|
-
|
|
1393
1396
|
if (action.jsoutput)
|
|
1394
1397
|
response = action.jsoutput.transform(response).response;
|
|
1395
1398
|
|
|
@@ -1406,11 +1409,17 @@ ActionCaller.prototype.exec = function() {
|
|
|
1406
1409
|
// close
|
|
1407
1410
|
self.cancel();
|
|
1408
1411
|
} else {
|
|
1412
|
+
|
|
1409
1413
|
$.response[$.id] = response;
|
|
1410
1414
|
meta.response && self.finish && self.finish(response);
|
|
1411
|
-
|
|
1415
|
+
|
|
1416
|
+
if (action.audit)
|
|
1417
|
+
F.audit('actions', $, action.audit(null, $) || '');
|
|
1418
|
+
|
|
1419
|
+
let key = '@' + $.id;
|
|
1412
1420
|
if (F.$events[key])
|
|
1413
1421
|
F.emit(key, $, response);
|
|
1422
|
+
|
|
1414
1423
|
self.exec();
|
|
1415
1424
|
}
|
|
1416
1425
|
};
|
package/changelog.txt
CHANGED
|
@@ -24,6 +24,20 @@
|
|
|
24
24
|
- fixed a problem with case-sensitive characters in the route parameters
|
|
25
25
|
- fixed markdown parser
|
|
26
26
|
- added missing ViewEngine `@{meta(...)}` method
|
|
27
|
+
- fixed `expires` argument in the `$.cookie(key, value, expires|options)` method
|
|
28
|
+
- fixed HTMLParser for XML, added support for `<!CDATA[[`
|
|
29
|
+
- added `outerHTML` property for the HTMLParser element
|
|
30
|
+
- improved `HTMLParser.text()` method
|
|
31
|
+
- added a new view engine property `@{version}` that appends `?ts=start_app_timestamp`
|
|
32
|
+
- extended `@{import()}` method now supports `@style_name.css` and `@script_name.js` (due to HTTP cache reasons, it automatically appends the argument `?ts=start_app_timestamp` to the URL)
|
|
33
|
+
- fixed loading extensions
|
|
34
|
+
- fixed unit-tests for HTMLParser
|
|
35
|
+
- added `Total.syslog(msg)` method for internal app logging
|
|
36
|
+
- added auto audit logs to Actions in the form: `NEWACTION({ ... audit: 'Executed by {{ $.user.name }}' })`
|
|
37
|
+
- added `called {Number}` property per action in the `F.actions` collection
|
|
38
|
+
- fixed `CONF.$root` functionality
|
|
39
|
+
- improved `F.backup()` by adding internal ignore list for `.DS_Store` and `.gitignore` files
|
|
40
|
+
- fixed `CONF.$root` in proxies
|
|
27
41
|
|
|
28
42
|
========================
|
|
29
43
|
0.0.12
|
package/controller.js
CHANGED
|
@@ -794,15 +794,15 @@ Controller.prototype.clear = function() {
|
|
|
794
794
|
|
|
795
795
|
Controller.prototype.cookie = function(name, value, expires, options) {
|
|
796
796
|
|
|
797
|
-
|
|
798
|
-
|
|
797
|
+
let ctrl = this;
|
|
798
|
+
let arr;
|
|
799
799
|
|
|
800
800
|
if (value === undefined) {
|
|
801
801
|
|
|
802
802
|
if (ctrl.cookies)
|
|
803
803
|
return F.TUtils.decodeURIComponent(ctrl.cookies[name] || '');
|
|
804
804
|
|
|
805
|
-
|
|
805
|
+
let cookie = ctrl.headers.cookie;
|
|
806
806
|
if (!cookie) {
|
|
807
807
|
ctrl.cookies = F.EMPTYOBJECT;
|
|
808
808
|
return '';
|
|
@@ -821,11 +821,11 @@ Controller.prototype.cookie = function(name, value, expires, options) {
|
|
|
821
821
|
return name ? F.TUtils.decodeURIComponent(ctrl.cookies[name] || '') : '';
|
|
822
822
|
}
|
|
823
823
|
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
824
|
+
let cookiename = name + '=';
|
|
825
|
+
let builder = [cookiename + value];
|
|
826
|
+
let type = typeof(expires);
|
|
827
827
|
|
|
828
|
-
if (expires && type === 'object') {
|
|
828
|
+
if (expires && !(expires instanceof Date) && type === 'object') {
|
|
829
829
|
options = expires;
|
|
830
830
|
expires = options.expires || options.expire || null;
|
|
831
831
|
}
|
|
@@ -849,7 +849,7 @@ Controller.prototype.cookie = function(name, value, expires, options) {
|
|
|
849
849
|
if (options.httpOnly || options.httponly || options.HttpOnly)
|
|
850
850
|
builder.push('HttpOnly');
|
|
851
851
|
|
|
852
|
-
|
|
852
|
+
let same = options.security || options.samesite || F.config.$cookiesamesite;
|
|
853
853
|
|
|
854
854
|
switch (same) {
|
|
855
855
|
case 1:
|
|
@@ -866,7 +866,7 @@ Controller.prototype.cookie = function(name, value, expires, options) {
|
|
|
866
866
|
|
|
867
867
|
// Cookie, already, can be in array, resulting in duplicate 'set-cookie' header
|
|
868
868
|
if (arr.length) {
|
|
869
|
-
|
|
869
|
+
let l = cookiename.length;
|
|
870
870
|
for (let i = 0; i < arr.length; i++) {
|
|
871
871
|
if (arr[i].substring(0, l) === cookiename) {
|
|
872
872
|
arr.splice(i, 1);
|
|
@@ -896,6 +896,9 @@ Controller.prototype.resume = function() {
|
|
|
896
896
|
if (ctrl.isfile) {
|
|
897
897
|
|
|
898
898
|
var path = ctrl.uri.key;
|
|
899
|
+
if (CONF.$root)
|
|
900
|
+
path = path.substring(CONF.$root.length - 1);
|
|
901
|
+
|
|
899
902
|
if (path[1] === '_') {
|
|
900
903
|
|
|
901
904
|
let tmp = path.substring(1);
|
package/htmlparser.js
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
'use strict';
|
|
6
6
|
|
|
7
|
+
const BLOCK = { DIV: 1, P: 1, H1: 1, H2: 1, H3: 1, H4: 1, H5: 1, H6: 1, UL: 1, OL: 1, TABLE: 1, SECTION: 1, HEADER: 1, FOOTER: 1 };
|
|
8
|
+
|
|
7
9
|
function HTMLElement() {
|
|
8
10
|
this.children = [];
|
|
9
11
|
}
|
|
@@ -12,8 +14,11 @@ HTMLElement.prototype = {
|
|
|
12
14
|
get innerHTML() {
|
|
13
15
|
return this.toString();
|
|
14
16
|
},
|
|
17
|
+
get outerHTML() {
|
|
18
|
+
return this.toString(false, true);
|
|
19
|
+
},
|
|
15
20
|
get innerText() {
|
|
16
|
-
return this.
|
|
21
|
+
return this.text();
|
|
17
22
|
}
|
|
18
23
|
};
|
|
19
24
|
|
|
@@ -154,7 +159,10 @@ function extendarr(output) {
|
|
|
154
159
|
};
|
|
155
160
|
|
|
156
161
|
output.text = function() {
|
|
157
|
-
|
|
162
|
+
let builder = [];
|
|
163
|
+
for (let item of this)
|
|
164
|
+
builder.push(item.text());
|
|
165
|
+
return builder.join('\n');
|
|
158
166
|
};
|
|
159
167
|
|
|
160
168
|
return output;
|
|
@@ -430,11 +438,29 @@ HTMLElement.prototype.prepend = function(str) {
|
|
|
430
438
|
return dom;
|
|
431
439
|
};
|
|
432
440
|
|
|
433
|
-
HTMLElement.prototype.text = function() {
|
|
434
|
-
|
|
441
|
+
HTMLElement.prototype.text = function(formatted) {
|
|
442
|
+
let self = this;
|
|
443
|
+
let builder = [];
|
|
444
|
+
let browse = function(children, newline) {
|
|
445
|
+
for (let item of children) {
|
|
446
|
+
switch (item.tagName) {
|
|
447
|
+
case 'TEXT':
|
|
448
|
+
if (builder.length)
|
|
449
|
+
builder.push(newline ? '\n' : '');
|
|
450
|
+
if (item.textContent)
|
|
451
|
+
builder.push(item.textContent.decode());
|
|
452
|
+
break;
|
|
453
|
+
default:
|
|
454
|
+
browse(item.children, self.xml ? true : BLOCK[item.tagName]);
|
|
455
|
+
break;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
};
|
|
459
|
+
browse(self.children, 0);
|
|
460
|
+
return builder.join('');
|
|
435
461
|
};
|
|
436
462
|
|
|
437
|
-
HTMLElement.prototype.toString =
|
|
463
|
+
HTMLElement.prototype.toString = function(formatted, outer) {
|
|
438
464
|
|
|
439
465
|
let self = this;
|
|
440
466
|
let builder = [];
|
|
@@ -457,7 +483,7 @@ HTMLElement.prototype.toString = HTMLElement.prototype.html = function(formatted
|
|
|
457
483
|
switch (item.tagName) {
|
|
458
484
|
case 'TEXT':
|
|
459
485
|
if (item.textContent)
|
|
460
|
-
builder.push(indent + item.textContent);
|
|
486
|
+
builder.push((item.cdata ? '<![CDATA[' : '') + indent + item.textContent + (item.cdata ? ']]>' : ''));
|
|
461
487
|
break;
|
|
462
488
|
default:
|
|
463
489
|
tag = item.raw;
|
|
@@ -475,10 +501,15 @@ HTMLElement.prototype.toString = HTMLElement.prototype.html = function(formatted
|
|
|
475
501
|
}
|
|
476
502
|
};
|
|
477
503
|
|
|
478
|
-
browse(self.tagName ? [self] : self.children, 0);
|
|
504
|
+
// browse(self.tagName ? [self] : self.children, 0);
|
|
505
|
+
browse(outer && self.tagName ? [self] : self.children, 0);
|
|
479
506
|
return builder.join(formatted ? '\n' : '');
|
|
480
507
|
};
|
|
481
508
|
|
|
509
|
+
HTMLElement.prototype.html = function(formatted = false) {
|
|
510
|
+
return this.toString(formatted, false);
|
|
511
|
+
};
|
|
512
|
+
|
|
482
513
|
function removeComments(html) {
|
|
483
514
|
let tagBeg = '<!--';
|
|
484
515
|
let tagEnd = '-->';
|
|
@@ -534,9 +565,16 @@ function parseHTML(html, trim, onerror, isxml) {
|
|
|
534
565
|
let beg = str.indexOf('<');
|
|
535
566
|
let end = -1;
|
|
536
567
|
let tmp;
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
568
|
+
let cdata = false;
|
|
569
|
+
|
|
570
|
+
if (beg !== -1) {
|
|
571
|
+
if (str.substring(beg, beg + 5) === '<![CD') {
|
|
572
|
+
// CDATA
|
|
573
|
+
cdata = true;
|
|
574
|
+
end = str.indexOf(']]>', beg + 6)
|
|
575
|
+
} else
|
|
576
|
+
end = str.indexOf('>', beg + 1);
|
|
577
|
+
}
|
|
540
578
|
|
|
541
579
|
if (beg === -1 || end === -1) {
|
|
542
580
|
if (parent) {
|
|
@@ -550,7 +588,6 @@ function parseHTML(html, trim, onerror, isxml) {
|
|
|
550
588
|
|
|
551
589
|
if (beg > 0) {
|
|
552
590
|
tmp = str.substring(0, beg);
|
|
553
|
-
|
|
554
591
|
if (trim)
|
|
555
592
|
tmp = tmp.trim();
|
|
556
593
|
|
|
@@ -558,20 +595,27 @@ function parseHTML(html, trim, onerror, isxml) {
|
|
|
558
595
|
parent.children.push(makeText(parent, tmp));
|
|
559
596
|
}
|
|
560
597
|
|
|
561
|
-
let node = str.substring(beg + 1, end);
|
|
598
|
+
let node = str.substring(beg + (cdata ? 9 : 1), end);
|
|
562
599
|
let dom = new HTMLElement();
|
|
563
600
|
|
|
564
601
|
dom.xml = isxml;
|
|
565
602
|
|
|
566
603
|
// Doctype or xml?
|
|
567
|
-
if (node[0] === '!' || node[0] === '?')
|
|
604
|
+
if (!cdata && (node[0] === '!' || node[0] === '?'))
|
|
568
605
|
return str.substring(end + 1);
|
|
569
606
|
|
|
570
|
-
if (node[node.length - 1] === '/') {
|
|
607
|
+
if (!cdata && node[node.length - 1] === '/') {
|
|
571
608
|
node = node.substring(0, node.length - 1);
|
|
572
609
|
dom.unpair = true;
|
|
573
610
|
}
|
|
574
611
|
|
|
612
|
+
if (cdata) {
|
|
613
|
+
let txt = makeText(dom, node);
|
|
614
|
+
txt.cdata = true;
|
|
615
|
+
parent.children.push(txt);
|
|
616
|
+
return str.substring(end + 3);
|
|
617
|
+
}
|
|
618
|
+
|
|
575
619
|
let tag = node;
|
|
576
620
|
let index = -1;
|
|
577
621
|
|
package/index.js
CHANGED
|
@@ -233,7 +233,6 @@ global.DEF = {};
|
|
|
233
233
|
F.path.directory = (type, path) => path ? F.path.$join(F.temporary.directories[type], path) : F.temporary.directories[type];
|
|
234
234
|
F.path.tmp = F.path.temp = path => path ? F.path.$join(F.temporary.directories.tmp, path) : F.temporary.directories.tmp;
|
|
235
235
|
F.path.exists = (path, callback) => callback ? (F.Fs.lstat(path, (err, stats) => callback(err ? false : true, stats ? stats.size : 0, stats ? stats.isFile() : false))) : new Promise(resolve => F.path.exists(path, resolve));
|
|
236
|
-
|
|
237
236
|
F.path.$join = function(directory, path) {
|
|
238
237
|
var key = '$' + directory;
|
|
239
238
|
if (!F.temporary.path[key])
|
|
@@ -277,6 +276,10 @@ global.DEF = {};
|
|
|
277
276
|
} catch {}
|
|
278
277
|
};
|
|
279
278
|
|
|
279
|
+
F.virtualpath = function(path) {
|
|
280
|
+
return F.config.$root ? (F.config.$root + (path[0] === '/' ? path.substring(1) : path)) : path;
|
|
281
|
+
};
|
|
282
|
+
|
|
280
283
|
})(global.F);
|
|
281
284
|
|
|
282
285
|
function mailsendforce(message) {
|
|
@@ -536,8 +539,9 @@ function unlink(arr, callback) {
|
|
|
536
539
|
|
|
537
540
|
F.loadconfig = function(value) {
|
|
538
541
|
|
|
539
|
-
|
|
540
|
-
|
|
542
|
+
let cfg = F.TUtils.parseConfig(value);
|
|
543
|
+
let smtp = null;
|
|
544
|
+
let isapi = false;
|
|
541
545
|
|
|
542
546
|
for (let key in cfg) {
|
|
543
547
|
|
|
@@ -597,11 +601,20 @@ F.loadconfig = function(value) {
|
|
|
597
601
|
for (var m of tmp)
|
|
598
602
|
F.config.$httpfiles[m] = true;
|
|
599
603
|
continue;
|
|
604
|
+
case '$api':
|
|
605
|
+
F.config.$apibk = val || '';
|
|
606
|
+
break;
|
|
600
607
|
}
|
|
601
608
|
|
|
602
609
|
F.config[key] = cfg[key];
|
|
603
610
|
}
|
|
604
611
|
|
|
612
|
+
if (cfg.$root) {
|
|
613
|
+
if (!F.config.$apibk)
|
|
614
|
+
F.config.$apibk = F.config.$api;
|
|
615
|
+
F.config.$api = cfg.$root + F.config.$apibk.substring(1);
|
|
616
|
+
}
|
|
617
|
+
|
|
605
618
|
if (!F.config.secret_uid)
|
|
606
619
|
F.config.secret_uid = (F.config.name).crc32(true) + '';
|
|
607
620
|
|
|
@@ -830,11 +843,11 @@ F.load = async function(types, callback) {
|
|
|
830
843
|
|
|
831
844
|
files.sort(function(a) {
|
|
832
845
|
|
|
833
|
-
if (a.type === '
|
|
834
|
-
return 1;
|
|
846
|
+
if (a.type === 'module')
|
|
847
|
+
return -1;
|
|
835
848
|
|
|
836
849
|
if (a.type === 'middleware')
|
|
837
|
-
return
|
|
850
|
+
return 1;
|
|
838
851
|
|
|
839
852
|
return 0;
|
|
840
853
|
});
|
|
@@ -867,6 +880,7 @@ F.load = async function(types, callback) {
|
|
|
867
880
|
case 'controllers':
|
|
868
881
|
case 'schemas':
|
|
869
882
|
case 'actions':
|
|
883
|
+
case 'extensions':
|
|
870
884
|
case 'models':
|
|
871
885
|
case 'definitions':
|
|
872
886
|
case 'middleware':
|
|
@@ -1411,7 +1425,7 @@ F.componentator = function(name, components, removeprev = true, attrs = '') {
|
|
|
1411
1425
|
let relative = 'ui-' + (removeprev ? (nameid + '-') : '') + meta.components.makeid() + '.min.js';
|
|
1412
1426
|
let filename = F.path.public(relative);
|
|
1413
1427
|
|
|
1414
|
-
F.repo[meta.name] = '/' + relative;
|
|
1428
|
+
F.repo[meta.name] = (F.config.$root || '/') + relative;
|
|
1415
1429
|
|
|
1416
1430
|
if (removeprev) {
|
|
1417
1431
|
F.Fs.readdir(F.path.public(), function(err, files) {
|
|
@@ -1449,6 +1463,11 @@ F.componentator = function(name, components, removeprev = true, attrs = '') {
|
|
|
1449
1463
|
|
|
1450
1464
|
};
|
|
1451
1465
|
|
|
1466
|
+
F.syslog = function(msg) {
|
|
1467
|
+
NOW = new Date();
|
|
1468
|
+
console.log('INFO ======= ' + (NOW.format('yyyy-MM-dd HH:mm:ss')) + ': ' + msg);
|
|
1469
|
+
};
|
|
1470
|
+
|
|
1452
1471
|
F.error = function(err, name, url) {
|
|
1453
1472
|
|
|
1454
1473
|
if (!arguments.length)
|
|
@@ -1504,7 +1523,7 @@ F.merge = function(url) {
|
|
|
1504
1523
|
if (url[0] !== '/')
|
|
1505
1524
|
url = '/' + url;
|
|
1506
1525
|
|
|
1507
|
-
url = url.toLowerCase();
|
|
1526
|
+
url = F.virtualpath(url.toLowerCase());
|
|
1508
1527
|
|
|
1509
1528
|
var ext = F.TUtils.getExtension(url);
|
|
1510
1529
|
var key = url.substring(1).replace(/\//g, '-').replace(/\.(js|html|css)$/, '') + '-min.' + ext;
|
|
@@ -2285,6 +2304,7 @@ F.backup = function(filename, files, callback, filter) {
|
|
|
2285
2304
|
var unlink = typeof(filename) === 'string' ? F.Fs.unlink : (filename, callback) => callback();
|
|
2286
2305
|
var concat = [];
|
|
2287
2306
|
var gzipoptions = { memLevel: 9 };
|
|
2307
|
+
var ignorelist = ['.ds_store', '.gitignore', '.npmignore', '.git'];
|
|
2288
2308
|
|
|
2289
2309
|
unlink(filename, function() {
|
|
2290
2310
|
|
|
@@ -2322,6 +2342,15 @@ F.backup = function(filename, files, callback, filter) {
|
|
|
2322
2342
|
|
|
2323
2343
|
files.wait(function(item, next) {
|
|
2324
2344
|
|
|
2345
|
+
let lowerfilename = item.toLowerCase();
|
|
2346
|
+
|
|
2347
|
+
for (let ignore of ignorelist) {
|
|
2348
|
+
if (lowerfilename.includes(ignore)) {
|
|
2349
|
+
next();
|
|
2350
|
+
return;
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2353
|
+
|
|
2325
2354
|
var file = F.Path.join(path, item);
|
|
2326
2355
|
|
|
2327
2356
|
if (F.is)
|
|
@@ -2900,6 +2929,7 @@ process.on('message', function(msg, h) {
|
|
|
2900
2929
|
F.syshash = (__dirname + '-' + F.Os.hostname() + '-' + F.Os.platform() + '-' + F.Os.arch() + '-' + F.Os.release() + '-' + F.Os.tmpdir() + JSON.stringify(process.versions)).md5();
|
|
2901
2930
|
F.isLE = F.Os.endianness ? F.Os.endianness() === 'LE' : true;
|
|
2902
2931
|
F.isWindows = F.Os.platform().substring(0, 3).toLowerCase() === 'win';
|
|
2932
|
+
F.stamp = Date.now().toString(36);
|
|
2903
2933
|
|
|
2904
2934
|
F.config.$total5 = F.Path.dirname(require.resolve('./index'));
|
|
2905
2935
|
|
package/package.json
CHANGED
package/routing.js
CHANGED
|
@@ -63,8 +63,13 @@ function Route(url, action, size) {
|
|
|
63
63
|
action = null;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
let skiproot = false;
|
|
67
|
+
|
|
66
68
|
// Apply a default API endpoint
|
|
67
|
-
|
|
69
|
+
if (url.includes('?')) {
|
|
70
|
+
skiproot = true;
|
|
71
|
+
url = url.replace(/\?/g, F.config.$api).replace(/\/{2,}/g, '/');
|
|
72
|
+
}
|
|
68
73
|
|
|
69
74
|
var t = this;
|
|
70
75
|
|
|
@@ -100,6 +105,9 @@ function Route(url, action, size) {
|
|
|
100
105
|
return;
|
|
101
106
|
}
|
|
102
107
|
|
|
108
|
+
if (!skiproot && t.url2 && CONF.$root)
|
|
109
|
+
t.url2 = CONF.$root + t.url2.substring(1);
|
|
110
|
+
|
|
103
111
|
t.url = exports.split(t.url2, true);
|
|
104
112
|
url = url.substring(index + 1);
|
|
105
113
|
t.id = t.method + '/' + t.url.join('/');
|
|
@@ -271,8 +279,18 @@ function Route(url, action, size) {
|
|
|
271
279
|
t.action = null;
|
|
272
280
|
}
|
|
273
281
|
|
|
274
|
-
if (!t.view && !t.action && t.method !== 'FILE' && t.method !== 'SOCKET')
|
|
275
|
-
|
|
282
|
+
if (!t.view && !t.action && t.method !== 'FILE' && t.method !== 'SOCKET') {
|
|
283
|
+
|
|
284
|
+
let arr = t.url;
|
|
285
|
+
|
|
286
|
+
if (F.config.$root) {
|
|
287
|
+
arr = t.url.join('~').substring(F.config.$root.length - 1).split('~');
|
|
288
|
+
if (arr[0] == '')
|
|
289
|
+
arr[0] = '/';
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
t.view = arr[0] && arr[0] !== '/' ? arr[0] : 'index';
|
|
293
|
+
}
|
|
276
294
|
|
|
277
295
|
if (t.wildcard)
|
|
278
296
|
t.priority -= 50;
|
|
@@ -847,6 +865,9 @@ Proxy.prototype.remove = function() {
|
|
|
847
865
|
|
|
848
866
|
exports.proxy = function(url, target) {
|
|
849
867
|
|
|
868
|
+
// Apply proxy
|
|
869
|
+
url = F.virtualpath(url);
|
|
870
|
+
|
|
850
871
|
if (!target) {
|
|
851
872
|
let index = F.routes.proxies.TfindIndex('url', url.toLowerCase());
|
|
852
873
|
if (index !== -1)
|
package/test.js
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
// The MIT License
|
|
3
3
|
// Copyright 2023 (c) Peter Širka <petersirka@gmail.com>
|
|
4
4
|
|
|
5
|
+
if (!global.Total)
|
|
6
|
+
require('total5');
|
|
7
|
+
|
|
5
8
|
var Test = { items: [], count: 0 };
|
|
6
9
|
|
|
7
10
|
Test.start = function(message) {
|
|
@@ -44,7 +47,7 @@ Test.run = function(callback) {
|
|
|
44
47
|
if (callback)
|
|
45
48
|
callback();
|
|
46
49
|
else
|
|
47
|
-
process.exit(0);
|
|
50
|
+
setTimeout(() => process.exit(0), 2);
|
|
48
51
|
});
|
|
49
52
|
};
|
|
50
53
|
|
package/viewengine.js
CHANGED
|
@@ -372,29 +372,24 @@ function prepare(command, dcommand, functions) {
|
|
|
372
372
|
case '!session':
|
|
373
373
|
case '!user':
|
|
374
374
|
return 'self.safehtml(' + command.substring(1) + ')';
|
|
375
|
-
|
|
376
375
|
case 'host':
|
|
377
376
|
case 'hostname':
|
|
378
377
|
return 'self.hostname';
|
|
379
|
-
|
|
380
378
|
case 'href':
|
|
381
379
|
return command.includes('(') ? ('self.' + command) : 'self.href()';
|
|
382
|
-
|
|
383
380
|
case 'url':
|
|
384
381
|
return 'self.' + command;
|
|
385
|
-
|
|
386
382
|
case 'title':
|
|
387
383
|
case 'description':
|
|
388
384
|
case 'keywords':
|
|
389
385
|
case 'author':
|
|
390
386
|
return command.includes('(') ? ('self.' + command) : '((repository[\'' + command + '\'] || \'\') + \'\').safehtml()';
|
|
391
|
-
|
|
392
387
|
case 'meta':
|
|
393
388
|
return command.includes('(') ? ('self.' + command) : ('self.' + command + '()');
|
|
394
|
-
|
|
395
389
|
case 'title2':
|
|
396
390
|
return 'self.' + command;
|
|
397
|
-
|
|
391
|
+
case 'version':
|
|
392
|
+
return '\'?ts=\'+F.' + command;
|
|
398
393
|
case '!title':
|
|
399
394
|
case '!description':
|
|
400
395
|
case '!keywords':
|
|
@@ -823,10 +818,10 @@ function makehtmlmeta(self) {
|
|
|
823
818
|
|
|
824
819
|
View.prototype.import = function() {
|
|
825
820
|
|
|
826
|
-
|
|
827
|
-
|
|
821
|
+
let builder = '';
|
|
822
|
+
let self = this;
|
|
828
823
|
|
|
829
|
-
for (
|
|
824
|
+
for (let m of arguments) {
|
|
830
825
|
|
|
831
826
|
switch (m) {
|
|
832
827
|
case 'meta':
|
|
@@ -841,7 +836,7 @@ View.prototype.import = function() {
|
|
|
841
836
|
let ext = m.substring(m.length - 3);
|
|
842
837
|
if (ext === 'ico')
|
|
843
838
|
ext = 'x-icon';
|
|
844
|
-
builder += '<link rel="icon" href="/' + m + '" type="image/' + ext + '" />';
|
|
839
|
+
builder += '<link rel="icon" href="' + F.virtualpath('/' + m) + '" type="image/' + ext + '" />';
|
|
845
840
|
break;
|
|
846
841
|
default:
|
|
847
842
|
|
|
@@ -853,22 +848,29 @@ View.prototype.import = function() {
|
|
|
853
848
|
continue;
|
|
854
849
|
}
|
|
855
850
|
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
} else {
|
|
851
|
+
let version = '';
|
|
852
|
+
|
|
853
|
+
if (m[0] === '@') {
|
|
854
|
+
m = m.substring(1);
|
|
855
|
+
version = '?ts=' + F.stamp;
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
if (m.includes('+')) {
|
|
865
859
|
let iscss = REG_CHECKCSS.test(m);
|
|
866
860
|
let path = '/' + F.TUtils.random_string(10).toLowerCase() + '-min.' + (iscss ? 'css' : 'js');
|
|
867
861
|
F.merge(path, m);
|
|
868
862
|
if (iscss)
|
|
869
|
-
tmp = '<link rel="stylesheet" href="' + path + '" />';
|
|
863
|
+
tmp = '<link rel="stylesheet" href="' + F.virtualpath(path) + version + '" />';
|
|
870
864
|
else
|
|
871
|
-
tmp = '<scri' + 'pt src="' + path + '"></scr' + 'ipt>';
|
|
865
|
+
tmp = '<scri' + 'pt src="' + F.virtualpath(path) + version + '"></scr' + 'ipt>';
|
|
866
|
+
} else {
|
|
867
|
+
let absolute = m[0] === '/';
|
|
868
|
+
let key = absolute ? m : ('/' + m);
|
|
869
|
+
if (REG_CHECKCSS.test(m)) {
|
|
870
|
+
tmp = '<link rel="stylesheet" href="' + F.virtualpath(absolute ? m : ('/' + (F.routes.virtual[key] ? '' : 'css/') + m)) + version + '" />';
|
|
871
|
+
} else {
|
|
872
|
+
tmp = '<scri' + 'pt src="' + F.virtualpath(absolute ? m : ('/' + (F.routes.virtual[key] ? '' : 'js/') + m)) + version + '"></scr' + 'ipt>';
|
|
873
|
+
}
|
|
872
874
|
}
|
|
873
875
|
|
|
874
876
|
F.temporary.views[key] = tmp;
|