total5 0.0.1-2 → 0.0.1-21

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/minificators.js CHANGED
@@ -167,7 +167,7 @@ exports.js = function(value) {
167
167
  }
168
168
  }
169
169
 
170
- if ((c === '}' && last === ';') || ((c === '}' || c === ']') && output[output.length - 1] === ' ' && alpha.test(output[output.length - 2])))
170
+ if (!scope && (c === '}' && last === ';') || ((c === '}' || c === ']') && output[output.length - 1] === ' ' && alpha.test(output[output.length - 2])))
171
171
  output.pop();
172
172
 
173
173
  output.push(c);
package/nosql-builder.js CHANGED
@@ -253,7 +253,7 @@ NoSQLQueryBuilder.prototype.sort = function(sort) {
253
253
 
254
254
  if (self.$fields && self.$fields.length) {
255
255
  // Internal hack
256
- var meta = F.temporary.other['sort_' + sort];
256
+ var meta = F.temporary.utils['sort_' + sort];
257
257
  for (var i = 0; i < meta.length; i++) {
258
258
  var sort = meta[i];
259
259
  if (!self.$fieldsall[sort.name]) {
package/nosql.js CHANGED
@@ -93,6 +93,17 @@ NoSQL.prototype.find = function(builder) {
93
93
  return builder;
94
94
  };
95
95
 
96
+ NoSQL.prototype.update = function(builder) {
97
+ var self = this;
98
+ if (builder instanceof NoSQLQueryBuilder)
99
+ builder.db = self;
100
+ else
101
+ builder = new NoSQLQueryBuilder(self);
102
+ self.pending_update.push(builder);
103
+ setImmediate(next_operation, self, 2);
104
+ return builder;
105
+ };
106
+
96
107
  NoSQL.prototype.find2 = function(builder) {
97
108
  var self = this;
98
109
  if (builder instanceof NoSQLQueryBuilder)
package/openclient.js CHANGED
@@ -197,7 +197,7 @@ exports.create = function(url, id) {
197
197
  opt.ws = F.openclients[url];
198
198
 
199
199
  if (!opt.ws) {
200
- opt.ws = require('./websocketclient').create();
200
+ opt.ws = F.websocketclient();
201
201
  setImmediate(() => opt.ws.connect(url));
202
202
  F.openclients[url] = opt.ws;
203
203
  opt.ws.options.reconnectserver = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "total5",
3
- "version": "0.0.1-2",
3
+ "version": "0.0.1-21",
4
4
  "description": "Total.js framework v5",
5
5
  "main": "index.js",
6
6
  "directories": {
package/querybuilder.js CHANGED
@@ -155,7 +155,7 @@ CTP.next = function(t) {
155
155
 
156
156
  CTP.callback = function($) {
157
157
  var t = this;
158
- t.$callback = typeof($) === 'function' ? $ : $.callback;
158
+ t.$callback = typeof($) === 'function' ? $ : $.callback();
159
159
  return t;
160
160
  };
161
161
 
@@ -380,7 +380,6 @@ CTP.command = function(table, name) {
380
380
  };
381
381
 
382
382
  DBP.evaluate = function(err, response) {
383
-
384
383
  var t = this;
385
384
 
386
385
  if (t.options.first && response instanceof Array)
@@ -501,7 +500,7 @@ QBP.set = function(name) {
501
500
 
502
501
  QBP.callback = function($) {
503
502
  var t = this;
504
- t.main.callback = typeof($) === 'function' ? $ : $.callback;
503
+ t.main.callback = typeof($) === 'function' ? $ : $.callback();
505
504
  return t;
506
505
  };
507
506
 
package/routing.js CHANGED
@@ -28,17 +28,17 @@ function parseSizeTimeout(route, value) {
28
28
  route.timeout = number * 60 * 60;
29
29
  break;
30
30
  case 'b':
31
- route.size = number / 1024;
31
+ route.size = number;
32
32
  break;
33
33
  case 'kb':
34
- route.size = number;
34
+ route.size = number / 1024;
35
35
  break;
36
36
  case 'gb':
37
- route.size = (number * 1024) * 1000;
37
+ route.size = (number * 1024 * 1024) * 1000;
38
38
  break;
39
39
  case 'mb':
40
40
  default:
41
- route.size = number * 1024;
41
+ route.size = number * 1024 * 1024;
42
42
  break;
43
43
  }
44
44
  }
@@ -100,6 +100,7 @@ function Route(url, action, size) {
100
100
  }
101
101
 
102
102
  if (t.method === 'FILE') {
103
+
103
104
  let types = t.url[t.url.length - 1];
104
105
 
105
106
  // fixed filename
@@ -117,6 +118,7 @@ function Route(url, action, size) {
117
118
  for (let type of types)
118
119
  t.ext[type] = 1;
119
120
  }
121
+
120
122
  } else {
121
123
  t.params = [];
122
124
  index = 0;
@@ -149,13 +151,19 @@ function Route(url, action, size) {
149
151
 
150
152
  t.priority = 100;
151
153
  t.type = t.method === 'WEBSOCKET' || t.method === 'SOCKET' ? 'websocket' : t.method === 'FILE' ? 'file' : 'route';
154
+ t.partial = t.method === 'PATCH';
152
155
 
153
156
  var endpoint = '';
157
+ var isapi = false;
154
158
 
155
159
  if (t.method === 'API') {
156
160
  t.method = 'POST';
157
- url = url.replace(/(\*|\+|-)?[a-z0-9-_/{}]+/i, function(text) {
158
- endpoint = text.trim().substring(1);
161
+ isapi = true;
162
+ t.id = t.id.replace(/^(\+|-)/, '');
163
+ url = url.replace(/(\*|\+|-|%)?[a-z0-9-_/{}]+/i, function(text) {
164
+ let tmp = text.trim();
165
+ endpoint = tmp.substring(1);
166
+ t.partial = tmp[0] === '%';
159
167
  return text;
160
168
  });
161
169
  }
@@ -181,8 +189,14 @@ function Route(url, action, size) {
181
189
  t.actions.push(text.trim());
182
190
  return '';
183
191
  }).trim();
184
- } else
185
- t.actions = url.substring(0, index + 3).replace(/\s{2,}/g, ' ').split(/\s|,/);
192
+ } else {
193
+ if (isapi)
194
+ t.actions = [url.replace(/\+|-|%|#/g, '').trim()];
195
+ else
196
+ t.actions = url.substring(0, index + 3).replace(/\s{2,}/g, ' ').split(/\s|,/);
197
+ }
198
+
199
+ var parent = null;
186
200
 
187
201
  if (endpoint) {
188
202
 
@@ -194,12 +208,15 @@ function Route(url, action, size) {
194
208
  params.push({ index: i, name: param });
195
209
  }
196
210
 
197
- var route = F.routes.routes.findItem('id', t.id);
211
+ parent = F.routes.routes.findItem('id', t.id);
212
+
198
213
  var apiroute = { auth: t.auth, params: params, actions: t.actions.join(',') };
199
214
 
200
- if (route) {
201
- route.api[arr[0]] = apiroute;
215
+ t.apiendpoint = arr[0];
216
+ if (parent) {
217
+ parent.api[arr[0]] = apiroute;
202
218
  t.skip = true;
219
+ t.parent = parent;
203
220
  } else {
204
221
  if (!t.api)
205
222
  t.api = {};
@@ -207,6 +224,10 @@ function Route(url, action, size) {
207
224
  }
208
225
 
209
226
  delete t.actions;
227
+
228
+ // Reset auth
229
+ t.auth = 0;
230
+
210
231
  } else
211
232
  t.actions = t.actions.join(',');
212
233
 
@@ -214,17 +235,29 @@ function Route(url, action, size) {
214
235
  if (!t.size) {
215
236
  switch (t.type) {
216
237
  case 'websocket':
217
- t.size = F.config.$wsmaxsize;
238
+ t.size = F.config.$wsmaxsize * 1024;
218
239
  t.connections = [];
219
240
  break;
220
241
  case 'route':
221
- t.size = F.config.$httpmaxsize;
242
+ t.size = F.config.$httpmaxsize * 1024;
222
243
  break;
223
244
  }
224
245
  }
225
246
 
247
+ if (parent && parent.size < t.size)
248
+ parent.size = t.size;
249
+
250
+ if (typeof(t.action) === 'string') {
251
+ t.view = t.action;
252
+ t.action = null;
253
+ }
254
+
255
+ if (!t.view && !t.action && t.method !== 'FILE' && t.method !== 'SOCKET')
256
+ t.view = t.url[0] && t.url[0] !== '/' ? t.url[0] : 'index';
257
+
226
258
  if (t.wildcard)
227
259
  t.priority -= 50;
260
+
228
261
  }
229
262
 
230
263
  Route.prototype.compare = function(ctrl) {
@@ -256,10 +289,27 @@ Route.prototype.remove = function() {
256
289
  F.routes.files.splice(index);
257
290
  break;
258
291
  default:
259
- index = F.routes.routes.indexOf(self);
260
- if (index !== -1)
261
- F.routes.routes.splice(index);
262
- delete F.routes.api[self.url.join('/')];
292
+ if (self.apiendpoint) {
293
+ if (self.parent) {
294
+ delete self.parent.api[self.apiendpoint];
295
+ if (Object.keys(self.parent.api).length == 0) {
296
+ index = F.routes.routes.indexOf(self.parent);
297
+ if (index !== -1)
298
+ F.routes.routes.splice(index);
299
+ }
300
+ } else {
301
+ delete self.api[self.apiendpoint];
302
+ if (Object.keys(self.api).length == 0) {
303
+ index = F.routes.routes.indexOf(self);
304
+ if (index !== -1)
305
+ F.routes.routes.splice(index);
306
+ }
307
+ }
308
+ } else {
309
+ index = F.routes.routes.indexOf(self);
310
+ if (index !== -1)
311
+ F.routes.routes.splice(index, 1);
312
+ }
263
313
  break;
264
314
  }
265
315
 
@@ -363,6 +413,10 @@ exports.sort = function() {
363
413
 
364
414
  tmp = cache;
365
415
  let key = route.url.join('/');
416
+
417
+ if (route.wildcard)
418
+ key += '/*';
419
+
366
420
  if (cache[key])
367
421
  cache[key].push(route);
368
422
  else
@@ -400,7 +454,7 @@ function compareflags(ctrl, routes, auth) {
400
454
  if (route.flags.xhr && !ctrl.xhr)
401
455
  continue;
402
456
 
403
- if (route.flags.upload && ctrl.datatype !== 'upload')
457
+ if (route.flags.upload && ctrl.datatype !== 'multipart')
404
458
  continue;
405
459
 
406
460
  if (route.flags.mobile && !ctrl.mobile)
@@ -413,7 +467,7 @@ function compareflags(ctrl, routes, auth) {
413
467
  }
414
468
  }
415
469
 
416
- exports.lookup = function(ctrl, auth, skip) {
470
+ exports.lookup = function(ctrl, auth = 0, skip = false) {
417
471
 
418
472
  // auth 0: does not matter
419
473
  // auth 1: logged
@@ -444,8 +498,7 @@ exports.lookup = function(ctrl, auth, skip) {
444
498
 
445
499
  // Dynamic routes
446
500
  if (tmp.D && !(length === 1 && arr[0] === '/')) {
447
- for (var i = 0; i < tmp.D.length; i++) {
448
- var r = tmp.D[i];
501
+ for (let r of tmp.D) {
449
502
  if (r.url.length === length || r.wildcard) {
450
503
  if (r.compare(ctrl)) {
451
504
  if (!routes)
@@ -537,11 +590,30 @@ exports.lookupcors = function(ctrl) {
537
590
  return false;
538
591
  }
539
592
 
540
- var origin = ctrl.headers.origin;
593
+ let origin = ctrl.headers.origin;
541
594
 
542
- if (!F.config.$cors || (F.config.$cors != '*' && F.config.$cors.indexOf(origin) == -1)) {
543
- ctrl.system(400, 'Invalid origin (CORS)');
544
- return false;
595
+ if (F.config.$cors !== '*' && !origin.endsWith(ctrl.headers.host)) {
596
+
597
+ let resume = false;
598
+ let cors = F.temporary.cors;
599
+
600
+ if (cors) {
601
+ if (cors.strict.length && cors.strict.includes(origin)) {
602
+ resume = true;
603
+ } else if (cors.wildcard.length) {
604
+ for (let m of cors.wildcard) {
605
+ if (origin.includes(m)) {
606
+ resume = true;
607
+ break;
608
+ }
609
+ }
610
+ }
611
+ }
612
+
613
+ if (!resume) {
614
+ ctrl.fallback(400, 'Invalid origin (CORS)');
615
+ return false;
616
+ }
545
617
  }
546
618
 
547
619
  ctrl.response.headers['access-control-allow-origin'] = origin;
@@ -560,7 +632,7 @@ exports.lookupcors = function(ctrl) {
560
632
 
561
633
  };
562
634
 
563
- exports.lookupfile = function(ctrl, auth) {
635
+ exports.lookupfile = function(ctrl, auth = 0) {
564
636
  if (F.routes.files.length) {
565
637
 
566
638
  // fixed
@@ -571,14 +643,24 @@ exports.lookupfile = function(ctrl, auth) {
571
643
  let key = '';
572
644
  for (let i = 0; i < ctrl.split2.length - 1; i++)
573
645
  key += (i ? '/' : '') + ctrl.split2[i];
574
-
575
646
  let routes = F.routes.filescache[key];
576
647
  if (routes)
577
648
  return compareflags(ctrl, routes, auth);
649
+
650
+ // Wildcard
651
+ let length = ctrl.split2.length;
652
+ routes = [];
653
+
654
+ for (let i = 0; i < length; i++) {
655
+ let url = ctrl.split2.slice(0, length - i).join('/') + '/*';
656
+ item = F.routes.filescache[url];
657
+ if (item)
658
+ return item[0];
659
+ }
578
660
  }
579
661
  };
580
662
 
581
- exports.lookupwebsocket = function(ctrl, auth, skip = false) {
663
+ exports.lookupwebsocket = function(ctrl, auth = 0, skip = false) {
582
664
 
583
665
  // auth 0: does not matter
584
666
  // auth 1: logged
@@ -715,7 +797,7 @@ Proxy.prototype.remove = function() {
715
797
  exports.proxy = function(url, target) {
716
798
 
717
799
  if (!target) {
718
- let index = F.routes.proxies.findIndex('url', url.toLowerCase());
800
+ let index = F.routes.proxies.TfindIndex('url', url.toLowerCase());
719
801
  if (index !== -1)
720
802
  F.routes.proxies.splice(index, 1);
721
803
  return;
@@ -774,11 +856,11 @@ function proxycreate(proxy, ctrl) {
774
856
  ctrl.$proxy = proxy;
775
857
 
776
858
  if (uri.socketPath) {
777
- uri.path = proxy.copypath == 'none' || proxy.copypath === 'replace' ? ctrl.url.substring(proxy.url.length - 1) : ctrl.uri.pathname;
859
+ uri.path = (proxy.copypath == 'none' || proxy.copypath === 'replace' ? ctrl.url.substring(proxy.url.length - 1) : ctrl.uri.pathname) + (ctrl.uri.search ? ((proxy.uri.search && proxy.uri.search.length > 1 ? '&' : '?') + ctrl.uri.search) : '');
778
860
  } else {
779
861
 
780
862
  if (proxy.copypath === 'none') {
781
- uri.path = proxy.uri.path;
863
+ uri.path = proxy.uri.path + (ctrl.uri.search ? ((proxy.uri.search && proxy.uri.search.length > 1 ? '&' : '?') + ctrl.uri.search) : '');
782
864
  } else if (proxy.copypath === 'replace')
783
865
  uri.path = ctrl.url.substring(proxy.url.length - 1);
784
866
  else if (proxy.copypath === 'extend') {
package/sourcemap.js CHANGED
@@ -66,7 +66,7 @@ exports.create = function() {
66
66
 
67
67
  if (route.flags.upload) {
68
68
  m.upload = true;
69
- m.limit = route.size / 1024;
69
+ m.limit = route.size;
70
70
  }
71
71
 
72
72
  if (route.api) {
package/test.js ADDED
@@ -0,0 +1,48 @@
1
+ // Total.js Tests
2
+ // The MIT License
3
+ // Copyright 2023 (c) Peter Širka <petersirka@gmail.com>
4
+
5
+ var Test = { items: [], count: 0 };
6
+
7
+ Test.start = function(message) {
8
+ var divider = '------------------------------------------------';
9
+
10
+ if (Test.count)
11
+ console.log('');
12
+
13
+ console.log(divider);
14
+ console.log('| ' + message.padRight(divider.length - 4) + ' |');
15
+ console.log(divider);
16
+ };
17
+
18
+ Test.print = function(message, err) {
19
+ console.log('[' + (err ? 'FAIL' : 'OK') + ']', message);
20
+ Test.count++;
21
+ if (err) {
22
+ setTimeout(() => process.exit(1), 1);
23
+ if (err instanceof Error)
24
+ throw err;
25
+ else
26
+ throw new Error(err.toString());
27
+ }
28
+ };
29
+
30
+ Test.push = function(name, fn) {
31
+ Test.items.push({ name: name, fn: fn });
32
+ };
33
+
34
+ Test.run = function(callback) {
35
+ console.time('Time');
36
+ Test.items.wait(function(item, next) {
37
+ Test.start(item.name);
38
+ item.fn(next);
39
+ }, function() {
40
+ console.log('');
41
+ console.log('Tests:', Test.count);
42
+ console.timeEnd('Time');
43
+ console.log('');
44
+ callback && callback();
45
+ });
46
+ };
47
+
48
+ global.Test = Test;
package/tms.js CHANGED
@@ -8,7 +8,6 @@ var Cache = {
8
8
  subscribers: {},
9
9
  swatchers: {}, // watchers for subscribers
10
10
  scache: {}, // cache for subscribers
11
- publishers: {},
12
11
  pcache: {}, // cache for publishers
13
12
  calls: {},
14
13
  socket: null,
@@ -46,7 +45,7 @@ function tmscontroller($) {
46
45
  }
47
46
 
48
47
  delete temporary.tmsblocked[client.ip];
49
- Cache.publishers = {};
48
+ client.$subscribers = {};
50
49
  client.tmsready = true;
51
50
  refresh(client);
52
51
  });
@@ -71,9 +70,9 @@ function tmscontroller($) {
71
70
  F.TTMS.subscribe(msg.id, response, client);
72
71
  }
73
72
  } 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;
73
+ client.$subscribers = {};
74
+ for (let sub of msg.subscribers)
75
+ client.$subscribers[sub] = true;
77
76
  } else if (msg.type === 'call' && msg.id) {
78
77
  var tmp = Cache.calls[msg.id];
79
78
  if (tmp) {
@@ -240,19 +239,15 @@ function refresh(client) {
240
239
  var subscribed = [];
241
240
  var published = [];
242
241
 
243
- for (let key in Cache.pcache) {
244
- let schema = F.jsonschemas[Cache.pcache[key]];
245
- published.push({ id: key, schema: schema });
246
- }
242
+ for (let key in Cache.pcache)
243
+ published.push({ id: key, schema: Cache.pcache[key] });
247
244
 
248
- for (let key in Cache.scache) {
249
- let schema = F.jsonschemas[Cache.scache[key]];
250
- subscribed.push({ id: key, schema: schema });
251
- }
245
+ for (let key in Cache.scache)
246
+ subscribed.push({ id: key, schema: Cache.scache[key] });
252
247
 
253
248
  var calls = [];
254
249
  for (let key in Cache.calls)
255
- calls.push({ id: key, schema: F.jsonschemas[Cache.calls[key].schema] });
250
+ calls.push({ id: key, schema: Cache.calls[key].schema });
256
251
 
257
252
  var msg = { type: 'meta', name: F.config.name, subscribe: subscribed, publish: published, subscribers: Object.keys(Cache.subscribers), call: calls };
258
253
  if (client)
@@ -315,9 +310,9 @@ exports.newsubscribe = function(name, schema, callback) {
315
310
  };
316
311
 
317
312
  exports.publish = function(name, value) {
318
- if (Cache.socket && Cache.pcache[name] && Cache.publishers[name]) {
313
+ if (Cache.socket && Cache.pcache[name]) {
319
314
  F.stats.performance.publish++;
320
- Cache.socket.send({ type: 'publish', id: name, data: value }, client => client.tmsready);
315
+ Cache.socket.send({ type: 'publish', id: name, data: value }, client => client.tmsready && client.$subscribers[name]);
321
316
  }
322
317
  };
323
318
 
@@ -361,7 +356,7 @@ exports.unsubscribe = function(name, callback) {
361
356
  return false;
362
357
  };
363
358
 
364
- F.on('@tms', function() {
359
+ F.on('$tms', function() {
365
360
 
366
361
  var endpoint = F.config.$tmsurl;
367
362
  var is = Cache.url !== endpoint;
@@ -372,7 +367,7 @@ F.on('@tms', function() {
372
367
  }
373
368
 
374
369
  if ((is && endpoint && F.config.$tms) || (endpoint && F.config.$tms && !Cache.route))
375
- Cache.route = F.route('SOCKET ' + endpoint, tmscontroller, F.config.$tmsmaxsize);
370
+ Cache.route = F.route('SOCKET ' + endpoint, tmscontroller, F.config.$tmsmaxsize * 1024);
376
371
 
377
372
  Cache.url = endpoint;
378
373
 
package/tmsclient.js CHANGED
@@ -1,3 +1,7 @@
1
+ // Total.js TMS Client
2
+ // The MIT License
3
+ // Copyright 2022-2023 (c) Peter Širka <petersirka@gmail.com>
4
+
1
5
  exports.create = function(url, token, callback) {
2
6
 
3
7
  if (typeof(token) === 'function') {
package/uibuilder.js CHANGED
@@ -7,6 +7,12 @@ const REG_STRING = /'|"/g;
7
7
 
8
8
  exports.compile = async function(opt, callback) {
9
9
 
10
+ // opt.schema {String/Object}
11
+ // |--- opt.schema.origin {String}
12
+ // opt.local {Boolean}
13
+ // opt.download {Boolean}
14
+ // opt.origin {String}
15
+
10
16
  if (!callback)
11
17
  return new Promise((resolve, reject) => exports.compile(opt, (err, response) => err ? reject(err) : resolve(response)));
12
18
 
@@ -24,7 +30,7 @@ exports.compile = async function(opt, callback) {
24
30
  if (opt.local) {
25
31
  response.components = used;
26
32
  } else {
27
- let components = await getComponents(schema, used, opt.download);
33
+ let components = await getComponents(opt, used);
28
34
  response.components = components;
29
35
  }
30
36
 
@@ -55,7 +61,7 @@ exports.download = async function(opt, callback) {
55
61
  return new Promise((resolve, reject) => exports.download(opt, (err, response) => err ? reject(err) : resolve(response)));
56
62
 
57
63
  try {
58
- let response = await getComponents2(opt.components, opt.origin);
64
+ let response = await getComponents2(opt);
59
65
  callback(null, response);
60
66
  } catch (e) {
61
67
  callback(e);
@@ -81,22 +87,44 @@ function getInstances(schema) {
81
87
  return response;
82
88
  }
83
89
 
84
- async function Download(url) {
90
+ async function Download(url, local = false) {
85
91
  return new Promise(function(resolve) {
86
- let opt = {};
87
- opt.url = url;
88
- opt.method = 'GET';
89
- opt.keepalive = true;
90
- opt.insecure = true;
91
- opt.callback = function(err, response) {
92
- resolve(response.status === 200 ? (response.body.isJSON() ? response.body.parseJSON(true) : response.body) : '');
93
- };
94
- REQUEST(opt);
92
+
93
+ if (local && url[0] === '~') {
94
+ // File on HDD (potential dangerous)
95
+ F.Fs.readFile(url.substring(1), 'utf8', function(err, response) {
96
+ resolve(err ? '' : (response.isJSON() ? response.parseJSON(true) : response));
97
+ });
98
+ } else {
99
+ let opt = {};
100
+ opt.url = url;
101
+ opt.method = 'GET';
102
+ opt.keepalive = true;
103
+ opt.insecure = true;
104
+ opt.callback = function(err, response) {
105
+ resolve(response.status === 200 ? (response.body.isJSON() ? response.body.parseJSON(true) : response.body) : '');
106
+ };
107
+ REQUEST(opt);
108
+ }
95
109
  });
96
110
  }
97
111
 
98
- async function getComponents(schema, used, download) {
112
+ function parseorigin(url) {
99
113
 
114
+ var origin = '';
115
+
116
+ if (url.charAt(0) !== '/') {
117
+ var index = url.indexOf('/', 9);
118
+ origin = index === -1 ? url : url.substring(0, index);
119
+ }
120
+
121
+ return origin;
122
+ }
123
+
124
+ async function getComponents(opt, used) {
125
+
126
+ var schema = opt.schema;
127
+ var download = opt.download;
100
128
  var components = {};
101
129
  var arr = [];
102
130
 
@@ -105,12 +133,16 @@ async function getComponents(schema, used, download) {
105
133
 
106
134
  for (let com of arr) {
107
135
 
108
- if (com.value.indexOf('.json') === -1 & !used[com.id])
136
+ if (com.value.indexOf('.json') === -1 && !used[com.id])
109
137
  continue;
110
138
 
111
139
  let url = com.value;
112
- if (url[0] === '/')
113
- url = schema.origin + url;
140
+ let origin = opt.origin || schema.origin;
141
+
142
+ if (url[0] === '/') {
143
+ url = origin + url;
144
+ } else
145
+ origin = parseorigin(url);
114
146
 
115
147
  let body = await Download(url.format(com.id));
116
148
 
@@ -132,12 +164,13 @@ async function getComponents(schema, used, download) {
132
164
 
133
165
  let render = body.substring(body.indexOf('=', index) + 1, index + end.index).trim().replace(REG_STRING, '').format(com.id);
134
166
 
167
+ if (render[0] === '/')
168
+ render = (origin || schema.origin || '') + render;
169
+
135
170
  if (download) {
136
171
  if (render.substring(0, 7) === 'base64 ') {
137
172
  components[com.id] = render;
138
173
  } else {
139
- if (render[0] === '/')
140
- render = schema.origin + render;
141
174
  let html = await Download(render);
142
175
  if (html)
143
176
  components[com.id] = 'base64 ' + Buffer.from(encodeURIComponent(html), 'utf8').toString('base64');
@@ -153,8 +186,10 @@ async function getComponents(schema, used, download) {
153
186
  return components;
154
187
  }
155
188
 
156
- async function getComponents2(list, origin) {
189
+ async function getComponents2(opt) {
157
190
 
191
+ var list = opt.components;
192
+ var origin = opt.origin;
158
193
  var components = {};
159
194
  var arr = [];
160
195