total5 0.0.1-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/503.html +65 -0
  2. package/CONTRIBUTING.md +55 -0
  3. package/LICENSE +211 -0
  4. package/README.md +32 -0
  5. package/api.js +289 -0
  6. package/bin/total5 +984 -0
  7. package/builders.js +1435 -0
  8. package/bundles.js +457 -0
  9. package/cache.js +58 -0
  10. package/changelog.txt +3 -0
  11. package/cluster.js +320 -0
  12. package/cms.js +625 -0
  13. package/controller.js +1419 -0
  14. package/cron.js +99 -0
  15. package/debug.js +539 -0
  16. package/edit.js +469 -0
  17. package/error.html +49 -0
  18. package/filestorage.js +1088 -0
  19. package/flow-flowstream.js +3152 -0
  20. package/flow.js +209 -0
  21. package/flowstream.js +1991 -0
  22. package/global.js +125 -0
  23. package/helpers/index.js +32 -0
  24. package/htmlparser.js +650 -0
  25. package/http.js +81 -0
  26. package/image.js +773 -0
  27. package/images.js +747 -0
  28. package/index.js +2658 -0
  29. package/jsonschema.js +691 -0
  30. package/ldap.js +792 -0
  31. package/mail.js +936 -0
  32. package/minificators.js +858 -0
  33. package/nosql-builder.js +440 -0
  34. package/nosql-querybuilder.js +316 -0
  35. package/nosql-reader.js +353 -0
  36. package/nosql-stream.js +617 -0
  37. package/nosql.js +763 -0
  38. package/openclient.js +219 -0
  39. package/package.json +32 -0
  40. package/pause.html +67 -0
  41. package/querybuilder.js +1361 -0
  42. package/release.js +167 -0
  43. package/routing.js +905 -0
  44. package/sourcemap.js +160 -0
  45. package/tangular.js +409 -0
  46. package/templates.js +145 -0
  47. package/templates.json +74 -0
  48. package/tms.js +384 -0
  49. package/tmsclient.js +125 -0
  50. package/todo.txt +7 -0
  51. package/tools/beta.sh +6 -0
  52. package/tools/release.sh +6 -0
  53. package/uibuilder.js +206 -0
  54. package/utils.js +6374 -0
  55. package/viewengine.js +880 -0
  56. package/websocket.js +1939 -0
  57. package/workers.js +129 -0
