total5 0.0.2 → 0.0.3-2
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/bin/total5 +7 -4
- package/changelog.txt +21 -0
- package/controller.js +122 -6
- package/debug.js +10 -5
- package/filestorage.js +7 -10
- package/flow-flowstream.js +9 -1
- package/global.js +4 -1
- package/http.js +13 -0
- package/images.js +1 -20
- package/index.js +13 -9
- package/jsonschema.js +1 -1
- package/markdown.js +8 -3
- package/minificators.js +5 -1
- package/package.json +1 -1
- package/routing.js +2 -2
- package/tms.js +2 -2
- package/utils.js +11 -0
- package/websocket.js +13 -1
- package/image.js +0 -777
package/bin/total5
CHANGED
|
@@ -93,10 +93,13 @@ FUNC.translate = function(filename) {
|
|
|
93
93
|
var dictionary = {};
|
|
94
94
|
|
|
95
95
|
for (let filename of files) {
|
|
96
|
-
let
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
96
|
+
let ext = U.getExtension(filename);
|
|
97
|
+
if (ext === 'js' || ext === 'html') {
|
|
98
|
+
let body = F.Fs.readFileSync(filename, 'utf8');
|
|
99
|
+
let dict = translate(body);
|
|
100
|
+
for (let key in dict)
|
|
101
|
+
dictionary[key] = dict[key];
|
|
102
|
+
}
|
|
100
103
|
}
|
|
101
104
|
|
|
102
105
|
let builder = [];
|
package/changelog.txt
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
========================
|
|
2
|
+
0.0.3
|
|
3
|
+
========================
|
|
4
|
+
|
|
5
|
+
- extended icon validator by adding support for `tic` keyword
|
|
6
|
+
- added new events `ON('request')`, `ON('controller')` and `ON('websocket')`
|
|
7
|
+
- fixed applying the `$insecure` option in the FlowStream
|
|
8
|
+
- fixed routing for unexpected content-type
|
|
9
|
+
- added `controller.authorize([callback])` method
|
|
10
|
+
- improved `translate` command in `total5` command-line tool
|
|
11
|
+
- fixed link generator for email and phone numbers in `Markdown`
|
|
12
|
+
- fixed auto-restarting app in the `debug` mode with bundles
|
|
13
|
+
- fixed global settings for JS/CSS/HTML minificator
|
|
14
|
+
- improved merging files
|
|
15
|
+
- fixed middleware with `_` underscore character in routes
|
|
16
|
+
- fixed `CORS()` method
|
|
17
|
+
- improved `CORS` checker
|
|
18
|
+
- added support for inheriting inline schemas in the form e.g. `id:String,@address,@products`
|
|
19
|
+
- added `ctrl.image(opt)` method
|
|
20
|
+
- extended `ctrl.filefs()` method by returing `opt` object
|
|
21
|
+
|
|
1
22
|
========================
|
|
2
23
|
0.0.2
|
|
3
24
|
========================
|
package/controller.js
CHANGED
|
@@ -188,6 +188,10 @@ Controller.prototype.callback = function(err, value) {
|
|
|
188
188
|
|
|
189
189
|
};
|
|
190
190
|
|
|
191
|
+
Controller.prototype.cancel = function() {
|
|
192
|
+
this.iscanceled = true;
|
|
193
|
+
};
|
|
194
|
+
|
|
191
195
|
Controller.prototype.csrf = function() {
|
|
192
196
|
return F.def.onCSRFcreate(this);
|
|
193
197
|
};
|
|
@@ -570,6 +574,67 @@ Controller.prototype.filefs = function(name, id, download, checkmeta) {
|
|
|
570
574
|
opt.check = checkmeta;
|
|
571
575
|
|
|
572
576
|
F.filestorage(name).http(ctrl, opt);
|
|
577
|
+
return opt;
|
|
578
|
+
};
|
|
579
|
+
|
|
580
|
+
Controller.prototype.image = function(opt) {
|
|
581
|
+
|
|
582
|
+
// opt.ext {String} required, image extension
|
|
583
|
+
// opt.date {Date} optional, for HTTP cache
|
|
584
|
+
// opt.cache {String} optional, a cache key
|
|
585
|
+
// opt.load {Function(next(stream), opt)};
|
|
586
|
+
// opt.image {Function(img, opt)}
|
|
587
|
+
|
|
588
|
+
var ctrl = this;
|
|
589
|
+
var date = opt.date ? opt.date instanceof Date ? opt.date.toUTCString() : opt.date : null;
|
|
590
|
+
|
|
591
|
+
// HTTP Cache
|
|
592
|
+
if (ctrl.response.cache && date && ctrl.notmodified(date))
|
|
593
|
+
return;
|
|
594
|
+
|
|
595
|
+
if (opt.cache) {
|
|
596
|
+
var tmp = F.path.tmp('img_' + opt.cache + '.' + opt.ext);
|
|
597
|
+
|
|
598
|
+
if (!DEBUG && date)
|
|
599
|
+
ctrl.httpcache(date);
|
|
600
|
+
|
|
601
|
+
F.Fs.lstat(tmp, function(err) {
|
|
602
|
+
if (err) {
|
|
603
|
+
opt.load.call(ctrl, function(stream) {
|
|
604
|
+
var img = F.TImages.load(stream);
|
|
605
|
+
opt.image.call(ctrl, img, opt);
|
|
606
|
+
img.save(tmp, function(err) {
|
|
607
|
+
if (err)
|
|
608
|
+
ctrl.fallback(404, err);
|
|
609
|
+
else
|
|
610
|
+
ctrl.file(tmp);
|
|
611
|
+
});
|
|
612
|
+
}, opt);
|
|
613
|
+
} else
|
|
614
|
+
ctrl.file(tmp);
|
|
615
|
+
});
|
|
616
|
+
} else {
|
|
617
|
+
|
|
618
|
+
opt.load.call(ctrl, function(stream) {
|
|
619
|
+
|
|
620
|
+
var img = F.TImages.load(stream);
|
|
621
|
+
var response = ctrl.response;
|
|
622
|
+
|
|
623
|
+
opt.image.call(ctrl, img, opt);
|
|
624
|
+
|
|
625
|
+
if (ctrl.response.headers.expires)
|
|
626
|
+
delete response.headers.expires;
|
|
627
|
+
|
|
628
|
+
if (!DEBUG && date)
|
|
629
|
+
ctrl.httpcache(date);
|
|
630
|
+
|
|
631
|
+
response.headers.etag = '858' + F.config.$httpetag;
|
|
632
|
+
response.headers['content-type'] = F.TUtils.getContentType(opt.ext);
|
|
633
|
+
ctrl.res.writeHead(response.status, response.headers);
|
|
634
|
+
F.stats.response.stream++;
|
|
635
|
+
img.pipe(ctrl.res);
|
|
636
|
+
}, opt);
|
|
637
|
+
}
|
|
573
638
|
};
|
|
574
639
|
|
|
575
640
|
Controller.prototype.binary = function(buffer, type, download) {
|
|
@@ -881,6 +946,7 @@ Controller.prototype.hostname = function(path) {
|
|
|
881
946
|
Controller.prototype.$route = function() {
|
|
882
947
|
|
|
883
948
|
var ctrl = this;
|
|
949
|
+
|
|
884
950
|
if (ctrl.isfile) {
|
|
885
951
|
|
|
886
952
|
if (F.routes.files.length) {
|
|
@@ -943,7 +1009,6 @@ Controller.prototype.$route = function() {
|
|
|
943
1009
|
|
|
944
1010
|
ctrl.payload = Buffer.concat(ctrl.payload);
|
|
945
1011
|
F.stats.performance.download += ctrl.payload.length / 1024 / 1024;
|
|
946
|
-
|
|
947
1012
|
switch (ctrl.datatype) {
|
|
948
1013
|
case 'json':
|
|
949
1014
|
ctrl.body = F.def.parsers.json(ctrl.payload.toString('utf8'));
|
|
@@ -987,6 +1052,29 @@ function readfile(filename, callback) {
|
|
|
987
1052
|
});
|
|
988
1053
|
}
|
|
989
1054
|
|
|
1055
|
+
/*
|
|
1056
|
+
@Path: Controller
|
|
1057
|
+
@Method: instance.authorize([callback]); #callback {Function(err, session)} optional;
|
|
1058
|
+
The method performs "manual" authorization. If the user is logged in, then `session {Object}` is not null, otherwise `null`. If you don't use the `callback` argument, then the method returns `Promise`.
|
|
1059
|
+
*/
|
|
1060
|
+
Controller.prototype.authorize = function(callback) {
|
|
1061
|
+
|
|
1062
|
+
var ctrl = this;
|
|
1063
|
+
|
|
1064
|
+
if (!callback)
|
|
1065
|
+
return new Promise((resolve, reject) => ctrl.authorize((err, response) => resolve(response)));
|
|
1066
|
+
|
|
1067
|
+
if (F.def.onAuthorize) {
|
|
1068
|
+
var opt = new F.TBuilders.Options(ctrl);
|
|
1069
|
+
opt.TYPE = 'auth';
|
|
1070
|
+
opt.query = ctrl.query;
|
|
1071
|
+
opt.next = opt.callback;
|
|
1072
|
+
opt.$callback = (err, response) => callback(null, response);
|
|
1073
|
+
F.def.onAuthorize(opt);
|
|
1074
|
+
} else
|
|
1075
|
+
callback();
|
|
1076
|
+
}
|
|
1077
|
+
|
|
990
1078
|
Controller.prototype.notmodified = function(date) {
|
|
991
1079
|
var ctrl = this;
|
|
992
1080
|
if (ctrl.headers['if-modified-since'] === date) {
|
|
@@ -1137,6 +1225,7 @@ function execute(ctrl, skipmiddleware) {
|
|
|
1137
1225
|
|
|
1138
1226
|
let schema = body.schema.split('/');
|
|
1139
1227
|
let endpoint = ctrl.route.api[schema[0]];
|
|
1228
|
+
|
|
1140
1229
|
if (endpoint) {
|
|
1141
1230
|
|
|
1142
1231
|
if ((endpoint.auth === 1 && ctrl.user == null) || (endpoint.auth === 2 && ctrl.user)) {
|
|
@@ -1170,29 +1259,56 @@ function execute(ctrl, skipmiddleware) {
|
|
|
1170
1259
|
|
|
1171
1260
|
ctrl.params = params;
|
|
1172
1261
|
ctrl.query = query ? query.parseEncoded() : {};
|
|
1262
|
+
|
|
1263
|
+
if (body)
|
|
1264
|
+
ctrl.body = body;
|
|
1265
|
+
|
|
1266
|
+
if (F.$events.controller) {
|
|
1267
|
+
F.emit('controller', ctrl);
|
|
1268
|
+
if (ctrl.iscanceled)
|
|
1269
|
+
return;
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1173
1272
|
let action = endpoint.action;
|
|
1174
|
-
if (action)
|
|
1175
|
-
ctrl.body = body || {};
|
|
1273
|
+
if (action)
|
|
1176
1274
|
action(ctrl);
|
|
1177
|
-
|
|
1178
|
-
F.action(endpoint.actions, body
|
|
1275
|
+
else
|
|
1276
|
+
F.action(endpoint.actions, ctrl.body, ctrl).autorespond();
|
|
1277
|
+
|
|
1179
1278
|
return;
|
|
1180
1279
|
}
|
|
1181
1280
|
}
|
|
1182
1281
|
|
|
1183
|
-
ctrl.fallback(400, 'Invalid data');
|
|
1184
1282
|
}
|
|
1283
|
+
|
|
1284
|
+
ctrl.fallback(400, 'Invalid data');
|
|
1285
|
+
|
|
1185
1286
|
} else {
|
|
1287
|
+
|
|
1288
|
+
if (F.$events.controller) {
|
|
1289
|
+
/*
|
|
1290
|
+
@Path: Framework
|
|
1291
|
+
@Event: ON('controller', function(ctrl) { ... }); #ctrl {Controller};
|
|
1292
|
+
The event captures all processed controllers on HTTP requests. The next processing can be canceled via the `ctrl.cancel()` method.
|
|
1293
|
+
*/
|
|
1294
|
+
F.emit('controller', ctrl);
|
|
1295
|
+
if (ctrl.iscanceled)
|
|
1296
|
+
return;
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1186
1299
|
if (ctrl.route.actions) {
|
|
1187
1300
|
F.action(ctrl.route.actions, ctrl.body, ctrl).autorespond();
|
|
1188
1301
|
} else {
|
|
1302
|
+
|
|
1189
1303
|
if (ctrl.route.view) {
|
|
1190
1304
|
ctrl.view(ctrl.route.view);
|
|
1191
1305
|
return;
|
|
1192
1306
|
}
|
|
1307
|
+
|
|
1193
1308
|
let action = ctrl.route.action;
|
|
1194
1309
|
if (!action)
|
|
1195
1310
|
action = auto_view;
|
|
1311
|
+
|
|
1196
1312
|
action(ctrl);
|
|
1197
1313
|
}
|
|
1198
1314
|
}
|
package/debug.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Debug module (Watcher)
|
|
2
2
|
// The MIT License
|
|
3
|
-
// Copyright 2012-
|
|
3
|
+
// Copyright 2012-2024 (c) Peter Širka <petersirka@gmail.com>
|
|
4
4
|
|
|
5
5
|
'use strict';
|
|
6
6
|
|
|
@@ -76,7 +76,7 @@ function runwatching() {
|
|
|
76
76
|
const REG_PUBLIC = /\/public\//i;
|
|
77
77
|
const REG_INDEX = new RegExp(FILENAME.replace(/\.js$/, '') + '_.*?\\.js$');
|
|
78
78
|
const REG_EXTENSION = /\.(js|ts|resource|package|bundle|build|flow|url)$/i;
|
|
79
|
-
const REG_RELOAD = /\.(js|ts|css|html|htm|jpg|png|gif|ico|svg|resource)$/i;
|
|
79
|
+
const REG_RELOAD = /\.(js|ts|css|html|htm|jpg|png|gif|ico|svg|webp|resource)$/i;
|
|
80
80
|
const isRELOAD = !!options.livereload;
|
|
81
81
|
const SPEED = isRELOAD ? 1000 : 1500;
|
|
82
82
|
const ARGV = F.TUtils.clone(process.argv);
|
|
@@ -124,8 +124,8 @@ function runwatching() {
|
|
|
124
124
|
F.Path.join(directory, 'middleware'),
|
|
125
125
|
F.Path.join(directory, 'bundles'),
|
|
126
126
|
F.Path.join(directory, 'flowstreams'),
|
|
127
|
-
F.Path.join(directory, '
|
|
128
|
-
F.Path.join(directory, '
|
|
127
|
+
F.Path.join(directory, 'startup'),
|
|
128
|
+
F.Path.join(directory, 'plugins')
|
|
129
129
|
];
|
|
130
130
|
|
|
131
131
|
const SRC = F.Path.join(directory, '.src');
|
|
@@ -186,7 +186,7 @@ function runwatching() {
|
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
-
if (skipbundle) {
|
|
189
|
+
if (!skipbundle) {
|
|
190
190
|
try {
|
|
191
191
|
F.Fs.statSync(F.path.root('bundles'));
|
|
192
192
|
isbundle = true;
|
|
@@ -200,14 +200,19 @@ function runwatching() {
|
|
|
200
200
|
|
|
201
201
|
function onFilter(path, isdir) {
|
|
202
202
|
var p = path.substring(directory.length);
|
|
203
|
+
|
|
203
204
|
if (isbundle)
|
|
204
205
|
return isdir ? SRC !== path : !ignore[p];
|
|
206
|
+
|
|
205
207
|
if (isRELOAD)
|
|
206
208
|
return isdir ? true : REG_RELOAD.test(path);
|
|
209
|
+
|
|
207
210
|
if (isdir)
|
|
208
211
|
return true;
|
|
212
|
+
|
|
209
213
|
if (!REG_PUBLIC.test(path) && REG_EXTENSION.test(path))
|
|
210
214
|
return true;
|
|
215
|
+
|
|
211
216
|
return false;
|
|
212
217
|
}
|
|
213
218
|
|
package/filestorage.js
CHANGED
|
@@ -1018,14 +1018,13 @@ FP.http = function(ctrl, opt) {
|
|
|
1018
1018
|
|
|
1019
1019
|
response.headers['x-size'] = obj.size;
|
|
1020
1020
|
|
|
1021
|
-
if (opt.image) {
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
*/
|
|
1021
|
+
if (opt.image && IMAGES[obj.ext]) {
|
|
1022
|
+
var img = {};
|
|
1023
|
+
img.ext = obj.ext;
|
|
1024
|
+
img.cache = opt.cache;
|
|
1025
|
+
img.load = next => next(F.Fs.createReadStream(filename, { start: HEADERSIZE }));
|
|
1026
|
+
img.image = opt.image;
|
|
1027
|
+
ctrl.image(img);
|
|
1029
1028
|
} else {
|
|
1030
1029
|
|
|
1031
1030
|
var range = ctrl.headers.range;
|
|
@@ -1077,10 +1076,8 @@ FP.http = function(ctrl, opt) {
|
|
|
1077
1076
|
|
|
1078
1077
|
} else {
|
|
1079
1078
|
var stream = F.Fs.createReadStream(filename, { start: HEADERSIZE });
|
|
1080
|
-
|
|
1081
1079
|
if (!opt.download && !DEBUG && date)
|
|
1082
1080
|
ctrl.httpcache(date);
|
|
1083
|
-
|
|
1084
1081
|
ctrl.stream(obj.type, stream);
|
|
1085
1082
|
}
|
|
1086
1083
|
}
|
package/flow-flowstream.js
CHANGED
|
@@ -1467,6 +1467,9 @@ function init_worker(meta, type, callback) {
|
|
|
1467
1467
|
|
|
1468
1468
|
var forkargs = [F.directory, '--fork'];
|
|
1469
1469
|
|
|
1470
|
+
if (F.config.$insecure)
|
|
1471
|
+
forkargs.push('--insecure');
|
|
1472
|
+
|
|
1470
1473
|
if (meta.memory)
|
|
1471
1474
|
forkargs.push('--max-old-space-size=' + meta.memory);
|
|
1472
1475
|
|
|
@@ -3323,7 +3326,12 @@ function makeunixsocket(id) {
|
|
|
3323
3326
|
|
|
3324
3327
|
if (process.argv[1].endsWith('flow-flowstream.js')) {
|
|
3325
3328
|
|
|
3326
|
-
isFLOWSTREAMWORKER = W.workerData || process.argv.
|
|
3329
|
+
isFLOWSTREAMWORKER = W.workerData || process.argv.includes('--fork');
|
|
3330
|
+
|
|
3331
|
+
if (process.argv.includes('--insecure')) {
|
|
3332
|
+
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '1';
|
|
3333
|
+
F.config.$insecure = true;
|
|
3334
|
+
}
|
|
3327
3335
|
|
|
3328
3336
|
// Runs the worker
|
|
3329
3337
|
if (W.workerData) {
|
package/global.js
CHANGED
|
@@ -11,6 +11,7 @@ global.OFF = (name, fn) => F.off(name, fn);
|
|
|
11
11
|
global.ROUTE = F.TRouting.route;
|
|
12
12
|
global.PROXY = F.TRouting.proxy;
|
|
13
13
|
global.print = console.log;
|
|
14
|
+
global.Utils = F.TUtils;
|
|
14
15
|
global.LOAD = F.load;
|
|
15
16
|
global.LOADCONFIG = F.loadconfig;
|
|
16
17
|
global.LOADRESOURCE = F.loadresource;
|
|
@@ -25,6 +26,7 @@ global.CLEANUP = F.cleanup;
|
|
|
25
26
|
global.NEWDB = F.newdb;
|
|
26
27
|
global.IMPORT = F.import;
|
|
27
28
|
global.REQUIRE = F.require;
|
|
29
|
+
global.RESTORE = F.restore;
|
|
28
30
|
global.CRON = F.cron;
|
|
29
31
|
global.UID = F.uid;
|
|
30
32
|
global.SUCCESS = value => DEF.onSuccess(value);
|
|
@@ -48,6 +50,7 @@ global.MODS = F.modules;
|
|
|
48
50
|
global.PLUGINS = F.plugins;
|
|
49
51
|
global.DECRYPT = F.decrypt;
|
|
50
52
|
global.ENCRYPT = F.encrypt;
|
|
53
|
+
global.BACKUP = F.backup;
|
|
51
54
|
global.DECRYPTREQ = F.decryptreq;
|
|
52
55
|
global.ENCRYPTREQ = F.encryptreq;
|
|
53
56
|
global.PATH = F.path;
|
|
@@ -105,7 +108,7 @@ global.LDAP = function(opt, callback) {
|
|
|
105
108
|
global.CORS = function(origin) {
|
|
106
109
|
if (origin && origin[0] === '+') {
|
|
107
110
|
if (F.config.$cors !== '*')
|
|
108
|
-
F.config.$cors
|
|
111
|
+
F.config.$cors += (F.config.$cors ? ',' : '') + origin.substring(1);
|
|
109
112
|
} else
|
|
110
113
|
F.config.$cors = origin || '*';
|
|
111
114
|
F.emit('$cors');
|
package/http.js
CHANGED
|
@@ -65,6 +65,19 @@ exports.listen = function(req, res) {
|
|
|
65
65
|
// Pending requests
|
|
66
66
|
F.temporary.pending.push(ctrl);
|
|
67
67
|
|
|
68
|
+
if (F.$events.request) {
|
|
69
|
+
|
|
70
|
+
/*
|
|
71
|
+
@Path: Framework
|
|
72
|
+
@Event: ON('request', function(ctrl) { ... }); #ctrl {Controller};
|
|
73
|
+
The event captures all incoming requests. The next processing can be canceled via the `ctrl.cancel()` method.
|
|
74
|
+
*/
|
|
75
|
+
F.emit('request', ctrl);
|
|
76
|
+
|
|
77
|
+
if (ctrl.iscanceled)
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
68
81
|
if (ctrl.headers.origin && (F.def.onCORS || F.config.$cors)) {
|
|
69
82
|
if (F.TRouting.lookupcors(ctrl))
|
|
70
83
|
ctrl.$route();
|
package/images.js
CHANGED
|
@@ -222,11 +222,6 @@ ImageProto.measure = function(callback) {
|
|
|
222
222
|
return self;
|
|
223
223
|
};
|
|
224
224
|
|
|
225
|
-
ImageProto.$$measure = function() {
|
|
226
|
-
var self = this;
|
|
227
|
-
return callback => self.measure(callback);
|
|
228
|
-
};
|
|
229
|
-
|
|
230
225
|
ImageProto.save = function(filename, callback, writer) {
|
|
231
226
|
|
|
232
227
|
var self = this;
|
|
@@ -284,13 +279,6 @@ ImageProto.save = function(filename, callback, writer) {
|
|
|
284
279
|
return self;
|
|
285
280
|
};
|
|
286
281
|
|
|
287
|
-
ImageProto.$$save = function(filename, writer) {
|
|
288
|
-
var self = this;
|
|
289
|
-
return function(callback) {
|
|
290
|
-
self.save(filename, callback, writer);
|
|
291
|
-
};
|
|
292
|
-
};
|
|
293
|
-
|
|
294
282
|
ImageProto.pipe = function(stream, type, options) {
|
|
295
283
|
|
|
296
284
|
var self = this;
|
|
@@ -327,7 +315,7 @@ ImageProto.pipe = function(stream, type, options) {
|
|
|
327
315
|
return self;
|
|
328
316
|
};
|
|
329
317
|
|
|
330
|
-
ImageProto.
|
|
318
|
+
ImageProto.writer = function(type, writer) {
|
|
331
319
|
|
|
332
320
|
var self = this;
|
|
333
321
|
|
|
@@ -428,13 +416,6 @@ ImageProto.identify = function(callback) {
|
|
|
428
416
|
return self;
|
|
429
417
|
};
|
|
430
418
|
|
|
431
|
-
ImageProto.$$identify = function() {
|
|
432
|
-
var self = this;
|
|
433
|
-
return function(callback) {
|
|
434
|
-
self.identify(callback);
|
|
435
|
-
};
|
|
436
|
-
};
|
|
437
|
-
|
|
438
419
|
ImageProto.push = function(key, value, priority, encode) {
|
|
439
420
|
var self = this;
|
|
440
421
|
var cmd = key;
|
package/index.js
CHANGED
|
@@ -36,7 +36,7 @@ global.DEF = {};
|
|
|
36
36
|
|
|
37
37
|
F.id = '';
|
|
38
38
|
F.clusterid = '';
|
|
39
|
-
F.is5 = F.version =
|
|
39
|
+
F.is5 = F.version = 5003;
|
|
40
40
|
F.isBundle = false;
|
|
41
41
|
F.isLoaded = false;
|
|
42
42
|
F.version_header = '5';
|
|
@@ -1452,11 +1452,15 @@ F.merge = function(url) {
|
|
|
1452
1452
|
}
|
|
1453
1453
|
|
|
1454
1454
|
if (link[0] !== '~' && link[0] !== '_') {
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1455
|
+
if (link[0] === '/') {
|
|
1456
|
+
link = F.path.public(link);
|
|
1457
|
+
} else {
|
|
1458
|
+
let ext = F.TUtils.getExtension(link);
|
|
1459
|
+
if (ext === 'js')
|
|
1460
|
+
link = F.path.public('/js/' + link);
|
|
1461
|
+
else
|
|
1462
|
+
link = F.path.public('/css/' + link);
|
|
1463
|
+
}
|
|
1460
1464
|
arr.push(link);
|
|
1461
1465
|
} else
|
|
1462
1466
|
arr.push(F.path.route(link, 'public'));
|
|
@@ -2831,9 +2835,9 @@ F.dir();
|
|
|
2831
2835
|
// Init CORS
|
|
2832
2836
|
F.on('$cors', function() {
|
|
2833
2837
|
|
|
2834
|
-
var arr = (F.config.$cors || '').toLowerCase().split(
|
|
2838
|
+
var arr = (F.config.$cors || '').toLowerCase().split(/,|;|\|/).trim();
|
|
2835
2839
|
var wildcard = [];
|
|
2836
|
-
var strict =
|
|
2840
|
+
var strict = {};
|
|
2837
2841
|
|
|
2838
2842
|
for (let i = 0; i < arr.length; i++) {
|
|
2839
2843
|
let val = arr[i];
|
|
@@ -2841,7 +2845,7 @@ F.on('$cors', function() {
|
|
|
2841
2845
|
if (val[0] === '*' && val.length > 1)
|
|
2842
2846
|
wildcard.push(val.substring(1));
|
|
2843
2847
|
else
|
|
2844
|
-
strict
|
|
2848
|
+
strict[val] = 1;
|
|
2845
2849
|
}
|
|
2846
2850
|
}
|
|
2847
2851
|
|
package/jsonschema.js
CHANGED
|
@@ -8,7 +8,7 @@ require('./index');
|
|
|
8
8
|
|
|
9
9
|
const REG_NUMBER = /[\d,.]+/;
|
|
10
10
|
const REG_COLOR = /^#([A-F0-9]{3}|[A-F0-9]{6}|[A-F0-9]{8})$/i;
|
|
11
|
-
const REG_ICON = /^(ti|far|fab|fad|fal|fas|fa)?\s(fa|ti)-[a-z0-9-]+$/;
|
|
11
|
+
const REG_ICON = /^(ti|tic|far|fab|fad|fal|fas|fa)?\s(fa|ti|tic)-[a-z0-9-]+$/;
|
|
12
12
|
const REG_WSPACE = /\u00A0/g;
|
|
13
13
|
|
|
14
14
|
function Value() {}
|
package/markdown.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Total.js Markdown
|
|
2
2
|
// The MIT License
|
|
3
|
-
// Copyright 2018-
|
|
3
|
+
// Copyright 2018-2024 (c) Peter Širka <petersirka@gmail.com>
|
|
4
4
|
|
|
5
5
|
const REG_DASH = /-{2,}/g;
|
|
6
6
|
const REG_TAGS = /<[^>]*>/g;
|
|
@@ -64,9 +64,14 @@ function markdown_links(value) {
|
|
|
64
64
|
var link = value.substring(end + 2, value.length - 1);
|
|
65
65
|
|
|
66
66
|
// footnotes
|
|
67
|
-
if ((/^#\d+$/).test(link))
|
|
67
|
+
if ((/^#\d+$/).test(link))
|
|
68
68
|
return (/^\d+$/).test(text) ? '<sup data-id="{0}" class="markdown-footnote">{1}</sup>'.format(link.substring(1), text) : '<span data-id="{0}" class="markdown-footnote">{1}</span>'.format(link.substring(1), text);
|
|
69
|
-
|
|
69
|
+
|
|
70
|
+
if (link.isEmail())
|
|
71
|
+
return '<a href="mailto:' + link + '" rel="nofollow">' + text + '</a>';
|
|
72
|
+
|
|
73
|
+
if (link.isPhone())
|
|
74
|
+
return '<a href="tel:' + link + '" rel="nofollow">' + text + '</a>';
|
|
70
75
|
|
|
71
76
|
if (link.substring(0, 4) === 'www.')
|
|
72
77
|
link = 'https://' + link;
|
package/minificators.js
CHANGED
|
@@ -301,7 +301,7 @@ exports.htmlremovecomments = function(value) {
|
|
|
301
301
|
return value;
|
|
302
302
|
};
|
|
303
303
|
|
|
304
|
-
exports.merge = async function(filename, filenames, minify
|
|
304
|
+
exports.merge = async function(filename, filenames, minify) {
|
|
305
305
|
|
|
306
306
|
// @filename {String/Boolean}
|
|
307
307
|
|
|
@@ -423,6 +423,7 @@ async function mergedownload(url, minify = true) {
|
|
|
423
423
|
}
|
|
424
424
|
|
|
425
425
|
async function mergefile(filename, minify) {
|
|
426
|
+
|
|
426
427
|
return new Promise(function(resolve) {
|
|
427
428
|
|
|
428
429
|
F.Fs.readFile(filename, 'utf8', function(err, response) {
|
|
@@ -445,6 +446,9 @@ async function mergefile(filename, minify) {
|
|
|
445
446
|
ext = ext.toLowerCase();
|
|
446
447
|
}
|
|
447
448
|
|
|
449
|
+
if (minify === undefined)
|
|
450
|
+
minify = !!F.config['$minify' + ext];
|
|
451
|
+
|
|
448
452
|
var output = { ext: ext };
|
|
449
453
|
|
|
450
454
|
response = response.ROOT();
|
package/package.json
CHANGED
package/routing.js
CHANGED
|
@@ -188,7 +188,7 @@ function Route(url, action, size) {
|
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
// Parse flags
|
|
191
|
-
url = url.replace(/(@|#)+[a-z0-
|
|
191
|
+
url = url.replace(/(@|#)+[a-z0-9_]+/gi, function(text) {
|
|
192
192
|
let tmp = text.trim();
|
|
193
193
|
if (tmp[0] === '#') {
|
|
194
194
|
t.middleware.push(tmp.substring(1));
|
|
@@ -618,7 +618,7 @@ exports.lookupcors = function(ctrl) {
|
|
|
618
618
|
let cors = F.temporary.cors;
|
|
619
619
|
|
|
620
620
|
if (cors) {
|
|
621
|
-
if (cors.strict
|
|
621
|
+
if (cors.strict[origin]) {
|
|
622
622
|
resume = true;
|
|
623
623
|
} else if (cors.wildcard.length) {
|
|
624
624
|
for (let m of cors.wildcard) {
|
package/tms.js
CHANGED
|
@@ -101,7 +101,7 @@ function tmscontroller($) {
|
|
|
101
101
|
}
|
|
102
102
|
} else {
|
|
103
103
|
msg.error = true;
|
|
104
|
-
msg.data = new ErrorBuilder.push(404).output();
|
|
104
|
+
msg.data = new ErrorBuilder().push(404).output();
|
|
105
105
|
client.send(msg);
|
|
106
106
|
}
|
|
107
107
|
}
|
|
@@ -377,4 +377,4 @@ F.on('$tms', function() {
|
|
|
377
377
|
Cache.socket && Cache.socket.close(1000, 'Changed TMS secret');
|
|
378
378
|
}
|
|
379
379
|
|
|
380
|
-
});
|
|
380
|
+
});
|
package/utils.js
CHANGED
|
@@ -5968,6 +5968,17 @@ SP.toJSONSchema = SP.parseSchema = function(name, url) {
|
|
|
5968
5968
|
var arr = prop[i].split(':').trim();
|
|
5969
5969
|
var tmp = null;
|
|
5970
5970
|
|
|
5971
|
+
if (arr[0][0] === '@') {
|
|
5972
|
+
let ext = F.jsonschemas[arr[0].substring(1)];
|
|
5973
|
+
if (ext) {
|
|
5974
|
+
for (let m of ext.required)
|
|
5975
|
+
required.push(m);
|
|
5976
|
+
for (let m in ext.properties)
|
|
5977
|
+
obj.properties[m] = ext.properties[m];
|
|
5978
|
+
}
|
|
5979
|
+
continue;
|
|
5980
|
+
}
|
|
5981
|
+
|
|
5971
5982
|
if (arr[0][0] === '!' || arr[0][0] === '*') {
|
|
5972
5983
|
// required
|
|
5973
5984
|
arr[0] = arr[0].substring(1);
|
package/websocket.js
CHANGED
|
@@ -110,7 +110,19 @@ Controller.prototype.upgrade = function(websocket) {
|
|
|
110
110
|
ctrl.socket.on('end', websocket_close);
|
|
111
111
|
ctrl.parent.add(ctrl);
|
|
112
112
|
websocket.online++;
|
|
113
|
-
|
|
113
|
+
|
|
114
|
+
// Deprecated:
|
|
115
|
+
// F.$events.websocket_begin && F.emit('websocket_begin', ctrl.parent, ctrl);
|
|
116
|
+
|
|
117
|
+
if (F.$events.websocket) {
|
|
118
|
+
/*
|
|
119
|
+
@Path: Framework
|
|
120
|
+
@Event: ON('websocket', function(ctrl) { ... }); #ctrl {Controller};
|
|
121
|
+
The event captures all incoming WebSocket connections. The next processing __can't be__ canceled via the `ctrl.cancel()` method.
|
|
122
|
+
*/
|
|
123
|
+
F.emit('websocket', ctrl);
|
|
124
|
+
}
|
|
125
|
+
|
|
114
126
|
ctrl.parent.$events.open && ctrl.parent.emit('open', ctrl);
|
|
115
127
|
};
|
|
116
128
|
|