@ygracs/xepg-lib-js 0.0.18 → 0.0.20

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.
@@ -1,4 +1,4 @@
1
- // [v0.1.056-20240717]
1
+ // [v0.1.077-20241028]
2
2
 
3
3
  // === module init block ===
4
4
 
@@ -22,6 +22,12 @@ const {
22
22
  convStringToDTValue, convDTValueToString,
23
23
  } = require('./dts-helper.js');
24
24
 
25
+ const {
26
+ checkFsError,
27
+ loadFileSync, loadFile,
28
+ saveToFileSync, saveToFile,
29
+ } = require('./file-helper.js');
30
+
25
31
  const xObj = require('@ygracs/xobj-lib-js');
26
32
 
27
33
  const TXmlContentParseOptions = xObj.TXmlContentParseOptions;
@@ -72,34 +78,6 @@ function writeXEpgDocDeclSection(obj, opt){
72
78
  };
73
79
  };
74
80
 
75
- /**
76
- * @function checkFsError
77
- * @param {object}
78
- * @param {Error}
79
- * @returns {object}
80
- * @inner
81
- * @description Checs an error code of a fs ops and sets descr info if succeed
82
- */
83
- function checkFsError(descr, err) {
84
- let isSucceed = false;
85
- if (isPlainObject(err) && isPlainObject(descr)) {
86
- switch (err.code) {
87
- case 'ENOENT':
88
- case 'EISDIR':
89
- case 'EPERM': {
90
- descr.errCode = err.errno;
91
- descr.errEvent = err.code;
92
- descr.errMsg = `ERR_FILE_${err.code}`;
93
- isSucceed = true;
94
- break;
95
- }
96
- default: {}
97
- };
98
- if (isSucceed) descr.isERR = true;
99
- };
100
- return { isSucceed, descr };
101
- };
102
-
103
81
  // === module main block ===
104
82
 
105
83
  /***
@@ -165,7 +143,7 @@ const defParseOptions = new TXmlContentParseOptions();
165
143
  */
166
144
 
167
145
  /**
168
- * @description This class implements an instance of a EPG-schedules list
146
+ * @classdesc This class implements an instance of a EPG-schedules list
169
147
  */
