terminusdb 12.0.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.
Files changed (86) hide show
  1. package/Contributing.md +36 -0
  2. package/LICENSE +201 -0
  3. package/README.md +175 -0
  4. package/RELEASE_NOTES.md +462 -0
  5. package/dist/index.html +22 -0
  6. package/dist/terminusdb-client.min.js +3 -0
  7. package/dist/terminusdb-client.min.js.LICENSE.txt +188 -0
  8. package/dist/terminusdb-client.min.js.map +1 -0
  9. package/dist/typescript/index.d.ts +14 -0
  10. package/dist/typescript/lib/accessControl.d.ts +554 -0
  11. package/dist/typescript/lib/axiosInstance.d.ts +2 -0
  12. package/dist/typescript/lib/connectionConfig.d.ts +381 -0
  13. package/dist/typescript/lib/const.d.ts +54 -0
  14. package/dist/typescript/lib/dispatchRequest.d.ts +17 -0
  15. package/dist/typescript/lib/errorMessage.d.ts +25 -0
  16. package/dist/typescript/lib/query/woqlBuilder.d.ts +75 -0
  17. package/dist/typescript/lib/query/woqlCore.d.ts +341 -0
  18. package/dist/typescript/lib/query/woqlDoc.d.ts +63 -0
  19. package/dist/typescript/lib/query/woqlLibrary.d.ts +718 -0
  20. package/dist/typescript/lib/query/woqlPrinter.d.ts +71 -0
  21. package/dist/typescript/lib/query/woqlQuery.d.ts +833 -0
  22. package/dist/typescript/lib/typedef.d.ts +624 -0
  23. package/dist/typescript/lib/utils.d.ts +199 -0
  24. package/dist/typescript/lib/valueHash.d.ts +146 -0
  25. package/dist/typescript/lib/viewer/chartConfig.d.ts +62 -0
  26. package/dist/typescript/lib/viewer/chooserConfig.d.ts +38 -0
  27. package/dist/typescript/lib/viewer/documentFrame.d.ts +44 -0
  28. package/dist/typescript/lib/viewer/frameConfig.d.ts +74 -0
  29. package/dist/typescript/lib/viewer/frameRule.d.ts +145 -0
  30. package/dist/typescript/lib/viewer/graphConfig.d.ts +73 -0
  31. package/dist/typescript/lib/viewer/objectFrame.d.ts +212 -0
  32. package/dist/typescript/lib/viewer/streamConfig.d.ts +23 -0
  33. package/dist/typescript/lib/viewer/tableConfig.d.ts +66 -0
  34. package/dist/typescript/lib/viewer/terminusRule.d.ts +75 -0
  35. package/dist/typescript/lib/viewer/viewConfig.d.ts +47 -0
  36. package/dist/typescript/lib/viewer/woqlChart.d.ts +1 -0
  37. package/dist/typescript/lib/viewer/woqlChooser.d.ts +56 -0
  38. package/dist/typescript/lib/viewer/woqlGraph.d.ts +26 -0
  39. package/dist/typescript/lib/viewer/woqlPaging.d.ts +1 -0
  40. package/dist/typescript/lib/viewer/woqlResult.d.ts +128 -0
  41. package/dist/typescript/lib/viewer/woqlRule.d.ts +96 -0
  42. package/dist/typescript/lib/viewer/woqlStream.d.ts +31 -0
  43. package/dist/typescript/lib/viewer/woqlTable.d.ts +102 -0
  44. package/dist/typescript/lib/viewer/woqlView.d.ts +49 -0
  45. package/dist/typescript/lib/woql.d.ts +1267 -0
  46. package/dist/typescript/lib/woqlClient.d.ts +1216 -0
  47. package/index.js +28 -0
  48. package/lib/.eslintrc +1 -0
  49. package/lib/accessControl.js +988 -0
  50. package/lib/axiosInstance.js +5 -0
  51. package/lib/connectionConfig.js +765 -0
  52. package/lib/const.js +59 -0
  53. package/lib/dispatchRequest.js +236 -0
  54. package/lib/errorMessage.js +110 -0
  55. package/lib/query/woqlBuilder.js +234 -0
  56. package/lib/query/woqlCore.js +934 -0
  57. package/lib/query/woqlDoc.js +177 -0
  58. package/lib/query/woqlLibrary.js +1015 -0
  59. package/lib/query/woqlPrinter.js +476 -0
  60. package/lib/query/woqlQuery.js +1865 -0
  61. package/lib/typedef.js +248 -0
  62. package/lib/utils.js +817 -0
  63. package/lib/valueHash.js_old +581 -0
  64. package/lib/viewer/chartConfig.js +411 -0
  65. package/lib/viewer/chooserConfig.js +234 -0
  66. package/lib/viewer/documentFrame.js +206 -0
  67. package/lib/viewer/frameConfig.js +469 -0
  68. package/lib/viewer/frameRule.js +519 -0
  69. package/lib/viewer/graphConfig.js +345 -0
  70. package/lib/viewer/objectFrame.js +1550 -0
  71. package/lib/viewer/streamConfig.js +82 -0
  72. package/lib/viewer/tableConfig.js +310 -0
  73. package/lib/viewer/terminusRule.js +196 -0
  74. package/lib/viewer/viewConfig.js +219 -0
  75. package/lib/viewer/woqlChart.js +17 -0
  76. package/lib/viewer/woqlChooser.js +171 -0
  77. package/lib/viewer/woqlGraph.js +295 -0
  78. package/lib/viewer/woqlPaging.js +148 -0
  79. package/lib/viewer/woqlResult.js +258 -0
  80. package/lib/viewer/woqlRule.js +312 -0
  81. package/lib/viewer/woqlStream.js +27 -0
  82. package/lib/viewer/woqlTable.js +332 -0
  83. package/lib/viewer/woqlView.js +107 -0
  84. package/lib/woql.js +1693 -0
  85. package/lib/woqlClient.js +2091 -0
  86. package/package.json +110 -0
