@cntwg/xml-lib-js 0.0.30 → 0.0.32

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/lib/xmldoc-lib.js CHANGED
@@ -1,9 +1,7 @@
1
- // [v0.1.092-20240922]
1
+ // [v0.2.107-20250208]
2
2
 
3
3
  // === module init block ===
4
4
 
5
- const fs = require('fs');
6
- const fse = fs.promises;
7
5
  const xmlParser = require('@ygracs/xml-js6');
8
6
 
9
7
  const {
@@ -13,6 +11,11 @@ const {
13
11
  valueToIDString,
14
12
  } = require('@ygracs/bsfoc-lib-js');
15
13
 
14
+ const {
15
+ loadFileSync, loadFile,
16
+ saveToFileSync, saveToFile,
17
+ } = require('./file-helper.js');
18
+
16
19
  const xObj = require('@ygracs/xobj-lib-js');
17
20
  const {
18
21
  TXmlContentParseOptions,
@@ -22,31 +25,62 @@ const {
22
25
  // === module extra block (helper functions) ===
23
26
 
24
27
  /**
25
- * @function checkFsError
26
- * @param {object} descr
27
- * @param {Error} err
28
- * @returns {object}
28
+ * @typedef {Object} OPT_xmlelemsett
29
+ * @property {object} [parseOptions] - parser options
30
+ * @property {boolean} [opt.proxyModeEnable=false]
31
+ * @property {boolean} [opt.isNullItemsAllowed=false] - <reserved>
32
+ * @description An XML-element controller settings.
33
+ */
34
+
35
+ /**
36
+ * @function __evalXMLElementSettings
37
+ * @param {any} value - element settings to evaluate
38
+ * @returns {OPT_xmlelemsett}
29
39
  * @inner
30
- * @description Checs an error code of a fs ops and sets descr info if succeed
40
+ * @description Evaluates an XML-element settings
31
41
  */
32
- function checkFsError(descr, err) {
33
- let isSucceed = false;
34
- if (isPlainObject(err) && isPlainObject(descr)) {
35
- switch (err.code) {
36
- case 'ENOENT':
37
- case 'EISDIR':
38
- case 'EPERM': {
39
- descr.errCode = err.errno;
40
- descr.errEvent = err.code;
41
- descr.errMsg = `ERR_FILE_${err.code}`;
42
- isSucceed = true;
43
- break;
44
- }
45
- default: {}
46
- };
47
- if (isSucceed) descr.isERR = true;
42
+ function __evalXMLElementSettings(value) {
43
+ const settings = isPlainObject(value) ? value : {};
44
+ let {
45
+ proxyModeEnable,
46
+ isNullItemsAllowed,
47
+ parseOptions,
48
+ } = settings;
49
+ if (!(parseOptions instanceof TXmlContentParseOptions)) {
50
+ settings.parseOptions = new TXmlContentParseOptions(parseOptions);
48
51
  };
49
- return { isSucceed, descr };
52
+ if (typeof proxyModeEnable !== 'boolean') settings.proxyModeEnable = false;
53
+ if (typeof isNullItemsAllowed !== 'boolean') settings.isNullItemsAllowed = false;
54
+ return settings;
55
+ };
56
+
57
+ /**
58
+ * @typedef {Object} OPT_xmlcontsett
59
+ * @augments OPT_xmlelemsett
60
+ * @property {string} [rootETagName]
61
+ * @property {boolean} [autoBindRoot=true]
62
+ * @description An XML-content container settings.
63
+ */
64
+
65
+ /**
66
+ * @function __evalXMLContainerSettings
67
+ * @param {any} value - container settings to evaluate
68
+ * @returns {OPT_xmlcontsett}
69
+ * @inner
70
+ * @description Evaluates an XML-container settings
71
+ */
72
+ function __evalXMLContainerSettings(value) {
73
+ const settings = __evalXMLElementSettings(value);
74
+ let { rootETagName, autoBindRoot } = settings;
75
+ if (
76
+ typeof rootETagName !== 'string'
77
+ || ((rootETagName = rootETagName.trim()) === '')
78
+ ) {
79
+ rootETagName = XML_DEF_ROOT_ETAG_NAME;
80
+ };
81
+ settings.rootETagName = rootETagName;
82
+ if (typeof autoBindRoot !== 'boolean') settings.autoBindRoot = true;
83
+ return settings;
50
84
  };
51
85
 
52
86
  // === module main block ===
@@ -68,10 +102,10 @@ const XML_TE_NROOT_EMSG = 'root element not found';
68
102
  */
69
103
 
70
104
  /**
105
+ * @since v0.0.28
71
106
  * @function readAsTagName
72
- * @param {any} value
107
+ * @param {any} value - some value
73
108
  * @returns {string}
74
- * @since v0.0.28
75
109
  * @description Tries to convert a given value to a valid tag name
76
110
  * of an XML-element.
77
111
  */
@@ -91,10 +125,10 @@ function readAsTagName(value) {
91
125
  };
92
126
 
93
127
  /**
128
+ * @since v0.0.28
94
129
  * @function readAsAttrName
95
- * @param {any} value
130
+ * @param {any} value - some value
96
131
  * @returns {string}
97
- * @since v0.0.28
98
132
  * @description Tries to convert a given value to a valid name
99
133
  * of an XML-attribute.
100
134
  */
@@ -114,10 +148,10 @@ function readAsAttrName(value) {
114
148
  };
115
149
 
116
150
  /**
151
+ * @since v0.0.28
117
152
  * @function valueToElementID
118
- * @param {any} value
153
+ * @param {any} value - some value
119
154
  * @returns {string}
120
- * @since v0.0.28
121
155
  * @description Tries to convert a given value to a valid identifier
122
156
  * suitable as a value for an "ID-attribute" of an XML-element.
123
157
  */
@@ -141,32 +175,28 @@ function valueToElementID(value) {
141
175
  */
142
176
 
143
177
  /**
144
- * @description This class implements an attributes mapper instance
178
+ * @classdesc This class implements an attributes mapper instance
145
179
  */
146
180
  class TXmlAttributesMapper {
147
181
  /** @property {?object} */
148
- #_host;// = null;
149
- /** @property {?object} */
150
- #_options;// = null;
182
+ #_host;
183
+ /** @property {OPT_xmlelemsett} */
184
+ #_options;
151
185
 
152
186
  /**
153
- * @param {object} obj
154
- * @param {object} [opt]
155
- * @param {object} [opt.parseOptions]
187
+ * @param {object} obj - some object
188
+ * @param {OPT_xmlelemsett} [opt] - options
156
189
  * @throws {TypeError}
190
+ * @description Creates an attributes mapper instance
157
191
  */
158
192
  constructor(obj, opt) {
159
193
  // init an elements content
160
194
  if (!isPlainObject(obj)) throw new TypeError(XML_TE_NOBJ_EMSG);
161
195
  this.#_host = obj;
162
196
  // load options
163
- const _options = isPlainObject(opt) ? opt : {};
164
- let { parseOptions } = _options;
165
- if (!isPlainObject(parseOptions)) {
166
- _options.parseOptions = parseOptions = {};
167
- };
168
- let { settings } = parseOptions;
169
- if (!isPlainObject(settings)) parseOptions.settings = settings = {};
197
+ const _options = __evalXMLElementSettings(opt);
198
+ const { parseOptions } = _options;
199
+ const { settings } = parseOptions;
170
200
  let { attributesKey } = settings;
171
201
  if (
172
202
  typeof attributesKey !== 'string'
@@ -180,7 +210,8 @@ class TXmlAttributesMapper {
180
210
  }
181
211
 
182
212
  /**
183
- * @property {Array}
213
+ * Contains a list of all instance attributes as a `<name>-<value>` pairs
214
+ * @property {any[]}
184
215
  * @readonly
185
216
  */
186
217
  get entries() {
@@ -192,7 +223,7 @@ class TXmlAttributesMapper {
192
223
  }
193
224
 
194
225
  /**
195
- * @param {string} name
226
+ * @param {string} name - attribute name
196
227
  * @returns {boolean}
197
228
  * @description Checks whether an attribute exists.
198
229
  */
@@ -212,7 +243,7 @@ class TXmlAttributesMapper {
212
243
  }
213
244
 
214
245
  /**
215
- * @param {string} name
246
+ * @param {string} name - attribute name
216
247
  * @returns {string}
217
248
  * @description Returns an attribute value.
218
249
  */
@@ -232,8 +263,8 @@ class TXmlAttributesMapper {
232
263
  }
233
264
 
234
265
  /**
235
- * @param {string} name
236
- * @param {any} value
266
+ * @param {string} name - attribute name
267
+ * @param {any} value - some value
237
268
  * @returns {boolean}
238
269
  * @description Sets an attribute value.
239
270
  */
@@ -257,7 +288,7 @@ class TXmlAttributesMapper {
257
288
  }
258
289
 
259
290
  /**
260
- * @param {string} name
291
+ * @param {string} name - attribute name
261
292
  * @returns {boolean}
262
293
  * @description Deletes an attribute.
263
294
  */
@@ -277,10 +308,10 @@ class TXmlAttributesMapper {
277
308
  }
278
309
 
279
310
  /**
280
- * @param {string} name
281
- * @param {string} value
282
- * @returns {boolean}
283
311
  * @since v0.0.30
312
+ * @param {string} name - attribute name
313
+ * @param {string} value - new name
314
+ * @returns {boolean}
284
315
  * @description Renames an attribute.
285
316
  */
286
317
  renameAttribute(name, value) {
@@ -320,34 +351,32 @@ class TXmlAttributesMapper {
320
351
  }
321
352
 
322
353
  /**
323
- * @description This class implements an instance of an element controller
354
+ * @classdesc This class implements an instance of an element controller
324
355
  */
325
356
  class TXmlElementController {
326
357
  /** @property {?object} */
327
- #_host;// = null;
328
- /** @property {?object} */
329
- #_options;// = null;
358
+ #_host;
359
+ /** @property {OPT_xmlelemsett} */
360
+ #_options;
330
361
  /** @property {?object} */
331
- #_parseOptions;// = null;
362
+ #_parseOptions;
332
363
  /** @property {?TXmlAttributesMapper} */
333
- #_attributes;// = null;
364
+ #_attributes;
334
365
  #_name = null;
335
366
 
336
367
  /**
337
- * @param {object} obj
338
- * @param {object} [opt]
339
- * @param {object} [opt.parseOptions]
340
- * @param {boolean} [opt.proxyModeEnable=false]
368
+ * @param {object} obj - some element
369
+ * @param {OPT_xmlelemsett} [opt] - options
341
370
  * @throws {TypeError}
371
+ * @description Creates an instance of an element controller
342
372
  */
343
373
  constructor(obj, opt) {
344
374
  // load options
345
- let _options = isPlainObject(opt) ? opt : {};
346
- let {
375
+ const _options = __evalXMLElementSettings(opt);
376
+ const {
347
377
  proxyModeEnable,
348
378
  parseOptions,
349
379
  } = _options;
350
- if (typeof proxyModeEnable !== 'boolean') proxyModeEnable = false;
351
380
  // init an element content
352
381
  if (isPlainObject(obj)) {
353
382
  // // TODO: split a plain object and class instances
@@ -360,33 +389,16 @@ class TXmlElementController {
360
389
  };
361
390
  this.#_host = {};
362
391
  };
363
- // set parser options
364
- if (!(parseOptions instanceof TXmlContentParseOptions)) {
365
- parseOptions = new TXmlContentParseOptions(parseOptions);
366
- _options.parseOptions = parseOptions;
367
- };
368
- //if (!isPlainObject(parseOptions)) {
369
- // _options.parseOptions = parseOptions = {};
370
- //};
371
- //let { settings } = parseOptions;
372
- //if (!isPlainObject(settings)) parseOptions.settings = settings = {};
373
- //let { textKey } = settings;
374
- //if (
375
- // typeof textKey !== 'string'
376
- // || ((textKey = textKey.trim()) === '')
377
- //) {
378
- // textKey = XML_DEF_PARSE_OPTIONS.textKey;
379
- //};
380
392
  // save options
381
- //settings.textKey = textKey;
382
393
  this.#_parseOptions = parseOptions;
383
- _options.proxyModeEnable = proxyModeEnable;
394
+ //_options.proxyModeEnable = proxyModeEnable;
384
395
  this.#_options = _options;
385
396
  // bind atributes mapper
386
397
  this.#_attributes = new TXmlAttributesMapper(obj, _options);
387
398
  }
388
399
 
389
400
  /**
401
+ * Contains an element attribute mapper instance
390
402
  * @property {TXmlAttributesMapper}
391
403
  * @readonly
392
404
  */
@@ -413,6 +425,7 @@ class TXmlElementController {
413
425
  }
414
426
 
415
427
  /**
428
+ * Contains an element text value
416
429
  * @property {string}
417
430
  */
418
431
  get textValue() {
@@ -424,26 +437,28 @@ class TXmlElementController {
424
437
  }
425
438
 
426
439
  /**
427
- * @param {string} name
440
+ * @param {string} name - attribute name
428
441
  * @returns {boolean}
429
442
  * @description Checks whether an attribute exists.
443
+ * @see TXmlAttributesMapper.hasAttribute
430
444
  */
431
445
  hasAttribute(name) {
432
446
  return this.#_attributes.hasAttribute(name);
433
447
  }
434
448
 
435
449
  /**
436
- * @param {string} name
450
+ * @param {string} name - attribute name
437
451
  * @returns {string}
438
452
  * @description Returns an attribute value.
453
+ * @see TXmlAttributesMapper.getAttribute
439
454
  */
440
455
  getAttribute(name) {
441
456
  return this.#_attributes.getAttribute(name);
442
457
  }
443
458
 
444
459
  /**
445
- * @param {string} name
446
- * @param {any} value
460
+ * @param {string} name - attribute name
461
+ * @param {any} value - some value
447
462
  * @returns {boolean}
448
463
  * @description Sets an attribute value.
449
464
  * @see TXmlAttributesMapper.setAttribute
@@ -453,19 +468,20 @@ class TXmlElementController {
453
468
  }
454
469
 
455
470
  /**
456
- * @param {string} name
471
+ * @param {string} name - attribute name
457
472
  * @returns {boolean}
458
473
  * @description Deletes an attribute.
474
+ * @see TXmlAttributesMapper.delAttribute
459
475
  */
460
476
  delAttribute(name) {
461
477
  return this.#_attributes.delAttribute(name);
462
478
  }
463
479
 
464
480
  /**
465
- * @param {string} name
466
- * @param {string} value
467
- * @returns {boolean}
468
481
  * @since v0.0.30
482
+ * @param {string} name - attribute name
483
+ * @param {string} value - new attribute name
484
+ * @returns {boolean}
469
485
  * @description Renames an attribute.
470
486
  * @see TXmlAttributesMapper.renameAttribute
471
487
  */
@@ -485,7 +501,7 @@ class TXmlElementController {
485
501
  }
486
502
 
487
503
  /**
488
- * @param {(string|string[])} value
504
+ * @param {(string|string[])} value - some text
489
505
  * @returns {boolean}
490
506
  * @description Sets a text value.
491
507
  */
@@ -514,7 +530,7 @@ class TXmlElementController {
514
530
  }
515
531
 
516
532
  /**
517
- * @param {string} name
533
+ * @param {string} name - some child element name
518
534
  * @returns {boolean}
519
535
  * @description Checks whether an element has a child element.
520
536
  */
@@ -533,8 +549,8 @@ class TXmlElementController {
533
549
  }
534
550
 
535
551
  /**
536
- * @param {string} name
537
- * @returns {(null|TXmlElementController|TXmlElementsListController)}
552
+ * @param {string} name - some child element name
553
+ * @returns {?(TXmlElementController|TXmlElementsListController)}
538
554
  * @description Returns a child element.
539
555
  */
540
556
  getChild(name) {
@@ -554,20 +570,15 @@ class TXmlElementController {
554
570
 
555
571
  /**
556
572
  * @param {string} name
557
- * @returns {object}
573
+ * @returns {?any}
558
574
  * @protected
575
+ * @deprecated
559
576
  * @description Returns a child element.
577
+ * @see TXmlElementController.__getChildRaw
560
578
  */
561
579
  _getChildRaw(name) {
562
580
  //console.log('CHECK: TXmlElementController._getChildRaw() => was called...');
563
- //console.log('CHECK: TXmlElementController._getChildRaw() => _host => '+JSON.stringify(this.#_host, null, 2));
564
- let item = xObj.getXObjElement(this.#_host, name);
565
- //console.log('CHECK: TXmlElementController._getChildRaw() => item => '+item);
566
- //console.log('CHECK: TXmlElementController._getChildRaw() => item.name() => ['+name+']');
567
- //console.log('CHECK: TXmlElementController._getChildRaw() => item.typeof() => '+typeof item);
568
- //console.log('CHECK: TXmlElementController._getChildRaw() => item => '+JSON.stringify(item, null, 2));
569
- //console.log('CHECK: TXmlElementController._getChildRaw() => was left...');
570
- return item !== undefined ? item : null;
581
+ return TXmlElementController.__getChildRaw(this, name);
571
582
  }
572
583
 
573
584
  /**
@@ -575,6 +586,7 @@ class TXmlElementController {
575
586
  * @param {object} obj
576
587
  * @returns {boolean}
577
588
  * @protected
589
+ * @deprecated
578
590
  * @description Sets a child element.
579
591
  * @see TXmlElementController.__setChildRaw
580
592
  */
@@ -585,24 +597,19 @@ class TXmlElementController {
585
597
 
586
598
  /**
587
599
  * @param {string} name
588
- * @returns {?object}
600
+ * @returns {?Object}
589
601
  * @protected
602
+ * @deprecated
590
603
  * @description Adds a new child element.
604
+ * @see TXmlElementController.__addChildRaw
591
605
  */
592
606
  _addChildRaw(name) {
593
607
  //console.log('CHECK: TXmlElementController._addChild() => was called...');
594
- //console.log('CHECK: TXmlElementController._addChildRaw() => _host => '+JSON.stringify(this.#_host, null, 2));
595
- let result = xObj.addXObjElement(this.#_host, name);
596
- //console.log('CHECK: TXmlElementController._addChildRaw() => result => '+result);
597
- //console.log('CHECK: TXmlElementController._addChildRaw() => item.name() => ['+name+']');
598
- //console.log('CHECK: TXmlElementController._addChildRaw() => item.typeof() => '+typeof result.item);
599
- //console.log('CHECK: TXmlElementController._addChildRaw() => item => '+JSON.stringify(result.item, null, 2));
600
- //console.log('CHECK: TXmlElementController._addChildRaw() => was left...');
601
- return result.isSucceed ? result.item : null;
608
+ return TXmlElementController.__addChildRaw(this, name);
602
609
  }
603
610
 
604
611
  /**
605
- * @param {string} name
612
+ * @param {string} name - some child element name
606
613
  * @returns {?TXmlElementController}
607
614
  * @description Adds a new child element.
608
615
  */
@@ -622,7 +629,7 @@ class TXmlElementController {
622
629
  }
623
630
 
624
631
  /**
625
- * @param {string} name
632
+ * @param {string} name - some child element name
626
633
  * @returns {boolean}
627
634
  * @description Deletes a child element.
628
635
  */
@@ -663,7 +670,8 @@ class TXmlElementController {
663
670
  }
664
671
 
665
672
  /**
666
- * @param {string} loadFromXMLString
673
+ * @since v0.0.30
674
+ * @param {string} xmlString - some content
667
675
  * @returns {boolean}
668
676
  * @throws {Error}
669
677
  * @experimental
@@ -722,6 +730,57 @@ class TXmlElementController {
722
730
  return (item instanceof TXmlElementController) ? item.#_host : null;
723
731
  }
724
732
 
733
+ /**
734
+ * @since v0.0.31
735
+ * @param {TXmlElementController} node
736
+ * @param {string} name
737
+ * @returns {?any}
738
+ * @protected
739
+ * @static
740
+ * @description Returns a child element.
741
+ */
742
+ static __getChildRaw(node, name) {
743
+ let item = null;
744
+ if (node instanceof TXmlElementController) {
745
+ try {
746
+ const obj = node.#_host;
747
+ item = xObj.getXObjElement(obj, name);
748
+ if (item === undefined) item = null;
749
+ } catch (err) {
750
+ // // TODO: [?] check what kind of error thrown
751
+ item = null;
752
+ };
753
+ };
754
+ return item;
755
+ }
756
+
757
+ /**
758
+ * @since v0.0.31
759
+ * @param {TXmlElementController} node
760
+ * @param {string} name
761
+ * @returns {?Object}
762
+ * @protected
763
+ * @static
764
+ * @description Adds a new child element.
765
+ */
766
+ static __addChildRaw(node, name) {
767
+ const childName = readAsTagName(name);
768
+ let item = null;
769
+ if (
770
+ node instanceof TXmlElementController
771
+ && childName !== ''
772
+ ) {
773
+ try {
774
+ const obj = node.#_host;
775
+ ({ item } = xObj.addXObjElement(obj, childName));
776
+ } catch (err) {
777
+ // // TODO: [?] check what kind of error thrown
778
+ item = null;
779
+ };
780
+ };
781
+ return item;
782
+ }
783
+
725
784
  /**
726
785
  * @param {TXmlElementController} node
727
786
  * @param {string} name
@@ -732,25 +791,17 @@ class TXmlElementController {
732
791
  * @description Sets a child element.
733
792
  */
734
793
  static __setChildRaw(node, name, obj) {
735
- //console.log('CHECK: TXmlElementController.__setChildRaw() => was called...');
736
- let isSUCCEED = false;
737
- if (node instanceof TXmlElementController) {
738
- let item = null;
739
- if (isArray(obj)) {
740
- //console.log('CHECK: TXmlElementController.__setChildRaw() => <obj> is array...');
741
- item = xObj.insertXObjEList(node.#_host, name, { force: true });
742
- // load elements
743
- for (let element of obj) {
744
- if (isPlainObject(element)) item.push(element);
745
- };
746
- } else if (isObject(obj)) {
747
- //console.log('CHECK: TXmlElementController.__setChildRaw() => <obj> is object...');
748
- item = xObj.insertXObjElement(node.#_host, name, { force: true });
749
- // // TODO: set element
750
- };
751
- if (item) isSUCCEED = true;
794
+ const childName = readAsTagName(name);
795
+ let isSucceed = false;
796
+ if (
797
+ node instanceof TXmlElementController
798
+ && childName !== ''
799
+ && isObject(obj)
800
+ ) {
801
+ node.#_host[childName] = obj;
802
+ isSucceed = true;
752
803
  };
753
- return isSUCCEED;
804
+ return isSucceed;
754
805
  }
755
806
 
756
807
  /**
@@ -770,9 +821,10 @@ class TXmlElementController {
770
821
  }
771
822
 
772
823
  /**
773
- * @param {object} obj
774
- * @param {object} [opt]
775
- * @returns {(null|TXmlElementController|TXmlElementsListController)}
824
+ * @since v0.0.30
825
+ * @param {object} obj - some object
826
+ * @param {object} [opt] - options
827
+ * @returns {?(TXmlElementController|TXmlElementsListController)}
776
828
  * @static
777
829
  * @description Creates new controller element.
778
830
  */
@@ -796,39 +848,27 @@ class TXmlElementController {
796
848
  };
797
849
 
798
850
  /**
799
- * @description This class implements an instance of a list controller
851
+ * @classdesc This class implements an instance of a list controller
800
852
  */
801
853
  class TXmlElementsListController {
802
- /** @property {?Array} */
803
- #_host;// = null;
804
- /** @property {?object} */
805
- #_options;// = null;
854
+ /** @property {?object[]} */
855
+ #_host;
856
+ /** @property {OPT_xmlelemsett} */
857
+ #_options;
806
858
  #_count = null;
807
859
 
808
860
  /**
809
- * @param {Array} obj
810
- * @param {object} [opt]
811
- * @param {object} [opt.parseOptions]
812
- * @param {boolean} [opt.proxyModeEnable=false]
813
- * @param {boolean} [opt.isNullItemsAllowed=false] - <reserved>
861
+ * @param {object[]} obj - elements list
862
+ * @param {OPT_xmlelemsett} [opt] - options
814
863
  * @throws {TypeError}
864
+ * @description Creates an instance of a list controller
815
865
  */
816
866
  constructor(obj, opt) {
817
867
  // load options
818
- let _options = isPlainObject(opt) ? opt : {};
819
- let {
868
+ const _options = __evalXMLElementSettings(opt);
869
+ const {
820
870
  proxyModeEnable,
821
- isNullItemsAllowed,
822
- parseOptions,
823
871
  } = _options;
824
- if (typeof proxyModeEnable !== 'boolean') proxyModeEnable = false;
825
- if (typeof isNullItemsAllowed !== 'boolean') isNullItemsAllowed = false;
826
- // set parser options
827
- if (!isPlainObject(parseOptions)) {
828
- _options.parseOptions = parseOptions = {};
829
- };
830
- let { settings } = parseOptions;
831
- if (!isPlainObject(settings)) parseOptions.settings = settings = {};
832
872
  // init an elements list content
833
873
  if (isArray(obj)) {
834
874
  this.#_host = obj;
@@ -843,12 +883,11 @@ class TXmlElementsListController {
843
883
  };
844
884
  };
845
885
  // save options
846
- _options.proxyModeEnable = proxyModeEnable;
847
- _options.isNullItemsAllowed = isNullItemsAllowed;
848
886
  this.#_options = _options;
849
887
  }
850
888
 
851
889
  /**
890
+ * Contains a quantity of an elements
852
891
  * @property {number}
853
892
  * @readonly
854
893
  */
@@ -857,6 +896,7 @@ class TXmlElementsListController {
857
896
  }
858
897
 
859
898
  /**
899
+ * Contains a quantity of an elements
860
900
  * @property {number}
861
901
  * @readonly
862
902
  */
@@ -865,6 +905,7 @@ class TXmlElementsListController {
865
905
  }
866
906
 
867
907
  /**
908
+ * Contains a maximum possible element index in the list
868
909
  * @property {number}
869
910
  * @readonly
870
911
  */
@@ -873,6 +914,7 @@ class TXmlElementsListController {
873
914
  }
874
915
 
875
916
  /**
917
+ * Indicates whether a `null`-element is allowed
876
918
  * @property {boolean}
877
919
  * @readonly
878
920
  */
@@ -905,7 +947,7 @@ class TXmlElementsListController {
905
947
  }
906
948
 
907
949
  /**
908
- * @param {any} value
950
+ * @param {(number|string)} value - some index
909
951
  * @returns {boolean}
910
952
  * @description Checks whether a given value is a valid index value
911
953
  * and it is not exceeds an index range within the instance.
@@ -916,7 +958,7 @@ class TXmlElementsListController {
916
958
  }
917
959
 
918
960
  /**
919
- * @param {any} obj
961
+ * @param {any} obj - some element
920
962
  * @returns {boolean}
921
963
  * @description Checks whether or not a given element is valid.
922
964
  */
@@ -939,7 +981,7 @@ class TXmlElementsListController {
939
981
  }
940
982
 
941
983
  /**
942
- * @param {number} index
984
+ * @param {number} index - element index
943
985
  * @returns {?TXmlElementController}
944
986
  * @description Returns an element.
945
987
  */
@@ -969,7 +1011,7 @@ class TXmlElementsListController {
969
1011
  }
970
1012
 
971
1013
  /**
972
- * @param {any} item
1014
+ * @param {any} item - some element
973
1015
  * @returns {number}
974
1016
  * @description Adds a new element.
975
1017
  */
@@ -995,8 +1037,8 @@ class TXmlElementsListController {
995
1037
  }
996
1038
 
997
1039
  /**
998
- * @param {string} index
999
- * @param {any} item
1040
+ * @param {string} index - element index
1041
+ * @param {any} item - some element
1000
1042
  * @returns {boolean}
1001
1043
  * @description Sets a new element.
1002
1044
  */
@@ -1036,8 +1078,8 @@ class TXmlElementsListController {
1036
1078
  }
1037
1079
 
1038
1080
  /**
1039
- * @param {number} index
1040
- * @param {any} item
1081
+ * @param {number} index - element index
1082
+ * @param {any} item - some element
1041
1083
  * @returns {boolean}
1042
1084
  * @description Insertes a new element.
1043
1085
  */
@@ -1050,7 +1092,7 @@ class TXmlElementsListController {
1050
1092
  }
1051
1093
 
1052
1094
  /**
1053
- * @param {number} index
1095
+ * @param {number} index - element index
1054
1096
  * @returns {boolean}
1055
1097
  * @description Deletes an element.
1056
1098
  */
@@ -1074,9 +1116,14 @@ class TXmlElementsListController {
1074
1116
  }
1075
1117
 
1076
1118
  /**
1077
- * @param {any} items
1078
- * @param {object} [opt]
1079
- * @param {boolean} [opt.useClear=true]
1119
+ * @typedef {Object} OPT_ELC_loaditems
1120
+ * @property {boolean} [useClear=true] - indicates whether to clear the list before load
1121
+ * @description A settings for the list load ops
1122
+ */
1123
+
1124
+ /**
1125
+ * @param {any} items - element or a list of an elements
1126
+ * @param {OPT_ELC_loaditems} [opt]
1080
1127
  * @returns {number}
1081
1128
  * @description Loads a list of an elements.
1082
1129
  */
@@ -1095,22 +1142,22 @@ class TXmlElementsListController {
1095
1142
  };
1096
1143
 
1097
1144
  /**
1098
- * @description This class implements an instance of an element
1099
- * that managea content of a document declaration
1145
+ * @classdesc This class implements an instance of an element
1146
+ * that managea content of a document declaration
1100
1147
  */
1101
1148
  class TXmlContentDeclaration {
1102
1149
  /** @property {?object} */
1103
- #_host;// = null;
1104
- /** @property {?object} */
1105
- #_options;// = null;
1150
+ #_host;
1151
+ /** @property {OPT_xmlcontsett} */
1152
+ #_options;
1106
1153
  /** @property {?TXmlElementController} */
1107
- #_ctrls;// = null;
1154
+ #_ctrls;
1108
1155
 
1109
1156
  /**
1110
- * @param {object} obj
1111
- * @param {object} [opt]
1112
- * @param {object} [opt.parseOptions]
1157
+ * @param {object} obj - some object
1158
+ * @param {OPT_xmlcontsett} [opt] - options
1113
1159
  * @throws {TypeError}
1160
+ * @description Creates an instance of the element
1114
1161
  */
1115
1162
  constructor(obj, opt) {
1116
1163
  // check <obj>-param
@@ -1118,14 +1165,11 @@ class TXmlContentDeclaration {
1118
1165
  throw new TypeError(`TXmlContentDeclaration : ${XML_TE_NOBJ_EMSG}`);
1119
1166
  };
1120
1167
  // load options
1121
- let _options = isPlainObject(opt) ? opt : {};
1168
+ const _options = __evalXMLContainerSettings(opt);
1122
1169
  // set parser options
1123
- let { parseOptions } = _options;
1124
- if (!isPlainObject(parseOptions)) {
1125
- _options.parseOptions = parseOptions = {};
1126
- };
1127
- let { settings } = parseOptions;
1128
- if (!isPlainObject(settings)) parseOptions.settings = settings = {};
1170
+ //let { parseOptions } = _options;
1171
+ let { settings } = _options.parseOptions;
1172
+ //if (!isPlainObject(settings)) parseOptions.settings = settings = {};
1129
1173
  let { declarationKey } = settings;
1130
1174
  if (
1131
1175
  typeof declarationKey !== 'string'
@@ -1143,6 +1187,7 @@ class TXmlContentDeclaration {
1143
1187
  }
1144
1188
 
1145
1189
  /**
1190
+ * Contains a version of an XML
1146
1191
  * @property {string}
1147
1192
  */
1148
1193
  get version() {
@@ -1154,6 +1199,7 @@ class TXmlContentDeclaration {
1154
1199
  }
1155
1200
 
1156
1201
  /**
1202
+ * Contains a document character set
1157
1203
  * @property {string}
1158
1204
  */
1159
1205
  get encoding() {
@@ -1190,16 +1236,13 @@ class TXmlContentDeclaration {
1190
1236
  */
1191
1237
  class TXmlContentRootElement extends TXmlElementController {
1192
1238
  /** @property {?object} */
1193
- #_content;// = null;
1194
- /** @property {?object} */
1195
- #_options;// = null;
1239
+ #_content;
1240
+ /** @property {OPT_xmlcontsett} */
1241
+ #_options;
1196
1242
 
1197
1243
  /**
1198
- * @param {object} obj
1199
- * @param {object} [opt]
1200
- * @param {object} [opt.parseOptions]
1201
- * @param {string} [opt.rootETagName='']
1202
- * @param {boolean} [opt.autoBindRoot=true]
1244
+ * @param {object} obj - some object
1245
+ * @param {OPT_xmlcontsett} [opt] - options
1203
1246
  * @throws {TypeError}
1204
1247
  */
1205
1248
  constructor(obj, opt) {
@@ -1208,18 +1251,8 @@ class TXmlContentRootElement extends TXmlElementController {
1208
1251
  throw new TypeError(`TXmlContentRootElement : ${XML_TE_NOBJ_EMSG}`);
1209
1252
  };
1210
1253
  // load options
1211
- const _options = isPlainObject(opt) ? opt : {};
1254
+ const _options = __evalXMLContainerSettings(opt);
1212
1255
  let { rootETagName, autoBindRoot, parseOptions } = _options;
1213
- if (
1214
- typeof rootETagName !== 'string'
1215
- || ((rootETagName = rootETagName.trim()) === '')
1216
- ) {
1217
- rootETagName = XML_DEF_ROOT_ETAG_NAME;
1218
- };
1219
- if (typeof autoBindRoot !== 'boolean') autoBindRoot = true;
1220
- if (!(parseOptions instanceof TXmlContentParseOptions)) {
1221
- parseOptions = new TXmlContentParseOptions(parseOptions);
1222
- };
1223
1256
  // get root element
1224
1257
  let rootItem = obj[rootETagName];
1225
1258
  if (obj[rootETagName] === undefined) {
@@ -1278,13 +1311,9 @@ class TXmlContentRootElement extends TXmlElementController {
1278
1311
  super(rootItem, _options);
1279
1312
  // save options
1280
1313
  _options.rootETagName = rootETagName;
1281
- _options.autoBindRoot = autoBindRoot;
1282
- _options.parseOptions = parseOptions;
1283
1314
  this.#_options = _options;
1284
1315
  // bind a documents content
1285
1316
  this.#_content = obj;
1286
- // init a content root element
1287
- //this.init(rootETagName);
1288
1317
  }
1289
1318
 
1290
1319
  /**
@@ -1295,7 +1324,7 @@ class TXmlContentRootElement extends TXmlElementController {
1295
1324
  }
1296
1325
 
1297
1326
  set tagName(value) {
1298
- value = readAsString(value, true);
1327
+ value = readAsString(value, { useTrim: true });
1299
1328
  this.#_options.rootETagName = isNotEmptyString(
1300
1329
  value
1301
1330
  ) ? value : XML_DEF_ROOT_ETAG_NAME;
@@ -1321,40 +1350,46 @@ class TXmlContentRootElement extends TXmlElementController {
1321
1350
  }
1322
1351
 
1323
1352
  /**
1324
- * @description This class implements an instance of a container
1325
- * that managea content of a document
1353
+ * @typedef {Object} fsoDescr
1354
+ * @property {boolean} isERR - flag
1355
+ * @property {number} [errCode] - error code
1356
+ * @property {string} errEvent - event ID
1357
+ * @property {string} errMsg - event message
1358
+ * @property {string} source - path to file
1359
+ * @property {any} content - file content
1360
+ * @description A fs ops description.
1361
+ */
1362
+
1363
+ /**
1364
+ * @classdesc This class implements an instance of a container
1365
+ * that managea content of a document
1326
1366
  */
1327
1367
  class TXmlContentContainer {
1328
1368
  /** @property {?object} */
1329
- #_content;// = null;
1369
+ #_content;
1370
+ /** @property {OPT_xmlcontsett} */
1371
+ #_options;
1330
1372
  /** @property {?object} */
1331
- #_options;// = null;
1332
- /** @property {?object} */
1333
- #_parseOptions;// = null;
1373
+ #_parseOptions;
1334
1374
  /** @property {?TXmlContentDeclaration} */
1335
- #_docDecl;// = null;
1375
+ #_docDecl;
1336
1376
  /** @property {?TXmlContentRootElement} */
1337
- #_docRoot;// = null;
1377
+ #_docRoot;
1338
1378
 
1339
1379
  /**
1340
- * @param {object} [opt]
1341
- * @param {object} [opt.parseOptions]
1380
+ * @param {OPT_xmlcontsett} [opt] - options
1381
+ * @description Creates an instance of the container
1342
1382
  */
1343
1383
  constructor(opt) {
1344
1384
  // load options
1345
- const _options = isPlainObject(opt) ? opt : {};
1346
- let { parseOptions } = _options;
1347
- if (!(parseOptions instanceof TXmlContentParseOptions)) {
1348
- parseOptions = new TXmlContentParseOptions(parseOptions);
1349
- };
1385
+ const _options = __evalXMLContainerSettings(opt);
1386
+ const { parseOptions } = _options;
1350
1387
  // save options
1351
- _options.parseOptions = parseOptions;
1352
1388
  this.#_options = _options;
1353
1389
  // save parser options
1354
1390
  this.#_parseOptions = parseOptions;
1355
1391
  // init a documents content
1356
- let _content = {};
1357
- this.#_content = _content;
1392
+ const _content = this.#_content = {};
1358
1393
  // init a content declaration element
1359
1394
  this.#_docDecl = new TXmlContentDeclaration(_content, _options);
1360
1395
  // init a content root element
@@ -1386,14 +1421,14 @@ class TXmlContentContainer {
1386
1421
  * @description Initializes an instance with a given content.
1387
1422
  */
1388
1423
  _bindContent(obj, opt) {
1389
- const _options = isPlainObject(opt) ? opt : this.#_options;
1390
1424
  let isSUCCEED = false;
1391
1425
  if (isPlainObject(obj)) {
1392
- let { parseOptions } = _options;
1393
- if (!(parseOptions instanceof TXmlContentParseOptions)) {
1394
- parseOptions = new TXmlContentParseOptions(parseOptions);
1395
- _options.parseOptions = parseOptions;
1396
- };
1426
+ const _options = __evalXMLContainerSettings(
1427
+ isPlainObject(opt)
1428
+ ? opt
1429
+ : this.#_options
1430
+ );
1431
+ const { parseOptions } = _options;
1397
1432
  const _docDecl = new TXmlContentDeclaration(obj, _options);
1398
1433
  const _docRoot = new TXmlContentRootElement(obj, _options);
1399
1434
  // // TODO: check elements
@@ -1429,8 +1464,8 @@ class TXmlContentContainer {
1429
1464
  }
1430
1465
 
1431
1466
  /**
1432
- * @param {string} source
1433
- * @returns {object}
1467
+ * @param {string} source - a path to a file
1468
+ * @returns {Promise<fsoDescr, Error>}
1434
1469
  * @throws {Error}
1435
1470
  * @async
1436
1471
  * @description Saves a document content to a file.
@@ -1438,73 +1473,62 @@ class TXmlContentContainer {
1438
1473
  saveToFile(source) {
1439
1474
  /**/// main part that return promise as a result
1440
1475
  return new Promise((resolve, reject) => {
1476
+ /** @type {fsoDescr} */
1441
1477
  let data = {
1442
- isSucceed: false,
1443
- source: typeof source === 'string' ? source.trim() : '',
1444
- content: '',
1445
1478
  isERR: false,
1479
+ errCode: 0,
1446
1480
  errEvent: '',
1481
+ errMsg: '',
1482
+ source: '',
1483
+ content: '',
1447
1484
  };
1448
- if (data.source === '') {
1449
- data.isERR = true;
1450
- data.errEvent = (
1451
- typeof source === 'string' ? 'EMPTY_SRCLINK' : 'NO_SRCLINK'
1452
- );
1453
- resolve(data);
1454
- } else {
1485
+ (new Promise((resolve, reject) => {
1455
1486
  data.content = this.saveToXMLString();
1456
- fse.writeFile(data.source, data.content, 'utf8').then(result => {
1457
- data.isSucceed = true;
1458
- data.errEvent = 'OPS_IS_SUCCEED';
1487
+ resolve(true);
1488
+ })).then(result => {
1489
+ saveToFile(source, data.content, null).then(data => {
1459
1490
  resolve(data);
1460
1491
  }).catch(err => {
1461
- let { isSucceed } = checkFsError(data, err);
1462
- if (isSucceed) {
1463
- data.content = '';
1464
- resolve(data);
1465
- } else {
1466
- //console.log('CHECK: TXmlContentContainer.saveToFile() => Error => '+err);
1467
- //console.log('CHECK: TXmlContentContainer.saveToFile() => Error => '+err.code);
1468
- reject(err);
1469
- };
1492
+ // // TODO: [?] consider check others
1493
+ //console.log('CHECK: TXmlContentContainer.saveToFile() => Error => '+err);
1494
+ //console.log('CHECK: TXmlContentContainer.saveToFile() => Error => '+err.code);
1495
+ reject(err);
1470
1496
  });
1471
- };
1497
+ }).catch(err => {
1498
+ data.isERR = true;
1499
+ //console.log('CHECK: TXmlContentContainer.saveToFile() => Error => '+err);
1500
+ //console.log('CHECK: TXmlContentContainer.saveToFile() => Error => '+err.code);
1501
+ data.errEvent = 'ERR_XML_UNKNOWN';
1502
+ resolve(data);
1503
+ });
1472
1504
  });
1473
1505
  }
1474
1506
 
1475
1507
  /**
1476
- * @param {string} source
1477
- * @returns {object}
1478
- * @throws {Error}
1508
+ * @param {string} source source - path to a file
1509
+ * @returns {fsoDescr}
1479
1510
  * @description Saves a document content to a file.
1480
1511
  */
1481
1512
  saveToFileSync(source) {
1513
+ /** @type {fsoDescr} */
1482
1514
  let data = {
1483
- isSucceed: false,
1484
- source: typeof source === 'string' ? source.trim() : '',
1485
- content: '',
1486
1515
  isERR: false,
1516
+ errCode: 0,
1487
1517
  errEvent: '',
1518
+ errMsg: '',
1519
+ source: '',
1520
+ content: '',
1488
1521
  };
1489
- if (data.source === '') {
1522
+ try {
1523
+ data.content = this.saveToXMLString();
1524
+ } catch (err) {
1490
1525
  data.isERR = true;
1491
- data.errEvent = (
1492
- typeof source === 'string' ? 'EMPTY_SRCLINK' : 'NO_SRCLINK'
1493
- );
1494
- } else {
1495
- try {
1496
- data.content = this.saveToXMLString();
1497
- fs.writeFileSync(data.source, data.content, 'utf8');
1498
- } catch (err) {
1499
- let { isSucceed } = checkFsError(data, err);
1500
- if (isSucceed) {
1501
- data.content = '';
1502
- } else {
1503
- //console.log('CHECK: TXmlContentContainer.saveToFileSync() => Error => '+err);
1504
- //console.log('CHECK: TXmlContentContainer.saveToFileSync() => Error => '+err.code);
1505
- throw err;
1506
- };
1507
- };
1526
+ //console.log('CHECK: TXmlContentContainer.saveToFileSync() => Error => '+err);
1527
+ //console.log('CHECK: TXmlContentContainer.saveToFileSync() => Error => '+err.code);
1528
+ data.errEvent = 'ERR_XML_UNKNOWN';
1529
+ };
1530
+ if (!data.isERR) {
1531
+ data = saveToFileSync(source, data.content, null);
1508
1532
  };
1509
1533
  return data;
1510
1534
  }
@@ -1534,8 +1558,8 @@ class TXmlContentContainer {
1534
1558
  }
1535
1559
 
1536
1560
  /**
1537
- * @param {string} source
1538
- * @returns {object}
1561
+ * @param {string} source - path to a file
1562
+ * @returns {Promise<fsoDescr, Error>}
1539
1563
  * @throws {Error}
1540
1564
  * @async
1541
1565
  * @description Loads a document content from a file.
@@ -1543,24 +1567,11 @@ class TXmlContentContainer {
1543
1567
  loadFromFile(source) {
1544
1568
  /**/// main part that return promise as a result
1545
1569
  return new Promise((resolve, reject) => {
1546
- let data = {
1547
- isLoaded: false,
1548
- source: typeof source === 'string' ? source.trim() : '',
1549
- content: '',
1550
- isERR: false,
1551
- errEvent: '',
1552
- };
1553
- if (data.source === '') {
1554
- data.isERR = true;
1555
- data.errEvent = (
1556
- typeof source === 'string' ? 'EMPTY_SRCLINK' : 'NO_SRCLINK'
1557
- );
1558
- resolve(data);
1559
- } else {
1560
- fse.readFile(data.source, 'utf8').then(result => {
1561
- data.content = result;
1562
- if (result !== '') {
1563
- if (this.loadFromXMLString(result)) {
1570
+ loadFile(source).then(data => {
1571
+ if (!data.isERR) {
1572
+ if (data.content !== '') {
1573
+ if (this.loadFromXMLString(data.content)) {
1574
+ // // TODO:
1564
1575
  data.isLoaded = true;
1565
1576
  data.errEvent = 'OPS_IS_SUCCEED';
1566
1577
  } else {
@@ -1571,65 +1582,37 @@ class TXmlContentContainer {
1571
1582
  data.isERR = true;
1572
1583
  data.errEvent = 'NO_CONTENT';
1573
1584
  };
1574
- resolve(data);
1575
- }).catch(err => {
1576
- let { isSucceed } = checkFsError(data, err);
1577
- if (isSucceed) {
1578
- data.content = '';
1579
- resolve(data);
1580
- } else {
1581
- //console.log('CHECK: TXmlContentContainer.loadFromFile() => Error => '+err);
1582
- //console.log('CHECK: TXmlContentContainer.loadFromFile() => Error => '+err.code);
1583
- reject(err);
1584
- };
1585
- });
1586
- };
1585
+ };
1586
+ resolve(data);
1587
+ }).catch(err => {
1588
+ //console.log('CHECK: TXmlContentContainer.loadFromFile() => Error => '+err);
1589
+ //console.log('CHECK: TXmlContentContainer.loadFromFile() => Error => '+err.code);
1590
+ reject(err);
1591
+ });
1587
1592
  });
1588
1593
  }
1589
1594
 
1590
1595
  /**
1591
- * @param {string} source
1592
- * @returns {object}
1596
+ * @param {string} source source - path to a file
1597
+ * @returns {fsoDescr}
1593
1598
  * @throws {Error}
1594
1599
  * @description Loads a document content from a file.
1595
1600
  */
1596
1601
  loadFromFileSync(source) {
1597
- let data = {
1598
- isLoaded: false,
1599
- source: typeof source === 'string' ? source.trim() : '',
1600
- content: '',
1601
- isERR: false,
1602
- errEvent: '',
1603
- };
1604
- if (data.source === '') {
1605
- data.isERR = true;
1606
- data.errEvent = (
1607
- typeof source === 'string' ? 'EMPTY_SRCLINK' : 'NO_SRCLINK'
1608
- );
1609
- } else {
1610
- try {
1611
- data.content = fs.readFileSync(data.source, 'utf8');
1612
- if (data.content !== '') {
1613
- if (this.loadFromXMLString(data.content)) {
1614
- data.isLoaded = true;
1615
- data.errEvent = 'OPS_IS_SUCCEED';
1616
- } else {
1617
- data.isERR = true;
1618
- data.errEvent = 'OPS_IS_FAILED';
1619
- };
1602
+ const data = loadFileSync(source);
1603
+ if (!data.isERR) {
1604
+ if (data.content !== '') {
1605
+ if (this.loadFromXMLString(data.content)) {
1606
+ // // TODO:
1607
+ data.isLoaded = true;
1608
+ data.errEvent = 'OPS_IS_SUCCEED';
1620
1609
  } else {
1621
1610
  data.isERR = true;
1622
- data.errEvent = 'NO_CONTENT';
1623
- };
1624
- } catch (err) {
1625
- let { isSucceed } = checkFsError(data, err);
1626
- if (isSucceed) {
1627
- data.content = '';
1628
- } else {
1629
- //console.log('CHECK: TXmlContentContainer.loadFromFileSync() => Error => '+err);
1630
- //console.log('CHECK: TXmlContentContainer.loadFromFileSync() => Error => '+err.code);
1631
- throw err;
1611
+ data.errEvent = 'OPS_IS_FAILED';
1632
1612
  };
1613
+ } else {
1614
+ data.isERR = true;
1615
+ data.errEvent = 'NO_CONTENT';
1633
1616
  };
1634
1617
  };
1635
1618
  return data;