170
148
  class TXEpgSchedulesList {
171
149
  #_content = null;
@@ -173,6 +151,13 @@ class TXEpgSchedulesList {
173
151
  #_dts_src = null;
174
152
  #_tz_src = null;
175
153
 
154
+ /**
155
+ * @param {any[]} obj
156
+ * @param {object} [opt]
157
+ * @param {?object} [opt.dts_src]
158
+ * @param {?object} [opt.tz_src]
159
+ * @description Creates an instance of the schedules list
160
+ */
176
161
  constructor(obj, opt) {
177
162
  const _content = isArray(obj) ? obj : [];
178
163
  const _options = isPlainObject(opt) ? opt : {};
@@ -188,12 +173,22 @@ class TXEpgSchedulesList {
188
173
  this.#_tz_src = tz_src;
189
174
  }
190
175
 
176
+ /**
177
+ * @param {(number|string)} value
178
+ * @returns {void}
179
+ * @private
180
+ */
191
181
  #_getItem = function(value){
192
- if (this.chkScheduleIndex(value)) {
182
+ if (this.chkIndex(value)) {
193
183
  return this.#_content[Number(value)];
194
184
  };
195
185
  };
196
186
 
187
+ /**
188
+ * @property {number}
189
+ * @readonly
190
+ * @description Contains a quantity of a schedules
191
+ */
197
192
  get schedQty(){
198
193
  return this.#_content.length;
199
194
  }
@@ -201,6 +196,11 @@ class TXEpgSchedulesList {
201
196
  // will deprecate
202
197
  //get SchedulesQty(){ return this.#_content.length; }
203
198
 
199
+ /**
200
+ * @property {number}
201
+ * @readonly
202
+ * @description Contains a dtstype ID
203
+ */
204
204
  get dtstype(){
205
205
  let result = valueToIndex(
206
206
  _getXmlChildElementParam(this.#_dts_src, 'value')
@@ -208,6 +208,11 @@ class TXEpgSchedulesList {
208
208
  return chkDTSysID(result) ? result : 0; //-1; // // TODO: [?]
209
209
  }
210
210
 
211
+ /**
212
+ * @property {number}
213
+ * @readonly
214
+ * @description Contains a TZ-offset
215
+ */
211
216
  get curDocTZ(){
212
217
  return (
213
218
  this.#_tz_src
@@ -216,19 +221,51 @@ class TXEpgSchedulesList {
216
221
  );
217
222
  }
218
223
 
224
+ /**
225
+ * @returns {boolean}
226
+ * @description Indicates whether an instance has none member
227
+ */
219
228
  hasNoSchedules(){
220
229
  return this.schedQty === 0;
221
230
  }
222
231
 
232
+ /**
233
+ * @returns {boolean}
234
+ * @description Indicates whether an instance has any member
235
+ */
223
236
  hasSchedules(){
224
237
  return this.schedQty > 0;
225
238
  }
226
239
 
227
- chkScheduleIndex(value){
240
+ /**
241
+ * @param {(number|string)} value
242
+ * @returns {boolean}
243
+ * @deprecated
244
+ * @description Checks whether a given value is a valid index
245
+ * and it fits the index range of an instance
246
+ */
247
+ chkScheduleIndex(value) {
248
+ return this.chkIndex(value);
249
+ }
250
+
251
+ /**
252
+ * @param {(number|string)} value
253
+ * @returns {boolean}
254
+ * @since 0.0.18
255
+ * @description Checks whether a given value is a valid index
256
+ * and it fits the index range of an instance
257
+ */
258
+ chkIndex(value) {
228
259
  const index = valueToIndex(value);
229
260
  return index !== -1 && index < this.schedQty;
230
261
  }
231
262
 
263
+ /**
264
+ * @param {(number|string)} index
265
+ * @returns {object}
266
+ * @description Returns a schedule info item for instance element
267
+ * addressed by a given index
268
+ */
232
269
  getScheduleInfo(index){
233
270
  //console.log('TXEpgSchedulesList => getScheduleInfo() => was called...');
234
271
  const curObj = this.#_getItem(index);
@@ -257,6 +294,10 @@ class TXEpgSchedulesList {
257
294
  return tmpObj;
258
295
  }
259
296
 
297
+ /**
298
+ * @returns {object[]}
299
+ * @description Returns a schedule info for instance members
300
+ */
260
301
  getAllSchedulesInfo(){
261
302
  let result = [];
262
303
  for (let i = 0; i < this.schedQty; i++) {
@@ -273,15 +314,26 @@ class TXEpgSchedulesList {
273
314
  };
274
315
 
275
316
  /**
276
- * @description This class implements an instance of a EPG-provider element
317
+ * @classdesc This class implements an instance of a EPG-provider element
277
318
  */
278
319
  class TXEpgProviderContainer {
279
- #_content = null;
280
- #_options = null;
320
+ /** @property {Object} */
321
+ #_host;// = null;
322
+ /** @property {Object} */
323
+ #_options;// = null;
324
+ /** @property {?TXmlContentParseOptions} */
325
+ #_parseOptions;// = null;
326
+ /** @property {?TXepgDTSProvider} */
281
327
 
328
+ /**
329
+ * @param {object} obj
330
+ * @param {object} [opt]
331
+ * @param {object} [opt.parseOptions]
332
+ * @description Creates an instance of the EPG-provider element
333
+ */
282
334
  constructor(obj, opt) {
283
335
  // load content
284
- const _content = isPlainObject(obj) ? obj : {};
336
+ const _host = isPlainObject(obj) ? obj : {};
285
337
  // load options
286
338
  const _options = isPlainObject(opt) ? opt : {};
287
339
  let {
@@ -291,10 +343,12 @@ class TXEpgProviderContainer {
291
343
  parseOptions = new TXmlContentParseOptions(parseOptions);
292
344
  _options.parseOptions = parseOptions;
293
345
  };
294
- // save content source
295
- this.#_content = _content;
296
346
  // save options
297
347
  this.#_options = _options;
348
+ // save parser options
349
+ this.#_parseOptions = parseOptions;
350
+ // save content source
351
+ this.#_host = _host;
298
352
  // init instance
299
353
  this.#_init();
300
354
  }
@@ -311,69 +365,95 @@ class TXEpgProviderContainer {
311
365
  //_options.docTypeETagName = docTypeETagName;
312
366
  }
313
367
 
314
- get name(){
315
- return _getXmlChildElementParam(this.#_content, 'name').trim();
368
+ /**
369
+ * @property {string}
370
+ * @description Contains a provider name
371
+ */
372
+ get name() {
373
+ return _getXmlChildElementParam(this.#_host, 'name').trim();
316
374
  }
317
375
 
318
- set name(value){
376
+ set name(value) {
319
377
  this.setName(value);
320
378
  }
321
379
 
322
- get version(){
323
- return _getXmlChildElementParam(this.#_content, 'version').trim();
380
+ /**
381
+ * @property {string}
382
+ * @description Contains a version of a provider
383
+ */
384
+ get version() {
385
+ return _getXmlChildElementParam(this.#_host, 'version').trim();
324
386
  }
325
387
 
326
- set version(value){
327
- if (this.name !== '') {
328
- const _value = typeof value === 'string' ? value.trim() : '';
329
- const item = insertXObjElement(
330
- this.#_content,
331
- 'version',
332
- { force: true },
333
- );
334
- if (item) writeXObjParam(item, _value);
388
+ set version(value) {
389
+ if (typeof value === 'string' && this.name !== '') {
390
+ const opt = { force: true };
391
+ const item = insertXObjElement(this.#_host, 'version', opt);
392
+ if (item) writeXObjParam(item, value.trim());
335
393
  };
336
394
  }
337
395
 
338
- get schema(){
339
- return _getXmlChildElementParam(this.#_content, XEPG_DOCSCH_ETAG_NAME).trim();
396
+ /**
397
+ * @property {string}
398
+ * @description Contains a version of a document schema
399
+ */
400
+ get schema() {
401
+ return _getXmlChildElementParam(this.#_host, XEPG_DOCSCH_ETAG_NAME).trim();
340
402
  }
341
403
 
342
- set schema(value){
343
- const _value = typeof value === 'string' ? value.trim() : '';
344
- const item = insertXObjElement(
345
- this.#_content,
346
- XEPG_DOCSCH_ETAG_NAME,
347
- { force: true },
348
- );
349
- if (item) writeXObjParam(item, _value);
404
+ set schema(value) {
405
+ if (typeof value === 'string') {
406
+ const opt = { force: true };
407
+ const item = insertXObjElement(this.#_host, XEPG_DOCSCH_ETAG_NAME, opt);
408
+ if (item) writeXObjParam(item, value.trim());
409
+ };
350
410
  }
351
411
 
352
- get doctype(){
353
- return _getXmlChildElementParam(this.#_content, XEPG_DOCTYP_ETAG_NAME).trim();
412
+ /**
413
+ * @property {string}
414
+ * @description Contains a document type
415
+ */
416
+ get doctype() {
417
+ return _getXmlChildElementParam(this.#_host, XEPG_DOCTYP_ETAG_NAME).trim();
354
418
  }
355
419
 
356
- set doctype(value){
357
- const _value = typeof value === 'string' ? value.trim() : '';
358
- const item = insertXObjElement(
359
- this.#_content,
360
- XEPG_DOCTYP_ETAG_NAME,
361
- { force: true },
362
- );
363
- if (item) writeXObjParam(item, _value);
420
+ set doctype(value) {
421
+ if (typeof value === 'string') {
422
+ const opt = { force: true };
423
+ const item = insertXObjElement(this.#_host, XEPG_DOCTYP_ETAG_NAME, opt);
424
+ if (item) writeXObjParam(item, value.trim());
425
+ };
364
426
  }
365
427
 
366
- setName(value){
367
- let isSUCCEED = false;
368
- let item = insertXObjElement(this.#_content, 'name', { force: true });
369
- if (item) {
370
- const name = typeof value === 'string' ? value.trim() : '';
371
- isSUCCEED = writeXObjParam(item, name);
428
+ /**
429
+ * @param {string} value - provider name
430
+ * @returns {boolean}
431
+ * @description Sets a provider name
432
+ */
433
+ setName(value) {
434
+ let isSucceed = false;
435
+ if (typeof value === 'string') {
436
+ const name = value.trim();
437
+ const item = insertXObjElement(this.#_host, 'name', { force: true });
438
+ if (item) isSucceed = writeXObjParam(item, name);
372
439
  };
373
- return isSUCCEED;
440
+ return isSucceed;
374
441
  }
375
442
 
376
- getInfo(){
443
+ /**
444
+ * @typedef {Object} xepgProvInfoDesc
445
+ * @property {string} name - provider name
446
+ * @property {string} version - provider version
447
+ * @property {string} schema - document schema
448
+ * @property {string} doctype - document type
449
+ * @description Contains a provider description
450
+ */
451
+
452
+ /**
453
+ * @returns {xepgProvInfoDesc}
454
+ * @description Returns a provider info item
455
+ */
456
+ getInfo() {
377
457
  return {
378
458
  name: this.name,
379
459
  version: this.version,
@@ -382,6 +462,11 @@ class TXEpgProviderContainer {
382
462
  };
383
463
  }
384
464
 
465
+ /**
466
+ * @param {object} obj
467
+ * @returns {void}
468
+ * @description Sets a provider info
469
+ */
385
470
  setInfo(obj){
386
471
  if (!isObject(obj)) return;
387
472
  let name = '';
@@ -411,6 +496,11 @@ class TXEpgProviderContainer {
411
496
  this.doctype = doctype;
412
497
  }
413
498
 
499
+ /**
500
+ * @param {object|string[]} opt
501
+ * @returns {void}
502
+ * @description Sets an initial instance state
503
+ */
414
504
  init(opt){
415
505
  let prov_opt = { ...defXEpgDocOptions.defProviderParam };
416
506
  let name = '';
@@ -433,15 +523,42 @@ class TXEpgProviderContainer {
433
523
  this.doctype = doctype;
434
524
  }
435
525
 
526
+ /**
527
+ * @returns {string}
528
+ * @since v0.0.20
529
+ * @description Returns an instance content as a string in an XML-format.
530
+ */
531
+ saveToXMLString() {
532
+ const options = this.#_parseOptions.js2xml;
533
+ options.ignoreDocType = true;
534
+ options.ignoreDeclaration = true;
535
+ const content = { [`${XEPG_PRVINFO_ETAG_NAME}`]: this.#_host };
536
+ let result = '';
537
+ try {
538
+ result = xmlParser.js2xml(content, options);
539
+ } catch (err) {
540
+ //console.log('CHECK: TXEpgHeaderContainer.saveToXMLString() => Error => '+err);
541
+ result = '';
542
+ //throw err;
543
+ };
544
+ return result;
545
+ }
546
+
436
547
  };
437
548
 
438
549
  /**
439
- * @description This class implements an instance of a DTS-provider element
550
+ * @classdesc This class implements an instance of a DTS-provider element
440
551
  */
441
552
  class TXepgDTSProvider {
442
553
  #_content = null;
443
554
  #_options = null;
444
555
 
556
+ /**
557
+ * @param {object} obj
558
+ * @param {object} [opt]
559
+ * @param {object} [opt.parseOptions]
560
+ * @description Creates an instance of the DTS-provider element
561
+ */
445
562
  constructor(obj, opt) {
446
563
  // load content
447
564
  const _content = isPlainObject(obj) ? obj : {};
@@ -462,10 +579,18 @@ class TXepgDTSProvider {
462
579
  this.#_init();
463
580
  }
464
581
 
582
+ /**
583
+ * @returns {void}
584
+ * @private
585
+ */
465
586
  #_init(){
466
587
  insertXObjElement(this.#_content, XEPG_DTSINFO_ETAG_NAME);
467
588
  }
468
589
 
590
+ /**
591
+ * @property {number}
592
+ * @description Contains a dtstype ID
593
+ */
469
594
  get dtstype(){
470
595
  const item = getXObjElement(this.#_content, XEPG_DTSINFO_ETAG_NAME);
471
596
  let result = 0; //-1; // // TODO: [?]
@@ -497,10 +622,15 @@ class TXepgDTSProvider {
497
622
  };
498
623
  }
499
624
 
625
+ /**
626
+ * @property {number}
627
+ * @description Contains a TZ-offset
628
+ */
500
629
  get curDocTZ(){
501
- return convTZStringToValue(
630
+ const tz = convTZStringToValue(
502
631
  _getXmlChildElementParam(this.#_content, XEPG_DOCTZ_ETAG_NAME)
503
632
  );
633
+ return Number.isNaN(tz) ? 0 : tz;
504
634
  }
505
635
 
506
636
  set curDocTZ(value){
@@ -518,18 +648,29 @@ class TXepgDTSProvider {
518
648
  };
519
649
 
520
650
  /**
521
- * @description This class implements an instance of a EPG-header element
651
+ * @classdesc This class implements an instance of a EPG-header element
522
652
  */
523
653
  class TXEpgHeaderContainer {
524
- #_content = null;
525
- #_options = null;
526
- #_dtsProv = null;
654
+ /** @property {Object} */
655
+ #_host;// = null;
656
+ /** @property {Object} */
657
+ #_options;// = null;
658
+ /** @property {?TXmlContentParseOptions} */
659
+ #_parseOptions;// = null;
660
+ /** @property {?TXepgDTSProvider} */
661
+ #_dtsProv;// = null;
527
662
 
663
+ /**
664
+ * @param {object} obj
665
+ * @param {object} [opt]
666
+ * @param {object} [opt.parseOptions]
667
+ * @description Creates an instance of the EPG-header element
668
+ */
528
669
  constructor(obj, opt) {
529
670
  // load content
530
- const _content = isPlainObject(obj) ? obj : {};
671
+ const _host = isPlainObject(obj) ? obj : {};
531
672
  // load options
532
- let _options = isPlainObject(opt) ? opt : {};
673
+ const _options = isPlainObject(opt) ? opt : {};
533
674
  let {
534
675
  parseOptions,
535
676
  } = _options;
@@ -537,18 +678,29 @@ class TXEpgHeaderContainer {
537
678
  parseOptions = new TXmlContentParseOptions(parseOptions);
538
679
  _options.parseOptions = parseOptions;
539
680
  };
540
- // save content source
541
- this.#_content = _content;
542
681
  // save options
543
682
  this.#_options = _options;
683
+ // save parser options
684
+ this.#_parseOptions = parseOptions;
685
+ // save content source
686
+ this.#_host = _host;
544
687
  // init DTS-provider
545
- this.#_dtsProv = new TXepgDTSProvider(this.#_content, _options);
688
+ this.#_dtsProv = new TXepgDTSProvider(_host, _options);
546
689
  }
547
690
 
691
+ /**
692
+ * @property {TXepgDTSProvider}
693
+ * @readonly
694
+ * @description Returns a `TXepgDTSProvider` instance
695
+ */
548
696
  get dts(){
549
697
  return this.#_dtsProv;
550
698
  }
551
699
 
700
+ /**
701
+ * @property {number}
702
+ * @description Contains a dtstype ID
703
+ */
552
704
  get dtstype(){
553
705
  return this.#_dtsProv.dtstype;
554
706
  }
@@ -557,6 +709,10 @@ class TXEpgHeaderContainer {
557
709
  this.#_dtsProv.dtstype = value;
558
710
  }
559
711
 
712
+ /**
713
+ * @property {number}
714
+ * @description Contains a TZ-offset
715
+ */
560
716
  get curDocTZ(){
561
717
  return this.#_dtsProv.curDocTZ;
562
718
  }
@@ -565,20 +721,33 @@ class TXEpgHeaderContainer {
565
721
  this.#_dtsProv.curDocTZ = value;
566
722
  }
567
723
 
568
- #_getProv(){
569
- const docProv = getXObjElement(this.#_content, XEPG_PRVINFO_ETAG_NAME);
724
+ /**
725
+ * @returns {?object}
726
+ * @private
727
+ */
728
+ #_getProv() {
729
+ const docProv = getXObjElement(this.#_host, XEPG_PRVINFO_ETAG_NAME);
570
730
  return isPlainObject(docProv) ? docProv : null;
571
731
  }
572
732
 
573
- #_initProv(){
574
- const _content = this.#_content;
575
- let docProv = getXObjElement(_content, XEPG_PRVINFO_ETAG_NAME);
733
+ /**
734
+ * @returns {?object}
735
+ * @private
736
+ */
737
+ #_initProv() {
738
+ const _host = this.#_host;
739
+ let docProv = getXObjElement(_host, XEPG_PRVINFO_ETAG_NAME);
576
740
  if (!docProv) {
577
- docProv = insertXObjElement(_content, XEPG_PRVINFO_ETAG_NAME);
741
+ docProv = insertXObjElement(_host, XEPG_PRVINFO_ETAG_NAME);
578
742
  };
579
743
  return isPlainObject(docProv) ? docProv : null;
580
744
  }
581
745
 
746
+ /**
747
+ * @property {?TXEpgProviderContainer}
748
+ * @readonly
749
+ * @description Returns a `TXEpgProviderContainer` instance
750
+ */
582
751
  get Provider(){
583
752
  const docProv = this.#_getProv();
584
753
  return (
@@ -588,8 +757,12 @@ class TXEpgHeaderContainer {
588
757
  );
589
758
  }
590
759
 
591
- getDocumentDT(){
592
- let dt_str = _getXmlChildElementParam(this.#_content, XEPG_DOCDTO_ETAG_NAME).trim();
760
+ /**
761
+ * @returns {number}
762
+ * @description Returns a document creation date as a timestamp
763
+ */
764
+ getDocumentDT() {
765
+ let dt_str = _getXmlChildElementParam(this.#_host, XEPG_DOCDTO_ETAG_NAME).trim();
593
766
  return (
594
767
  dt_str !== ''
595
768
  ? convStringToDTValue(dt_str, this.dtstype, this.curDocTZ)
@@ -597,18 +770,26 @@ class TXEpgHeaderContainer {
597
770
  );
598
771
  }
599
772
 
600
- setDocumentDT(){
773
+ /**
774
+ * @returns {void}
775
+ * @description Sets a document creation date to a current system time
776
+ */
777
+ setDocumentDT() {
601
778
  let dt_str = convDTValueToString(Date.now(), this.dtstype, this.curDocTZ);
602
779
  let item = insertXObjElement(
603
- this.#_content,
780
+ this.#_host,
604
781
  XEPG_DOCDTO_ETAG_NAME,
605
782
  { force: true },
606
783
  );
607
784
  if (item) writeXObjParam(item, dt_str);
608
785
  }
609
786
 
610
- getDocumentEDT(){
611
- let dt_str = _getXmlChildElementParam(this.#_content, XEPG_DOCDTE_ETAG_NAME).trim();
787
+ /**
788
+ * @returns {number}
789
+ * @description Returns a document expire date as a timestamp
790
+ */
791
+ getDocumentEDT() {
792
+ let dt_str = _getXmlChildElementParam(this.#_host, XEPG_DOCDTE_ETAG_NAME).trim();
612
793
  return (
613
794
  dt_str !== ''
614
795
  ? convStringToDTValue(dt_str, this.dtstype, this.curDocTZ)
@@ -616,28 +797,52 @@ class TXEpgHeaderContainer {
616
797
  );
617
798
  }
618
799
 
619
- setDocumentEDT(value){
800
+ /**
801
+ * @param {any} value
802
+ * @returns {void}
803
+ * @description Sets a document expire date to a given time
804
+ */
805
+ setDocumentEDT(value) {
620
806
  // TODO: check if value is a DateTime-string
621
807
  let dt_str = convDTValueToString(value, this.dtstype, this.curDocTZ);
622
808
  let item = insertXObjElement(
623
- this.#_content,
809
+ this.#_host,
624
810
  XEPG_DOCDTE_ETAG_NAME,
625
811
  { force: true },
626
812
  );
627
813
  if (item) writeXObjParam(item, dt_str);
628
814
  }
629
815
 
630
- getChannelInfo(){
631
- const _content = this.#_content;
816
+ /**
817
+ * @typedef {Object} xepgChnInfoDesc
818
+ * @property {string} chnid - channel ID
819
+ * @property {string} chngid - channel 'Group ID'
820
+ * @property {string} chname - channel name
821
+ * @property {string} srcurl - EPG-source URL
822
+ * @description Contains a channel description
823
+ */
824
+
825
+ /**
826
+ * @returns {xepgChnInfoDesc}
827
+ * @description Returns a channel info
828
+ */
829
+ getChannelInfo() {
830
+ const _host = this.#_host;
831
+ /** @type {xepgChnInfoDesc} */
632
832
  let item = {
633
- chnid: _getXmlChildElementParam(_content, XEPG_CHNID_ETAG_NAME).trim(),
634
- chname: _getXmlChildElementParam(_content, XEPG_CHNNAME_ETAG_NAME).trim(),
635
- chngid: _getXmlChildElementParam(_content, XEPG_CHNGID_ETAG_NAME).trim(),
636
- srcurl: _getXmlChildElementParam(_content, XEPG_CHNURL_ETAG_NAME).trim(),
833
+ chnid: _getXmlChildElementParam(_host, XEPG_CHNID_ETAG_NAME).trim(),
834
+ chname: _getXmlChildElementParam(_host, XEPG_CHNNAME_ETAG_NAME).trim(),
835
+ chngid: _getXmlChildElementParam(_host, XEPG_CHNGID_ETAG_NAME).trim(),
836
+ srcurl: _getXmlChildElementParam(_host, XEPG_CHNURL_ETAG_NAME).trim(),
637
837
  };
638
838
  return item;
639
839
  }
640
840
 
841
+ /**
842
+ * @param {object} obj
843
+ * @returns {void}
844
+ * @description Sets a channel info
845
+ */
641
846
  setChannelInfo(obj){
642
847
  let chnid = '';
643
848
  let chname = '';
@@ -671,22 +876,31 @@ class TXEpgHeaderContainer {
671
876
  srcurl = typeof srcurl === 'string' ? srcurl.trim() : '';
672
877
  };
673
878
  let item = null;
674
- const _content = this.#_content;
675
- item = insertXObjElement(_content, XEPG_CHNID_ETAG_NAME, { force: true });
879
+ const _host = this.#_host;
880
+ item = insertXObjElement(_host, XEPG_CHNID_ETAG_NAME, { force: true });
676
881
  if (item) writeXObjParam(item, chnid);
677
- item = insertXObjElement(_content, XEPG_CHNNAME_ETAG_NAME, { force: true });
882
+ item = insertXObjElement(_host, XEPG_CHNNAME_ETAG_NAME, { force: true });
678
883
  if (item) writeXObjParam(item, chname);
679
- item = insertXObjElement(_content, XEPG_CHNGID_ETAG_NAME, { force: true });
884
+ item = insertXObjElement(_host, XEPG_CHNGID_ETAG_NAME, { force: true });
680
885
  if (item) writeXObjParam(item, chngid);
681
- item = insertXObjElement(_content, XEPG_CHNURL_ETAG_NAME, { force: true });
886
+ item = insertXObjElement(_host, XEPG_CHNURL_ETAG_NAME, { force: true });
682
887
  if (item) writeXObjParam(item, srcurl);
683
888
  }
684
889
 
890
+ /**
891
+ * @returns {?object}
892
+ * @description Returns a provider info
893
+ */
685
894
  getProviderInfo(){
686
895
  const docProv = this.Provider;
687
896
  return docProv ? docProv.getInfo() : null;
688
897
  }
689
898
 
899
+ /**
900
+ * @param {object} obj
901
+ * @returns {void}
902
+ * @description Sets a provider info
903
+ */
690
904
  setProviderInfo(obj){
691
905
  if (isArray(obj) || isObject(obj)) {
692
906
  let docProv = this.Provider;
@@ -698,17 +912,47 @@ class TXEpgHeaderContainer {
698
912
  };
699
913
  }
700
914
 
915
+ /**
916
+ * @returns {string}
917
+ * @since v0.0.20
918
+ * @description Returns an instance content as a string in an XML-format.
919
+ */
920
+ saveToXMLString() {
921
+ const options = this.#_parseOptions.js2xml;
922
+ options.ignoreDocType = true;
923
+ options.ignoreDeclaration = true;
924
+ const content = { [`${XEPG_HEADER_ETAG_NAME}`]: this.#_host };
925
+ let result = '';
926
+ try {
927
+ result = xmlParser.js2xml(content, options);
928
+ } catch (err) {
929
+ //console.log('CHECK: TXEpgHeaderContainer.saveToXMLString() => Error => '+err);
930
+ result = '';
931
+ //throw err;
932
+ };
933
+ return result;
934
+ }
935
+
701
936
  };
702
937
 
703
938
  /**
704
- * @description This class implements an instance of a container
705
- * that managea content of a document
939
+ * @classdesc This class implements an interface of the container
940
+ * that manages a content of a XEPG-document
706
941
  */
707
942
  class TXEpgContentProvider {
708
- #_content = null;
709
- #_options = null;
710
- #_parseOptions = null;
943
+ /** @property {Object} */
944
+ #_content;// = null;
945
+ /** @property {Object} */
946
+ #_options;// = null;
947
+ /** @property {?TXmlContentParseOptions} */
948
+ #_parseOptions;// = null;
711
949
 
950
+ /**
951
+ * @param {object} [opt]
952
+ * @param {object} [opt.parseOptions]
953
+ * @param {boolean} [opt.autoBindRoot] - <*reserved*> ([?] - deprecate)
954
+ * @description Creates an instance of the XEPG-content provider
955
+ */
712
956
  constructor(opt) {
713
957
  // load options
714
958
  const _options = isPlainObject(opt) ? opt : {};
@@ -731,11 +975,19 @@ class TXEpgContentProvider {
731
975
  this.init();
732
976
  }
733
977
 
734
- #_getRoot(){
978
+ /**
979
+ * @returns {?Object}
980
+ * @private
981
+ */
982
+ #_getRoot() {
735
983
  const docRoot = getXObjElement(this.#_content, XEPG_ROOT_ETAG_NAME);
736
984
  return isPlainObject(docRoot) ? docRoot : null;
737
985
  }
738
986
 
987
+ /**
988
+ * @returns {?object}
989
+ * @private
990
+ */
739
991
  #_initRoot(){
740
992
  const _content = this.#_content;
741
993
  let docRoot = getXObjElement(_content, XEPG_ROOT_ETAG_NAME);
@@ -748,7 +1000,11 @@ class TXEpgContentProvider {
748
1000
  return isPlainObject(docRoot) ? docRoot : null;
749
1001
  }
750
1002
 
751
- #_getHdr(){
1003
+ /**
1004
+ * @returns {?Object}
1005
+ * @private
1006
+ */
1007
+ #_getHdr() {
752
1008
  const docRoot = this.#_getRoot();
753
1009
  let docHdr = null;
754
1010
  if (docRoot) {
@@ -757,6 +1013,10 @@ class TXEpgContentProvider {
757
1013
  return isPlainObject(docHdr) ? docHdr : null;
758
1014
  }
759
1015
 
1016
+ /**
1017
+ * @returns {?object}
1018
+ * @private
1019
+ */
760
1020
  #_initHdr(){
761
1021
  let docHdr = this.#_getHdr();
762
1022
  if (!docHdr) {
@@ -769,7 +1029,11 @@ class TXEpgContentProvider {
769
1029
  return isPlainObject(docHdr) ? docHdr : null;
770
1030
  }
771
1031
 
772
- #_getBody(){
1032
+ /**
1033
+ * @returns {?Object}
1034
+ * @private
1035
+ */
1036
+ #_getBody() {
773
1037
  const docRoot = this.#_getRoot();
774
1038
  let docBody = null;
775
1039
  if (docRoot) {
@@ -778,6 +1042,10 @@ class TXEpgContentProvider {
778
1042
  return isPlainObject(docBody) ? docBody : null;
779
1043
  }
780
1044
 
1045
+ /**
1046
+ * @returns {?object}
1047
+ * @private
1048
+ */
781
1049
  #_initBody(){
782
1050
  let docBody = this.#_getBody();
783
1051
  if (!docBody) {
@@ -790,7 +1058,12 @@ class TXEpgContentProvider {
790
1058
  return isPlainObject(docBody) ? docBody : null;
791
1059
  }
792
1060
 
793
- get Header(){
1061
+ /**
1062
+ * @property {?TXEpgHeaderContainer}
1063
+ * @readonly
1064
+ * @description Returns a `TXEpgHeaderContainer` instance
1065
+ */
1066
+ get Header() {
794
1067
  const docHdr = this.#_getHdr();
795
1068
  return (
796
1069
  docHdr
@@ -799,20 +1072,37 @@ class TXEpgContentProvider {
799
1072
  );
800
1073
  }
801
1074
 
1075
+ /**
1076
+ * @property {?TXEpgProviderContainer}
1077
+ * @readonly
1078
+ * @description Returns a `TXEpgProviderContainer` instance
1079
+ */
802
1080
  get Provider(){
803
1081
  const docHdr = this.Header;
804
1082
  return docHdr ? docHdr.Provider : null;
805
1083
  }
806
1084
 
1085
+ /**
1086
+ * @property {?TXepgDTSProvider}
1087
+ * @readonly
1088
+ * @description Returns a `TXepgDTSProvider` instance
1089
+ */
807
1090
  get dts(){
808
1091
  const docHdr = this.Header;
809
1092
  return docHdr ? docHdr.dts : null;
810
1093
  }
811
1094
 
812
1095
  /* [!] a temporary special method */
813
- /* will deprecate */
1096
+ /**
1097
+ * @deprecated
1098
+ */
814
1099
  get Content(){ return this; }
815
1100
 
1101
+ /**
1102
+ * @property {TXEpgSchedulesList}
1103
+ * @readonly
1104
+ * @description Returns a `TXEpgSchedulesList` instance
1105
+ */
816
1106
  get SchedulesList(){
817
1107
  const _options = this.#_options;
818
1108
  const docBody = this.#_getBody();
@@ -828,6 +1118,9 @@ class TXEpgContentProvider {
828
1118
  };
829
1119
  }
830
1120
 
1121
+ /**
1122
+ * @returns {void}
1123
+ */
831
1124
  init(){
832
1125
  const _options = this.#_options;
833
1126
  const _content = this.#_content;
@@ -880,8 +1173,19 @@ class TXEpgContentProvider {
880
1173
  }
881
1174
 
882
1175
  /**
883
- * @param {string}
884
- * @returns {object}
1176
+ * @typedef {Object} fsoDescr
1177
+ * @property {boolean} isERR - flag
1178
+ * @property {number|undefined} errCode - error code
1179
+ * @property {string} errEvent - event ID
1180
+ * @property {string} errMsg - event message
1181
+ * @property {string} source - path to file
1182
+ * @property {any} content - file content
1183
+ * @description A fs ops description.
1184
+ */
1185
+
1186
+ /**
1187
+ * @param {string} source - a path to a file
1188
+ * @returns {fsoDescr}
885
1189
  * @throws {Error}
886
1190
  * @async
887
1191
  * @description Saves a document content to a file.
@@ -889,88 +1193,77 @@ class TXEpgContentProvider {
889
1193
  saveToFile(source) {
890
1194
  /**/// main part that return promise as a result
891
1195
  return new Promise((resolve, reject) => {
1196
+ /** @type {fsoDescr} */
892
1197
  let data = {
893
- isSucceed: false,
894
- source: typeof source === 'string' ? source.trim() : '',
895
- content: '',
896
1198
  isERR: false,
1199
+ errCode: 0,
897
1200
  errEvent: '',
1201
+ errMsg: '',
1202
+ source: '',
1203
+ content: '',
898
1204
  };
899
- if (data.source === '') {
900
- data.isERR = true;
901
- data.errEvent = (
902
- typeof source === 'string' ? 'EMPTY_SRCLINK' : 'NO_SRCLINK'
903
- );
904
- resolve(data);
905
- } else {
1205
+ (new Promise((resolve, reject) => {
906
1206
  data.content = this.saveToXMLString();
907
- fse.writeFile(data.source, data.content, 'utf8').then(result => {
908
- data.isSucceed = true;
909
- data.errEvent = 'OPS_IS_SUCCEED';
1207
+ resolve(true);
1208
+ })).then(result => {
1209
+ saveToFile(source, data.content, null).then(data => {
910
1210
  resolve(data);
911
1211
  }).catch(err => {
912
- let { isSucceed } = checkFsError(data, err);
913
- if (isSucceed) {
914
- data.content = '';
915
- resolve(data);
916
- } else {
917
- //console.log('CHECK: TXEpgContentProvider.saveToFile() => Error => '+err);
918
- //console.log('CHECK: TXEpgContentProvider.saveToFile() => Error => '+err.code);
919
- reject(err);
920
- };
1212
+ // // TODO: [?] consider check others
1213
+ //console.log('CHECK: TXEpgContentProvider.saveToFile() => Error => '+err);
1214
+ //console.log('CHECK: TXEpgContentProvider.saveToFile() => Error => '+err.code);
1215
+ reject(err);
921
1216
  });
922
- };
1217
+ }).catch(err => {
1218
+ data.isERR = true;
1219
+ //console.log('CHECK: TXEpgContentProvider.saveToFile() => Error => '+err);
1220
+ //console.log('CHECK: TXEpgContentProvider.saveToFile() => Error => '+err.code);
1221
+ data.errEvent = 'ERR_XEPG_UNKNOWN';
1222
+ resolve(data);
1223
+ });
923
1224
  });
924
1225
  }
925
1226
 
926
1227
  /**
927
- * @param {string}
928
- * @returns {object}
929
- * @throws {Error}
1228
+ * @param {string} source - path to a file
1229
+ * @returns {fsoDescr}
930
1230
  * @description Saves a document content to a file.
931
1231
  */
932
1232
  saveToFileSync(source) {
1233
+ /** @type {fsoDescr} */
933
1234
  let data = {
934
- isSucceed: false,
935
- source: typeof source === 'string' ? source.trim() : '',
936
- content: '',
937
1235
  isERR: false,
1236
+ errCode: 0,
938
1237
  errEvent: '',
1238
+ errMsg: '',
1239
+ source: '',
1240
+ content: '',
939
1241
  };
940
- if (data.source === '') {
1242
+ try {
1243
+ data.content = this.saveToXMLString();
1244
+ } catch (err) {
941
1245
  data.isERR = true;
942
- data.errEvent = (
943
- typeof source === 'string' ? 'EMPTY_SRCLINK' : 'NO_SRCLINK'
944
- );
945
- } else {
946
- try {
947
- data.content = this.saveToXMLString();
948
- fs.writeFileSync(data.source, data.content, 'utf8');
949
- } catch (err) {
950
- let { isSucceed } = checkFsError(data, err);
951
- if (isSucceed) {
952
- data.content = '';
953
- } else {
954
- //console.log('CHECK: TXEpgContentProvider.saveToFileSync() => Error => '+err);
955
- //console.log('CHECK: TXEpgContentProvider.saveToFileSync() => Error => '+err.code);
956
- throw err;
957
- };
958
- };
1246
+ //console.log('CHECK: TXEpgContentProvider.saveToFileSync() => Error => '+err);
1247
+ //console.log('CHECK: TXEpgContentProvider.saveToFileSync() => Error => '+err.code);
1248
+ data.errEvent = 'ERR_XEPG_UNKNOWN';
1249
+ };
1250
+ if (!data.isERR) {
1251
+ data = saveToFileSync(source, data.content, null);
959
1252
  };
960
1253
  return data;
961
1254
  }
962
1255
 
963
- loadFromXMLString(xmlString, opt) {
1256
+ /**
1257
+ * @param {string} xmlString - a document content in XML-format
1258
+ * @returns {boolean}
1259
+ * @throws {Error}
1260
+ * @since 0.0.18
1261
+ * @description Loads a document content from a string.
1262
+ */
1263
+ loadFromXMLString(xmlString) {
964
1264
  let isSUCCEED = false;
965
1265
  if (typeof xmlString === 'string') {
966
- let _options = this.#_options;
967
- let parseOptions = null;
968
- if (isPlainObject(opt)) {
969
- parseOptions = new TXmlContentParseOptions(opt);
970
- // // TODO: init user options
971
- } else {
972
- parseOptions = _options.parseOptions;
973
- };
1266
+ const { parseOptions } = this.#_options;
974
1267
  try {
975
1268
  this.#_content = xmlParser.xml2js(xmlString, parseOptions.xml2js);
976
1269
  // init a document header element
@@ -997,13 +1290,16 @@ class TXEpgContentProvider {
997
1290
  return isSUCCEED;
998
1291
  }
999
1292
 
1293
+ /**
1294
+ * @deprecated
1295
+ */
1000
1296
  loadFromString(...args){
1001
1297
  return this.loadFromXMLString(...args);
1002
1298
  }
1003
1299
 
1004
1300
  /**
1005
- * @param {string}
1006
- * @returns {object}
1301
+ * @param {string} source - path to a file
1302
+ * @returns {fsoDescr}
1007
1303
  * @throws {Error}
1008
1304
  * @async
1009
1305
  * @description Loads a document content from a file.
@@ -1011,24 +1307,11 @@ class TXEpgContentProvider {
1011
1307
  loadFromFile(source) {
1012
1308
  /**/// main part that return promise as a result
1013
1309
  return new Promise((resolve, reject) => {
1014
- let data = {
1015
- isLoaded: false,
1016
- source: typeof source === 'string' ? source.trim() : '',
1017
- content: '',
1018
- isERR: false,
1019
- errEvent: '',
1020
- };
1021
- if (data.source === '') {
1022
- data.isERR = true;
1023
- data.errEvent = (
1024
- typeof source === 'string' ? 'EMPTY_SRCLINK' : 'NO_SRCLINK'
1025
- );
1026
- resolve(data);
1027
- } else {
1028
- fse.readFile(data.source, 'utf8').then(result => {
1029
- data.content = result;
1030
- if (result !== '') {
1031
- if (this.loadFromXMLString(result)) {
1310
+ loadFile(source).then(data => {
1311
+ if (!data.isERR) {
1312
+ if (data.content !== '') {
1313
+ if (this.loadFromXMLString(data.content)) {
1314
+ // // TODO:
1032
1315
  data.isLoaded = true;
1033
1316
  data.errEvent = 'OPS_IS_SUCCEED';
1034
1317
  } else {
@@ -1039,76 +1322,53 @@ class TXEpgContentProvider {
1039
1322
  data.isERR = true;
1040
1323
  data.errEvent = 'NO_CONTENT';
1041
1324
  };
1042
- resolve(data);
1043
- }).catch(err => {
1044
- let { isSucceed } = checkFsError(data, err);
1045
- if (isSucceed) {
1046
- data.content = '';
1047
- resolve(data);
1048
- } else {
1049
- //console.log('CHECK: TXEpgContentProvider.loadFromFile() => Error => '+err);
1050
- //console.log('CHECK: TXEpgContentProvider.loadFromFile() => Error => '+err.code);
1051
- reject(err);
1052
- };
1053
- });
1054
- };
1325
+ };
1326
+ resolve(data);
1327
+ }).catch(err => {
1328
+ //console.log('CHECK: TXEpgContentProvider.loadFromFile() => Error => '+err);
1329
+ //console.log('CHECK: TXEpgContentProvider.loadFromFile() => Error => '+err.code);
1330
+ reject(err);
1331
+ });
1055
1332
  });
1056
1333
  }
1057
1334
 
1058
1335
  /**
1059
- * @param {string}
1060
- * @returns {object}
1061
- * @throws {Error}
1336
+ * @param {string} source - path to a file
1337
+ * @returns {fsoDescr}
1062
1338
  * @description Loads a document content from a file.
1063
1339
  */
1064
1340
  loadFromFileSync(source) {
1065
- let data = {
1066
- isLoaded: false,
1067
- source: typeof source === 'string' ? source.trim() : '',
1068
- content: '',
1069
- isERR: false,
1070
- errEvent: '',
1071
- };
1072
- if (data.source === '') {
1073
- data.isERR = true;
1074
- data.errEvent = (
1075
- typeof source === 'string' ? 'EMPTY_SRCLINK' : 'NO_SRCLINK'
1076
- );
1077
- } else {
1078
- try {
1079
- data.content = fs.readFileSync(data.source, 'utf8');
1080
- if (data.content !== '') {
1081
- if (this.loadFromXMLString(data.content)) {
1082
- data.isLoaded = true;
1083
- data.errEvent = 'OPS_IS_SUCCEED';
1084
- } else {
1085
- data.isERR = true;
1086
- data.errEvent = 'OPS_IS_FAILED';
1087
- };
1341
+ const data = loadFileSync(source);
1342
+ if (!data.isERR) {
1343
+ if (data.content !== '') {
1344
+ if (this.loadFromXMLString(data.content)) {
1345
+ // // TODO:
1346
+ data.isLoaded = true;
1347
+ data.errEvent = 'OPS_IS_SUCCEED';
1088
1348
  } else {
1089
1349
  data.isERR = true;
1090
- data.errEvent = 'NO_CONTENT';
1091
- };
1092
- } catch (err) {
1093
- let { isSucceed } = checkFsError(data, err);
1094
- if (isSucceed) {
1095
- data.content = '';
1096
- } else {
1097
- //console.log('CHECK: TXEpgContentProvider.loadFromFileSync() => Error => '+err);
1098
- //console.log('CHECK: TXEpgContentProvider.loadFromFileSync() => Error => '+err.code);
1099
- throw err;
1350
+ data.errEvent = 'OPS_IS_FAILED';
1100
1351
  };
1352
+ } else {
1353
+ data.isERR = true;
1354
+ data.errEvent = 'NO_CONTENT';
1101
1355
  };
1102
1356
  };
1103
1357
  return data;
1104
1358
  }
1105
1359
 
1106
1360
  // will deprecate
1361
+ /**
1362
+ * @deprecated
1363
+ */
1107
1364
  asXML(opt){
1108
1365
  let parseOptions = isPlainObject(opt) ? opt : defParseOptions.js2xml;
1109
1366
  return xmlParser.js2xml(this.#_content, parseOptions);
1110
1367
  }
1111
1368
 
1369
+ /**
1370
+ * @protected
1371
+ */
1112
1372
  asJSON(){
1113
1373
  return JSON.stringify(this.#_content, null, 2);
1114
1374
  }