package/lib/utils.js ADDED
@@ -0,0 +1,817 @@
1
+ /* eslint-disable no-undef */
2
+ /* eslint-disable guard-for-in */
3
+ /* eslint-disable no-plusplus */
4
+ /* eslint-disable no-shadow */
5
+ /* eslint-disable camelcase */
6
+ /* eslint-disable no-restricted-syntax */
7
+ /* eslint-disable no-param-reassign */
8
+ /**
9
+ * @file Terminus Client Utility Functions
10
+ * @license Apache Version 2
11
+ * Object for bunding up common Terminus Utility Functions
12
+ */
13
+ const Utils = {};
14
+
15
+ Utils.checkValidName = function (str) {
16
+ if (typeof str !== 'string' || str.trim() === '') return false;
17
+ return /^[a-zA-Z0-9_]*$/.test(str);
18
+ };
19
+
20
+ Utils.ACTIONS = {
21
+ CREATE_DATABASE: 'create_database',
22
+ DELETE_DATABASE: 'delete_database',
23
+ SCHEMA_READ_ACCESS: 'schema_read_access',
24
+ SCHEMA_WRITE_ACCESS: 'schema_write_access',
25
+ INSTANCE_READ_ACCESS: 'instance_read_access',
26
+ INSTANCE_WRITE_ACCESS: 'instance_write_access',
27
+ COMMIT_READ_ACCESS: 'commit_read_access',
28
+ COMMIT_WRITE_ACCESS: 'commit_write_access',
29
+ META_READ_ACCESS: 'meta_read_access',
30
+ META_WRITE_ACCESS: 'meta_write_access',
31
+ CLASS_FRAME: 'class_frame',
32
+ BRANCH: 'branch',
33
+ CLONE: 'clone',
34
+ FETCH: 'fetch',
35
+ PUSH: 'push',
36
+ REBASE: 'rebase',
37
+ /* MANAGE_CAPABILITIES: 'manage_capabilities', */
38
+ };
39
+
40
+ // encodeURI() will not encode: ~!@#$&*()=:/,;?+
41
+ // =%25team =%team
42
+ // terminusDB do not encode =@ too
43
+ Utils.encodeURISegment = function (str) {
44
+ if (typeof str !== 'string') return str;
45
+ str = encodeURI(str);
46
+ str = str.replace(/\?/g, '%3F');
47
+ // we not need = because the server does not encode it
48
+ // str = str.replace(/=/g, '%3D');
49
+ // str = str.replace(/@/g, '%40');
50
+ str = str.replace(/&/g, '%26');
51
+ str = str.replace(/\+/g, '%2B');
52
+ str = str.replace(/#/g, '%23');
53
+ return str;
54
+ };
55
+
56
+ Utils.decodeURISegment = function (str) {
57
+ if (typeof str !== 'string') return str;
58
+ str = str.replace(/%3F/g, '?');
59
+ // str = str.replace(/%3D/g, '=');
60
+ // str = str.replace(/%26/g, '&');
61
+ str = str.replace(/%2B/g, '+');
62
+ str = str.replace(/%23/g, '#');
63
+ // str = str.replace(/%40/g, '@');
64
+ str = decodeURI(str);
65
+ return str;
66
+ };
67
+
68
+ Utils.removeDocType = function (str) {
69
+ if (typeof str === 'string' && str.lastIndexOf('/') > -1) {
70
+ return str.substr(str.lastIndexOf('/') + 1);
71
+ }
72
+ return str;
73
+ };
74
+
75
+ // %253D%25team
76
+
77
+ /**
78
+ * default set of prefixes that will be used for URL compression
79
+ * @type {object}
80
+ */
81
+ Utils.standard_urls = {
82
+ rdf: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
83
+ rdfs: 'http://www.w3.org/2000/01/rdf-schema#',
84
+ xsd: 'http://www.w3.org/2001/XMLSchema#',
85
+ xdd: 'http://terminusdb.com/schema/xdd#',
86
+ owl: 'http://www.w3.org/2002/07/owl#',
87
+ system: 'http://terminusdb.com/schema/system#',
88
+ vio: 'http://terminusdb.com/schema/vio#',
89
+ repo: 'http://terminusdb.com/schema/repository#',
90
+ layer: 'http://terminusdb.com/schema/layer#',
91
+ woql: 'http://terminusdb.com/schema/woql#',
92
+ ref: 'http://terminusdb.com/schema/ref#',
93
+ api: 'http://terminusdb.com/schema/api#',
94
+ };
95
+
96
+ /**
97
+ * Encode document payload for GET
98
+ * @param {string | object} payload
99
+ * @returns {string}
100
+ */
101
+ Utils.URIEncodePayload = function (payload) {
102
+ if (typeof payload === 'string') return encodeURIComponent(payload);
103
+ const payloadArr = [];
104
+ for (const key of Object.keys(payload)) {
105
+ if (typeof payload[key] === 'object') {
106
+ for (const keyElement of Object.keys(payload[key])) {
107
+ const valueElement = payload[key][keyElement];
108
+ payloadArr.push(
109
+ `${encodeURIComponent(keyElement)}=${encodeURIComponent(valueElement)}`,
110
+ );
111
+ }
112
+ } else {
113
+ payloadArr.push(`${encodeURIComponent(key)}=${encodeURIComponent(payload[key])}`);
114
+ }
115
+ }
116
+ return payloadArr.join('&');
117
+ };
118
+
119
+ /**
120
+ * Adds an entry to the list of known standard URL prefixes
121
+ * @param {string} prefix
122
+ * @param {string} url
123
+ */
124
+ Utils.addURLPrefix = function (prefix, url) {
125
+ this.standard_urls[prefix] = url;
126
+ };
127
+
128
+ /**
129
+ * is the object empty?
130
+ * returns true if the json object is empty
131
+ * @param {object|array} [obj]
132
+ * @returns {boolean}
133
+ */
134
+ Utils.empty = function (obj) {
135
+ // null and undefined are "empty"
136
+ if (!obj) return true;
137
+ // Assume if it has a length property with a non-zero value
138
+ // that that property is correct.
139
+ if (obj.length > 0) return false;
140
+ if (obj.length === 0) return true;
141
+ // Otherwise, does it have any properties of its own?
142
+ // Note that this doesn't handle
143
+ // toString and valueOf enumeration bugs in IE < 9
144
+ // for (const key in obj) {
145
+ if (typeof obj === 'object') {
146
+ for (const key of Object.keys(obj)) {
147
+ if (Object.prototype.hasOwnProperty.call(obj, key)) return false;
148
+ }
149
+ }
150
+ return true;
151
+ };
152
+
153
+ /**
154
+ * Generates a unique node id
155
+ * @param {string} [base]
156
+ * @returns {string}
157
+ */
158
+ Utils.genBNID = function (base) {
159
+ base = base || '';
160
+ const r = Math.random()
161
+ .toString(36)
162
+ .substring(7);
163
+ const d = new Date();
164
+ const bnid = `${base}${r}${d.getTime()}`;// `doc:${base}${r}${d.getTime()}`
165
+ return bnid;
166
+ };
167
+
168
+ /**
169
+ * Returns the shorthand version (compressed to prefix:id ) of a url or
170
+ * false if there is none known for that URL
171
+ * @param {object | string} link
172
+ * @returns {string | boolean}
173
+ */
174
+
175
+ Utils.getShorthand = function (link) {
176
+ // eslint-disable-next-line prefer-destructuring
177
+ if (typeof link === 'object' && link.length) link = link[0];
178
+ if (link && typeof link === 'string') {
179
+ for (const pref of Object.keys(this.standard_urls)) {
180
+ const full = this.standard_urls[pref];
181
+ if (link.substring(0, full.length) === full) {
182
+ const sh = `${pref}:${link.substring(full.length)}`;
183
+ return sh;
184
+ }
185
+ }
186
+ }
187
+ return false;
188
+ };
189
+
190
+ /**
191
+ * Compares 2 IRIs for equality by checking compressed and expanded versions of both sides
192
+ * @param {string} ida
193
+ * @param {string} idb
194
+ * @returns {boolean}
195
+ */
196
+ Utils.compareIDs = function (ida, idb) {
197
+ if (ida === idb) return true;
198
+ if (this.unshorten(ida) === idb) return true;
199
+ if (this.shorten(ida) === idb) return true;
200
+ if (this.unshorten(ida) === this.unshorten(idb)) return true;
201
+ return false;
202
+ };
203
+
204
+ /**
205
+ * Shortens a URL to its compressed format - returns the full URL if not possible
206
+ * @param {string} [url]
207
+ * @param {string} [prefixes]
208
+ * @returns {string | undefined}
209
+ */
210
+ // we don't have any more visualize prefix
211
+ // terminusdb://layer/data/Layer_44ce76721ebe179fdf2c015b0d38eadfa49de3ba
212
+ // eslint-disable-next-line no-unused-vars
213
+ Utils.shorten = function (url, prefixes) {
214
+ if (!url) return undefined;
215
+ if (url.indexOf('#') !== -1) {
216
+ const urlArr = url.split('#');
217
+ return urlArr.pop();
218
+ }
219
+ if (url.indexOf('terminusdb://') !== -1) {
220
+ const urlArr = url.split('/');
221
+ return urlArr.pop();
222
+ }
223
+ return url;
224
+
225
+ /* if (!url) return undefined
226
+ if (typeof url === 'function') return undefined
227
+ prefixes = prefixes || Utils.standard_urls
228
+ for (const pref in prefixes) {
229
+ if (prefixes[pref] === url.substring(0, prefixes[pref].length)) {
230
+ return `${pref}:${url.substring(prefixes[pref].length)}`
231
+ }
232
+ }
233
+ return url */
234
+ };
235
+
236
+ /**
237
+ * Expands a URL to its full URL format - returns the passed string if not possible to expand
238
+ * @param {string} [url]
239
+ * @returns {string | undefined}
240
+ */
241
+ Utils.unshorten = function (url) {
242
+ if (!url) return undefined;
243
+ if (this.validURL(url)) return url;
244
+ if (!url) return url;
245
+ const bits = url.split(':');
246
+ if (bits[1]) {
247
+ if (this.standard_urls[bits[0]]) {
248
+ return this.standard_urls[bits[0]] + bits[1];
249
+ }
250
+ }
251
+ return url;
252
+ };
253
+
254
+ /**
255
+ * shortens a jsonld document to its prefixed form
256
+ * @param {array|object|string} jsonld
257
+ * @param {string} [prefixes]
258
+ * @returns {string|array|object}
259
+ */
260
+
261
+ Utils.json_shorten = function (jsonld, prefixes) {
262
+ const shorten_json_val = (val, prefixes) => {
263
+ if (Array.isArray(val)) {
264
+ const nvals = [];
265
+ for (let i = 0; i < val.length; i++) {
266
+ nvals.push(shorten_json_val(val[i], prefixes));
267
+ }
268
+ return nvals;
269
+ } if (typeof val === 'object') {
270
+ return this.json_shorten(val, prefixes);
271
+ } if (typeof val === 'string') {
272
+ return this.shorten(val, prefixes);
273
+ }
274
+ return val;
275
+ };
276
+ prefixes = prefixes || jsonld['@context'];
277
+ const nujson = {};
278
+ for (const key in jsonld) {
279
+ const nkey = key[0] === '@' ? key : this.shorten(key, prefixes);
280
+ const nval = shorten_json_val(jsonld[key], prefixes);
281
+ nujson[nkey] = nval;
282
+ }
283
+ return nujson;
284
+ };
285
+
286
+ /**
287
+ * Unshortens a jsonld document to its full form
288
+ * @param {array|object|string} jsonld
289
+ * @param {string} [prefixes]
290
+ * @returns {string|array|object}
291
+ */
292
+
293
+ Utils.json_unshorten = function (jsonld, prefixes) {
294
+ const unshorten_json_val = (val, prefixes) => {
295
+ if (Array.isArray(val)) {
296
+ const nvals = [];
297
+ for (let i = 0; i < val.length; i++) {
298
+ nvals.push(unshorten_json_val(val[i], prefixes));
299
+ }
300
+ return nvals;
301
+ } if (typeof val === 'object') {
302
+ return this.json_unshorten(val, prefixes);
303
+ } if (typeof val === 'string') {
304
+ return this.unshorten(val, prefixes);
305
+ }
306
+ return val;
307
+ };
308
+ prefixes = prefixes || jsonld['@context'];
309
+ const nujson = {};
310
+ for (const key in jsonld) {
311
+ const nkey = key[0] === '@' ? key : this.unshorten(key, prefixes);
312
+ const nval = unshorten_json_val(jsonld[key], prefixes);
313
+ nujson[nkey] = nval;
314
+ }
315
+ return nujson;
316
+ };
317
+
318
+ /**
319
+ * Tests a string to see if it is a valid URL -
320
+ * Valid URLs are those that start with http:// or https://
321
+ */
322
+ Utils.validURL = function (str) {
323
+ if (str && typeof str !== 'string') str = `${str}`;
324
+ if (str && (str.substring(0, 7) === 'http://' || str.substring(0, 8) === 'https://')) return true;
325
+ return false;
326
+ };
327
+
328
+ /**
329
+ * Tests a string to see if it is a valid URL -
330
+ * Valid URLs are those that start with http:// or https://
331
+ * @param {string} str
332
+ * @param {string | object} [context]
333
+ * @param {boolean} [allow_shorthand]
334
+ * @returns {boolean}
335
+ */
336
+ Utils.isIRI = function (str, context, allow_shorthand) {
337
+ if (!str) return false;
338
+ if (allow_shorthand && context && context[str.split(':')[0]]) return true;
339
+ if (context) {
340
+ for (pref in context) {
341
+ if (str.substring(0, context[pref].length) === context[pref]) return true;
342
+ }
343
+ }
344
+ const prot = str.split(':')[0];
345
+ const valids = ['http', 'https', 'terminusdb'];
346
+ if (valids.indexOf(prot) !== -1) return true;
347
+ return false;
348
+ };
349
+
350
+ /**
351
+ * Generates a text label from a URL
352
+ * @param {string} url
353
+ * @returns {string}
354
+ */
355
+ Utils.labelFromURL = function (url) {
356
+ let nurl = this.urlFragment(url);
357
+ nurl = nurl || url;
358
+ if (nurl.lastIndexOf('/') < nurl.length - 1) {
359
+ nurl = nurl.substring(nurl.lastIndexOf('/') + 1);
360
+ }
361
+ nurl = nurl.replace(/_/g, ' ');
362
+ return nurl.charAt(0).toUpperCase() + nurl.slice(1);
363
+ };
364
+
365
+ /**
366
+ * Generates a text label from a URL
367
+ */
368
+ Utils.labelFromVariable = function (v) {
369
+ v = v.replace(/_/g, ' ');
370
+ return v.charAt(0).toUpperCase() + v.slice(1);
371
+ };
372
+
373
+ /**
374
+ * returns the fragment part of a URL (whether compressed or not)
375
+ */
376
+ Utils.urlFragment = function (url) {
377
+ url = typeof url !== 'string' ? window.location.href : url;
378
+ let bits = url.split('#');
379
+ if (bits.length <= 1) {
380
+ if (!this.validURL(url)) {
381
+ bits = url.split(':');
382
+ }
383
+ }
384
+ if (bits.length >= 1) {
385
+ const [, urlStr] = bits;
386
+
387
+ if (urlStr) {
388
+ const [baseUrl] = urlStr.split('?');
389
+ url = baseUrl;
390
+ }
391
+ }
392
+ return url;
393
+ };
394
+
395
+ /**
396
+ * returns the last part of a URL after the last /
397
+ */
398
+ Utils.lastURLBit = function (url) {
399
+ url = typeof url === 'undefined' ? window.location.href : url;
400
+ const [urlFirst] = url.split('#');
401
+ const [urlTmp] = urlFirst.split('?');
402
+ url = urlTmp.substring(url.lastIndexOf('/') + 1);
403
+ return url;
404
+ };
405
+
406
+ /**
407
+ * returns the a standard URL associated with a given prefix and extension
408
+ */
409
+ Utils.getStdURL = function (pref, ext, url) {
410
+ if (this.standard_urls[pref]) {
411
+ if (url) {
412
+ if (url === this.standard_urls[pref] + ext) return url;
413
+ } else {
414
+ return this.standard_urls[pref] + ext;
415
+ }
416
+ }
417
+ return false;
418
+ };
419
+
420
+ /*
421
+ * Utility function adds v: to variables...
422
+ */
423
+ Utils.addNamespacesToVariables = function (vars) {
424
+ const nvars = [];
425
+ for (let i = 0; i < vars.length; i++) {
426
+ if (vars[i]) nvars.push(this.addNamespaceToVariable(vars[i]));
427
+ }
428
+ return nvars;
429
+ };
430
+
431
+ Utils.addNamespaceToVariable = function (v) {
432
+ if (typeof v === 'string' && v.substring(0, 2) !== 'v:') return `v:${v}`;
433
+ return v;
434
+ };
435
+
436
+ /*
437
+ * Utility function removes v: prefix from a variable...
438
+ */
439
+ Utils.removeNamespaceFromVariable = function (mvar) {
440
+ if (mvar.substring(0, 2) === 'v:') return mvar.substring(2);
441
+ return mvar;
442
+ };
443
+
444
+ /*
445
+ * Utility function removes v: prefix from an array of variables
446
+ */
447
+ Utils.removeNamespacesFromVariables = function (vars) {
448
+ const nvars = [];
449
+ for (let i = 0; i < vars.length; i++) {
450
+ nvars.push(this.removeNamespaceFromVariable(vars[i]));
451
+ }
452
+ return nvars;
453
+ };
454
+
455
+ /*
456
+ * Utility function to extract a value from a config rule - if the value is a variable,
457
+ take the value of that variable instead
458
+ */
459
+ Utils.getConfigValue = function (val, row) {
460
+ if (typeof val === 'string') val = this.removeNamespaceFromVariable(val);
461
+ if (typeof val === 'string' && row[val]) {
462
+ const rad = row[val];
463
+ if (rad && rad['@value']) return rad['@value'];
464
+ return rad;
465
+ }
466
+ return val;
467
+ };
468
+
469
+ /**
470
+ * TypeHelper bundles together utility functions dealing with datatypes
471
+ */
472
+ Utils.TypeHelper = {};
473
+
474
+ /**
475
+ * Returns true if the passed type is an xsd:string (compressed or not)
476
+ */
477
+ Utils.TypeHelper.isStringType = function (stype) {
478
+ if (stype === 'http://www.w3.org/2001/XMLSchema#string') return true;
479
+ if (stype === 'xsd:string') return true;
480
+ return false;
481
+ };
482
+
483
+ Utils.TypeHelper.isDatatype = function (stype) {
484
+ const sh = Utils.shorten(stype);
485
+ if ((sh && sh.substring(0, 4) === 'xsd:') || sh.substring(0, 4) === 'xdd:') return true;
486
+ return false;
487
+ };
488
+
489
+ /**
490
+ * Adds 3 order magnitude separators ( default ,) into big numbers for legibility
491
+ */
492
+ Utils.TypeHelper.numberWithCommas = function (value, separator) {
493
+ separator = separator || ',';
494
+ if (value >= 1000 || value <= -1000) {
495
+ const parts = value.toString().split('.');
496
+ if (value <= -1000) parts[0] = parts[0].substring(1);
497
+ parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, separator);
498
+ if (value <= -1000) value = `-${parts.join('.')}`;
499
+ else value = parts.join('.');
500
+ }
501
+ return value;
502
+ };
503
+
504
+ Utils.TypeHelper.formatBytes = function (bytes, decimals = 2) {
505
+ if (bytes === 0) return '0 Bytes';
506
+ const k = 1024;
507
+ const dm = decimals < 0 ? 0 : decimals;
508
+ const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
509
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
510
+ return `${parseFloat((bytes / k ** i).toFixed(dm))} ${sizes[i]}`;
511
+ };
512
+
513
+ /**
514
+ * List of supported datatypes
515
+ */
516
+ Utils.TypeHelper.datatypes = [
517
+ 'xdd:coordinate',
518
+ 'xdd:coordinatePolyline',
519
+ 'xdd:coordinatePolygon',
520
+ 'xdd:dateRange',
521
+ 'xdd:gYearRange',
522
+ 'xdd:integerRange',
523
+ 'xdd:decimalRange',
524
+ 'xdd:cc',
525
+ 'xdd:email',
526
+ 'xdd:html',
527
+ 'xdd:url',
528
+ 'xsd:anySimpleType',
529
+ 'xsd:string',
530
+ 'xsd:boolean',
531
+ 'xsd:decimal',
532
+ 'xsd:double',
533
+ 'xsd:float',
534
+ 'xsd:time',
535
+ 'xsd:date',
536
+ 'xsd:dateTime',
537
+ 'xsd:dateTimeStamp',
538
+ 'xsd:gYear',
539
+ 'xsd:gMonth',
540
+ 'xsd:gDay',
541
+ 'xsd:gYearMonth',
542
+ 'xsd:gMonthDay',
543
+ 'xsd:duration',
544
+ 'xsd:yearMonthDuration',
545
+ 'xsd:dayTimeDuration',
546
+ 'xsd:byte',
547
+ 'xsd:short',
548
+ 'xsd:integer',
549
+ 'xsd:long',
550
+ 'xsd:unsignedByte',
551
+ 'xsd:unsignedInt',
552
+ 'xsd:unsignedLong',
553
+ 'xsd:nonNegativeInteger',
554
+ 'xsd:positiveInteger',
555
+ 'xsd:negativeInteger',
556
+ 'xsd:nonPositiveInteger',
557
+ 'xsd:base64Binary',
558
+ 'xsd:anyURI',
559
+ 'xsd:language',
560
+ 'xsd:normalizedString',
561
+ 'xsd:token',
562
+ 'xsd:NMTOKEN',
563
+ 'xsd:Name',
564
+ 'xsd:NCName',
565
+ 'xsd:NOTATION',
566
+ 'xsd:QName',
567
+ 'xsd:ID',
568
+ 'xsd:IDREF',
569
+ 'xsd:ENTITY',
570
+ 'rdf:XMLLiteral',
571
+ 'rdf:PlainLiteral',
572
+ 'rdfs:Literal',
573
+ 'xdd:json',
574
+ ];
575
+
576
+ Utils.TypeHelper.parseRangeValue = function (val, dividor) {
577
+ dividor = dividor || ',';
578
+ let vals = [];
579
+ if (typeof val === 'object' && val.length) {
580
+ vals = val;
581
+ } else if (val) {
582
+ if (typeof val !== 'string') {
583
+ val = `${val}`;
584
+ }
585
+ if (val.length && val.charAt(0) === '[' && val.charAt(val.length - 1) === ']') {
586
+ vals.push(val.substring(1, val.indexOf(dividor)));
587
+ vals.push(val.substring(val.indexOf(dividor) + 1, val.length - 1));
588
+ } else {
589
+ vals.push(val);
590
+ }
591
+ }
592
+ return vals;
593
+ };
594
+
595
+ /**
596
+ * DateHelper bundles together utility functions dealing with xsd date types
597
+ */
598
+ Utils.DateHelper = {};
599
+
600
+ /**
601
+ * Takes an xsd time string and returns a structure {hour: HH, minute: MM,
602
+ * second ss.ssssss, timezone: tz}
603
+ */
604
+ Utils.DateHelper.parseXsdTime = function (val) {
605
+ if (!val) return {};
606
+ const tz = this.extractXsdTimezone(val);
607
+ if (tz) {
608
+ val = val.substring(0, val.length - tz.length);
609
+ }
610
+ const parsed = {
611
+ hour: val.substring(0, 2),
612
+ minute: val.substring(3, 5),
613
+ second: val.substring(6),
614
+ timezone: tz,
615
+ };
616
+ return parsed;
617
+ };
618
+
619
+ /**
620
+ * Takes an xsd time string and returns a structure {year: [-]YYYY, month: MM, day: dd}
621
+ */
622
+ Utils.DateHelper.parseXsdDate = function (val) {
623
+ const tz = this.extractXsdTimezone(val);
624
+ if (tz) {
625
+ val = val.substring(0, val.length - tz.length);
626
+ }
627
+ let year;
628
+ if (val.substring(0, 1) === '-') {
629
+ year = val.substring(0, 5);
630
+ } else {
631
+ year = val.substring(0, 4);
632
+ }
633
+ let parsed;
634
+ if (year && Math.abs(year) < 10000) {
635
+ let month = val.substring(year.length + 1, year.length + 3);
636
+ if (month) {
637
+ month = parseInt(month, 10);
638
+ } else return false;
639
+ let day = val.substring(year.length + 4);
640
+ if (day) day = parseInt(day, 10);
641
+ else return false;
642
+ parsed = {
643
+ year,
644
+ month,
645
+ day,
646
+ timezone: tz,
647
+ };
648
+ }
649
+ return parsed;
650
+ };
651
+
652
+ /**
653
+ * Parses a date string of type ty
654
+ */
655
+ Utils.DateHelper.parseDate = function (ty, value) {
656
+ let parsed;
657
+ if (ty === 'xsd:date') {
658
+ parsed = this.parseXsdDate(value);
659
+ } else if (ty === 'xsd:time') {
660
+ parsed = this.parseXsdTime(value);
661
+ } else if (ty === 'xsd:dateTime') {
662
+ parsed = this.parseXsdDateTime(value);
663
+ } else if (ty === 'xsd:gYear') {
664
+ parsed = { year: value };
665
+ } else if (ty === 'xsd:gYearRange') {
666
+ parsed = { year: value };
667
+ } else if (ty === 'xsd:gMonth') {
668
+ parsed = { month: value.substring(2) };
669
+ } else if (ty === 'xsd:gDay') {
670
+ parsed = { day: value };
671
+ } else if (ty === 'xsd:gYearMonth') {
672
+ const bits = value.split('-');
673
+ while (bits.length < 2) bits.push('');
674
+ parsed = { year: bits[0], month: bits[1] };
675
+ } else if (ty === 'xsd:gMonthDay') {
676
+ const bits = value.split('-');
677
+ while (bits.length < 2) bits.push('');
678
+ parsed = { month: bits[0], day: bits[1] };
679
+ } else if (ty === 'xsd:dateTimeStamp') {
680
+ parsed = this.parseXsdDateTime(value);
681
+ }
682
+ return parsed;
683
+ };
684
+
685
+ /**
686
+ * adds appropriate padding to date type for xsd rules
687
+ */
688
+ Utils.DateHelper.addXsdPadding = function (parsed) {
689
+ const nparsed = {};
690
+ if (typeof parsed.year !== 'undefined' && parsed.year !== false && parsed.year < 1000) {
691
+ if (Math.abs(parsed.year) < 10) nparsed.year = parsed.year < 0 ? `-000${Math.abs(parsed.year)}` : `000${parsed.year}`;
692
+ else if (Math.abs(parsed.year) < 100) nparsed.year = parsed.year < 0 ? `-00${Math.abs(parsed.year)}` : `00${parsed.year}`;
693
+ else nparsed.year = parsed.year < 0 ? `-0${Math.abs(parsed.year)}` : `0${parsed.year}`;
694
+ } else if (parsed.year) {
695
+ nparsed.year = parsed.year;
696
+ }
697
+ if (typeof parsed.month !== 'undefined' && parsed.month !== false && parsed.month < 10) {
698
+ nparsed.month = `0${parsed.month}`;
699
+ } else if (parsed.month) {
700
+ nparsed.month = parsed.month;
701
+ }
702
+ if (typeof parsed.day !== 'undefined' && parsed.day !== false && parsed.day < 10) {
703
+ nparsed.day = `0${parsed.day}`;
704
+ } else if (parsed.day) {
705
+ nparsed.day = parsed.day;
706
+ }
707
+ if (typeof parsed.hour !== 'undefined' && parsed.hour !== false && parsed.hour < 10) {
708
+ nparsed.hour = `0${parsed.hour}`;
709
+ } else if (parsed.hour) {
710
+ nparsed.hour = parsed.hour;
711
+ }
712
+ if (typeof parsed.minute !== 'undefined' && parsed.minute !== false && parsed.minute < 10) {
713
+ nparsed.minute = `0${parsed.minute}`;
714
+ } else if (parsed.minute) {
715
+ nparsed.minute = parsed.minute;
716
+ }
717
+ if (typeof parsed.second !== 'undefined' && parsed.second !== false && parsed.second < 10) {
718
+ nparsed.second = `0${parsed.second}`;
719
+ } else if (parsed.second) {
720
+ nparsed.second = parsed.second;
721
+ }
722
+ return nparsed;
723
+ };
724
+
725
+ /**
726
+ * generates an xsd string of type ty for the passed parsed structure (year, month, day, hour,
727
+ * minute, second, timezone)
728
+ */
729
+ Utils.DateHelper.xsdFromParsed = function (parsed, ty) {
730
+ const xparsed = this.addXsdPadding(parsed);
731
+ let ret;
732
+ if (ty === 'xsd:gYear') {
733
+ ret = xparsed.year ? xparsed.year : false;
734
+ } else if (ty === 'xsd:time') {
735
+ return xparsed.hour && xparsed.minute && xparsed.second
736
+ ? `${xparsed.hour}:${xparsed.minute}:${xparsed.second}`
737
+ : false;
738
+ } else if (ty === 'xsd:date') {
739
+ return xparsed.year && xparsed.month && xparsed.day
740
+ ? `${xparsed.year}-${xparsed.month}-${xparsed.day}`
741
+ : false;
742
+ } else if (ty === 'xsd:dateTime' || ty === 'xsd:dateTimeStamp') {
743
+ ret = xparsed.year && xparsed.month && xparsed.day
744
+ ? `${xparsed.year}-${xparsed.month}-${xparsed.day}T`
745
+ : false;
746
+ if (ret) {
747
+ ret += `${xparsed.hour ? xparsed.hour : '12'}:${
748
+ xparsed.minute ? xparsed.minute : '00'
749
+ }:${xparsed.second ? xparsed.second : '00'}`;
750
+ }
751
+ } else if (ty === 'xsd:gMonth') {
752
+ ret = xparsed.month ? `--${xparsed.month}` : false;
753
+ } else if (ty === 'xsd:gDay') {
754
+ ret = xparsed.day ? `---${xparsed.day}` : false;
755
+ } else if (ty === 'xsd:gYearMonth') {
756
+ ret = xparsed.year && xparsed.month ? `${xparsed.year}-${xparsed.month}` : false;
757
+ } else if (ty === 'xsd:gMonthDay') {
758
+ ret = xparsed.day && xparsed.month ? `--${xparsed.month}-${xparsed.day}` : false;
759
+ }
760
+ if (xparsed.timezone) {
761
+ ret += xparsed.timezone;
762
+ }
763
+ return ret;
764
+ };
765
+
766
+ /**
767
+ * Converts between a unix timestamp and a parsed structure
768
+ */
769
+ Utils.DateHelper.convertTimestampToXsd = function (val) {
770
+ const a = new Date(val * 1000);
771
+ const parsed = {
772
+ year: a.getFullYear(),
773
+ month: a.getMonth() + 1,
774
+ day: a.getDate(),
775
+ hour: a.getHours(),
776
+ minute: a.getMinutes(),
777
+ second: a.getSeconds(),
778
+ };
779
+ return parsed;
780
+ };
781
+
782
+ /**
783
+ * Parses an xsd date time into a structure
784
+ */
785
+ Utils.DateHelper.parseXsdDateTime = function (val) {
786
+ if (!val) return {};
787
+ if (typeof val === 'number') {
788
+ return this.convertTimestampToXsd(val);
789
+ }
790
+ const tz = this.extractXsdTimezone(val);
791
+ if (tz) {
792
+ val = val.substring(0, val.length - tz.length);
793
+ }
794
+ const datetime = this.parseXsdDate(val);
795
+ const ptime = this.parseXsdTime(val.substring(val.indexOf('T') + 1));
796
+
797
+ for (const i of Object.keys(ptime)) {
798
+ datetime[i] = ptime[i];
799
+ }
800
+ datetime.timezone = tz;
801
+ return datetime;
802
+ };
803
+
804
+ /**
805
+ * Extracts the timezone data from an xsd date string
806
+ */
807
+ Utils.DateHelper.extractXsdTimezone = function (val) {
808
+ if (typeof val === 'string' && val.endsWith('Z')) {
809
+ return 'Z';
810
+ }
811
+ if (typeof val === 'string' && (val.charAt(val.length - 6) === '+' || val.charAt(val.length - 6) === '-')) {
812
+ val.substring(val.length - 6);
813
+ }
814
+ return false;
815
+ };
816
+
817
+ module.exports = Utils;