@cntwg/xml-lib-js 0.0.25 → 0.0.26

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/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ #### *v0.0.26*
2
+
3
+ Pre-release version.
4
+
5
+ > - `xmldoc-lib.md` updated;
6
+ > - updated dependency on `@ygracs/bsfoc-lib-js` module to v0.2.1;
7
+ > - updated dependency on `@ygracs/xobj-lib-js` module to v0.1.2;
8
+ > - improve error handling on file load/save ops for `TXmlContentContainer`;
9
+ > - fix behavior for a `setTextValue` method of a `TXmlElementController`;
10
+ > - add `xml-helper.js` module.
11
+
1
12
  #### *v0.0.25*
2
13
 
3
14
  Pre-release version.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2019-2023 Yuri Grachev
3
+ Copyright (c) 2019-2024 Yuri Grachev
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
6
 
package/README.md CHANGED
@@ -1,17 +1,11 @@
1
- |***rev.*:**|0.1.4|
1
+ |***rev.*:**|0.1.5|
2
2
  |:---|---:|
3
- |***date***:|2023-09-19|
3
+ |***date***:|2024-06-26|
4
4
 
5
5
  ## Introduction
6
6
 
7
7
  This module provide a base functionality for handling an XML-documents.
8
8
 
9
- ## Use cases
10
-
11
- ### Installation
12
-
13
- `npm install @cntwg/xml-lib-js`
14
-
15
9
  ## Description
16
10
 
17
11
  This module contains the following components:
