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/templates.json ADDED
@@ -0,0 +1,74 @@
1
+ {
2
+ "empty": {
3
+ "id": "emptyproject",
4
+ "name": "Empty",
5
+ "total": 4,
6
+ "description": "Empty project without any special setup"
7
+ },
8
+ "typescript": {
9
+ "id": "emptyproject-typescript",
10
+ "name": "Typescript",
11
+ "total": 4,
12
+ "description": "Total.js with typescript"
13
+ },
14
+ "website": {
15
+ "id": "emptyproject-website",
16
+ "name": "Website",
17
+ "total": 4,
18
+ "description": "Website example"
19
+ },
20
+ "postgres": {
21
+ "id": "emptyproject-postgresql",
22
+ "name": "Postgres template",
23
+ "total": 4,
24
+ "description": "Empty project ready to be used with PostgreSQL"
25
+ },
26
+ "app-builder": {
27
+ "id": "emptyproject-builder",
28
+ "name": "App Builder",
29
+ "total": 4,
30
+ "description": "Tool for creating Total.js server-side applications"
31
+ },
32
+ "empty-spa": {
33
+ "id": "emptyproject-emptyspa",
34
+ "name": "Empty SPA",
35
+ "total": 4,
36
+ "description": "Empty single page application project"
37
+ },
38
+ "spa": {
39
+ "id": "emptyproject-spa",
40
+ "name": "SPA",
41
+ "total": 4,
42
+ "description": "Single page application template"
43
+ },
44
+ "pwa": {
45
+ "id": "emptyproject-emptyspa",
46
+ "name": "PWA",
47
+ "total": 4,
48
+ "description": "Progressive web application template"
49
+ },
50
+ "flow": {
51
+ "id": "emptyproject-flow",
52
+ "name": "Flow",
53
+ "total": 4,
54
+ "description": "Visual programming interface for IoT"
55
+ },
56
+ "flowstream": {
57
+ "id": "flowstream",
58
+ "name": "FlowStream",
59
+ "total": 4,
60
+ "description": "Total.js FlowStream"
61
+ },
62
+ "tms": {
63
+ "id": "tms",
64
+ "name": "TMS",
65
+ "total": 4,
66
+ "description": "Total.js Message Service integrator"
67
+ },
68
+ "cms": {
69
+ "id": "cmsbundle",
70
+ "name": "CMS",
71
+ "total": 4,
72
+ "description": "Total.js CMS"
73
+ }
74
+ }
package/tms.js ADDED
@@ -0,0 +1,384 @@
1
+ // Total.js TMS
2
+ // The MIT License
3
+ // Copyright 2022-2023 (c) Peter Širka <petersirka@gmail.com>
4
+
5
+ const ErrorBuilder = F.TBuilders.ErrorBuilder;
6
+
7
+ var Cache = {
8
+ subscribers: {},
9
+ swatchers: {}, // watchers for subscribers
10
+ scache: {}, // cache for subscribers
11
+ publishers: {},
12
+ pcache: {}, // cache for publishers
13
+ calls: {},
14
+ socket: null,
15
+ timeout: null,
16
+ url: ''
17
+ };
18
+
19
+ exports.cache = Cache;
20
+
21
+ function tmscontroller($) {
22
+
23
+ var temporary = F.temporary;
24
+
25
+ Cache.socket = $;
26
+
27
+ $.autodestroy(() => Cache.socket = null);
28
+
29
+ $.on('open', function(client) {
30
+
31
+ if (temporary.tmsblocked[client.ip] > 5) {
32
+ client.close(4001);
33
+ return;
34
+ }
35
+
36
+ if (F.config.secret_tms) {
37
+ var token = client.headers['x-token']; // || client.query.token;
38
+ if (token != F.config.secret_tms) {
39
+ if (temporary.tmsblocked[client.ip])
40
+ temporary.tmsblocked[client.ip]++;
41
+ else
42
+ temporary.tmsblocked[client.ip] = 1;
43
+ client.close(4001);
44
+ return;
45
+ }
46
+ }
47
+
48
+ delete temporary.tmsblocked[client.ip];
49
+ Cache.publishers = {};
50
+ client.tmsready = true;
51
+ refresh(client);
52
+ });
53
+
54
+ $.on('message', function(client, msg) {
55
+
56
+ // msg.type {String}
57
+ // msg.data {Object}
58
+
59
+ var response;
60
+
61
+ if (client.tmsready) {
62
+ if (msg.type === 'ping') {
63
+ msg.type = 'pong';
64
+ client.send(msg);
65
+ } else if (msg.type === 'subscribe' && msg.id) {
66
+ F.stats.performance.subscribe++;
67
+ var schema = Cache.scache[msg.id];
68
+ if (schema) {
69
+ response = schema.transform(msg.data);
70
+ if (!response.error)
71
+ F.TTMS.subscribe(msg.id, response, client);
72
+ }
73
+ } else if (msg.type === 'subscribers' && msg.subscribers instanceof Array) {
74
+ Cache.publishers = {};
75
+ for (var i = 0; i < msg.subscribers.length; i++)
76
+ Cache.publishers[msg.subscribers[i]] = 1;
77
+ } else if (msg.type === 'call' && msg.id) {
78
+ var tmp = Cache.calls[msg.id];
79
+ if (tmp) {
80
+ F.stats.performance.call++;
81
+ response = tmp.schema.transform(msg.data);
82
+ if (response.error) {
83
+ msg.data = response.error instanceof ErrorBuilder ? response.error.output() : response.response.toString();
84
+ msg.error = true;
85
+ client.send(msg);
86
+ } else {
87
+ tmp.callback(response.response, function(err, response) {
88
+ if (err) {
89
+ msg.error = true;
90
+ if (err instanceof ErrorBuilder)
91
+ msg.data = err.output();
92
+ else
93
+ msg.data = [{ error: err + '' }];
94
+ } else {
95
+ msg.success = true;
96
+ msg.data = response;
97
+ }
98
+ if (client && !client.isClosed)
99
+ client.send(msg);
100
+ }, client);
101
+ }
102
+ }
103
+ } else {
104
+ msg.error = true;
105
+ msg.data = new ErrorBuilder.push(404).output();
106
+ client.send(msg);
107
+ }
108
+ }
109
+ });
110
+ }
111
+
112
+ exports.client = function(url, token, callback) {
113
+
114
+ if (typeof(token) === 'function') {
115
+ callback = token;
116
+ token = undefined;
117
+ }
118
+
119
+ var client = new F.TWebSocket.WebSocketClient();
120
+ var publishers = {};
121
+ var subscribers = {};
122
+ var callbacks = {};
123
+ var isopen = false;
124
+ var callbackid = 0;
125
+ var timeout;
126
+
127
+ if (token)
128
+ client.headers['x-token'] = token;
129
+
130
+ client.options.reconnectserver = true;
131
+ client.connect(url.replace(/^http/, 'ws'));
132
+ client.ready = false;
133
+
134
+ client.on('destroy', function() {
135
+
136
+ publishers = null;
137
+ subscribers = null;
138
+
139
+ for (let key in callbacks) {
140
+ let item = callbacks[key];
141
+ clearTimeout(item.timeout);
142
+ item.callback && item.callback('TMS has been destroyed');
143
+ }
144
+
145
+ callbacks = null;
146
+
147
+ timeout && clearTimeout(timeout);
148
+ timeout = null;
149
+ });
150
+
151
+ client.on('close', function() {
152
+ isopen = false;
153
+ client.ready = false;
154
+ });
155
+
156
+ client.on('message', function(msg) {
157
+ if (msg.type === 'call') {
158
+ if (callbacks[msg.callbackid]) {
159
+ let tmp = callbacks[msg.callbackid];
160
+ tmp.callback(msg.error ? ErrorBuilder.assign(msg.data) : null, msg.success ? msg.data : null);
161
+ tmp.timeout && clearTimeout(tmp.timeout);
162
+ delete callbacks[msg.callbackid];
163
+ }
164
+ } else if (msg.type === 'publish' && subscribers[msg.id] && publishers[msg.id]) {
165
+ var err = new ErrorBuilder();
166
+ var data = F.TJSONSchema.transform(publishers[msg.id], err, msg.data, true);
167
+ if (data) {
168
+ for (let fn of subscribers[msg.id])
169
+ fn(data);
170
+ }
171
+ } else if (msg.type === 'meta') {
172
+ publishers = {};
173
+ for (let item of msg.publish)
174
+ publishers[item.id] = item.schema;
175
+ sync_subscribers();
176
+ isopen = true;
177
+ client.ready = true;
178
+ client.meta = msg;
179
+ if (callback) {
180
+ setImmediate(callback, null, client, client.meta);
181
+ callback = null;
182
+ }
183
+ client.emit('meta', msg);
184
+ client.emit('ready');
185
+ }
186
+ });
187
+
188
+ var timeouthandler = function(id) {
189
+ let obj = callbacks[id];
190
+ obj.callback && obj.callback('408: Timeout');
191
+ delete callbacks[id];
192
+ };
193
+
194
+ client.call = function(name, data, callback, timeout) {
195
+ if (callback)
196
+ client.$call(name, data, callback, timeout);
197
+ else
198
+ return new Promise((resolve, reject) => client.$call(name, data, (err, res) => err ? reject(err) : resolve(res), timeout));
199
+ };
200
+
201
+ client.$call = function(name, data, callback, timeout) {
202
+ if (isopen) {
203
+ let key = (callbackid++) + '';
204
+ let obj = {};
205
+ obj.callback = callback;
206
+ obj.timeout = setTimeout(timeouthandler, timeout || 10000, key);
207
+ callbacks[key] = obj;
208
+ client.send({ type: 'call', id: name, data: data, callbackid: key });
209
+ } else
210
+ callback('TMS is offline');
211
+ };
212
+
213
+ client.subscribe = function(name, callback) {
214
+ timeout && clearTimeout(timeout);
215
+ timeout = setTimeout(sync_subscribers, 50, true);
216
+ if (subscribers[name])
217
+ subscribers[name].push(callback);
218
+ else
219
+ subscribers[name] = [callback];
220
+ };
221
+
222
+ client.publish = function(name, data) {
223
+ isopen && client.send({ type: 'subscribe', id: name, data: data });
224
+ };
225
+
226
+ var sync_subscribers = function(force) {
227
+ timeout && clearTimeout(timeout);
228
+ timeout = null;
229
+ let keys = Object.keys(subscribers);
230
+ if (force || keys.length)
231
+ client.send({ type: 'subscribers', subscribers: keys });
232
+ };
233
+
234
+ };
235
+
236
+ function refresh(client) {
237
+
238
+ if (Cache.socket) {
239
+
240
+ var subscribed = [];
241
+ var published = [];
242
+
243
+ for (let key in Cache.pcache) {
244
+ let schema = F.jsonschemas[Cache.pcache[key]];
245
+ published.push({ id: key, schema: schema });
246
+ }
247
+
248
+ for (let key in Cache.scache) {
249
+ let schema = F.jsonschemas[Cache.scache[key]];
250
+ subscribed.push({ id: key, schema: schema });
251
+ }
252
+
253
+ var calls = [];
254
+ for (let key in Cache.calls)
255
+ calls.push({ id: key, schema: F.jsonschemas[Cache.calls[key].schema] });
256
+
257
+ var msg = { type: 'meta', name: F.config.name, subscribe: subscribed, publish: published, subscribers: Object.keys(Cache.subscribers), call: calls };
258
+ if (client)
259
+ client.send(msg);
260
+ else
261
+ Cache.socket.send(msg);
262
+ }
263
+ }
264
+
265
+ exports.refresh = function() {
266
+ Cache.timeout && clearTimeout(Cache.timeout);
267
+ Cache.timeout = setTimeout(refresh, 500);
268
+ };
269
+
270
+ exports.newpublish = function(name, schema) {
271
+
272
+ if (schema == null) {
273
+ delete Cache.pcache[name];
274
+ exports.refresh();
275
+ return;
276
+ }
277
+
278
+ Cache.pcache[name] = F.TUtils.jsonschema(schema);
279
+ exports.refresh();
280
+ };
281
+
282
+ exports.newcall = function(name, schema, callback) {
283
+
284
+ if (schema == null) {
285
+ delete Cache.calls[name];
286
+ exports.refresh();
287
+ return;
288
+ }
289
+
290
+ if (!callback)
291
+ callback = (data, callback, client) => F.action(schema, data, client).callback(callback);
292
+
293
+ let obj = {};
294
+ obj.schema = F.TUtils.jsonschema(schema);
295
+ obj.callback = callback;
296
+ Cache.calls[name] = obj;
297
+ exports.refresh();
298
+ };
299
+
300
+ exports.newsubscribe = function(name, schema, callback) {
301
+
302
+ if (typeof(schema) === 'function') {
303
+ callback = schema;
304
+ schema = null;
305
+ }
306
+
307
+ if (schema)
308
+ Cache.scache[name] = F.TUtils.jsonschema(schema);
309
+ else
310
+ delete Cache.scache[name];
311
+
312
+ exports.subscribe(name, callback);
313
+ exports.refresh();
314
+
315
+ };
316
+
317
+ exports.publish = function(name, value) {
318
+ if (Cache.socket && Cache.pcache[name] && Cache.publishers[name]) {
319
+ F.stats.performance.publish++;
320
+ Cache.socket.send({ type: 'publish', id: name, data: value }, client => client.tmsready);
321
+ }
322
+ };
323
+
324
+ exports.subscribe = function(name, callback, client) {
325
+ if (client) {
326
+ var arr = Cache.swatchers[name];
327
+ if (arr) {
328
+ for (let fn of Cache.arr)
329
+ fn(callback, client);
330
+ }
331
+ } else {
332
+ if (Cache.swatchers[name])
333
+ Cache.swatchers[name].push(callback);
334
+ else
335
+ Cache.swatchers[name] = [callback];
336
+ Cache.subscribers[name] = 1;
337
+ exports.refresh();
338
+ }
339
+ };
340
+
341
+ exports.unsubscribe = function(name, callback) {
342
+ if (Cache.swatchers[name]) {
343
+ exports.refresh();
344
+ if (callback) {
345
+ let index = Cache.swatchers[name].indexOf(callback);
346
+ if (index !== -1)
347
+ Cache.swatchers[name].splice(index, 1);
348
+ if (!Cache.swatchers[name].length)
349
+ delete Cache.swatchers[name];
350
+ if (Cache.swatchers[name])
351
+ Cache.subscribers[name] = 1;
352
+ else
353
+ delete Cache.subscribers[name];
354
+ return index !== -1;
355
+ } else {
356
+ delete Cache.swatchers[name];
357
+ delete Cache.subscribers[name];
358
+ return true;
359
+ }
360
+ }
361
+ return false;
362
+ };
363
+
364
+ F.on('@tms', function() {
365
+
366
+ var endpoint = F.config.$tmsurl;
367
+ var is = Cache.url !== endpoint;
368
+
369
+ if (is && Cache.route) {
370
+ Cache.route.remove();
371
+ Cache.route = null;
372
+ }
373
+
374
+ if ((is && endpoint && F.config.$tms) || (endpoint && F.config.$tms && !Cache.route))
375
+ Cache.route = F.route('SOCKET ' + endpoint, tmscontroller, F.config.$tmsmaxsize);
376
+
377
+ Cache.url = endpoint;
378
+
379
+ if (endpoint && Cache.token !== F.config.secret_tms) {
380
+ Cache.token = F.config.secret_tms;
381
+ Cache.socket && Cache.socket.close(1000, 'Changed TMS secret');
382
+ }
383
+
384
+ });
package/tmsclient.js ADDED
@@ -0,0 +1,125 @@
1
+ exports.create = function(url, token, callback) {
2
+
3
+ if (typeof(token) === 'function') {
4
+ callback = token;
5
+ token = undefined;
6
+ }
7
+
8
+ var client = F.TWebSocket.createclient();
9
+
10
+ var publishers = {};
11
+ var subscribers = {};
12
+ var callbacks = {};
13
+ var isopen = false;
14
+ var callbackid = 0;
15
+ var timeout;
16
+
17
+ if (token)
18
+ client.headers['x-token'] = token;
19
+
20
+ client.options.reconnectserver = true;
21
+ client.connect(url.replace(/^http/, 'ws'));
22
+ client.ready = false;
23
+
24
+ client.on('destroy', function() {
25
+ publishers = null;
26
+ subscribers = null;
27
+
28
+ for (var key in callbacks) {
29
+ var item = callbacks[key];
30
+ clearTimeout(item.timeout);
31
+ item.callback && item.callback('TMS has been destroyed');
32
+ }
33
+
34
+ callbacks = null;
35
+
36
+ timeout && clearTimeout(timeout);
37
+ timeout = null;
38
+ });
39
+
40
+ client.on('close', function() {
41
+ isopen = false;
42
+ client.ready = false;
43
+ });
44
+
45
+ client.on('message', function(msg) {
46
+
47
+ if (msg.type === 'call') {
48
+ if (callbacks[msg.callbackid]) {
49
+ var tmp = callbacks[msg.callbackid];
50
+ tmp.callback(msg.error ? ErrorBuilder.assign(msg.data) : null, msg.success ? msg.data : null);
51
+ tmp.timeout && clearTimeout(tmp.timeout);
52
+ delete callbacks[msg.callbackid];
53
+ }
54
+ } else if (msg.type === 'publish' && subscribers[msg.id] && publishers[msg.id]) {
55
+ var err = new ErrorBuilder();
56
+ var data = framework_jsonschema.transform(publishers[msg.id], err, msg.data, true);
57
+ if (data) {
58
+ for (var fn of subscribers[msg.id])
59
+ fn(data);
60
+ }
61
+ } else if (msg.type === 'meta') {
62
+ publishers = {};
63
+ for (var item of msg.publish)
64
+ publishers[item.id] = item.schema;
65
+ sync_subscribers();
66
+ isopen = true;
67
+ client.ready = true;
68
+ client.meta = msg;
69
+ if (callback) {
70
+ setImmediate(callback, null, client, client.meta);
71
+ callback = null;
72
+ }
73
+ client.emit('meta', msg);
74
+ client.emit('ready');
75
+ }
76
+ });
77
+
78
+ var timeouthandler = function(id) {
79
+ var obj = callbacks[id];
80
+ obj.callback && obj.callback('408: Timeout');
81
+ delete callbacks[id];
82
+ };
83
+
84
+ client.call = function(name, data, callback, timeout) {
85
+ if (callback)
86
+ client._call(name, data, callback, timeout);
87
+ else
88
+ return new Promise((resolve, reject) => client._call(name, data, (err, res) => err ? reject(err) : resolve(res), timeout));
89
+ };
90
+
91
+ client._call = function(name, data, callback, timeout) {
92
+ if (isopen) {
93
+ var key = (callbackid++) + '';
94
+ var obj = {};
95
+ obj.callback = callback;
96
+ obj.timeout = setTimeout(timeouthandler, timeout || 10000, key);
97
+ callbacks[key] = obj;
98
+ client.send({ type: 'call', id: name, data: data, callbackid: key });
99
+ } else
100
+ callback('TMS is offline');
101
+ };
102
+
103
+ client.subscribe = function(name, callback) {
104
+ timeout && clearTimeout(timeout);
105
+ timeout = setTimeout(sync_subscribers, 50, true);
106
+ if (subscribers[name])
107
+ subscribers[name].push(callback);
108
+ else
109
+ subscribers[name] = [callback];
110
+ };
111
+
112
+ client.publish = function(name, data) {
113
+ isopen && client.send({ type: 'subscribe', id: name, data: data });
114
+ };
115
+
116
+ var sync_subscribers = function(force) {
117
+ timeout && clearTimeout(timeout);
118
+ timeout = null;
119
+ var keys = Object.keys(subscribers);
120
+ if (force || keys.length)
121
+ client.send({ type: 'subscribers', subscribers: keys });
122
+ };
123
+
124
+ return client;
125
+ };
package/todo.txt ADDED
@@ -0,0 +1,7 @@
1
+ - openclient
2
+ - update
3
+ - workers (check)
4
+ - autoquery
5
+
6
+ - CSRF tokeny
7
+ - encryption/decryption
package/tools/beta.sh ADDED
@@ -0,0 +1,6 @@
1
+ #!/bin/bash
2
+
3
+ DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
4
+ cd "$DIR"
5
+ cd ..
6
+ npm publish --tag beta
@@ -0,0 +1,6 @@
1
+ #!/bin/bash
2
+
3
+ DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
4
+ cd "$DIR"
5
+ cd ..
6
+ npm publish