package/cron.js ADDED
@@ -0,0 +1,99 @@
1
+ // Total.js Cron utility
2
+ // The MIT License
3
+ // Copyright 2023 (c) Peter Širka <petersirka@gmail.com>
4
+
5
+ 'use strict';
6
+
7
+ const Days = ['su', 'mo', 'tu', 'we', 'th', 'fr', 'sa'];
8
+
9
+ // The method compares date with parsed cron data
10
+ function cronexec(output, date) {
11
+
12
+ var m = date.getMinutes();
13
+ var h = date.getHours();
14
+ var d = date.getDate();
15
+ var M = date.getMonth() + 1;
16
+ var day = date.getDay();
17
+ var is = true;
18
+ var values = [m, h, d, M, day];
19
+
20
+ for (var i = 0; i < output.length; i++) {
21
+
22
+ var val = values[i];
23
+ var m = output[i];
24
+
25
+ if (m.type === 'equal') {
26
+ if (m.value !== val) {
27
+ is = false;
28
+ break;
29
+ }
30
+ } else if (m.type === 'every') {
31
+ if (m.value % val !== 0) {
32
+ is = false;
33
+ break;
34
+ }
35
+ } else if (m.type === 'in') {
36
+ if (!m.value.includes(val)) {
37
+ is = false;
38
+ break;
39
+ }
40
+ } else if (m.type === 'between') {
41
+ if (val < m.value[0] || val > m.value[1]) {
42
+ is = false;
43
+ break;
44
+ }
45
+ }
46
+ }
47
+
48
+ return is;
49
+ }
50
+
51
+ // A parser that returns "function(date)" that returns {Boolean}
52
+ exports.make = function(line) {
53
+
54
+ // */15 = every 15
55
+ // 1-2 = BETWEEN
56
+ // 1,2 = IN
57
+
58
+ var arr = line.toLowerCase().replace(/[a-z]+/g, text => Days.indexOf(text.substring(0, 2))).split(/\s|\t/).trim();
59
+ var output = [];
60
+
61
+ for (var m of arr) {
62
+
63
+ var obj = {};
64
+ var tmp = null;
65
+
66
+ if (m === '*') {
67
+ obj.type = '*';
68
+ } else if (m.indexOf('/') !== -1) {
69
+ tmp = m.split('/');
70
+ obj.type = 'every';
71
+ for (let i = 0; i < tmp.length; i++) {
72
+ if (tmp[i] !== '*')
73
+ tmp[i] = +tmp[i];
74
+ }
75
+ obj.value = tmp;
76
+ } else if (m.indexOf(',') !== -1) {
77
+ tmp = m.split(',');
78
+ obj.type = 'in';
79
+ for (let i = 0; i < tmp.length; i++)
80
+ tmp[i] = +tmp[i];
81
+ obj.value = tmp;
82
+ } else if (m.indexOf('-') !== -1) {
83
+ tmp = m.split('-');
84
+ obj.type = 'between';
85
+ for (let i = 0; i < tmp.length; i++)
86
+ tmp[i] = +tmp[i];
87
+ obj.value = tmp;
88
+ } else {
89
+ obj.type = 'equal';
90
+ obj.value = +m;
91
+ }
92
+
93
+ output.push(obj);
94
+ }
95
+
96
+ return function(date) {
97
+ return cronexec(output, date);
98
+ };
99
+ };
package/debug.js ADDED
@@ -0,0 +1,539 @@
1
+ // Debug module (Watcher)
2
+ // The MIT License
3
+ // Copyright 2012-2023 (c) Peter Širka <petersirka@gmail.com>
4
+
5
+ 'use strict';
6
+
7
+ require('./index');
8
+
9
+ var Meta = {
10
+ isWatcher: process.connected !== true,
11
+ callback: null, // watcher callback
12
+ delay: null
13
+ };
14
+
15
+ var first = process.argv.indexOf('--restart') === -1;
16
+ var options = null;
17
+
18
+ module.exports = function(opt) {
19
+
20
+ options = opt || {};
21
+
22
+ // options.ip = '127.0.0.1';
23
+ // options.port = parseInt(process.argv[2]);
24
+ // options.unixsocket = require('node:path').join(require('node:os').tmpdir(), 'app_name');
25
+ // options.config = { name: 'Total.js' };
26
+ // options.https = { key: Fs.readFileSync('keys/agent2-key.pem'), cert: Fs.readFileSync('keys/agent2-cert.pem')};
27
+ // options.sleep = 3000;
28
+ // options.inspector = 9229;
29
+ // options.debugger = 40894;
30
+ // options.watch = ['adminer'];
31
+ // options.livereload = true;
32
+ // options.cluster = 'auto' || or NUMBER
33
+ // options.limit = 10;
34
+ // options.timeout = 5000;
35
+ // options.edit = 'wss://.....com/?id=myprojectname'
36
+
37
+ };
38
+
39
+ module.exports.watcher = function(callback) {
40
+ Meta.delay && clearTimeout(Meta.delay);
41
+ Meta.delay = null;
42
+ Meta.callback = callback;
43
+ runwatching();
44
+ };
45
+
46
+ function runapp() {
47
+ !options && (options = {});
48
+ if (options.servicemode) {
49
+ var types = options.servicemode === true || options.servicemode === 1 ? '' : options.servicemode.split(',').trim();
50
+ global.DEBUG = true;
51
+ F.load(types);
52
+ } else
53
+ F.http(options);
54
+ }
55
+
56
+ function runwatching() {
57
+
58
+ if (!options)
59
+ options = {};
60
+
61
+ var directory = process.cwd();
62
+ var root = directory;
63
+
64
+ var LIVERELOADCHANGE = '';
65
+
66
+ const FILENAME = F.TUtils.getName(process.argv[1] || 'index.js');
67
+ const VERSION = F.version_header;
68
+ const REG_FILES = /(config|bundles\.debug|\.js|\.ts|\.flow|\.resource)+$/i;
69
+ const REG_PUBLIC = /\/public\//i;
70
+ const REG_INDEX = new RegExp(FILENAME.replace(/\.js$/, '') + '_.*?\\.js$');
71
+ const REG_EXTENSION = /\.(js|ts|resource|package|bundle|build|flow|url)$/i;
72
+ const REG_RELOAD = /\.(js|ts|css|html|htm|jpg|png|gif|ico|svg|resource)$/i;
73
+ const isRELOAD = !!options.livereload;
74
+ const SPEED = isRELOAD ? 1000 : 1500;
75
+ const ARGV = F.TUtils.clone(process.argv);
76
+ const PIDNAME = FILENAME.replace(/\.(js|ts)$/, '.pid');
77
+
78
+ if (isRELOAD && typeof(options.livereload) === 'string')
79
+ options.livereload = options.livereload.replace(/^(https|http):\/\//g, '');
80
+
81
+ function copyFile(oldname, newname, callback) {
82
+ var writer = F.Fs.createWriteStream(newname);
83
+ callback && writer.on('finish', callback);
84
+ F.Fs.createReadStream(oldname).pipe(writer);
85
+ }
86
+
87
+ function app() {
88
+
89
+ if (!Meta.callback) {
90
+ global.OBSOLETE = NOOP;
91
+ process.env.NODE_TLS_REJECT_UNAUTHORIZED = '1';
92
+ }
93
+
94
+ var skipbundle = false;
95
+ F.directory = directory;
96
+
97
+ try {
98
+ if (F.Fs.readFileSync(F.path.join(directory, 'bundles.debug'))) {
99
+ skipbundle = true;
100
+ F.directory = directory = F.path.join(directory, '.src');
101
+ }
102
+
103
+ } catch(e) {}
104
+
105
+ const fork = F.Child.fork;
106
+ const directories = [
107
+ F.Path.join(directory, 'controllers'),
108
+ F.Path.join(directory, 'definitions'),
109
+ F.Path.join(directory, 'extensions'),
110
+ F.Path.join(directory, 'modules'),
111
+ F.Path.join(directory, 'models'),
112
+ F.Path.join(directory, 'schemas'),
113
+ F.Path.join(directory, 'actions'),
114
+ F.Path.join(directory, 'resources'),
115
+ F.Path.join(directory, 'source'),
116
+ F.Path.join(directory, 'workers'),
117
+ F.Path.join(directory, 'middleware'),
118
+ F.Path.join(directory, 'bundles'),
119
+ F.Path.join(directory, 'flowstreams'),
120
+ F.Path.join(directory, '/startup/'),
121
+ F.Path.join(directory, '/plugins/')
122
+ ];
123
+
124
+ const SRC = F.Path.join(directory, '.src');
125
+ const prefix = '--------> ';
126
+
127
+ if (options.watch) {
128
+ for (let item of options.watch) {
129
+ if (item[0] === '/')
130
+ item = item.substring(1);
131
+ if (item[item.length - 1] === '/')
132
+ item = item.substring(0, item.length - 1);
133
+ directories.push(F.Path.join(directory, item));
134
+ }
135
+ }
136
+
137
+ var WS = null;
138
+ var files = {};
139
+ var force = false;
140
+ var changes = [];
141
+ var app = null;
142
+ var status = Meta.callback ? 1 : 0;
143
+ var pid = '';
144
+ var isloaded = false;
145
+ var skiprestart = false;
146
+ var isbundle = false;
147
+ var ignore = {};
148
+ var counter = 0;
149
+ var speed = isRELOAD ? 1000 : 4000;
150
+
151
+ ignore['/' + PIDNAME] = 1;
152
+ ignore['/debug.pid'] = 1;
153
+ ignore['/debug.js'] = 1;
154
+ ignore['/bundle.json'] = 1;
155
+ ignore['/package.json'] = 1;
156
+ ignore['/readme.md'] = 1;
157
+
158
+ if (isRELOAD && !Meta.callback) {
159
+ if (typeof(options.livereload) === 'string') {
160
+ WEBSOCKETCLIENT(function(client) {
161
+ client.options.type = 'text';
162
+ client.on('open', () => WS = client);
163
+ client.on('close', () => WS = null);
164
+ client.connect('wss://livereload.totaljs.com/?hostname=' + encodeURIComponent(options.livereload));
165
+ });
166
+ } else {
167
+ var tmppath = F.Path.join(F.Os.tmpdir(), 'total5livereload');
168
+ F.Fs.mkdir(tmppath, function() {
169
+ F.console = NOOP;
170
+ F.route('SOCKET / @text', function($) {
171
+ $.autodestroy(() => WS = null);
172
+ WS = self;
173
+ });
174
+ var port = typeof(options.livereload) === 'number' ? options.livereload : 35729;
175
+ F.directory = tmppath;
176
+ F.http({ port: port });
177
+ console.log('> Live reload: ws://127.0.0.1:' + port);
178
+ });
179
+ }
180
+ }
181
+
182
+ if (skipbundle) {
183
+ try {
184
+ F.Fs.statSync(F.path.root('bundles'));
185
+ isbundle = true;
186
+ } catch(e) {}
187
+ }
188
+
189
+ if (isbundle || isRELOAD) {
190
+ directories.push(F.Path.join(directory, 'public'));
191
+ directories.push(F.Path.join(directory, 'views'));
192
+ }
193
+
194
+ function onFilter(path, isdir) {
195
+ var p = path.substring(directory.length);
196
+ if (isbundle)
197
+ return isdir ? SRC !== path : !ignore[p];
198
+ if (isRELOAD)
199
+ return isdir ? true : REG_RELOAD.test(path);
200
+ if (isdir)
201
+ return true;
202
+ if (!REG_PUBLIC.test(path) && REG_EXTENSION.test(path))
203
+ return true;
204
+ return false;
205
+ }
206
+
207
+ function skiproot(filename) {
208
+ if (filename.substring(filename.length - 3) === '.js') {
209
+ for (var i = 0; i < filename.length - 3; i++) {
210
+ if (filename[i] === '/' || filename[i] === '\\')
211
+ return;
212
+ }
213
+ return true;
214
+ }
215
+ }
216
+
217
+ function onComplete(f) {
218
+
219
+ F.Fs.readdir(directory, function(err, arr) {
220
+
221
+ var length = arr.length;
222
+ for (var i = 0; i < length; i++) {
223
+ var name = arr[i];
224
+ if (name !== FILENAME && !REG_INDEX.test(name) && REG_FILES.test(name) && !skiproot(name))
225
+ f.push(name);
226
+ }
227
+
228
+ length = f.length;
229
+
230
+ for (var i = 0; i < length; i++) {
231
+ var name = f[i];
232
+ if (files[name] === undefined)
233
+ files[name] = isloaded ? 0 : null;
234
+ }
235
+
236
+ refresh();
237
+ });
238
+ }
239
+
240
+ function livereload(filename) {
241
+ isRELOAD && setTimeout2('livereload', (filename) => WS && WS.send(filename || 'unknown'), 500, null, filename);
242
+ }
243
+
244
+ function isViewPublic(filename) {
245
+
246
+ if (!isbundle && !isRELOAD)
247
+ return false;
248
+
249
+ var fn = filename.substring(directory.length);
250
+ var index = fn.indexOf('/', 1);
251
+ var dir = fn.substring(0, index + 1);
252
+
253
+ if (dir === CONF.directory_themes) {
254
+ index = fn.indexOf('/', index + 1);
255
+ dir = fn.substring(index, fn.indexOf('/', index + 1) + 1);
256
+ }
257
+
258
+ return CONF.directory_views === dir || CONF.directory_public === dir ? fn : '';
259
+ }
260
+
261
+ function makestamp() {
262
+ return '--- # --- [ ' + new Date().format('yyyy-MM-dd HH:mm:ss') + ' ] ';
263
+ }
264
+
265
+ function refresh() {
266
+
267
+ var reload = false;
268
+ LIVERELOADCHANGE = '';
269
+
270
+ Object.keys(files).wait(function(filename, next) {
271
+
272
+ F.Fs.stat(filename, function(err, stat) {
273
+ var stamp = makestamp();
274
+ if (err) {
275
+ delete files[filename];
276
+ var tmp = isViewPublic(filename);
277
+ LIVERELOADCHANGE = normalize(filename.replace(directory, ''));
278
+ var log = stamp.replace('#', 'REM') + prefix + LIVERELOADCHANGE;
279
+ if (tmp) {
280
+ if (isbundle) {
281
+ F.Fs.unlinkSync(F.Path.join(SRC, tmp));
282
+ console.log(log);
283
+ }
284
+ reload = true;
285
+ } else {
286
+ changes.push(log);
287
+ force = true;
288
+ }
289
+ } else {
290
+
291
+ var ticks = stat.mtime.getTime();
292
+ if (files[filename] != null && files[filename] !== ticks) {
293
+
294
+ if (filename.endsWith('.bundle') && files[filename.replace(/\.bundle$/, '.url')]) {
295
+ // Bundle from URL address
296
+ files[filename] = ticks;
297
+ reload = true;
298
+ next();
299
+ return;
300
+ }
301
+
302
+ if (options.threads && filename.substring(directory.length).indexOf('/threads/') !== -1 && files[filename]) {
303
+ files[filename] = ticks;
304
+ next();
305
+ return;
306
+ }
307
+
308
+ LIVERELOADCHANGE = normalize(filename.replace(directory, ''));
309
+
310
+ var log = stamp.replace('#', files[filename] === 0 ? 'ADD' : 'UPD') + prefix + LIVERELOADCHANGE;
311
+ if (files[filename]) {
312
+ var tmp = isViewPublic(filename);
313
+ if (tmp) {
314
+ var skip = true;
315
+ if (isbundle) {
316
+ if (filename.lastIndexOf('--') === -1)
317
+ copyFile(filename, F.Path.join(SRC, tmp));
318
+ else
319
+ skip = false;
320
+ }
321
+ if (skip) {
322
+ files[filename] = ticks;
323
+ reload = true;
324
+ next();
325
+ return;
326
+ }
327
+ }
328
+ }
329
+
330
+ changes.push(log);
331
+ force = true;
332
+ }
333
+ files[filename] = ticks;
334
+ }
335
+
336
+ next();
337
+ });
338
+ }, function() {
339
+
340
+ isloaded = true;
341
+
342
+ if (status !== 1 || !force) {
343
+
344
+ // Due to bundes/*.url
345
+ if (status === 2) {
346
+ status = 1;
347
+ force = false;
348
+ changes.length = 0;
349
+ }
350
+
351
+ reload && livereload(LIVERELOADCHANGE);
352
+ if (counter % 150 === 0)
353
+ speed = isRELOAD ? 3000 : 6000;
354
+ setTimeout(refresh_directory, speed);
355
+ return;
356
+ }
357
+
358
+ restart();
359
+ counter = 0;
360
+ speed = SPEED;
361
+ setTimeout(refresh_directory, speed);
362
+
363
+ var length = changes.length;
364
+ for (var i = 0; i < length; i++)
365
+ console.log(changes[i]);
366
+
367
+ changes.length = 0;
368
+ force = false;
369
+ }, 3);
370
+ }
371
+
372
+ function refresh_directory() {
373
+ counter++;
374
+ F.TUtils.ls(directories, onComplete, onFilter);
375
+ }
376
+
377
+ function restart() {
378
+
379
+ if (Meta.callback) {
380
+ if (first)
381
+ first = false;
382
+ else
383
+ Meta.callback(changes);
384
+ return;
385
+ }
386
+
387
+ if (app !== null) {
388
+ try
389
+ {
390
+ skiprestart = true;
391
+ process.kill(app.pid);
392
+ if (options.inspector) {
393
+ setTimeout(restart, 1000);
394
+ return;
395
+ }
396
+ } catch (err) {}
397
+ app = null;
398
+ }
399
+
400
+ var arr = ARGV.slice(2);
401
+ var port = arr.pop();
402
+
403
+ if (process.execArgv.indexOf('--debug') !== -1 || options.debugger) {
404
+ var key = '--debug=' + (options.debugger || 40894);
405
+ process.execArgv.indexOf(key) === -1 && process.execArgv.push(key);
406
+ }
407
+
408
+ if (process.execArgv.indexOf('--inspect') !== -1 || options.inspector) {
409
+ var key = '--inspect=' + (options.inspector || 9229);
410
+ process.execArgv.indexOf(key) === -1 && process.execArgv.push(key);
411
+ }
412
+
413
+ if (first)
414
+ first = false;
415
+ else
416
+ arr.push('--restart');
417
+
418
+ port && arr.push(port);
419
+ app = fork(F.Path.join(root, FILENAME), arr);
420
+
421
+ app.on('message', function(msg) {
422
+ switch (msg) {
423
+ case 'total:eaddrinuse':
424
+ process.exit(1);
425
+ break;
426
+ case 'total:restart':
427
+ console.log(makestamp().replace('#', 'RES'));
428
+ restart();
429
+ break;
430
+ case 'total:ready':
431
+ if (status === 0)
432
+ app.send('total:debug');
433
+ status = 2;
434
+ livereload(LIVERELOADCHANGE);
435
+ break;
436
+ }
437
+ });
438
+
439
+ app.on('exit', function() {
440
+
441
+ // checks unexpected exit
442
+ if (skiprestart === false) {
443
+ app = null;
444
+ process.exit(1);
445
+ return;
446
+ }
447
+
448
+ skiprestart = false;
449
+ if (status === 255)
450
+ app = null;
451
+ });
452
+
453
+ F.emit('$watcher', app);
454
+ }
455
+
456
+ process.on('SIGTERM', end);
457
+ process.on('SIGINT', end);
458
+ process.on('exit', end);
459
+
460
+ function end() {
461
+
462
+ if (process.isending)
463
+ return;
464
+
465
+ process.isending = true;
466
+ F.Fs.unlink(pid, noop);
467
+
468
+ if (app === null) {
469
+ process.exit(0);
470
+ return;
471
+ }
472
+
473
+ skiprestart = true;
474
+ process.kill(app.pid);
475
+ app = null;
476
+ process.exit(0);
477
+ }
478
+
479
+ function noop() {}
480
+
481
+ if (process.pid > 0) {
482
+
483
+ !Meta.callback && console.log(prefix.substring(8) + 'DEBUG PID: ' + process.pid + ' (v' + VERSION + ')');
484
+
485
+ pid = F.Path.join(directory, PIDNAME);
486
+ F.Fs.writeFileSync(pid, process.pid + '');
487
+
488
+ setInterval(function() {
489
+ F.Fs.stat(pid, function(err) {
490
+ if (err) {
491
+ F.Fs.unlink(pid, noop);
492
+ if (app !== null) {
493
+ skiprestart = true;
494
+ process.kill(app.pid);
495
+ }
496
+ process.exit(0);
497
+ }
498
+ });
499
+ }, 4000);
500
+ }
501
+
502
+ restart();
503
+ refresh_directory();
504
+ }
505
+
506
+ var filename = F.Path.join(process.cwd(), PIDNAME);
507
+ if (F.Fs.existsSync(filename)) {
508
+ F.Fs.unlinkSync(filename);
509
+ setTimeout(app, 3500);
510
+ } else
511
+ app();
512
+ }
513
+
514
+ function normalize(path) {
515
+ return F.isWindows ? path.replace(/\\/g, '/') : path;
516
+ }
517
+
518
+ function init() {
519
+
520
+ if (options.cluster) {
521
+ options.count = options.cluster;
522
+ F.TCluster.http(options);
523
+ return;
524
+ }
525
+
526
+ process.on('uncaughtException', e => e.toString().indexOf('ESRCH') == -1 && console.log(e));
527
+ process.title = 'total: debug';
528
+
529
+ if (Meta.isWatcher) {
530
+ if (options.edit) {
531
+ require('./edit').init(options.edit.replace(/^http/, 'ws'));
532
+ setTimeout(runwatching, 1000);
533
+ } else
534
+ setImmediate(runwatching);
535
+ } else
536
+ setImmediate(runapp);
537
+ }
538
+
539
+ Meta.delay = setTimeout(init, 100);