@@ -38,3 +32,18 @@ xObj-manipulator is a set of functions (see docs for [`@ygracs/xobj-lib-js` modu
38
32
  + `TXmlContentContainer`.
39
33
 
40
34
  For more read the `xmldoc-lib.md` in the project `doc` directory.
35
+
36
+ ### 3. an `xmlHelper` module extention
37
+
38
+ - functions:
39
+
40
+ + `getChildByPath`;
41
+ + `addChildByPath`.
42
+
43
+ For more read the `xmldoc-lib.md` in the project `doc` directory.
44
+
45
+ ## Use cases
46
+
47
+ ### Installation
48
+
49
+ `npm install @cntwg/xml-lib-js`
package/doc/xmldoc-lib.md CHANGED
@@ -1,6 +1,6 @@
1
- >|***rev.*:**|0.1.22|
1
+ >|***rev.*:**|0.1.23|
2
2
  >|:---|---:|
3
- >|date:|2023-09-19|
3
+ >|date:|2024-06-26|
4
4
 
5
5
  ## Introduction
6
6
 
@@ -189,6 +189,7 @@ This method returns an array witch contain a value of a `textValue` property and
189
189
  This method sets the value of a `textValue` property and its `lang` attribute and if succeed returns `true`.
190
190
 
191
191
  The method received value that can be a string or an array. If value is an array it must be in the following format:
192
+
192
193
  `[ <textValue> ]`
193
194
  or
194
195
  `[ <lang>, <textValue> ]`.
@@ -501,3 +502,27 @@ This method returns a document content as a string in the JSON-format.
501
502
  This method binds a given object as a document content.
502
503
 
503
504
  For `options` parameter details see the class constructor description.
505
+
506
+ ## Module `xmlHelper`
507
+
508
+ This section contains functions provided by `xmlHelper` module.
509
+
510
+ ### Experimental functions
511
+
512
+ > Note: Purpose of those functions will be discussed and some may be deprecate and make obsolete or functionality may be altered. So use it with cautions in mind.
513
+
514
+ #### **getChildByPath(object, chain)**
515
+
516
+ > since: \[v0.0.26]
517
+
518
+ This function tries to get a child element from a given object following path provided by `chain` parameter. If failed `null` is returned.
519
+
520
+ The `chain` parameter contains an array of an element names.
521
+
522
+ #### **addChildByPath(object, chain)**
523
+
524
+ > since: \[v0.0.26]
525
+
526
+ This function tries to add a new child element into a given object following path provided by `chain` parameter. If succeed a new element returned. If failed `null` is returned.
527
+
528
+ The `chain` parameter contains an array of an element names. The last name in `chain` is a name of the element which will be added.
package/index.js CHANGED
@@ -1,9 +1,10 @@
1
- // [v0.1.011-20230919]
1
+ // [v0.1.012-20240626]
2
2
 
3
3
  // === module init block ===
4
4
 
5
5
  const xObj = require('@ygracs/xobj-lib-js');
6
6
  const xmldoc = require('./lib/xmldoc-lib.js');
7
+ const xmlHelper = require('./lib/xml-helper.js');
7
8
 
8
9
  // === module extra block (helper functions) ===
9
10
 
@@ -11,16 +12,17 @@ const xmldoc = require('./lib/xmldoc-lib.js');
11
12
 
12
13
  // === module exports block ===
13
14
 
14
- exports.xObj = xObj;
15
+ module.exports.xObj = xObj;
16
+ module.exports.xmlHelper = xmlHelper;
15
17
 
16
- exports.XML_DEF_PARSE_OPTIONS = xmldoc.XML_DEF_PARSE_OPTIONS;
17
- exports.XML_DEF_ROOT_ETAG_NAME = xmldoc.XML_DEF_ROOT_ETAG_NAME;
18
+ module.exports.XML_DEF_PARSE_OPTIONS = xmldoc.XML_DEF_PARSE_OPTIONS;
19
+ module.exports.XML_DEF_ROOT_ETAG_NAME = xmldoc.XML_DEF_ROOT_ETAG_NAME;
18
20
 
19
- exports.TXmlContentParseOptions = xmldoc.TXmlContentParseOptions;
21
+ module.exports.TXmlContentParseOptions = xmldoc.TXmlContentParseOptions;
20
22
 
21
- exports.TXmlAttributesMapper = xmldoc.TXmlAttributesMapper;
22
- exports.TXmlElementController = xmldoc.TXmlElementController;
23
- exports.TXmlElementsListController = xmldoc.TXmlElementsListController;
24
- exports.TXmlContentDeclaration = xmldoc.TXmlContentDeclaration;
25
- exports.TXmlContentRootElement = xmldoc.TXmlContentRootElement;
26
- exports.TXmlContentContainer = xmldoc.TXmlContentContainer;
23
+ module.exports.TXmlAttributesMapper = xmldoc.TXmlAttributesMapper;
24
+ module.exports.TXmlElementController = xmldoc.TXmlElementController;
25
+ module.exports.TXmlElementsListController = xmldoc.TXmlElementsListController;
26
+ module.exports.TXmlContentDeclaration = xmldoc.TXmlContentDeclaration;
27
+ module.exports.TXmlContentRootElement = xmldoc.TXmlContentRootElement;
28
+ module.exports.TXmlContentContainer = xmldoc.TXmlContentContainer;
@@ -0,0 +1,88 @@
1
+ // [v0.0.001-20240626]
2
+
3
+ // === module init block ===
4
+
5
+ const {
6
+ valueToArray,
7
+ } = require('@ygracs/bsfoc-lib-js');
8
+
9
+ const {
10
+ TXmlElementController,
11
+ } = require('./xmldoc-lib');
12
+
13
+ // === module extra block (helper functions) ===
14
+
15
+ // === module main block ===
16
+
17
+ /***
18
+ * (* constant definitions *)
19
+ */
20
+
21
+ /***
22
+ * (* function definitions *)
23
+ */
24
+
25
+ /**
26
+ * @function getChildByPath
27
+ * @param {TXmlElementController}
28
+ * @param {array}
29
+ * @returns {?TXmlElementController}
30
+ * @description Tries to get a child element.
31
+ */
32
+ function getChildByPath(obj, chain) {
33
+ let result = null;
34
+ if (obj instanceof TXmlElementController) {
35
+ const list = valueToArray(chain);
36
+ let child = obj;
37
+ let isFound = false;
38
+ for (let name of list) {
39
+ child = child.getChild(name);
40
+ if (
41
+ child !== null
42
+ && (child instanceof TXmlElementController)
43
+ ) {
44
+ isFound = true;
45
+ } else {
46
+ isFound = false;
47
+ break;
48
+ };
49
+ };
50
+ if (isFound) result = child;
51
+ };
52
+ return result;
53
+ };
54
+
55
+ /**
56
+ * @function addChildByPath
57
+ * @param {TXmlElementController}
58
+ * @param {array}
59
+ * @returns {?TXmlElementController}
60
+ * @description Tries to get a child element.
61
+ */
62
+ function addChildByPath(obj, chain){
63
+ let child = null;
64
+ if (obj instanceof TXmlElementController) {
65
+ const list = valueToArray(chain);
66
+ for (let name of list) {
67
+ child = item.getChild(name);
68
+ if (child === null) {
69
+ child = item.addChild(name);
70
+ };
71
+ if ((child instanceof TXmlElementController)) {
72
+ item = child;
73
+ } else {
74
+ child = null; break;
75
+ };
76
+ };
77
+ };
78
+ return child;
79
+ };
80
+
81
+ /***
82
+ * (* class definitions *)
83
+ */
84
+
85
+ // === module exports block ===
86
+
87
+ module.exports.getChildByPath = getChildByPath;
88
+ module.exports.addChildByPath = addChildByPath;
package/lib/xmldoc-lib.js CHANGED
@@ -1,4 +1,4 @@
1
- // [v0.1.069-20230926]
1
+ // [v0.1.077-20240625]
2
2
 
3
3
  // === module init block ===
4
4
 
@@ -9,12 +9,50 @@ const xmlParser = require('@ygracs/xml-js6');
9
9
  const {
10
10
  valueToIndex, readAsBool, readAsString, isNotEmptyString,
11
11
  isArray, isObject, isPlainObject,
12
- valueToArray,
12
+ valueToArray, valueToEntry,
13
13
  } = require('@ygracs/bsfoc-lib-js');
14
14
 
15
15
  const xObj = require('@ygracs/xobj-lib-js');
16
- const TXmlContentParseOptions = xObj.TXmlContentParseOptions;
17
- const XML_DEF_PARSE_OPTIONS = xObj.DEF_XML_PARSE_OPTIONS;
16
+ const {
17
+ TXmlContentParseOptions,
18
+ DEF_XML_PARSE_OPTIONS: XML_DEF_PARSE_OPTIONS,
19
+ } = xObj;
20
+
21
+ // === module extra block (helper functions) ===
22
+
23
+ /**
24
+ * @function checkFsError
25
+ * @param {object}
26
+ * @param {Error}
27
+ * @returns {object}
28
+ * @inner
29
+ * @description Checs an error code of a fs ops and sets descr info if succeed
30
+ */
31
+ function checkFsError(descr, err) {
32
+ let isSucceed = false;
33
+ if (isPlainObject(err) && isPlainObject(descr)) {
34
+ switch (err.code) {
35
+ case 'ENOENT':
36
+ case 'EISDIR':
37
+ case 'EPERM': {
38
+ descr.errCode = err.errno;
39
+ descr.errEvent = err.code;
40
+ descr.errMsg = `ERR_FILE_${err.code}`;
41
+ isSucceed = true;
42
+ break;
43
+ }
44
+ default: {}
45
+ };
46
+ if (isSucceed) descr.isERR = true;
47
+ };
48
+ return { isSucceed, descr };
49
+ };
50
+
51
+ // === module main block ===
52
+
53
+ /***
54
+ * (* constant definitions *)
55
+ */
18
56
 
19
57
  const XML_DEF_ROOT_ETAG_NAME = 'root';
20
58
  const XML_LANG_ATTR_TNAME = 'lang';
@@ -24,16 +62,27 @@ const XML_TE_NOBJ_EMSG = `${XML_TE_INVARG_EMSG} (an object is expected)`;
24
62
  const XML_TE_NARR_EMSG = `${XML_TE_INVARG_EMSG} (an array is expected)`;
25
63
  const XML_TE_NROOT_EMSG = 'root element not found';
26
64
 
27
- // === module extra block (helper functions) ===
28
-
29
- // === module main block (function definitions) ===
65
+ /***
66
+ * (* function definitions *)
67
+ */
30
68
 
31
- // === module main block (class definitions) ===
69
+ /***
70
+ * (* class definitions *)
71
+ */
32
72
 
73
+ /**
74
+ * @description This class implements an attributes mapper instance
75
+ */
33
76
  class TXmlAttributesMapper {
34
77
  #_host = null;
35
78
  #_options = null;
36
79
 
80
+ /**
81
+ * @param {object}
82
+ * @param {object} [opt]
83
+ * @param {object} [opt.parseOptions]
84
+ * @throws {TypeError}
85
+ */
37
86
  constructor(obj, opt){
38
87
  // init an elements content
39
88
  if (!isPlainObject(obj)) throw new TypeError(XML_TE_NOBJ_EMSG);
@@ -58,6 +107,10 @@ class TXmlAttributesMapper {
58
107
  this.#_options = parseOptions;
59
108
  }
60
109
 
110
+ /**
111
+ * @property {array}
112
+ * @readonly
113
+ */
61
114
  get entries(){
62
115
  let items = xObj.getXObjAttributes(
63
116
  this.#_host,
@@ -66,6 +119,11 @@ class TXmlAttributesMapper {
66
119
  return isPlainObject(items) ? Object.entries(items) : [];
67
120
  }
68
121
 
122
+ /**
123
+ * @param {ID_STRING}
124
+ * @returns {bool}
125
+ * @description Checks whether an attribute exists.
126
+ */
69
127
  hasAttribute(name){
70
128
  let result = false;
71
129
  try {
@@ -81,6 +139,11 @@ class TXmlAttributesMapper {
81
139
  return result;
82
140
  }
83
141
 
142
+ /**
143
+ * @param {ID_STRING}
144
+ * @returns {string}
145
+ * @description Returns an attribute value.
146
+ */
84
147
  getAttribute(name){
85
148
  let result = '';
86
149
  try {
@@ -96,6 +159,12 @@ class TXmlAttributesMapper {
96
159
  return result;
97
160
  }
98
161
 
162
+ /**
163
+ * @param {ID_STRING}
164
+ * @param {any}
165
+ * @returns {bool}
166
+ * @description Sets an attribute value.
167
+ */
99
168
  setAttribute(name, value){
100
169
  let result = false;
101
170
  try {
@@ -112,6 +181,11 @@ class TXmlAttributesMapper {
112
181
  return result;
113
182
  }
114
183
 
184
+ /**
185
+ * @param {ID_STRING}
186
+ * @returns {bool}
187
+ * @description Deletes an attribute.
188
+ */
115
189
  delAttribute(name){
116
190
  let result = false;
117
191
  try {
@@ -127,6 +201,10 @@ class TXmlAttributesMapper {
127
201
  return result;
128
202
  }
129
203
 
204
+ /**
205
+ * @returns {none}
206
+ * @description Deletes all attributes.
207
+ */
130
208
  clear(){
131
209
  xObj.insertXObjElement(
132
210
  this.#_host,
@@ -140,6 +218,9 @@ class TXmlAttributesMapper {
140
218
 
141
219
  }
142
220
 
221
+ /**
222
+ * @description This class implements an instance of an element controller
223
+ */
143
224
  class TXmlElementController {
144
225
  #_host = null;
145
226
  #_options = null;
@@ -147,6 +228,13 @@ class TXmlElementController {
147
228
  #_attributes = null;
148
229
  #_name = null;
149
230
 
231
+ /**
232
+ * @param {object}
233
+ * @param {object} [opt]
234
+ * @param {object} [opt.parseOptions]
235
+ * @param {bool} [opt.proxyModeEnable=false]
236
+ * @throws {TypeError}
237
+ */
150
238
  constructor(obj, opt){
151
239
  // load options
152
240
  let _options = isPlainObject(opt) ? opt : {};
@@ -190,10 +278,19 @@ class TXmlElementController {
190
278
  this.#_attributes = new TXmlAttributesMapper(obj, _options);
191
279
  }
192
280
 
281
+ /**
282
+ * @property {TXmlAttributesMapper}
283
+ * @readonly
284
+ */
193
285
  get attributes(){
194
286
  return this.#_attributes;
195
287
  }
196
288
 
289
+ /**
290
+ * @property {string}
291
+ * @readonly
292
+ * @experimental
293
+ */
197
294
  get name(){
198
295
  let result = '';
199
296
  if (this.#_parseOptions.settings.compact) {
@@ -207,6 +304,9 @@ class TXmlElementController {
207
304
  return result;
208
305
  }
209
306
 
307
+ /**
308
+ * @property {string}
309
+ */
210
310
  get textValue(){
211
311
  return xObj.readXObjParam(this.#_host, this.#_parseOptions.settings.textKey);
212
312
  }
@@ -215,22 +315,44 @@ class TXmlElementController {
215
315
  xObj.writeXObjParam(this.#_host, value, this.#_parseOptions.settings.textKey);
216
316
  }
217
317
 
318
+ /**
319
+ * @param {ID_STRING}
320
+ * @returns {bool}
321
+ * @description Checks whether an attribute exists.
322
+ */
218
323
  hasAttribute(name){
219
324
  return this.#_attributes.hasAttribute(name);
220
325
  }
221
326
 
327
+ /**
328
+ * @param {ID_STRING}
329
+ * @returns {string}
330
+ * @description Returns an attribute value.
331
+ */
222
332
  getAttribute(name){
223
333
  return this.#_attributes.getAttribute(name);
224
334
  }
225
335
 
336
+ /**
337
+ * @see TXmlAttributesMapper.setAttribute
338
+ */
226
339
  setAttribute(...args){
227
340
  return this.#_attributes.setAttribute(...args);
228
341
  }
229
342
 
343
+ /**
344
+ * @param {ID_STRING}
345
+ * @returns {bool}
346
+ * @description Deletes an attribute.
347
+ */
230
348
  delAttribute(name){
231
349
  return this.#_attributes.delAttribute(name);
232
350
  }
233
351
 
352
+ /**
353
+ * @returns {array}
354
+ * @description Returns a text value in format of a `[ <lang>, <text> ]` pair.
355
+ */
234
356
  getTextValue(){
235
357
  return [
236
358
  this.#_attributes.getAttribute(XML_LANG_ATTR_TNAME),
@@ -238,30 +360,40 @@ class TXmlElementController {
238
360
  ];
239
361
  }
240
362
 
363
+ /**
364
+ * @param {(string|entry)}
365
+ * @returns {bool}
366
+ * @description Sets a text value.
367
+ */
241
368
  setTextValue(value){
242
- const _value = valueToArray(value);
243
- const len = _value.length;
244
- if (len > 0) {
245
- if (len === 1) {
246
- return xObj.writeXObjParam(
247
- this.#_host,
248
- _value[0],
249
- this.#_parseOptions.settings.textKey,
250
- );
251
- } else {
252
- const [ lang, param ] = _value;
253
- if (xObj.writeXObjParam(
254
- this.#_host,
255
- param,
256
- this.#_parseOptions.settings.textKey,
257
- )) {
258
- return this.#_attributes.setAttribute(XML_LANG_ATTR_TNAME, lang);
369
+ const _value = valueToEntry(value);
370
+ if (_value !== null) {
371
+ const [ lang, param ] = _value;
372
+ if (xObj.writeXObjParam(
373
+ this.#_host,
374
+ param,
375
+ this.#_parseOptions.settings.textKey,
376
+ )) {
377
+ const attributes = this.#_attributes;
378
+ if (lang === '') {
379
+ if (attributes.hasAttribute(XML_LANG_ATTR_TNAME)) {
380
+ return attributes.delAttribute(XML_LANG_ATTR_TNAME);
381
+ } else {
382
+ return true;
383
+ };
384
+ } else {
385
+ return attributes.setAttribute(XML_LANG_ATTR_TNAME, lang);
259
386
  };
260
387
  };
261
388
  };
262
389
  return false;
263
390
  }
264
391
 
392
+ /**
393
+ * @param {ID_STRING}
394
+ * @returns {bool}
395
+ * @description Checks whether an element has a child element.
396
+ */
265
397
  hasChild(name){
266
398
  const _name = xObj.evalXObjEName(name);
267
399
  let result = false;
@@ -276,6 +408,11 @@ class TXmlElementController {
276
408
  return result;
277
409
  }
278
410
 
411
+ /**
412
+ * @param {ID_STRING}
413
+ * @returns {(null|TXmlElementController|TXmlElementsListController)}
414
+ * @description Returns a child element.
415
+ */
279
416
  getChild(name){
280
417
  const _name = xObj.evalXObjEName(name);
281
418
  let result = null;
@@ -295,6 +432,12 @@ class TXmlElementController {
295
432
  return result;
296
433
  }
297
434
 
435
+ /**
436
+ * @param {ID_STRING}
437
+ * @returns {object}
438
+ * @protected
439
+ * @description Returns a child element.
440
+ */
298
441
  _getChildRaw(name){
299
442
  //console.log('CHECK: TXmlElementController._getChildRaw() => was called...');
300
443
  //console.log('CHECK: TXmlElementController._getChildRaw() => _host => '+JSON.stringify(this.#_host, null, 2));
@@ -307,11 +450,22 @@ class TXmlElementController {
307
450
  return item !== undefined ? item : null;
308
451
  }
309
452
 
453
+ /**
454
+ * @see TXmlElementController.__setChildRaw
455
+ * @protected
456
+ * @description Sets a child element.
457
+ */
310
458
  _setChildRaw(...args){
311
459
  //console.log('CHECK: TXmlElementController._setChildRaw() => was called...');
312
460
  return TXmlElementController.__setChildRaw(this, ...args);
313
461
  }
314
462
 
463
+ /**
464
+ * @param {ID_STRING}
465
+ * @returns {?object}
466
+ * @protected
467
+ * @description Adds a new child element.
468
+ */
315
469
  _addChildRaw(name){//}, obj){
316
470
  //console.log('CHECK: TXmlElementController._addChild() => was called...');
317
471
  //console.log('CHECK: TXmlElementController._addChildRaw() => _host => '+JSON.stringify(this.#_host, null, 2));
@@ -324,6 +478,11 @@ class TXmlElementController {
324
478
  return result.isSucceed ? result.item : null;
325
479
  }
326
480
 
481
+ /**
482
+ * @param {ID_STRING}
483
+ * @returns {?TXmlElementController}
484
+ * @description Adds a new child element.
485
+ */
327
486
  addChild(name){
328
487
  const _name = xObj.evalXObjEName(name);
329
488
  let result = null;
@@ -339,6 +498,11 @@ class TXmlElementController {
339
498
  return result;
340
499
  }
341
500
 
501
+ /**
502
+ * @param {ID_STRING}
503
+ * @returns {bool}
504
+ * @description Deletes a child element.
505
+ */
342
506
  delChild(name){
343
507
  const _name = xObj.evalXObjEName(name);
344
508
  let isSUCCEED = false;
@@ -368,14 +532,34 @@ class TXmlElementController {
368
532
  return isSUCCEED;
369
533
  }
370
534
 
535
+ /**
536
+ * @returns {none}
537
+ * @description Deletes all child elements and attributes.
538
+ */
371
539
  clear(){
372
540
  TXmlElementController.clear(this);
373
541
  }
374
542
 
543
+ /**
544
+ * @param {object}
545
+ * @returns {?object}
546
+ * @protected
547
+ * @static
548
+ * @description Tries to unwraps a given object.
549
+ */
375
550
  static __unwrap(item){
376
551
  return (item instanceof TXmlElementController) ? item.#_host : null;
377
552
  }
378
553
 
554
+ /**
555
+ * @param {TXmlElementController}
556
+ * @param {ID_STRING}
557
+ * @param {object}
558
+ * @returns {bool}
559
+ * @protected
560
+ * @static
561
+ * @description Sets a child element.
562
+ */
379
563
  static __setChildRaw(node, name, obj){
380
564
  //console.log('CHECK: TXmlElementController.__setChildRaw() => was called...');
381
565
  let isSUCCEED = false;
@@ -398,6 +582,12 @@ class TXmlElementController {
398
582
  return isSUCCEED;
399
583
  }
400
584
 
585
+ /**
586
+ * @param {object}
587
+ * @returns {none}
588
+ * @static
589
+ * @description Tries to clean a given object.
590
+ */
401
591
  static clear(obj){
402
592
  let item = TXmlElementController.__unwrap(obj);
403
593
  if (item) {
@@ -410,11 +600,22 @@ class TXmlElementController {
410
600
 
411
601
  };
412
602
 
603
+ /**
604
+ * @description This class implements an instance of a list controller
605
+ */
413
606
  class TXmlElementsListController {
414
607
  #_host = null;
415
608
  #_options = null;
416
609
  #_count = null;
417
610
 
611
+ /**
612
+ * @param {array}
613
+ * @param {object} [opt]
614
+ * @param {object} [opt.parseOptions]
615
+ * @param {bool} [opt.proxyModeEnable=false]
616
+ * @param {bool} [opt.isNullItemsAllowed=false] - <reserved>
617
+ * @throws {TypeError}
618
+ */
418
619
  constructor(obj, opt){
419
620
  // load options
420
621
  let _options = isPlainObject(opt) ? opt : {};
@@ -450,39 +651,78 @@ class TXmlElementsListController {
450
651
  this.#_options = _options;
451
652
  }
452
653
 
654
+ /**
655
+ * @property {number}
656
+ * @readonly
657
+ */
453
658
  get count(){
454
659
  return this.#_host.length;
455
660
  }
456
661
 
662
+ /**
663
+ * @property {number}
664
+ * @readonly
665
+ */
457
666
  get size(){
458
667
  return this.#_host.length;
459
668
  }
460
669
 
670
+ /**
671
+ * @property {index}
672
+ * @readonly
673
+ */
461
674
  get maxIndex(){
462
675
  return this.#_host.length - 1;
463
676
  }
464
677
 
678
+ /**
679
+ * @property {bool}
680
+ * @readonly
681
+ */
465
682
  get isNullItemsAllowed(){
466
683
  return readAsBool(this.#_options.isNullItemsAllowed);
467
684
  }
468
685
 
686
+ /**
687
+ * @returns {none}
688
+ * @description Deletes all child elements and attributes.
689
+ */
469
690
  clear(){
470
691
  this.#_host.length = 0;
471
692
  }
472
693
 
694
+ /**
695
+ * @returns {bool}
696
+ * @description Checks whether an instance holds none element.
697
+ */
473
698
  isEmpty(){
474
699
  return this.count === 0;
475
700
  }
476
701
 
702
+ /**
703
+ * @returns {bool}
704
+ * @description Checks whether an instance holds at least one element.
705
+ */
477
706
  isNotEmpty(){
478
707
  return this.count > 0;
479
708
  }
480
709
 
710
+ /**
711
+ * @param {any}
712
+ * @returns {bool}
713
+ * @description Checks whether a given value is a valid index value
714
+ * and it is not exceeds an index range within the instance.
715
+ */
481
716
  chkIndex(value){
482
717
  const index = valueToIndex(value);
483
718
  return index !== -1 && index < this.size;
484
719
  }
485
720
 
721
+ /**
722
+ * @param {any}
723
+ * @returns {bool}
724
+ * @description Checks whether or not a given element is valid.
725
+ */
486
726
  isValidItem(obj){
487
727
  return (
488
728
  (this.#_options.isNullItemsAllowed && obj === null)
@@ -490,11 +730,22 @@ class TXmlElementsListController {
490
730
  );
491
731
  }
492
732
 
733
+ /**
734
+ * @param {index}
735
+ * @returns {?object}
736
+ * @protected
737
+ * @description Returns an element.
738
+ */
493
739
  _getItemRaw(index){
494
740
  let item = this.#_host[valueToIndex(index)];
495
741
  return item !== undefined ? item : null;
496
742
  }
497
743
 
744
+ /**
745
+ * @param {index}
746
+ * @returns {?TXmlElementController}
747
+ * @description Returns an element.
748
+ */
498
749
  getItem(index){
499
750
  let item = this.#_host[valueToIndex(index)];
500
751
  // wrap item in container
@@ -505,6 +756,12 @@ class TXmlElementsListController {
505
756
  );
506
757
  }
507
758
 
759
+ /**
760
+ * @param {any}
761
+ * @returns {index}
762
+ * @protected
763
+ * @description Adds a new element.
764
+ */
508
765
  _addItemRaw(item){
509
766
  let index = -1;
510
767
  if (this.isValidItem(item)) {
@@ -514,6 +771,11 @@ class TXmlElementsListController {
514
771
  return index;
515
772
  }
516
773
 
774
+ /**
775
+ * @param {any}
776
+ * @returns {index}
777
+ * @description Adds a new element.
778
+ */
517
779
  addItem(item){
518
780
  // unwrap item from container
519
781
  if (item instanceof TXmlElementController) {
@@ -522,12 +784,25 @@ class TXmlElementsListController {
522
784
  return this._addItemRaw(item);
523
785
  }
524
786
 
787
+ /**
788
+ * @param {index}
789
+ * @param {any}
790
+ * @returns {bool}
791
+ * @protected
792
+ * @description Sets a new element.
793
+ */
525
794
  _setItemRaw(index, item){
526
795
  let isSUCCEED = this.chkIndex(index) && this.isValidItem(item);
527
796
  if (isSUCCEED) this.#_host[Number(index)] = item; // // TODO: correct count
528
797
  return isSUCCEED;
529
798
  }
530
799
 
800
+ /**
801
+ * @param {index}
802
+ * @param {any}
803
+ * @returns {bool}
804
+ * @description Sets a new element.
805
+ */
531
806
  setItem(index, item){
532
807
  // unwrap item from container
533
808
  if (item instanceof TXmlElementController) {
@@ -536,6 +811,13 @@ class TXmlElementsListController {
536
811
  return this._setItemRaw(index, item);
537
812
  }
538
813
 
814
+ /**
815
+ * @param {index}
816
+ * @param {any}
817
+ * @returns {bool}
818
+ * @protected
819
+ * @description Insertes a new element.
820
+ */
539
821
  _insItemRaw(index, item){
540
822
  index = valueToIndex(index);
541
823
  let size = this.size;
@@ -556,6 +838,12 @@ class TXmlElementsListController {
556
838
  return isSUCCEED;
557
839
  }
558
840
 
841
+ /**
842
+ * @param {index}
843
+ * @param {any}
844
+ * @returns {bool}
845
+ * @description Insertes a new element.
846
+ */
559
847
  insItem(index, item){
560
848
  // unwrap item from container
561
849
  if (item instanceof TXmlElementController) {
@@ -564,6 +852,11 @@ class TXmlElementsListController {
564
852
  return this._insItemRaw(index, item);
565
853
  }
566
854
 
855
+ /**
856
+ * @param {index}
857
+ * @returns {bool}
858
+ * @description Deletes an element.
859
+ */
567
860
  delItem(value){
568
861
  let isSUCCEED = this.chkIndex(value);
569
862
  if (isSUCCEED) {
@@ -583,6 +876,13 @@ class TXmlElementsListController {
583
876
  return isSUCCEED;
584
877
  }
585
878
 
879
+ /**
880
+ * @param {any}
881
+ * @param {object} [opt]
882
+ * @param {bool} [opt.useClear=true]
883
+ * @returns {number}
884
+ * @description Loads a list of an elements.
885
+ */
586
886
  loadItems(items, opt){
587
887
  const _options = isPlainObject(opt) ? opt : {};
588
888
  let {
@@ -597,11 +897,21 @@ class TXmlElementsListController {
597
897
 
598
898
  };
599
899
 
900
+ /**
901
+ * @description This class implements an instance of an element
902
+ * that managea content of a document declaration
903
+ */
600
904
  class TXmlContentDeclaration {
601
905
  #_host = null;
602
906
  #_options = null;
603
907
  #_ctrls = null;
604
908
 
909
+ /**
910
+ * @param {object}
911
+ * @param {object} [opt]
912
+ * @param {object} [opt.parseOptions]
913
+ * @throws {TypeError}
914
+ */
605
915
  constructor(obj, opt){
606
916
  // check <obj>-param
607
917
  if (!isPlainObject(obj)) {
@@ -632,6 +942,9 @@ class TXmlContentDeclaration {
632
942
  this.init();
633
943
  }
634
944
 
945
+ /**
946
+ * @property {string}
947
+ */
635
948
  get version(){
636
949
  return this.#_ctrls.getAttribute('version');
637
950
  }
@@ -640,6 +953,9 @@ class TXmlContentDeclaration {
640
953
  this.#_ctrls.setAttribute('version', value);
641
954
  }
642
955
 
956
+ /**
957
+ * @property {string}
958
+ */
643
959
  get encoding(){
644
960
  return this.#_ctrls.getAttribute('encoding');
645
961
  }
@@ -648,6 +964,10 @@ class TXmlContentDeclaration {
648
964
  this.#_ctrls.setAttribute('encoding', value);
649
965
  }
650
966
 
967
+ /**
968
+ * @returns {bool}
969
+ * @description Initializes an instance content.
970
+ */
651
971
  init(){
652
972
  const _options = this.#_options;
653
973
  this.#_ctrls = new TXmlElementController(
@@ -664,10 +984,22 @@ class TXmlContentDeclaration {
664
984
 
665
985
  };
666
986
 
987
+ /**
988
+ * @augments TXmlElementController
989
+ * @description This class implements an instance of a root element
990
+ */
667
991
  class TXmlContentRootElement extends TXmlElementController {
668
992
  #_content = null;
669
993
  #_options = null;
670
994
 
995
+ /**
996
+ * @param {object}
997
+ * @param {object} [opt]
998
+ * @param {object} [opt.parseOptions]
999
+ * @param {ID_STRING} [opt.rootETagName='']
1000
+ * @param {bool} [opt.autoBindRoot=true]
1001
+ * @throws {TypeError}
1002
+ */
671
1003
  constructor(obj, opt){
672
1004
  // check <obj>-param
673
1005
  if (!isPlainObject(obj)) {
@@ -753,6 +1085,9 @@ class TXmlContentRootElement extends TXmlElementController {
753
1085
  //this.init(rootETagName);
754
1086
  }
755
1087
 
1088
+ /**
1089
+ * @property {string}
1090
+ */
756
1091
  get tagName(){
757
1092
  return this.#_options.rootETagName;
758
1093
  }
@@ -764,6 +1099,14 @@ class TXmlContentRootElement extends TXmlElementController {
764
1099
  ) ? value : XML_DEF_ROOT_ETAG_NAME;
765
1100
  }
766
1101
 
1102
+ /**
1103
+ * @param {object}
1104
+ * @param {bool} [opt=false]
1105
+ * @returns {?object}
1106
+ * @protected
1107
+ * @static
1108
+ * @description Tries to unwraps a given object.
1109
+ */
767
1110
  static __unwrap(item, opt){
768
1111
  return (
769
1112
  item instanceof TXmlContentRootElement
@@ -775,6 +1118,10 @@ class TXmlContentRootElement extends TXmlElementController {
775
1118
 
776
1119
  }
777
1120
 
1121
+ /**
1122
+ * @description This class implements an instance of a container
1123
+ * that managea content of a document
1124
+ */
778
1125
  class TXmlContentContainer {
779
1126
  #_content = null;
780
1127
  #_options = null;
@@ -782,6 +1129,10 @@ class TXmlContentContainer {
782
1129
  #_docDecl = null;
783
1130
  #_docRoot = null;
784
1131
 
1132
+ /**
1133
+ * @param {object} [opt]
1134
+ * @param {object} [opt.parseOptions]
1135
+ */
785
1136
  constructor(opt){
786
1137
  // load options
787
1138
  const _options = isPlainObject(opt) ? opt : {};
@@ -803,15 +1154,29 @@ class TXmlContentContainer {
803
1154
  this.#_docRoot = new TXmlContentRootElement(_content, _options);
804
1155
  }
805
1156
 
1157
+ /**
1158
+ * @property {TXmlContentRootElement}
1159
+ * @readonly
1160
+ */
806
1161
  get rootElement(){
807
1162
  return this.#_docRoot;
808
1163
  }
809
1164
 
1165
+ /**
1166
+ * @returns {none}
1167
+ * @description Cleans a document content.
1168
+ */
810
1169
  clear(){
811
1170
  this.#_docDecl.init();
812
1171
  this.rootElement.clear();
813
1172
  }
814
1173
 
1174
+ /**
1175
+ * @param {object}
1176
+ * @returns {bool}
1177
+ * @protected
1178
+ * @description Initializes an instance with a given content.
1179
+ */
815
1180
  _bindContent(obj, opt){
816
1181
  const _options = isPlainObject(opt) ? opt : this.#_options;
817
1182
  let isSUCCEED = false;
@@ -840,6 +1205,10 @@ class TXmlContentContainer {
840
1205
  return isSUCCEED;
841
1206
  }
842
1207
 
1208
+ /**
1209
+ * @returns {string}
1210
+ * @description Returns a document content as a string in an XML-format.
1211
+ */
843
1212
  saveToXMLString(){
844
1213
  let result = '';
845
1214
  try {
@@ -851,6 +1220,13 @@ class TXmlContentContainer {
851
1220
  return result;
852
1221
  }
853
1222
 
1223
+ /**
1224
+ * @param {string}
1225
+ * @returns {object}
1226
+ * @throws {Error}
1227
+ * @async
1228
+ * @description Saves a document content to a file.
1229
+ */
854
1230
  saveToFile(source){
855
1231
  /**/// main part that return promise as a result
856
1232
  return new Promise((resolve, reject) => {
@@ -874,26 +1250,26 @@ class TXmlContentContainer {
874
1250
  data.errEvent = 'OPS_IS_SUCCEED';
875
1251
  resolve(data);
876
1252
  }).catch(err => {
877
- switch (err.code) {
878
- case 'ENOENT': {
879
- data.isERR = true;
880
- data.errEvent = err.code;
881
- data.content = '';
882
- resolve(data);
883
- break;
884
- }
885
- default: {
886
- //console.log('CHECK: TXmlContentContainer.saveToFile() => Error => '+err);
887
- //console.log('CHECK: TXmlContentContainer.saveToFile() => Error => '+err.code);
888
- reject(err);
889
- break;
890
- }
1253
+ let { isSucceed } = checkFsError(data, err);
1254
+ if (isSucceed) {
1255
+ data.content = '';
1256
+ resolve(data);
1257
+ } else {
1258
+ //console.log('CHECK: TXmlContentContainer.saveToFile() => Error => '+err);
1259
+ //console.log('CHECK: TXmlContentContainer.saveToFile() => Error => '+err.code);
1260
+ reject(err);
891
1261
  };
892
1262
  });
893
1263
  };
894
1264
  });
895
1265
  }
896
1266
 
1267
+ /**
1268
+ * @param {string}
1269
+ * @returns {object}
1270
+ * @throws {Error}
1271
+ * @description Saves a document content to a file.
1272
+ */
897
1273
  saveToFileSync(source){
898
1274
  let data = {
899
1275
  isSucceed: false,
@@ -912,25 +1288,25 @@ class TXmlContentContainer {
912
1288
  data.content = this.saveToXMLString();
913
1289
  fs.writeFileSync(data.source, data.content, 'utf8');
914
1290
  } catch (err) {
915
- switch (err.code) {
916
- case 'ENOENT': {
917
- data.isERR = true;
918
- data.errEvent = err.code;
919
- data.content = '';
920
- break;
921
- }
922
- default: {
923
- //console.log('CHECK: TXmlContentContainer.saveToFileSync() => Error => '+err);
924
- //console.log('CHECK: TXmlContentContainer.saveToFileSync() => Error => '+err.code);
925
- throw err;
926
- break;
927
- }
1291
+ let { isSucceed } = checkFsError(data, err);
1292
+ if (isSucceed) {
1293
+ data.content = '';
1294
+ } else {
1295
+ //console.log('CHECK: TXmlContentContainer.saveToFileSync() => Error => '+err);
1296
+ //console.log('CHECK: TXmlContentContainer.saveToFileSync() => Error => '+err.code);
1297
+ throw err;
928
1298
  };
929
1299
  };
930
1300
  };
931
1301
  return data;
932
1302
  }
933
1303
 
1304
+ /**
1305
+ * @param {string}
1306
+ * @returns {bool}
1307
+ * @throws {Error}
1308
+ * @description Loads a document content from a string.
1309
+ */
934
1310
  loadFromXMLString(xmlString){
935
1311
  let isSUCCEED = false;
936
1312
  if (typeof xmlString === 'string') {
@@ -949,6 +1325,13 @@ class TXmlContentContainer {
949
1325
  return isSUCCEED;
950
1326
  }
951
1327
 
1328
+ /**
1329
+ * @param {string}
1330
+ * @returns {object}
1331
+ * @throws {Error}
1332
+ * @async
1333
+ * @description Loads a document content from a file.
1334
+ */
952
1335
  loadFromFile(source){
953
1336
  /**/// main part that return promise as a result
954
1337
  return new Promise((resolve, reject) => {
@@ -982,26 +1365,26 @@ class TXmlContentContainer {
982
1365
  };
983
1366
  resolve(data);
984
1367
  }).catch(err => {
985
- switch (err.code) {
986
- case 'ENOENT':
987
- case 'EISDIR': {
988
- data.isERR = true;
989
- data.errEvent = err.code;
990
- resolve(data);
991
- break;
992
- }
993
- default: {
994
- //console.log('CHECK: TXmlContentContainer.loadFromFile() => Error => '+err);
995
- //console.log('CHECK: TXmlContentContainer.loadFromFile() => Error => '+err.code);
996
- reject(err);
997
- break;
998
- }
1368
+ let { isSucceed } = checkFsError(data, err);
1369
+ if (isSucceed) {
1370
+ data.content = '';
1371
+ resolve(data);
1372
+ } else {
1373
+ //console.log('CHECK: TXmlContentContainer.loadFromFile() => Error => '+err);
1374
+ //console.log('CHECK: TXmlContentContainer.loadFromFile() => Error => '+err.code);
1375
+ reject(err);
999
1376
  };
1000
1377
  });
1001
1378
  };
1002
1379
  });
1003
1380
  }
1004
1381
 
1382
+ /**
1383
+ * @param {string}
1384
+ * @returns {object}
1385
+ * @throws {Error}
1386
+ * @description Loads a document content from a file.
1387
+ */
1005
1388
  loadFromFileSync(source){
1006
1389
  let data = {
1007
1390
  isLoaded: false,
@@ -1031,25 +1414,24 @@ class TXmlContentContainer {
1031
1414
  data.errEvent = 'NO_CONTENT';
1032
1415
  };
1033
1416
  } catch (err) {
1034
- switch (err.code) {
1035
- case 'ENOENT':
1036
- case 'EISDIR': {
1037
- data.isERR = true;
1038
- data.errEvent = err.code;
1039
- break;
1040
- }
1041
- default: {
1042
- //console.log('CHECK: TXmlContentContainer.loadFromFileSync() => Error => '+err);
1043
- //console.log('CHECK: TXmlContentContainer.loadFromFileSync() => Error => '+err.code);
1044
- throw err;
1045
- break;
1046
- }
1417
+ let { isSucceed } = checkFsError(data, err);
1418
+ if (isSucceed) {
1419
+ data.content = '';
1420
+ } else {
1421
+ //console.log('CHECK: TXmlContentContainer.loadFromFileSync() => Error => '+err);
1422
+ //console.log('CHECK: TXmlContentContainer.loadFromFileSync() => Error => '+err.code);
1423
+ throw err;
1047
1424
  };
1048
1425
  };
1049
1426
  };
1050
1427
  return data;
1051
1428
  }
1052
1429
 
1430
+ /**
1431
+ * @returns {string}
1432
+ * @protected
1433
+ * @description Returns a document content a string in a JSON-format.
1434
+ */
1053
1435
  asJSON(){
1054
1436
  return JSON.stringify(this.#_content, null, 2);
1055
1437
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cntwg/xml-lib-js",
3
- "version": "0.0.25",
3
+ "version": "0.0.26",
4
4
  "description": "A library for handling an XML-documents",
5
5
  "author": "ygracs <cs70th-om@rambler.ru>",
6
6
  "license": "MIT",
@@ -15,6 +15,7 @@
15
15
  "files": [
16
16
  "doc/xmldoc-lib.md",
17
17
  "lib/xmldoc-lib.js",
18
+ "lib/xml-helper.js",
18
19
  "index.js",
19
20
  "CHANGELOG.md"
20
21
  ],
@@ -26,18 +27,22 @@
26
27
  "test-xml:lc": "jest TXmlElementsListController",
27
28
  "test-xml:re": "jest TXmlContentRootElement",
28
29
  "test-xml:cdec": "jest TXmlContentDeclaration",
29
- "test-xml:cc": "jest TXmlContentContainer"
30
+ "test-xml:cc": "jest TXmlContentContainer",
31
+ "build-doc-md": "jsdoc2md",
32
+ "build-doc-html": "jsdoc"
30
33
  },
31
34
  "imports": {
32
- "#lib/*": "./lib/*"
35
+ "#lib/*": "./lib/*",
36
+ "#test-dir/*": "./__test__/*"
33
37
  },
34
38
  "dependencies": {
35
- "@ygracs/bsfoc-lib-js": "^0.2.0",
39
+ "@ygracs/bsfoc-lib-js": "^0.2.1",
36
40
  "@ygracs/xml-js6": "^0.0.3-b",
37
- "@ygracs/xobj-lib-js": "^0.1.1"
41
+ "@ygracs/xobj-lib-js": "^0.1.2"
38
42
  },
39
43
  "devDependencies": {
40
44
  "jest": "^29.7.0",
41
- "minimist": "^1.2.8"
45
+ "minimist": "^1.2.8",
46
+ "jsdoc-to-markdown": "^8.0.1"
42
47
  }
43
48
  }