total5 0.0.7-1 → 0.0.7-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/builders.js CHANGED
@@ -75,6 +75,10 @@ Options.prototype = {
75
75
  return this.controller ? this.controller.ip : null;
76
76
  },
77
77
 
78
+ get address() {
79
+ return this.controller ? this.controller.address : null;
80
+ },
81
+
78
82
  get files() {
79
83
  return this.controller ? this.controller.files : null;
80
84
  },
@@ -1457,6 +1461,11 @@ ActionCaller.prototype.error = function(value) {
1457
1461
  return this;
1458
1462
  };
1459
1463
 
1464
+ ActionCaller.prototype.ctrl = function(ctrl) {
1465
+ this.controller = ctrl ? (ctrl.controller || ctrl) : null;
1466
+ return this;
1467
+ };
1468
+
1460
1469
  ActionCaller.prototype.done = function($, fn) {
1461
1470
  this.options.callback = function(err, response) {
1462
1471
  if (err)
package/changelog.txt CHANGED
@@ -3,6 +3,16 @@
3
3
  ========================
4
4
 
5
5
  - improved user-agent parser (added support for new headers `Sec-CH-UA`)
6
+ - improved `Number.pluralize()` method
7
+ - reduced DNS cache flush time to 3 minutes
8
+ - added `$.address` property with the absolute URL address
9
+ - added `$.ctrl(ctrl_instance)` method
10
+ - extended `Mail.from(email, [name])` method by adding `name` argument by [Marek Mráz](https://github.com/Mrazbb)
11
+ - added `CONF.mail_from_name {String}` option
12
+ - improved `$.query` parser
13
+ - improved `Total.run()` method
14
+ - added a new method `NEWCOMPONENT(html, [callback])`
15
+ - it compiles a FlowStream component to a method
6
16
 
7
17
  ========================
8
18
  0.0.6
package/components.js ADDED
@@ -0,0 +1,318 @@
1
+ 'use strict';
2
+
3
+ const REG_ARGS = /\{{1,2}[a-z0-9_.-\s]+\}{1,2}/gi;
4
+
5
+ function variables(str, data, encoding) {
6
+
7
+ if (typeof(str) === 'object') {
8
+ var obj = {};
9
+ for (var key in str) {
10
+ var val = str[key];
11
+ if (typeof(val) === 'string')
12
+ obj[key] = variables.call(this, val, data, encoding);
13
+ else
14
+ obj[key] = val;
15
+ }
16
+ return obj;
17
+ }
18
+
19
+ if (typeof(str) !== 'string' || str.indexOf('{') === -1)
20
+ return str;
21
+
22
+ var main = this.instance ? this.instance.module : (this.module || this);
23
+
24
+ if (data == null || data == true)
25
+ data = this;
26
+
27
+ return str.replace(REG_ARGS, function(text) {
28
+
29
+ var l = text[1] === '{' ? 2 : 1;
30
+ var key = text.substring(l, text.length - l).trim();
31
+ var val = null;
32
+
33
+ if (main.variables)
34
+ val = main.variables[key];
35
+
36
+ if (!val && main.variables2)
37
+ val = main.variables2[key];
38
+
39
+ if (!val && main.secrets)
40
+ val = main.secrets[key];
41
+
42
+ /*
43
+ if (!val && key === 'hostname') {
44
+ val = '';
45
+ if (val[val.length - 1] === '/')
46
+ val = val.substring(0, val.length - 1);
47
+ }*/
48
+
49
+ var customencoding = typeof(encoding) === 'function';
50
+
51
+ if (!val && data != null && typeof(data) === 'object') {
52
+ var nested = key.indexOf('.') !== -1;
53
+ val = nested ? F.TUtils.get(data, key) : data[key];
54
+ }
55
+
56
+ if (customencoding) {
57
+
58
+ val = encoding(val, key);
59
+
60
+ } else {
61
+
62
+ if (encoding !== 'json') {
63
+ if (val instanceof Date)
64
+ val = val.format();
65
+ }
66
+
67
+ switch (encoding) {
68
+ case 'urlencoded':
69
+ case 'url':
70
+ val = encodeURIComponent(val);
71
+ break;
72
+ case 'json':
73
+ val = JSON.stringify(val);
74
+ break;
75
+ case 'querify':
76
+ val = F.TUtils.querify(val).substring(1);
77
+ break;
78
+ }
79
+ }
80
+
81
+ return val == null ? text : val;
82
+
83
+ });
84
+ }
85
+
86
+ function Component() {
87
+ let t = this;
88
+ t.variables = t.variables2 = {};
89
+ t.secrets = {};
90
+ t.instances = [];
91
+ }
92
+
93
+ Component.prototype.service = function(counter) {
94
+ for (let m of this.instances)
95
+ m.service && m.service(counter);
96
+ };
97
+
98
+ Component.prototype.status = function(instance, msg) {
99
+ console.log('STATUS', this.name, msg);
100
+ };
101
+
102
+ Component.prototype.debug = function(instance, msg) {
103
+ console.log('DEBUG', this.name + ':', msg);
104
+ };
105
+
106
+ Component.prototype.dashboard = function(instance, msg) {
107
+ console.log('DASHBOARD', this.name + ':', msg);
108
+ };
109
+
110
+ Component.prototype.throw = function(instance, err) {
111
+ console.log('ERROR', this.name + ':', err);
112
+ };
113
+
114
+ Component.prototype.output = function(instance, response) {
115
+ console.log('OUTPUT', this.name + ' | ' + response.output + ':', response.data);
116
+ };
117
+
118
+ Component.prototype.create = function(opt, status) {
119
+
120
+ let t = this;
121
+ let instance = new Instance();
122
+ instance.id = U.random_text(8);
123
+ instance.config = t.config ? F.TUtils.clone(t.config) : {};
124
+ instance.module = t;
125
+
126
+ if (opt) {
127
+ for (let key in opt)
128
+ instance.config[key] = opt[key];
129
+ }
130
+
131
+ t.instances.push(instance);
132
+ t.make.call(instance, instance, instance.config, status);
133
+ t.oncreate && setImmediate(() => t.oncreate(instance));
134
+ return instance;
135
+ };
136
+
137
+ Component.prototype.remove = function() {
138
+ let t = this;
139
+ t.instances.wait(function(instance, next) {
140
+ instance.remove();
141
+ setImmediate(next);
142
+ }, function() {
143
+ t.uninstall && t.uninstall.call(t, t);
144
+ });
145
+ };
146
+
147
+ Component.prototype.save = function(instance) {
148
+ // save state
149
+ };
150
+
151
+ function Message() {
152
+ let t = this;
153
+ t.repo = {};
154
+ t.vars = {};
155
+ t.used = 1;
156
+ t.main = null;
157
+ t.processed = 0;
158
+ }
159
+
160
+ Message.prototype.replace = variables;
161
+
162
+ Message.prototype.send = function(output, data) {
163
+ let t = this;
164
+ if (!t.instance)
165
+ return;
166
+ if (data != null)
167
+ t.data = data;
168
+ t.output = output;
169
+ t.instance.output && t.instance.output(t);
170
+ };
171
+
172
+ Message.prototype.end = Message.prototype.destroy = function() {
173
+ let t = this;
174
+ t.data = null;
175
+ t.fromcomponent = null;
176
+ t.instance = null;
177
+ t.vars = null;
178
+ t.repo = null;
179
+ t.refs = null;
180
+ }
181
+
182
+ function Instance() {
183
+ let t = this;
184
+ t.id = U.random_text(8);
185
+ t.cache = {};
186
+ t.middleware = NOOP;
187
+ t.transform = NOOP;
188
+ t.replace = variables;
189
+ t.instances = EMPTYOBJECT;
190
+ t.components = EMPTYOBJECT;
191
+ }
192
+
193
+ Instance.prototype.replace = variables;
194
+
195
+ Instance.prototype.remove = function() {
196
+ let t = this;
197
+ t.close && t.close.call(t, true);
198
+ t.destroy && t.destroy.call(t);
199
+ t.module.onremove && t.module.onremove(t);
200
+ let index = t.module.instances.indexOf(t);
201
+ t.module.instances.splice(index, 1);
202
+ };
203
+
204
+ Instance.prototype.input = function(input, data) {
205
+ let t = this;
206
+ if (t.message) {
207
+ let msg = t.newmessage(data);
208
+ msg.input = input;
209
+ t.message(msg);
210
+ }
211
+ };
212
+
213
+ Instance.prototype.send = function(output, data) {
214
+ let msg = data instanceof Message ? data : this.newmessage();
215
+ msg.output = output;
216
+ msg.data = data;
217
+ msg.send(output);
218
+ };
219
+
220
+ Instance.prototype.newmessage = function(data) {
221
+ var t = this;
222
+ var msg = new Message();
223
+ msg.from = msg.instance = t;
224
+ msg.fromid = msg.id;
225
+ msg.fromcomponent = msg.component;
226
+ msg.data = data instanceof Message ? data.data : data;
227
+ return msg;
228
+ };
229
+
230
+ Instance.prototype.save = function() {
231
+ this.module.save(this);
232
+ };
233
+
234
+ Instance.prototype.output = function(response) {
235
+ this.module.output(this, response);
236
+ };
237
+
238
+ Instance.prototype.debug = function(msg) {
239
+ this.module.debug(this, msg);
240
+ };
241
+
242
+ Instance.prototype.throw = function(err) {
243
+ this.module.throw(this, error);
244
+ };
245
+
246
+ Instance.prototype.dashboard = function(msg) {
247
+ this.module.dashboard(this, msg);
248
+ };
249
+
250
+ Instance.prototype.reconfigure = function(opt) {
251
+ let t = this;
252
+ for (let key in opt)
253
+ t.config[key] = opt[key];
254
+ t.configure && t.configure(t.config);
255
+ t.save();
256
+ };
257
+
258
+ Instance.prototype.status = function(msg) {
259
+ this.module.status(this, msg);
260
+ };
261
+
262
+ Instance.prototype.logger = NOOP;
263
+ Instance.prototype.transform = NOOP;
264
+ Instance.prototype.middleware = NOOP;
265
+
266
+ exports.compile = function(html, callback) {
267
+
268
+ if (callback == null) {
269
+ return new Promise(function(resolve, reject) {
270
+ exports.compile(html, function(err, com) {
271
+ if (err)
272
+ reject(err);
273
+ else
274
+ resolve(com);
275
+ });
276
+ })
277
+ }
278
+
279
+ var meta = html.parseComponent({ readme: '<readme>', settings: '<settings>', css: '<style>', be: '<script total>', be2: '<script node>', js: '<script>', html: '<body>', schema: '<schema>', template: '<template>' });
280
+ var node = (meta.be || meta.be2 || '').trim().replace(/\n\t/g, '\n');
281
+
282
+ if (!meta.be && !meta.be2) {
283
+ var e = new Error('Invalid component content');
284
+ callback(e);
285
+ return;
286
+ }
287
+
288
+ var fn = null;
289
+ var com = new Component();
290
+
291
+ delete meta.be;
292
+ delete meta.be2;
293
+ com.ui = meta;
294
+
295
+ try {
296
+ fn = new Function('exports', 'require', node);
297
+ fn(com, F.require);
298
+ } catch (e) {
299
+ callback(e);
300
+ return;
301
+ }
302
+
303
+ var errors = [];
304
+
305
+ (com.npm || EMPTYARRAY).wait(function(name, next) {
306
+ NPMINSTALL(name, function(err) {
307
+ if (err) {
308
+ callback(err);
309
+ next = null;
310
+ } else
311
+ next();
312
+ });
313
+ }, function() {
314
+ com.install && com.install.call(com, com);
315
+ callback(null, com);
316
+ });
317
+
318
+ };
package/controller.js CHANGED
@@ -42,7 +42,7 @@ function Controller(req, res) {
42
42
  ctrl.url = ctrl.uri.pathname;
43
43
  ctrl.released = false;
44
44
  ctrl.downloaded = false;
45
- ctrl.protocol = req.connection.encrypted || (req.headers['x-forwarded-protocol'] || req.headers['x-forwarded-proto']) === 'https' ? 'https' : 'http';
45
+ ctrl.protocol = req.connection.encrypted || req.headers['x-forwarded-ssl'] === 'on' || req.headers['x-forwarded-port'] === '443' || (req.headers['x-forwarded-proto'] || req.headers['x-forwarded-protocol']) === 'https' ? 'https' : 'http';
46
46
 
47
47
  for (let path of ctrl.split)
48
48
  ctrl.split2.push(path.toLowerCase());
@@ -113,6 +113,14 @@ function Controller(req, res) {
113
113
 
114
114
  Controller.prototype = {
115
115
 
116
+ get query() {
117
+ return this.$query || (this.$query = ctrl.uri.search.parseEncoded());
118
+ },
119
+
120
+ set query(val) {
121
+ this.$query = val;
122
+ },
123
+
116
124
  get mobile() {
117
125
  let ua = this.headers['user-agent'];
118
126
  return ua ? REG_MOBILE.test(ua) : false;
@@ -159,6 +167,10 @@ Controller.prototype = {
159
167
 
160
168
  get host() {
161
169
  return this.headers.host;
170
+ },
171
+
172
+ get address() {
173
+ return (this.protocol + '://' + this.headers?.host || '') + (this.req?.url || '');
162
174
  }
163
175
 
164
176
  };
@@ -1013,12 +1025,16 @@ Controller.prototype.$route = function() {
1013
1025
 
1014
1026
  ctrl.payload = Buffer.concat(ctrl.payload);
1015
1027
  F.stats.performance.download += ctrl.payload.length / 1024 / 1024;
1028
+ let val;
1029
+
1016
1030
  switch (ctrl.datatype) {
1017
1031
  case 'json':
1018
- ctrl.body = F.def.parsers.json(ctrl.payload.toString('utf8'));
1032
+ val = ctrl.payload.toString('utf8');
1033
+ ctrl.body = val ? F.def.parsers.json(val) : null;
1019
1034
  break;
1020
1035
  case 'urlencoded':
1021
- ctrl.body = F.def.parsers.urlencoded(ctrl.payload.toString('utf8'));
1036
+ val = ctrl.payload.toString('utf8');
1037
+ ctrl.body = val ? F.def.parsers.urlencoded(val) : {};
1022
1038
  break;
1023
1039
  }
1024
1040
 
package/flowstream.js CHANGED
@@ -999,7 +999,6 @@ function newmessage(data) {
999
999
  msg.data = data instanceof Message ? data.data : data;
1000
1000
  msg.cloned = 0;
1001
1001
  msg.count = 0;
1002
- msg.instance = self;
1003
1002
  msg.duration = msg.ts = Date.now();
1004
1003
  msg.used = 1;
1005
1004
  msg.main = self instanceof FlowStream ? self : self.main;
package/global.js CHANGED
@@ -40,6 +40,7 @@ global.DATA = new F.TQueryBuilder.Controller(true);
40
40
  global.DB = () => new F.TQueryBuilder.Controller();
41
41
  global.CACHE = F.cache;
42
42
  global.NEWACTION = F.TBuilders.newaction;
43
+ global.NEWCOMPONENT = F.newcomponent;
43
44
  global.NEWSCHEMA = F.TBuilders.newschema;
44
45
  global.ACTION = global.EXEC = F.TBuilders.action;
45
46
  global.TEMPLATE = F.template;
package/index.js CHANGED
@@ -460,7 +460,7 @@ function unlink(arr, callback) {
460
460
  } else
461
461
  msg.to(email);
462
462
 
463
- msg.from(F.config.mail_from || F.config.smtp.from || F.config.smtp.user);
463
+ msg.from(F.config.mail_from || F.config.smtp.from || F.config.smtp.user, F.config.mail_from_name || F.config.smtp.name);
464
464
  callback && msg.callback(callback);
465
465
 
466
466
  if (reply)
@@ -1243,6 +1243,11 @@ F.httpload = function(opt) {
1243
1243
  F.server = F.Http.createServer(F.THttp.listen);
1244
1244
  F.server.on('upgrade', F.TWebSocket.listen);
1245
1245
 
1246
+ CONF.$performance && F.server.on('connection', function(socket) {
1247
+ socket.setNoDelay(true);
1248
+ socket.setKeepAlive(true, 10);
1249
+ });
1250
+
1246
1251
  var unixsocket = opt.unixsocket || F.config.$unixsocket;
1247
1252
  if (unixsocket) {
1248
1253
 
@@ -1724,7 +1729,7 @@ F.service = function(count) {
1724
1729
  if (count % F.config.$tmsclearblocked === 0)
1725
1730
  F.temporary.tmsblocked = {};
1726
1731
 
1727
- if (count % 30 === 0)
1732
+ if (count % 3 === 0)
1728
1733
  F.temporary.dnscache = {};
1729
1734
 
1730
1735
  let blocked = F.temporary.blocked;
@@ -2499,7 +2504,7 @@ F.filestorage = function(name) {
2499
2504
 
2500
2505
  F.encryptreq = function(ctrl, val, key, strict) {
2501
2506
  var obj = {};
2502
- obj.ua = ctrl.ua;
2507
+ obj.ua = HASH(ctrl.headers['user-agent'] || '').toString(36);
2503
2508
  if (strict)
2504
2509
  obj.ip = ctrl.ip;
2505
2510
  obj.data = val;
@@ -2510,7 +2515,7 @@ F.decryptreq = function(ctrl, val, key) {
2510
2515
  if (!val)
2511
2516
  return;
2512
2517
  var obj = F.decrypt(val, key || '', true);
2513
- if (!obj || (obj.ip && obj.ip !== ctrl.ip) || (obj.ua !== ctrl.ua))
2518
+ if (!obj || (obj.ip && obj.ip !== ctrl.ip) || (obj.ua !== HASH(ctrl.headers['user-agent'] || '').toString(36)))
2514
2519
  return;
2515
2520
  return obj.data;
2516
2521
  };
@@ -2572,6 +2577,8 @@ F.dir = function(val) {
2572
2577
  };
2573
2578
 
2574
2579
  F.run = function(opt) {
2580
+ if (!opt)
2581
+ opt = {};
2575
2582
  var type = opt.watcher === false ? 'release' : 'debug';
2576
2583
  opt.watcher = false;
2577
2584
  require('./' + type)(opt);
@@ -2648,6 +2655,10 @@ F.datauri = function(path) {
2648
2655
  }));
2649
2656
  };
2650
2657
 
2658
+ F.newcomponent = function(html, callback) {
2659
+ return require('./components').compile(html, callback);
2660
+ };
2661
+
2651
2662
  F.loadstats = function() {
2652
2663
 
2653
2664
  var main = {};
package/mail.js CHANGED
@@ -60,8 +60,9 @@ Message.prototype.callback = function(fn) {
60
60
  return this;
61
61
  };
62
62
 
63
- Message.prototype.sender = Message.prototype.from = function(email) {
63
+ Message.prototype.sender = Message.prototype.from = function(email, name) {
64
64
  this.email_from = email;
65
+ this.email_from_name = name;
65
66
  return this;
66
67
  };
67
68
 
@@ -571,7 +572,7 @@ Mailer.$writemessage = function(obj, buffer) {
571
572
  self.$priority && message.push('X-Priority: ' + self.$priority);
572
573
  self.$confidential && message.push('Sensitivity: Company-Confidential');
573
574
 
574
- message.push('From: <' + msg.email_from + '>');
575
+ message.push('From: ' + (msg.email_from_name ? (unicode_encode(msg.email_from_name) + ' <' + msg.email_from + '>') : msg.email_from));
575
576
 
576
577
  if (msg.headers) {
577
578
  for (let key in msg.headers)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "total5",
3
- "version": "0.0.7-1",
3
+ "version": "0.0.7-3",
4
4
  "description": "Total.js framework v5",
5
5
  "main": "index.js",
6
6
  "directories": {
package/utils.js CHANGED
@@ -4319,13 +4319,7 @@ NP.pluralize = function(zero, one, few, other) {
4319
4319
  else
4320
4320
  value = other;
4321
4321
 
4322
- var beg = value.indexOf('#');
4323
- if (beg === -1)
4324
- return value;
4325
-
4326
- var end = value.lastIndexOf('#');
4327
- var format = value.substring(beg, end + 1);
4328
- return num.format(format) + value.replace(format, '');
4322
+ return value.replace('#', num.toString());
4329
4323
  };
4330
4324
 
4331
4325
  NP.VAT = NP.TAX = function(percentage, decimals, includedVAT) {