@ygracs/xobj-lib-js 0.1.2 → 0.2.1

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/xObj-lib.js CHANGED
@@ -1,4 +1,4 @@
1
- // [v0.1.063-20240624]
1
+ // [v0.2.099-20250128]
2
2
 
3
3
  // === module init block ===
4
4
 
@@ -13,6 +13,54 @@ const {
13
13
 
14
14
  // === module extra block (helper functions) ===
15
15
 
16
+ /**
17
+ * @typedef {Object} RVAL_reason
18
+ * @property {string} code - message ID
19
+ * @property {string} msg - message text
20
+ * @description A result of a value check ops.
21
+ */
22
+
23
+ /**
24
+ * @typedef {Object} VCOR_evalkname
25
+ * @property {boolean} isSucceed - ops flag
26
+ * @property {(string|RVAL_reason)} value - result value or reson if failed
27
+ * @description A result of a value check ops.
28
+ */
29
+
30
+ /**
31
+ * @function evalKeyName
32
+ * @param {any} value - key to validate
33
+ * @param {boolean} [opt=true]
34
+ * @returns {VCOR_evalkname}
35
+ * @inner
36
+ * @description Tries to convert a value into an ID.
37
+ */
38
+ function evalKeyName(value, opt = true) {
39
+ if (typeof value !== 'string') {
40
+ return {
41
+ isSucceed: false,
42
+ value: {
43
+ code: XOBJ_TE_NSTR_ECODE,
44
+ msg: XOBJ_TE_NSTR_EMSG,
45
+ },
46
+ };
47
+ };
48
+ const key = value.trim();
49
+ if (opt && key === '') {
50
+ return {
51
+ isSucceed: false,
52
+ value: {
53
+ code: XOBJ_TE_KNES_ECODE,
54
+ msg: XOBJ_TE_KNES_EMSG,
55
+ },
56
+ };
57
+ };
58
+ return {
59
+ isSucceed: true,
60
+ value: key,
61
+ };
62
+ };
63
+
16
64
  // === module main block ===
17
65
 
18
66
  /***
@@ -40,7 +88,13 @@ const XOBJ_TE_KNES_ECODE = 'ERR_XOBJ_INVARG_KEY';
40
88
  * (* function definitions *)
41
89
  */
42
90
 
43
- function evalXObjEName(value){
91
+ /**
92
+ * @function evalXObjEName
93
+ * @param {any} value - some value to evaluate
94
+ * @returns {(null|number|string)}
95
+ * @description Tries to convert a value into an ID.
96
+ */
97
+ function evalXObjEName(value) {
44
98
  //return valueToIDString(value); // // TODO: [?]
45
99
  let name = value;
46
100
  switch (typeof name) {
@@ -71,7 +125,13 @@ function evalXObjEName(value){
71
125
  return name;
72
126
  };
73
127
 
74
- function genXObjENameDescr(value){
128
+ /**
129
+ * @function genXObjENameDescr
130
+ * @param {any} value
131
+ * @returns {object}
132
+ * @description Tries to convert a value into an element name description.
133
+ */
134
+ function genXObjENameDescr(value) {
75
135
  let result = null;
76
136
  let name = null;
77
137
  let conditions = null;
@@ -124,28 +184,24 @@ function genXObjENameDescr(value){
124
184
 
125
185
  /**
126
186
  * @function getXObjElement
127
- * @param {object}
128
- * @param {ID_STRING}
129
- * @returns {?object}
130
- * @throws {TypeError}
187
+ * @param {object} obj - some object
188
+ * @param {string} name - some child element
189
+ * @returns {?any}
190
+ * @throws {TypeError} if first param is not an object
191
+ * @throws {TypeError} if second param is empty string or not a string at all
131
192
  * @description Extracts an element from a given object by its key.
132
193
  */
133
- function getXObjElement(obj, name){
134
- let err = null;
194
+ function getXObjElement(obj, name) {
135
195
  if (!isPlainObject(obj)) {
136
- err = new TypeError(XOBJ_TE_NPOBJ_EMSG);
196
+ const err = new TypeError(XOBJ_TE_NPOBJ_EMSG);
137
197
  err.code = XOBJ_TE_NPOBJ_ECODE;
138
198
  throw err;
139
199
  };
140
- if (typeof name !== 'string') {
141
- err = new TypeError(XOBJ_TE_NSTR_EMSG);
142
- err.code = XOBJ_TE_NSTR_ECODE;
143
- throw err;
144
- };
145
- const key = name.trim();
146
- if (key === '') {
147
- err = new TypeError(XOBJ_TE_KNES_EMSG);
148
- err.code = XOBJ_TE_KNES_ECODE;
200
+ let { isSucceed, value: key } = evalKeyName(name);
201
+ if (!isSucceed) {
202
+ const { code, msg } = key;
203
+ const err = new TypeError(msg);
204
+ err.code = code;
149
205
  throw err;
150
206
  };
151
207
  // TODO: [?] check type of obj[key_name]
@@ -154,13 +210,13 @@ function getXObjElement(obj, name){
154
210
 
155
211
  /**
156
212
  * @function getXObjAttributes
157
- * @param {object}
158
- * @param {ID_STRING} [key]
213
+ * @param {object} obj - some object
214
+ * @param {string} [key=XOBJ_DEF_ATTR_TNAME] - some key
159
215
  * @returns {?object}
160
- * @throws {TypeError}
216
+ * @throws {TypeError} if first param is not an object
161
217
  * @description Extracts an attributes from a given object by its key.
162
218
  */
163
- function getXObjAttributes(obj, key = XOBJ_DEF_ATTR_TNAME){
219
+ function getXObjAttributes(obj, key = XOBJ_DEF_ATTR_TNAME) {
164
220
  let result = null;
165
221
  try {
166
222
  result = getXObjElement(obj, key);
@@ -172,46 +228,48 @@ function getXObjAttributes(obj, key = XOBJ_DEF_ATTR_TNAME){
172
228
  }
173
229
  default: {
174
230
  throw err;
175
- break;
176
231
  }
177
232
  };
178
233
  };
179
234
  return isPlainObject(result) ? result : null;
180
235
  };
181
236
 
237
+ /**
238
+ * @typedef {Object} RVAL_emodif
239
+ * @property {boolean} isSucceed - flag that indicates whether an ops is succeed or not
240
+ * @property {?(object|object[])} item - some element as a result
241
+ * @description A result of an xObj modification ops
242
+ */
243
+
182
244
  /**
183
245
  * @function addXObjElement
184
- * @param {object}
185
- * @param {ID_STRING}
186
- * @returns {?object}
187
- * @throws {TypeError}
246
+ * @param {object} obj - some object
247
+ * @param {string} name - some child element
248
+ * @returns {RVAL_emodif}
249
+ * @throws {TypeError} if first param is not an object
250
+ * @throws {TypeError} if second param is empty string or not a string at all
188
251
  * @description Adds an element addressed by its key to a given object.
189
252
  */
190
- function addXObjElement(obj, name){
191
- let err = null;
253
+ function addXObjElement(obj, name) {
192
254
  if (!isPlainObject(obj)) {
193
- err = new TypeError(XOBJ_TE_NPOBJ_EMSG);
255
+ const err = new TypeError(XOBJ_TE_NPOBJ_EMSG);
194
256
  err.code = XOBJ_TE_NPOBJ_ECODE;
195
257
  throw err;
196
258
  };
197
- if (typeof name !== 'string') {
198
- err = new TypeError(XOBJ_TE_NSTR_EMSG);
199
- err.code = XOBJ_TE_NSTR_ECODE;
200
- throw err;
201
- };
202
- const key = name.trim();
203
- if (key === '') {
204
- err = new TypeError(XOBJ_TE_KNES_EMSG);
205
- err.code = XOBJ_TE_KNES_ECODE;
259
+ let { isSucceed, value: key } = evalKeyName(name);
260
+ if (!isSucceed) {
261
+ const { code, msg } = key;
262
+ const err = new TypeError(msg);
263
+ err.code = code;
206
264
  throw err;
207
265
  };
208
266
  const item = {};
209
267
  let prop = obj[key];
210
- let isSUCCEED = false;
211
- // // TODO: [?] consider wheter or not do ops if new_key exists
268
+ isSucceed = false;
269
+ // // TODO: [?] consider whether or not do ops if new_key exists
212
270
  if (isNullOrUndef(prop)) {
213
271
  obj[key] = prop = item;
214
- isSUCCEED = true;
272
+ isSucceed = true;
215
273
  } else if (isObject(prop)) {
216
274
  if (isArray(prop)) {
217
275
  prop.push(item);
@@ -219,394 +277,489 @@ function addXObjElement(obj, name){
219
277
  obj[key] = [ prop, item ];
220
278
  };
221
279
  prop = item;
222
- isSUCCEED = true;
280
+ isSucceed = true;
223
281
  };
224
282
  return {
225
- isSucceed: isSUCCEED,
226
- item: isSUCCEED ? prop : null,
283
+ isSucceed,
284
+ item: isSucceed ? prop : null,
227
285
  };
228
286
  };
229
287
 
288
+ /**
289
+ * @typedef {Object} OPT_inselops_L
290
+ * @property {boolean} [force=false]
291
+ * @property {boolean} [ripOldies=false]
292
+ * @property {boolean} [acceptIfList=false]
293
+ */
294
+
230
295
  /**
231
296
  * @function insertXObjElement
232
- * @param {object}
233
- * @param {ID_STRING}
234
- * @param {object} [opt]
235
- * @param {bool} [opt.force=false]
236
- * @param {bool} [opt.ripOldies=false]
297
+ * @param {object} obj - some object
298
+ * @param {string} name - some child element
299
+ * @param {OPT_inselops_L} [opt] - options
237
300
  * @returns {?object}
238
- * @throws {TypeError}
301
+ * @throws {TypeError} if first param is not an object
302
+ * @description Inserts an element addressed by its key into a given object.
303
+ */
304
+ function insertXObjElement(...args) {
305
+ let item = null;
306
+ try {
307
+ ({ item } = insertXObjElementEx(...args));
308
+ } catch (err) {
309
+ switch (err.code) {
310
+ case XOBJ_TE_NSTR_ECODE :
311
+ case XOBJ_TE_KNES_ECODE : {
312
+ break;
313
+ }
314
+ default: {
315
+ throw err;
316
+ }
317
+ };
318
+ };
319
+ return item;
320
+ };
321
+
322
+ /**
323
+ * @function insertXObjElementEx
324
+ * @param {object} obj - some object
325
+ * @param {string} name - some child element
326
+ * @param {OPT_inselops_L} [opt] - options
327
+ * @returns {RVAL_emodif}
328
+ * @throws {TypeError} if first param is not an object
329
+ * @throws {TypeError} if second param is empty string or not a string at all
330
+ * @since 0.2.0
239
331
  * @description Inserts an element addressed by its key into a given object.
240
332
  */
241
- function insertXObjElement(obj, name, opt){
242
- let err = null;
333
+ function insertXObjElementEx(obj, name, opt) {
243
334
  if (!isPlainObject(obj)) {
244
- err = new TypeError(XOBJ_TE_NPOBJ_EMSG);
335
+ const err = new TypeError(XOBJ_TE_NPOBJ_EMSG);
245
336
  err.code = XOBJ_TE_NPOBJ_ECODE;
246
337
  throw err;
247
338
  };
248
- if (typeof name !== 'string') {
249
- err = new TypeError(XOBJ_TE_NSTR_EMSG);
250
- err.code = XOBJ_TE_NSTR_ECODE;
339
+ let { isSucceed, value: key } = evalKeyName(name);
340
+ if (!isSucceed) {
341
+ const { code, msg } = key;
342
+ const err = new TypeError(msg);
343
+ err.code = code;
251
344
  throw err;
252
345
  };
253
- const key = name.trim();
254
- if (key === '') {
255
- err = new TypeError(XOBJ_TE_KNES_EMSG);
256
- err.code = XOBJ_TE_KNES_ECODE;
257
- throw err;
258
- };
259
- const _options = isPlainObject(opt) ? opt : {};
260
- let { force, ripOldies } = _options;
261
- if (typeof force !== 'boolean') force = false;
262
- if (typeof ripOldies !== 'boolean') ripOldies = false;
346
+ const item = {};
263
347
  let prop = obj[key];
264
- let isACCEPTED = (
265
- isNullOrUndef(prop)
266
- || (force && (ripOldies || !isPlainObject(prop)))
267
- );
268
- if (isACCEPTED) {
269
- obj[key] = prop = {};
348
+ isSucceed = false;
349
+ if (isNullOrUndef(prop)) {
350
+ obj[key] = prop = item;
351
+ isSucceed = true;
270
352
  } else {
271
- isACCEPTED = isPlainObject(prop);
353
+ const _opt = isPlainObject(opt) ? opt : {};
354
+ let { force, ripOldies, acceptIfList } = _opt;
355
+ if (typeof force !== 'boolean') force = false;
356
+ if (typeof ripOldies !== 'boolean') ripOldies = false;
357
+ if (typeof acceptIfList !== 'boolean') acceptIfList = false;
358
+ if (force && (ripOldies || !isObject(prop))) {
359
+ obj[key] = prop = item;
360
+ isSucceed = true;
361
+ } else {
362
+ isSucceed = isPlainObject(prop) || (isArray(prop) && acceptIfList);
363
+ };
364
+ };
365
+ return {
366
+ isSucceed,
367
+ item: isSucceed ? prop : null,
272
368
  };
273
- return isACCEPTED ? prop : null;
274
369
  };
275
370
 
276
371
  /**
277
372
  * @function deleteXObjElement
278
- * @param {object}
279
- * @param {ID_STRING}
280
- * @returns {bool}
281
- * @throws {TypeError}
373
+ * @param {object} obj - some object
374
+ * @param {string} name - some child element
375
+ * @returns {boolean}
376
+ * @throws {TypeError} if first param is not an object
282
377
  * @description Deletes an element addressed by its key from a given object.
283
378
  */
284
- function deleteXObjElement(obj, name){
285
- let err = null;
286
- if (!isPlainObject(obj)) {
287
- err = new TypeError(XOBJ_TE_NPOBJ_EMSG);
288
- err.code = XOBJ_TE_NPOBJ_ECODE;
289
- throw err;
290
- };
291
- if (typeof name !== 'string') {
292
- err = new TypeError(XOBJ_TE_NSTR_EMSG);
293
- err.code = XOBJ_TE_NSTR_ECODE;
294
- throw err;
295
- };
296
- const key = name.trim();
297
- if (key === '') {
298
- err = new TypeError(XOBJ_TE_KNES_EMSG);
299
- err.code = XOBJ_TE_KNES_ECODE;
300
- throw err;
379
+ function deleteXObjElement(...args) {
380
+ let isSucceed = false;
381
+ try {
382
+ ({ isSucceed } = deleteXObjElementEx(...args));
383
+ } catch (err) {
384
+ switch (err.code) {
385
+ case XOBJ_TE_NSTR_ECODE :
386
+ case XOBJ_TE_KNES_ECODE : {
387
+ break;
388
+ }
389
+ default: {
390
+ throw err;
391
+ }
392
+ };
301
393
  };
302
- let result = false;
303
- // // TODO: catch errors in strict mode
304
- result = delete obj[key];
305
- return result;
394
+ return isSucceed;
306
395
  };
307
396
 
308
397
  /**
309
398
  * @function deleteXObjElementEx
310
- * @param {object}
311
- * @param {ID_STRING}
312
- * @returns {object}
313
- * @throws {TypeError}
399
+ * @param {object} obj - some object
400
+ * @param {string} name - some child element
401
+ * @returns {RVAL_emodif}
402
+ * @throws {TypeError} if first param is not an object
403
+ * @throws {TypeError} if second param is empty string or not a string at all
314
404
  * @description Deletes an element addressed by its key from a given object.
315
405
  */
316
- function deleteXObjElementEx(obj, name){
317
- let err = null;
406
+ function deleteXObjElementEx(obj, name) {
318
407
  if (!isPlainObject(obj)) {
319
- err = new TypeError(XOBJ_TE_NPOBJ_EMSG);
408
+ const err = new TypeError(XOBJ_TE_NPOBJ_EMSG);
320
409
  err.code = XOBJ_TE_NPOBJ_ECODE;
321
410
  throw err;
322
411
  };
323
- if (typeof name !== 'string') {
324
- err = new TypeError(XOBJ_TE_NSTR_EMSG);
325
- err.code = XOBJ_TE_NSTR_ECODE;
326
- throw err;
327
- };
328
- const key = name.trim();
329
- if (key === '') {
330
- err = new TypeError(XOBJ_TE_KNES_EMSG);
331
- err.code = XOBJ_TE_KNES_ECODE;
412
+ let { isSucceed, value: key } = evalKeyName(name);
413
+ if (!isSucceed) {
414
+ const { code, msg } = key;
415
+ const err = new TypeError(msg);
416
+ err.code = code;
332
417
  throw err;
333
418
  };
334
419
  let prop = obj[key];
335
- let result = false;
420
+ isSucceed = false;
336
421
  // // TODO: catch errors in strict mode
337
- result = delete obj[key];
422
+ isSucceed = delete obj[key];
338
423
  return {
339
- isSucceed: result,
340
- item: result && isObject(prop) ? prop : null,
424
+ isSucceed,
425
+ item: isSucceed && isObject(prop) ? prop : null,
341
426
  };
342
427
  };
343
428
 
344
429
  /**
345
430
  * @function renameXObjElement
346
- * @param {object}
347
- * @param {ID_STRING} - old key
348
- * @param {ID_STRING} - new key
349
- * @returns {bool}
350
- * @throws {TypeError}
431
+ * @param {object} obj - some object
432
+ * @param {string} name - some child element
433
+ * @param {string} value - new element ID
434
+ * @returns {boolean}
435
+ * @throws {TypeError} if first param is not an object
436
+ * @throws {TypeError} if second param is not a string
437
+ * @throws {TypeError} if third param is not a string
351
438
  * @description Renames an element addressed by its key.
352
439
  */
353
- function renameXObjElement(obj, name, newName){
354
- let err = null;
440
+ function renameXObjElement(obj, name = '', value = '') {
355
441
  if (!isPlainObject(obj)) {
356
- err = new TypeError(XOBJ_TE_NPOBJ_EMSG);
442
+ const err = new TypeError(XOBJ_TE_NPOBJ_EMSG);
357
443
  err.code = XOBJ_TE_NPOBJ_ECODE;
358
444
  throw err;
359
445
  };
360
- if (typeof name !== 'string' || typeof newName !== 'string') {
361
- err = new TypeError(XOBJ_TE_NSTR_EMSG);
362
- err.code = XOBJ_TE_NSTR_ECODE;
446
+ const opt = false;
447
+ let { isSucceed: isAcceptON, value: oname } = evalKeyName(name, opt);
448
+ if (!isAcceptON) {
449
+ const { code, msg } = oname;
450
+ const err = new TypeError(msg);
451
+ err.code = code;
363
452
  throw err;
364
453
  };
365
- const key = name.trim();
366
- const newKey = newName.trim();
367
- if (key === '' || newKey === '') {
368
- err = new TypeError(XOBJ_TE_KNES_EMSG);
369
- err.code = XOBJ_TE_KNES_ECODE;
454
+ let { isSucceed: isAcceptNN, value: nname } = evalKeyName(value, opt);
455
+ if (!isAcceptNN) {
456
+ const { code, msg } = nname;
457
+ const err = new TypeError(msg);
458
+ err.code = code;
370
459
  throw err;
371
460
  };
372
- const prop = obj[key];
373
- let result = false;
374
- if (prop !== undefined) {
375
- if (key === newKey) return isObject(prop);
376
- // // TODO: consider wheter or not do ops if new_key exists
377
- // // TODO: catch errors in strict mode
378
- result = delete obj[key];
379
- if (result) {
380
- obj[newKey] = isObject(prop) ? prop : {};
461
+ let isSucceed = false;
462
+ if (oname !== '' && oname in obj && nname !== '') {
463
+ isSucceed = true;
464
+ if (oname !== nname) {
465
+ const prop = obj[oname];
466
+ obj[nname] = prop;
467
+ isSucceed = delete obj[oname];
468
+ if (!isSucceed) {
469
+ // undo change if failed delete old element
470
+ delete obj[nname];
471
+ };
381
472
  };
382
473
  };
383
- return result;
474
+ return isSucceed;
384
475
  };
385
476
 
386
477
  /**
387
478
  * @function checkXObjAttribute
388
- * @param {object}
389
- * @param {ID_STRING}
390
- * @param {ID_STRING} [key]
391
- * @returns {bool}
392
- * @throws {TypeError}
393
- * @description Checks wheter an attribute is exists.
479
+ * @param {object} obj - some object
480
+ * @param {string} attr - some attribute ID
481
+ * @param {string} [key] - some key
482
+ * @returns {boolean}
483
+ * @throws {TypeError} if first param is not an object
484
+ * @description Checks whether an attribute is exists.
394
485
  */
395
- function checkXObjAttribute(obj, attr = '', key){
396
- if (typeof attr !== 'string') {
397
- let err = new TypeError(XOBJ_TE_NSTR_EMSG);
398
- err.code = XOBJ_TE_NSTR_ECODE;
399
- throw err;
400
- };
401
- let objAttr = null;
486
+ function checkXObjAttribute(obj, attr = '', key) {
487
+ let _obj = null;
402
488
  try {
403
- objAttr = getXObjAttributes(obj, key);
489
+ _obj = getXObjAttributes(obj, key);
404
490
  } catch (err) {
405
491
  throw err;
406
492
  };
407
- const attrName = attr.trim();
408
- let result = false;
409
- if (
410
- objAttr !== null
411
- && attrName !== ''
412
- && objAttr[attrName] !== undefined
413
- ) {
414
- result = true;
493
+ if (_obj === null) return false;
494
+ let { isSucceed, value: name } = evalKeyName(attr, false);
495
+ if (isSucceed) {
496
+ if (name === '') return false;
497
+ } else {
498
+ const { code, msg } = name;
499
+ const err = new TypeError(msg);
500
+ err.code = code;
501
+ throw err;
415
502
  };
416
- return result;
503
+ return _obj[name] !== undefined;
417
504
  };
418
505
 
419
506
  /**
420
507
  * @function deleteXObjAttribute
421
- * @param {object}
422
- * @param {ID_STRING}
423
- * @param {ID_STRING} [key]
424
- * @returns {bool}
425
- * @throws {TypeError}
426
- * @description Deletes an attribute addressed by a given key.
508
+ * @param {object} obj - some object
509
+ * @param {string} attr - some attribute ID
510
+ * @param {string} [key] - some key
511
+ * @returns {boolean}
512
+ * @throws {TypeError} if first param is not an object
513
+ * @description Deletes an attribute addressed by a given name.
427
514
  */
428
- function deleteXObjAttribute(obj, attr = '', key){
429
- if (typeof attr !== 'string') {
430
- let err = new TypeError(XOBJ_TE_NSTR_EMSG);
431
- err.code = XOBJ_TE_NSTR_ECODE;
432
- throw err;
433
- };
434
- let objAttr = null;
515
+ function deleteXObjAttribute(obj, attr = '', key) {
516
+ let _obj = null;
435
517
  try {
436
- objAttr = getXObjAttributes(obj, key);
518
+ _obj = getXObjAttributes(obj, key);
437
519
  } catch (err) {
438
520
  throw err;
439
521
  };
440
- const attrName = attr.trim();
441
- let result = false;
442
- if (objAttr !== null && attrName !== '') {
522
+ if (_obj === null) return false;
523
+ let { isSucceed, value: name } = evalKeyName(attr, false);
524
+ if (!isSucceed) {
525
+ const { code, msg } = name;
526
+ const err = new TypeError(msg);
527
+ err.code = code;
528
+ throw err;
529
+ };
530
+ isSucceed = false;
531
+ if (name !== '') {
443
532
  // // TODO: catch errors in strict mode
444
- result = delete objAttr[attrName];
533
+ isSucceed = delete _obj[name];
445
534
  };
446
- return result;
535
+ return isSucceed;
536
+ };
537
+
538
+ /**
539
+ * @function renameXObjAttribute
540
+ * @param {object} obj - some object
541
+ * @param {string} attr - some attribute ID
542
+ * @param {string} value - new attribute ID
543
+ * @param {string} [key] - some key
544
+ * @returns {boolean}
545
+ * @throws {TypeError} if first param is not an object
546
+ * @throws {TypeError} if second param is not an object
547
+ * @throws {TypeError} if third param is not an object
548
+ * @since 0.2.0
549
+ * @description Renames an attribute addressed by a given name.
550
+ */
551
+ function renameXObjAttribute(obj, attr = '', value = '', key = XOBJ_DEF_ATTR_TNAME) {
552
+ if (!isPlainObject(obj)) {
553
+ const err = new TypeError(XOBJ_TE_NPOBJ_EMSG);
554
+ err.code = XOBJ_TE_NPOBJ_ECODE;
555
+ throw err;
556
+ };
557
+ const opt = false;
558
+ let { isSucceed, value: _key } = evalKeyName(key, opt);
559
+ if (!isSucceed) {
560
+ const { code, msg } = _key;
561
+ const err = new TypeError(msg);
562
+ err.code = code;
563
+ throw err;
564
+ };
565
+ isSucceed = false;
566
+ if (_key !== '') {
567
+ let _obj = obj[_key];
568
+ if (isPlainObject(_obj)) {
569
+ let { isSucceed: isAcceptON, value: oname } = evalKeyName(attr, opt);
570
+ if (!isAcceptON) {
571
+ const { code, msg } = oname;
572
+ const err = new TypeError(msg);
573
+ err.code = code;
574
+ throw err;
575
+ };
576
+ let { isSucceed: isAcceptNN, value: nname } = evalKeyName(value, opt);
577
+ if (!isAcceptNN) {
578
+ const { code, msg } = nname;
579
+ const err = new TypeError(msg);
580
+ err.code = code;
581
+ throw err;
582
+ };
583
+ if (oname !== '' && oname in _obj && nname !== '') {
584
+ if (oname !== nname) {
585
+ _obj = Object.entries(_obj);
586
+ const index = _obj.findIndex((item) => item[0] === oname);
587
+ _obj[index][0] = nname;
588
+ obj[_key] = Object.fromEntries(_obj);
589
+ };
590
+ isSucceed = true;
591
+ };
592
+ };
593
+ };
594
+ return isSucceed;
447
595
  };
448
596
 
449
597
  /**
450
598
  * @function readXObjParamRaw
451
- * @param {object}
452
- * @param {ID_STRING} [key]
599
+ * @param {object} obj - some object
600
+ * @param {string} [key=XOBJ_DEF_PARAM_TNAME] - some key
453
601
  * @returns {any}
454
- * @throws {TypeError}
455
- * @description Extracts a parameter from a given object.
602
+ * @throws {TypeError} if first param is not an object
603
+ * @throws {TypeError} if third param is not a string
604
+ * @description Extracts a parameter 'AS IS' from a given object.
456
605
  */
457
- function readXObjParamRaw(obj, key = XOBJ_DEF_PARAM_TNAME){
458
- let err = null;
606
+ function readXObjParamRaw(obj, key = XOBJ_DEF_PARAM_TNAME) {
459
607
  if (!isPlainObject(obj)) {
460
- err = new TypeError(XOBJ_TE_NPOBJ_EMSG);
608
+ const err = new TypeError(XOBJ_TE_NPOBJ_EMSG);
461
609
  err.code = XOBJ_TE_NPOBJ_ECODE;
462
610
  throw err;
463
611
  };
464
- if (typeof key !== 'string') {
465
- err = new TypeError(XOBJ_TE_NSTR_EMSG);
466
- err.code = XOBJ_TE_NSTR_ECODE;
612
+ let { isSucceed, value: _key } = evalKeyName(key, false);
613
+ if (!isSucceed) {
614
+ const { code, msg } = _key;
615
+ const err = new TypeError(msg);
616
+ err.code = code;
467
617
  throw err;
468
618
  };
469
- const _key = key.trim();
470
619
  return _key !== '' ? obj[_key] : undefined;
471
620
  };
472
621
 
473
622
  /**
474
623
  * @function writeXObjParamRaw
475
- * @param {object}
476
- * @param {any}
477
- * @param {ID_STRING} [key]
478
- * @returns {bool}
479
- * @throws {TypeError}
480
- * @description Writes a parameter into a given object.
624
+ * @param {object} obj - some object
625
+ * @param {any} value - some value
626
+ * @param {string} [key=XOBJ_DEF_PARAM_TNAME] - some key
627
+ * @returns {boolean}
628
+ * @throws {TypeError} if first param is not an object
629
+ * @throws {TypeError} if third param is not a string
630
+ * @description Writes a parameter 'AS IS' into a given object.
481
631
  */
482
- function writeXObjParamRaw(obj, value, key = XOBJ_DEF_PARAM_TNAME){
483
- let err = null;
632
+ function writeXObjParamRaw(obj, value, key = XOBJ_DEF_PARAM_TNAME) {
484
633
  if (!isPlainObject(obj)) {
485
- err = new TypeError(XOBJ_TE_NPOBJ_EMSG);
634
+ const err = new TypeError(XOBJ_TE_NPOBJ_EMSG);
486
635
  err.code = XOBJ_TE_NPOBJ_ECODE;
487
636
  throw err;
488
637
  };
489
- if (typeof key !== 'string') {
490
- err = new TypeError(XOBJ_TE_NSTR_EMSG);
491
- err.code = XOBJ_TE_NSTR_ECODE;
638
+ let { isSucceed, value: _key } = evalKeyName(key, false);
639
+ if (!isSucceed) {
640
+ const { code, msg } = _key;
641
+ const err = new TypeError(msg);
642
+ err.code = code;
492
643
  throw err;
493
644
  };
494
- const _key = key.trim();
495
- let isSUCCEED = false;
496
- if (_key !== '' && value !== undefined){
645
+ if (_key === '' || value === undefined) {
646
+ isSucceed = false;
647
+ } else {
497
648
  obj[_key] = value;
498
- isSUCCEED = true;
499
649
  };
500
- return isSUCCEED;
650
+ return isSucceed;
501
651
  };
502
652
 
503
653
  /**
504
654
  * @function readXObjAttrRaw
505
- * @param {object}
506
- * @param {ID_STRING}
507
- * @param {ID_STRING} [key]
655
+ * @param {object} obj - some object
656
+ * @param {string} attr - some attribute
657
+ * @param {string} [key] - some key
508
658
  * @returns {any}
509
- * @throws {TypeError}
510
- * @description Extracts an attribute from a given object.
659
+ * @throws {TypeError} if first param is not an object
660
+ * @throws {TypeError} if third param is not a string
661
+ * @description Extracts an attribute 'AS IS' from a given object.
511
662
  */
512
- function readXObjAttrRaw(obj, attr = '', key){
513
- if (typeof attr !== 'string') {
514
- let err = new TypeError(XOBJ_TE_NSTR_EMSG);
515
- err.code = XOBJ_TE_NSTR_ECODE;
516
- throw err;
517
- };
518
- let objAttr = null;
663
+ function readXObjAttrRaw(obj, attr = '', key) {
664
+ let _obj = null;
519
665
  try {
520
- objAttr = getXObjAttributes(obj, key);
666
+ _obj = getXObjAttributes(obj, key);
521
667
  } catch (err) {
522
668
  throw err;
523
669
  };
524
- const attrName = attr.trim();
525
- if (objAttr !== null && attrName !== '') return objAttr[attrName];
670
+ if (_obj !== null) {
671
+ let { isSucceed, value: name } = evalKeyName(attr, false);
672
+ if (!isSucceed) {
673
+ const { code, msg } = name;
674
+ const err = new TypeError(msg);
675
+ err.code = code;
676
+ throw err;
677
+ };
678
+ if (name !== '') return _obj[name];
679
+ };
526
680
  };
527
681
 
528
682
  /**
529
683
  * @function writeXObjAttrRaw
530
- * @param {object}
531
- * @param {ID_STRING}
532
- * @param {any}
533
- * @param {ID_STRING} [key]
534
- * @returns {bool}
535
- * @throws {TypeError}
684
+ * @param {object} obj - some object
685
+ * @param {string} attr - some attribute
686
+ * @param {any} value - some value
687
+ * @param {string} [key=XOBJ_DEF_ATTR_TNAME] - some key
688
+ * @returns {boolean}
689
+ * @throws {TypeError} if first param is not an object
690
+ * @throws {TypeError} if third param is not a string
536
691
  * @description Writes a parameter into a given object.
537
692
  */
538
- function writeXObjAttrRaw(obj, attr = '', value, key = XOBJ_DEF_ATTR_TNAME){
539
- if (typeof attr !== 'string') {
540
- let err = new TypeError(XOBJ_TE_NSTR_EMSG);
541
- err.code = XOBJ_TE_NSTR_ECODE;
693
+ function writeXObjAttrRaw(obj, attr = '', value, key = XOBJ_DEF_ATTR_TNAME) {
694
+ let { isSucceed, value: name } = evalKeyName(attr, false);
695
+ if (!isSucceed) {
696
+ const { code, msg } = name;
697
+ const err = new TypeError(msg);
698
+ err.code = code;
542
699
  throw err;
543
700
  };
544
- const attrName = attr.trim();
545
- let objAttr = null;
546
- let isSUCCEED = false;
547
- if (attrName !== '' && value !== undefined) {
701
+ isSucceed = false;
702
+ if (name !== '' && value !== undefined) {
703
+ let _obj = null;
548
704
  try {
549
- objAttr = insertXObjElement(obj, key, { force: true });
705
+ const opt = { force: true, acceptIfList: true };
706
+ _obj = insertXObjElement(obj, key, opt);
550
707
  } catch (err) {
551
- switch (err.code) {
552
- case XOBJ_TE_NSTR_ECODE :
553
- case XOBJ_TE_KNES_ECODE : {
554
- break;
555
- }
556
- default: {
557
- throw err;
558
- break;
559
- }
708
+ throw err;
709
+ };
710
+ if (isArray(_obj)) {
711
+ // force a replacement of the old element if it's array
712
+ try {
713
+ const opt = { force: true, ripOldies: true };
714
+ _obj = insertXObjElement(obj, key, opt);
715
+ } catch (err) {
716
+ throw err;
560
717
  };
561
718
  };
562
- if (objAttr !== null) {
563
- objAttr[attrName] = value;
564
- isSUCCEED = true;
719
+ if (_obj !== null) {
720
+ _obj[name] = value;
721
+ isSucceed = true;
565
722
  };
566
723
  };
567
- return isSUCCEED;
724
+ return isSucceed;
568
725
  };
569
726
 
570
727
  /**
571
728
  * @function readXObjParam
572
- * @param {object}
573
- * @param {ID_STRING} [key]
729
+ * @param {object} obj - some object
730
+ * @param {string} [key] - some key
574
731
  * @returns {string}
575
- * @throws {TypeError}
576
- * @description Extracts a parameter from a given object.
732
+ * @throws {TypeError} if first param is not an object
733
+ * @description Extracts a parameter from a given object
734
+ * and returns it as string.
577
735
  */
578
- function readXObjParam(obj, key){
736
+ function readXObjParam(obj, key) {
737
+ const opt = {
738
+ useTrim: false,
739
+ numberToString: true,
740
+ boolToString: true,
741
+ defValue: '',
742
+ };
579
743
  let result = undefined;
580
744
  try {
581
- result = readXObjParamRaw(obj, key);
745
+ result = readXObjParamEx(obj, opt, key);
582
746
  } catch (err) {
583
- switch (err.code) {
584
- case XOBJ_TE_NSTR_ECODE : {
585
- break;
586
- }
587
- default: {
588
- throw err;
589
- break;
590
- }
591
- };
747
+ throw err;
592
748
  };
593
- return readAsString(result, {
594
- useTrim: false,
595
- numberToString: true,
596
- boolToString: true,
597
- });
749
+ return result;
598
750
  };
599
751
 
600
752
  /**
601
- * @function readXObjParam
602
- * @param {object}
603
- * @param {bool}
604
- * @param {ID_STRING} [key]
605
- * @returns {bool}
606
- * @throws {TypeError}
607
- * @description Extracts a parameter from a given object.
753
+ * @function readXObjParamAsBool
754
+ * @param {object} obj - some object
755
+ * @param {boolean} [defValue] - default value
756
+ * @param {string} [key] - some key
757
+ * @returns {boolean}
758
+ * @throws {TypeError} if first param is not an object
759
+ * @description Extracts a parameter from a given object
760
+ * and returns it as boolean.
608
761
  */
609
- function readXObjParamAsBool(obj, defValue, key){
762
+ function readXObjParamAsBool(obj, defValue, key) {
610
763
  let result = undefined;
611
764
  try {
612
765
  result = readXObjParamRaw(obj, key);
@@ -617,7 +770,6 @@ function readXObjParamAsBool(obj, defValue, key){
617
770
  }
618
771
  default: {
619
772
  throw err;
620
- break;
621
773
  }
622
774
  };
623
775
  };
@@ -625,15 +777,16 @@ function readXObjParamAsBool(obj, defValue, key){
625
777
  };
626
778
 
627
779
  /**
628
- * @function readXObjParam
629
- * @param {object}
630
- * @param {number}
631
- * @param {ID_STRING} [key]
780
+ * @function readXObjParamAsNum
781
+ * @param {object} obj - some object
782
+ * @param {number} [defValue] - default value
783
+ * @param {string} [key] - some key
632
784
  * @returns {number}
633
- * @throws {TypeError}
634
- * @description Extracts a parameter from a given object.
785
+ * @throws {TypeError} if first param is not an object
786
+ * @description Extracts a parameter from a given object
787
+ * and returns it as number.
635
788
  */
636
- function readXObjParamAsNum(obj, defValue, key){
789
+ function readXObjParamAsNum(obj, defValue, key) {
637
790
  let result = undefined;
638
791
  try {
639
792
  result = readXObjParamRaw(obj, key);
@@ -644,7 +797,6 @@ function readXObjParamAsNum(obj, defValue, key){
644
797
  }
645
798
  default: {
646
799
  throw err;
647
- break;
648
800
  }
649
801
  };
650
802
  };
@@ -652,15 +804,17 @@ function readXObjParamAsNum(obj, defValue, key){
652
804
  };
653
805
 
654
806
  /**
655
- * @function readXObjParam
656
- * @param {object}
657
- * @param {string}
658
- * @param {ID_STRING} [key]
807
+ * @function readXObjParamEx
808
+ * @param {object} obj - some object
809
+ * @param {object} [opt] - options
810
+ * @param {string} [key] - some key
659
811
  * @returns {string}
660
- * @throws {TypeError}
661
- * @description Extracts a parameter from a given object.
812
+ * @throws {TypeError} if first param is not an object
813
+ * @description Extracts a parameter from a given object
814
+ * and returns it as string.
815
+ * @todo [since `v0.2.1`] deprecate use of `opt` as `string`
662
816
  */
663
- function readXObjParamAsStr(obj, defValue, key){
817
+ function readXObjParamEx(obj, opt, key) {
664
818
  let result = undefined;
665
819
  try {
666
820
  result = readXObjParamRaw(obj, key);
@@ -671,27 +825,31 @@ function readXObjParamAsStr(obj, defValue, key){
671
825
  }
672
826
  default: {
673
827
  throw err;
674
- break;
675
828
  }
676
829
  };
677
830
  };
678
- return readAsString(result, {
679
- useTrim: false,
680
- numberToString: true,
681
- boolToString: true,
682
- defValue,
683
- });
831
+ let _opt = opt;
832
+ if (!isPlainObject(_opt)) {
833
+ _opt = {
834
+ useTrim: false,
835
+ numberToString: true,
836
+ boolToString: true,
837
+ defValue: _opt,
838
+ };
839
+ };
840
+ return readAsString(result, _opt);
684
841
  };
685
842
 
686
843
  /**
687
- * @function readXObjParam
688
- * @param {object}
689
- * @param {ID_STRING} [key]
690
- * @returns {index}
691
- * @throws {TypeError}
692
- * @description Extracts a parameter from a given object.
844
+ * @function readXObjParamAsIndex
845
+ * @param {object} obj - some object
846
+ * @param {string} [key] - some key
847
+ * @returns {number}
848
+ * @throws {TypeError} if first param is not an object
849
+ * @description Extracts a parameter from a given object
850
+ * and returns it as 'index' value.
693
851
  */
694
- function readXObjParamAsIndex(obj, key){
852
+ function readXObjParamAsIndex(obj, key) {
695
853
  let result = undefined;
696
854
  try {
697
855
  result = readXObjParamRaw(obj, key);
@@ -702,7 +860,6 @@ function readXObjParamAsIndex(obj, key){
702
860
  }
703
861
  default: {
704
862
  throw err;
705
- break;
706
863
  }
707
864
  };
708
865
  };
@@ -711,54 +868,47 @@ function readXObjParamAsIndex(obj, key){
711
868
 
712
869
  /**
713
870
  * @function writeXObjParam
714
- * @param {object}
715
- * @param {any}
716
- * @param {ID_STRING} [key]
717
- * @returns {bool}
718
- * @throws {TypeError}
719
- * @description Writes a parameter into a given object.
871
+ * @param {object} obj - some object
872
+ * @param {any} value - some value
873
+ * @param {string} [key] - some key
874
+ * @returns {boolean}
875
+ * @throws {TypeError} if first param is not an object
876
+ * @description Tries to convert a given value to a string
877
+ * and writes it as a parameter into a given object.
720
878
  */
721
- function writeXObjParam(obj, value, key){
722
- let isSUCCEED = false;
723
- if (value !== undefined) {
724
- const _value = readAsString(value, {
879
+ function writeXObjParam(obj, value, key) {
880
+ let isSucceed = false;
881
+ try {
882
+ const opt = {
725
883
  useTrim: false,
726
884
  numberToString: true,
727
885
  boolToString: true,
728
- });
729
- try {
730
- isSUCCEED = writeXObjParamRaw(obj, _value, key);
731
- } catch (err) {
732
- switch (err.code) {
733
- case XOBJ_TE_NSTR_ECODE : {
734
- break;
735
- }
736
- default: {
737
- throw err;
738
- break;
739
- }
740
- };
886
+ defValue: '',
741
887
  };
888
+ isSucceed = writeXObjParamEx(obj, value, opt, key);
889
+ } catch (err) {
890
+ throw err;
742
891
  };
743
- return isSUCCEED;
892
+ return isSucceed;
744
893
  };
745
894
 
746
895
  /**
747
896
  * @function writeXObjParamAsBool
748
- * @param {object}
749
- * @param {any}
750
- * @param {bool}
751
- * @param {ID_STRING} [key]
752
- * @returns {bool}
753
- * @throws {TypeError}
754
- * @description Writes a parameter into a given object.
897
+ * @param {object} obj - some object
898
+ * @param {any} value - some value
899
+ * @param {boolean} [defValue] - default value
900
+ * @param {string} [key] - some key
901
+ * @returns {boolean}
902
+ * @throws {TypeError} if first param is not an object
903
+ * @description Tries to convert a given value to a boolean
904
+ * and writes it as a parameter into a given object.
755
905
  */
756
- function writeXObjParamAsBool(obj, value, defValue, key){
757
- let isSUCCEED = false;
758
- if (value !== undefined) {
906
+ function writeXObjParamAsBool(obj, value, defValue, key) {
907
+ let isSucceed = false;
908
+ if (value !== undefined || typeof defValue === 'boolean') {
759
909
  const _value = readAsBoolEx(value, defValue).toString();
760
910
  try {
761
- isSUCCEED = writeXObjParamRaw(obj, _value, key);
911
+ isSucceed = writeXObjParamRaw(obj, _value, key);
762
912
  } catch (err) {
763
913
  switch (err.code) {
764
914
  case XOBJ_TE_NSTR_ECODE : {
@@ -766,30 +916,30 @@ function writeXObjParamAsBool(obj, value, defValue, key){
766
916
  }
767
917
  default: {
768
918
  throw err;
769
- break;
770
919
  }
771
920
  };
772
921
  };
773
922
  };
774
- return isSUCCEED;
923
+ return isSucceed;
775
924
  };
776
925
 
777
926
  /**
778
927
  * @function writeXObjParamAsNum
779
- * @param {object}
780
- * @param {any}
781
- * @param {number}
782
- * @param {ID_STRING} [key]
783
- * @returns {bool}
784
- * @throws {TypeError}
785
- * @description Writes a parameter into a given object.
928
+ * @param {object} obj - some object
929
+ * @param {any} value - some value
930
+ * @param {number} [defValue] - default value
931
+ * @param {string} [key] - some key
932
+ * @returns {boolean}
933
+ * @throws {TypeError} if first param is not an object
934
+ * @description Tries to convert a given value to a number
935
+ * and writes it as a parameter into a given object.
786
936
  */
787
- function writeXObjParamAsNum(obj, value, defValue, key){
788
- let isSUCCEED = false;
789
- if (value !== undefined) {
937
+ function writeXObjParamAsNum(obj, value, defValue, key) {
938
+ let isSucceed = false;
939
+ if (value !== undefined || typeof defValue === 'number') {
790
940
  const _value = readAsNumberEx(value, defValue).toString();
791
941
  try {
792
- isSUCCEED = writeXObjParamRaw(obj, _value, key);
942
+ isSucceed = writeXObjParamRaw(obj, _value, key);
793
943
  } catch (err) {
794
944
  switch (err.code) {
795
945
  case XOBJ_TE_NSTR_ECODE : {
@@ -797,29 +947,29 @@ function writeXObjParamAsNum(obj, value, defValue, key){
797
947
  }
798
948
  default: {
799
949
  throw err;
800
- break;
801
950
  }
802
951
  };
803
952
  };
804
953
  };
805
- return isSUCCEED;
954
+ return isSucceed;
806
955
  };
807
956
 
808
957
  /**
809
958
  * @function writeXObjParamAsIndex
810
- * @param {object}
811
- * @param {any}
812
- * @param {ID_STRING} [key]
813
- * @returns {bool}
814
- * @throws {TypeError}
815
- * @description Writes a parameter into a given object.
959
+ * @param {object} obj - some object
960
+ * @param {any} value - some value
961
+ * @param {string} [key] - some key
962
+ * @returns {boolean}
963
+ * @throws {TypeError} if first param is not an object
964
+ * @description Tries to convert a given value into an 'index' value
965
+ * and writes it as a parameter into a given object.
816
966
  */
817
- function writeXObjParamAsIndex(obj, value, key){
818
- let isSUCCEED = false;
967
+ function writeXObjParamAsIndex(obj, value, key) {
968
+ let isSucceed = false;
819
969
  if (value !== undefined) {
820
970
  const _value = valueToIndex(value).toString();
821
971
  try {
822
- isSUCCEED = writeXObjParamRaw(obj, _value, key);
972
+ isSucceed = writeXObjParamRaw(obj, _value, key);
823
973
  } catch (err) {
824
974
  switch (err.code) {
825
975
  case XOBJ_TE_NSTR_ECODE : {
@@ -827,40 +977,45 @@ function writeXObjParamAsIndex(obj, value, key){
827
977
  }
828
978
  default: {
829
979
  throw err;
830
- break;
831
980
  }
832
981
  };
833
982
  };
834
983
  };
835
- return isSUCCEED;
984
+ return isSucceed;
836
985
  };
837
986
 
838
987
  /**
839
988
  * @function writeXObjParamEx
840
- * @param {object}
841
- * @param {any}
842
- * @param {any}
843
- * @param {ID_STRING} [key]
844
- * @returns {bool}
845
- * @throws {TypeError}
846
- * @description Writes a parameter into a given object.
989
+ * @param {object} obj - some object
990
+ * @param {any} value - some value
991
+ * @param {object} [opt] - options
992
+ * @param {string} [key] - some key
993
+ * @returns {boolean}
994
+ * @throws {TypeError} if first param is not an object
995
+ * @description Tries to convert a given value to a string
996
+ * and writes it as a parameter into a given object.
997
+ * @todo [since `v0.2.1`] deprecate use of `opt` as `string`
847
998
  */
848
- function writeXObjParamEx(obj, value, defValue, key){
849
- let isSUCCEED = false;
999
+ function writeXObjParamEx(obj, value, opt, key) {
1000
+ let isSucceed = false;
850
1001
  if (value !== undefined) {
851
- const _defValue = readAsString(defValue, {
852
- useTrim: false,
853
- numberToString: true,
854
- boolToString: true,
855
- });
856
- const _value = readAsString(value, {
857
- useTrim: false,
858
- numberToString: true,
859
- boolToString: true,
860
- defValue: _defValue,
861
- });
1002
+ let _opt = opt;
1003
+ if (!isPlainObject(_opt)) {
1004
+ const defValue = readAsString(_opt, {
1005
+ useTrim: false,
1006
+ numberToString: true,
1007
+ boolToString: true,
1008
+ });
1009
+ _opt = {
1010
+ useTrim: false,
1011
+ numberToString: true,
1012
+ boolToString: true,
1013
+ defValue,
1014
+ };
1015
+ };
1016
+ const _value = readAsString(value, _opt);
862
1017
  try {
863
- isSUCCEED = writeXObjParamRaw(obj, _value, key);
1018
+ isSucceed = writeXObjParamRaw(obj, _value, key);
864
1019
  } catch (err) {
865
1020
  switch (err.code) {
866
1021
  case XOBJ_TE_NSTR_ECODE : {
@@ -868,56 +1023,51 @@ function writeXObjParamEx(obj, value, defValue, key){
868
1023
  }
869
1024
  default: {
870
1025
  throw err;
871
- break;
872
1026
  }
873
1027
  };
874
1028
  };
875
1029
  };
876
- return isSUCCEED;
1030
+ return isSucceed;
877
1031
  };
878
1032
 
879
1033
  /**
880
1034
  * @function readXObjAttr
881
- * @param {object}
882
- * @param {ID_STRING}
883
- * @param {ID_STRING} [key]
1035
+ * @param {object} obj - some object
1036
+ * @param {string} attr - some attribute
1037
+ * @param {string} [key] - some key
884
1038
  * @returns {string}
885
- * @throws {TypeError}
886
- * @description Extracts an attribute from a given object.
1039
+ * @throws {TypeError} if first param is not an object
1040
+ * @description Extracts an attribute from a given object
1041
+ * and returns it as string.
887
1042
  */
888
- function readXObjAttr(obj, attr, key){
1043
+ function readXObjAttr(obj, attr, key) {
1044
+ const opt = {
1045
+ useTrim: true,
1046
+ numberToString: true,
1047
+ boolToString: true,
1048
+ defValue: '',
1049
+ };
889
1050
  let result = undefined;
890
1051
  try {
891
- result = readXObjAttrRaw(obj, attr, key);
1052
+ result = readXObjAttrEx(obj, attr, opt, key);
892
1053
  } catch (err) {
893
- switch (err.code) {
894
- case XOBJ_TE_NSTR_ECODE : {
895
- break;
896
- }
897
- default: {
898
- throw err;
899
- break;
900
- }
901
- };
1054
+ throw err;
902
1055
  };
903
- return readAsString(result, {
904
- useTrim: true,
905
- numberToString: true,
906
- boolToString: true,
907
- });
1056
+ return result;
908
1057
  };
909
1058
 
910
1059
  /**
911
1060
  * @function readXObjAttrAsBool
912
- * @param {object}
913
- * @param {ID_STRING}
914
- * @param {bool}
915
- * @param {ID_STRING} [key]
916
- * @returns {bool}
917
- * @throws {TypeError}
918
- * @description Extracts an attribute from a given object.
1061
+ * @param {object} obj - some object
1062
+ * @param {string} attr - some attribute
1063
+ * @param {boolean} [defValue] - default value
1064
+ * @param {string} [key] - some key
1065
+ * @returns {boolean}
1066
+ * @throws {TypeError} if first param is not an object
1067
+ * @description Extracts an attribute from a given object
1068
+ * and returns it as boolean.
919
1069
  */
920
- function readXObjAttrAsBool(obj, attr, defValue, key){
1070
+ function readXObjAttrAsBool(obj, attr, defValue, key) {
921
1071
  let result = undefined;
922
1072
  try {
923
1073
  result = readXObjAttrRaw(obj, attr, key);
@@ -928,7 +1078,6 @@ function readXObjAttrAsBool(obj, attr, defValue, key){
928
1078
  }
929
1079
  default: {
930
1080
  throw err;
931
- break;
932
1081
  }
933
1082
  };
934
1083
  };
@@ -937,15 +1086,16 @@ function readXObjAttrAsBool(obj, attr, defValue, key){
937
1086
 
938
1087
  /**
939
1088
  * @function readXObjAttrAsNum
940
- * @param {object}
941
- * @param {ID_STRING}
942
- * @param {number}
943
- * @param {ID_STRING} [key]
1089
+ * @param {object} obj - some object
1090
+ * @param {string} attr - some attribute
1091
+ * @param {number} [defValue] - default value
1092
+ * @param {string} [key] - some key
944
1093
  * @returns {number}
945
- * @throws {TypeError}
946
- * @description Extracts an attribute from a given object.
1094
+ * @throws {TypeError} if first param is not an object
1095
+ * @description Extracts an attribute from a given object
1096
+ * and returns it as number.
947
1097
  */
948
- function readXObjAttrAsNum(obj, attr, defValue, key){
1098
+ function readXObjAttrAsNum(obj, attr, defValue, key) {
949
1099
  let result = undefined;
950
1100
  try {
951
1101
  result = readXObjAttrRaw(obj, attr, key);
@@ -956,7 +1106,6 @@ function readXObjAttrAsNum(obj, attr, defValue, key){
956
1106
  }
957
1107
  default: {
958
1108
  throw err;
959
- break;
960
1109
  }
961
1110
  };
962
1111
  };
@@ -964,16 +1113,18 @@ function readXObjAttrAsNum(obj, attr, defValue, key){
964
1113
  };
965
1114
 
966
1115
  /**
967
- * @function readXObjAttrAsStr
968
- * @param {object}
969
- * @param {ID_STRING}
970
- * @param {string}
971
- * @param {ID_STRING} [key]
1116
+ * @function readXObjAttrEx
1117
+ * @param {object} obj - some object
1118
+ * @param {string} attr - some attribute
1119
+ * @param {object} [opt] - options
1120
+ * @param {string} [key] - some key
972
1121
  * @returns {string}
973
- * @throws {TypeError}
974
- * @description Extracts an attribute from a given object.
1122
+ * @throws {TypeError} if first param is not an object
1123
+ * @description Extracts an attribute from a given object
1124
+ * and returns it as string.
1125
+ * @todo [since `v0.2.1`] deprecate use of `opt` as `string`
975
1126
  */
976
- function readXObjAttrAsStr(obj, attr, defValue, key){
1127
+ function readXObjAttrEx(obj, attr, opt, key) {
977
1128
  let result = undefined;
978
1129
  try {
979
1130
  result = readXObjAttrRaw(obj, attr, key);
@@ -984,28 +1135,32 @@ function readXObjAttrAsStr(obj, attr, defValue, key){
984
1135
  }
985
1136
  default: {
986
1137
  throw err;
987
- break;
988
1138
  }
989
1139
  };
990
1140
  };
991
- return readAsString(result, {
992
- useTrim: true,
993
- numberToString: true,
994
- boolToString: true,
995
- defValue,
996
- });
1141
+ let _opt = opt;
1142
+ if (!isPlainObject(_opt)) {
1143
+ _opt = {
1144
+ useTrim: true,
1145
+ numberToString: true,
1146
+ boolToString: true,
1147
+ defValue: _opt,
1148
+ };
1149
+ };
1150
+ return readAsString(result, _opt);
997
1151
  };
998
1152
 
999
1153
  /**
1000
1154
  * @function readXObjAttrAsIndex
1001
- * @param {object}
1002
- * @param {ID_STRING}
1003
- * @param {ID_STRING} [key]
1004
- * @returns {index}
1005
- * @throws {TypeError}
1006
- * @description Extracts an attribute from a given object.
1155
+ * @param {object} obj - some object
1156
+ * @param {string} attr - some attribute
1157
+ * @param {string} [key] - some key
1158
+ * @returns {number}
1159
+ * @throws {TypeError} if first param is not an object
1160
+ * @description Extracts an attribute from a given object
1161
+ * and returns it as 'index' value.
1007
1162
  */
1008
- function readXObjAttrAsIndex(obj, attr, key){
1163
+ function readXObjAttrAsIndex(obj, attr, key) {
1009
1164
  let result = undefined;
1010
1165
  try {
1011
1166
  result = readXObjAttrRaw(obj, attr, key);
@@ -1016,7 +1171,6 @@ function readXObjAttrAsIndex(obj, attr, key){
1016
1171
  }
1017
1172
  default: {
1018
1173
  throw err;
1019
- break;
1020
1174
  }
1021
1175
  };
1022
1176
  };
@@ -1025,56 +1179,49 @@ function readXObjAttrAsIndex(obj, attr, key){
1025
1179
 
1026
1180
  /**
1027
1181
  * @function writeXObjAttr
1028
- * @param {object}
1029
- * @param {ID_STRING}
1030
- * @param {any}
1031
- * @param {ID_STRING} [key]
1032
- * @returns {bool}
1033
- * @throws {TypeError}
1034
- * @description Writes a parameter into a given object.
1182
+ * @param {object} obj - some object
1183
+ * @param {string} attr - some attribute
1184
+ * @param {any} value - some value
1185
+ * @param {string} [key] - some key
1186
+ * @returns {boolean}
1187
+ * @throws {TypeError} if first param is not an object
1188
+ * @description Tries to convert a given value to a string
1189
+ * and writes it as an attribute into a given object.
1035
1190
  */
1036
- function writeXObjAttr(obj, attr, value, key){
1037
- let isSUCCEED = false;
1038
- if (value !== undefined) {
1039
- const _value = readAsString(value, {
1191
+ function writeXObjAttr(obj, attr, value, key) {
1192
+ let isSucceed = false;
1193
+ try {
1194
+ const opt = {
1040
1195
  useTrim: true,
1041
1196
  numberToString: true,
1042
1197
  boolToString: true,
1043
- });
1044
- try {
1045
- isSUCCEED = writeXObjAttrRaw(obj, attr, _value, key);
1046
- } catch (err) {
1047
- switch (err.code) {
1048
- case XOBJ_TE_NSTR_ECODE : {
1049
- break;
1050
- }
1051
- default: {
1052
- throw err;
1053
- break;
1054
- }
1055
- };
1198
+ defValue: '',
1056
1199
  };
1200
+ isSucceed = writeXObjAttrEx(obj, attr, value, opt, key);
1201
+ } catch (err) {
1202
+ throw err;
1057
1203
  };
1058
- return isSUCCEED;
1204
+ return isSucceed;
1059
1205
  };
1060
1206
 
1061
1207
  /**
1062
1208
  * @function writeXObjAttrAsBool
1063
- * @param {object}
1064
- * @param {ID_STRING}
1065
- * @param {any}
1066
- * @param {bool}
1067
- * @param {ID_STRING} [key]
1068
- * @returns {bool}
1069
- * @throws {TypeError}
1070
- * @description Writes a parameter into a given object.
1209
+ * @param {object} obj - some object
1210
+ * @param {string} attr - some attribute
1211
+ * @param {any} value - some value
1212
+ * @param {boolean} [defValue] - default value
1213
+ * @param {string} [key] - some key
1214
+ * @returns {boolean}
1215
+ * @throws {TypeError} if first param is not an object
1216
+ * @description Tries to convert a given value to a boolean
1217
+ * and writes it as an attribute into a given object.
1071
1218
  */
1072
- function writeXObjAttrAsBool(obj, attr, value, defValue, key){
1073
- let isSUCCEED = false;
1074
- if (value !== undefined) {
1219
+ function writeXObjAttrAsBool(obj, attr, value, defValue, key) {
1220
+ let isSucceed = false;
1221
+ if (value !== undefined || typeof defValue === 'boolean') {
1075
1222
  const _value = readAsBoolEx(value, defValue).toString();
1076
1223
  try {
1077
- isSUCCEED = writeXObjAttrRaw(obj, attr, _value, key);
1224
+ isSucceed = writeXObjAttrRaw(obj, attr, _value, key);
1078
1225
  } catch (err) {
1079
1226
  switch (err.code) {
1080
1227
  case XOBJ_TE_NSTR_ECODE : {
@@ -1082,31 +1229,31 @@ function writeXObjAttrAsBool(obj, attr, value, defValue, key){
1082
1229
  }
1083
1230
  default: {
1084
1231
  throw err;
1085
- break;
1086
1232
  }
1087
1233
  };
1088
1234
  };
1089
1235
  };
1090
- return isSUCCEED;
1236
+ return isSucceed;
1091
1237
  };
1092
1238
 
1093
1239
  /**
1094
1240
  * @function writeXObjAttrAsNum
1095
- * @param {object}
1096
- * @param {ID_STRING}
1097
- * @param {any}
1098
- * @param {number}
1099
- * @param {ID_STRING} [key]
1100
- * @returns {bool}
1101
- * @throws {TypeError}
1102
- * @description Writes a parameter into a given object.
1241
+ * @param {object} obj - some object
1242
+ * @param {string} attr - some attribute
1243
+ * @param {any} value - some value
1244
+ * @param {number} [defValue] - default value
1245
+ * @param {string} [key] - some key
1246
+ * @returns {boolean}
1247
+ * @throws {TypeError} if first param is not an object
1248
+ * @description Tries to convert a given value to a number
1249
+ * and writes it as an attribute into a given object.
1103
1250
  */
1104
- function writeXObjAttrAsNum(obj, attr, value, defValue, key){
1105
- let isSUCCEED = false;
1106
- if (value !== undefined) {
1251
+ function writeXObjAttrAsNum(obj, attr, value, defValue, key) {
1252
+ let isSucceed = false;
1253
+ if (value !== undefined || typeof defValue === 'number') {
1107
1254
  const _value = readAsNumberEx(value, defValue).toString();
1108
1255
  try {
1109
- isSUCCEED = writeXObjAttrRaw(obj, attr, _value, key);
1256
+ isSucceed = writeXObjAttrRaw(obj, attr, _value, key);
1110
1257
  } catch (err) {
1111
1258
  switch (err.code) {
1112
1259
  case XOBJ_TE_NSTR_ECODE : {
@@ -1114,30 +1261,30 @@ function writeXObjAttrAsNum(obj, attr, value, defValue, key){
1114
1261
  }
1115
1262
  default: {
1116
1263
  throw err;
1117
- break;
1118
1264
  }
1119
1265
  };
1120
1266
  };
1121
1267
  };
1122
- return isSUCCEED;
1268
+ return isSucceed;
1123
1269
  };
1124
1270
 
1125
1271
  /**
1126
1272
  * @function writeXObjAttrAsIndex
1127
- * @param {object}
1128
- * @param {ID_STRING}
1129
- * @param {any}
1130
- * @param {ID_STRING} [key]
1131
- * @returns {bool}
1132
- * @throws {TypeError}
1133
- * @description Writes a parameter into a given object.
1273
+ * @param {object} obj - some object
1274
+ * @param {string} attr - some attribute
1275
+ * @param {any} value - some value
1276
+ * @param {string} [key] - some key
1277
+ * @returns {boolean}
1278
+ * @throws {TypeError} if first param is not an object
1279
+ * @description Tries to convert a given value into an 'index' value
1280
+ * and writes it as an attribute into a given object.
1134
1281
  */
1135
- function writeXObjAttrAsIndex(obj, attr, value, key){
1136
- let isSUCCEED = false;
1282
+ function writeXObjAttrAsIndex(obj, attr, value, key) {
1283
+ let isSucceed = false;
1137
1284
  if (value !== undefined) {
1138
1285
  const _value = valueToIndex(value).toString();
1139
1286
  try {
1140
- isSUCCEED = writeXObjAttrRaw(obj, attr, _value, key);
1287
+ isSucceed = writeXObjAttrRaw(obj, attr, _value, key);
1141
1288
  } catch (err) {
1142
1289
  switch (err.code) {
1143
1290
  case XOBJ_TE_NSTR_ECODE : {
@@ -1145,41 +1292,46 @@ function writeXObjAttrAsIndex(obj, attr, value, key){
1145
1292
  }
1146
1293
  default: {
1147
1294
  throw err;
1148
- break;
1149
1295
  }
1150
1296
  };
1151
1297
  };
1152
1298
  };
1153
- return isSUCCEED;
1299
+ return isSucceed;
1154
1300
  };
1155
1301
 
1156
1302
  /**
1157
1303
  * @function writeXObjAttrEx
1158
- * @param {object}
1159
- * @param {ID_STRING}
1160
- * @param {any}
1161
- * @param {any}
1162
- * @param {ID_STRING} [key]
1163
- * @returns {bool}
1164
- * @throws {TypeError}
1165
- * @description Writes a parameter into a given object.
1304
+ * @param {object} obj - some object
1305
+ * @param {string} attr - some attribute
1306
+ * @param {any} value - some value
1307
+ * @param {object} [opt] - options
1308
+ * @param {string} [key] - some key
1309
+ * @returns {boolean}
1310
+ * @throws {TypeError} if first param is not an object
1311
+ * @description Tries to convert a given value to a string
1312
+ * and writes it as an attribute into a given object.
1313
+ * @todo [since `v0.2.1`] deprecate use of `opt` as `string`
1166
1314
  */
1167
- function writeXObjAttrEx(obj, attr, value, defValue, key){
1168
- let isSUCCEED = false;
1315
+ function writeXObjAttrEx(obj, attr, value, opt, key) {
1316
+ let isSucceed = false;
1169
1317
  if (value !== undefined) {
1170
- const _defValue = readAsString(defValue, {
1171
- useTrim: true,
1172
- numberToString: true,
1173
- boolToString: true,
1174
- });
1175
- const _value = readAsString(value, {
1176
- useTrim: true,
1177
- numberToString: true,
1178
- boolToString: true,
1179
- defValue: _defValue,
1180
- });
1318
+ let _opt = opt;
1319
+ if (!isPlainObject(_opt)) {
1320
+ const defValue = readAsString(_opt, {
1321
+ useTrim: true,
1322
+ numberToString: true,
1323
+ boolToString: true,
1324
+ });
1325
+ _opt = {
1326
+ useTrim: true,
1327
+ numberToString: true,
1328
+ boolToString: true,
1329
+ defValue,
1330
+ };
1331
+ };
1332
+ const _value = readAsString(value, _opt);
1181
1333
  try {
1182
- isSUCCEED = writeXObjAttrRaw(obj, attr, _value, key);
1334
+ isSucceed = writeXObjAttrRaw(obj, attr, _value, key);
1183
1335
  } catch (err) {
1184
1336
  switch (err.code) {
1185
1337
  case XOBJ_TE_NSTR_ECODE : {
@@ -1187,125 +1339,158 @@ function writeXObjAttrEx(obj, attr, value, defValue, key){
1187
1339
  }
1188
1340
  default: {
1189
1341
  throw err;
1190
- break;
1191
1342
  }
1192
1343
  };
1193
1344
  };
1194
1345
  };
1195
- return isSUCCEED;
1346
+ return isSucceed;
1196
1347
  };
1197
1348
 
1198
1349
  /**
1199
1350
  * @function insertXObjElements
1200
- * @param {object}
1201
- * @param {...ID_STRING} args - list of a keys
1202
- * @param {object} [opt]
1351
+ * @param {object} obj
1352
+ * @param {...string} name
1353
+ * @param {OPT_inselops_L} [opt]
1203
1354
  * @returns {number}
1204
- * @throws {TypeError}
1355
+ * @throws {TypeError} if first param is not an object
1205
1356
  * @description Inserts an elements into a given object.
1206
1357
  */
1207
- function insertXObjElements(obj, ...args){
1358
+ function insertXObjElements(obj, ...args) {
1208
1359
  if (!isPlainObject(obj)) {
1209
- let err = new TypeError(XOBJ_TE_NPOBJ_EMSG);
1360
+ const err = new TypeError(XOBJ_TE_NPOBJ_EMSG);
1210
1361
  err.code = XOBJ_TE_NPOBJ_ECODE;
1211
1362
  throw err;
1212
1363
  };
1213
- const len = args.length;
1214
- const hasOpt = len > 0 && isPlainObject(args[len - 1]);
1215
- const opt = hasOpt ? args.pop() : {};
1216
- const names = readAsListS({
1217
- useTrim: true,
1218
- keepEmpty: false,
1219
- }, ...args);
1220
1364
  let count = 0;
1221
- for (let key of names) {
1365
+ let len = args.length;
1366
+ const opt = (
1367
+ len > 0 && isPlainObject(args[len - 1])
1368
+ ? (len--, args.pop())
1369
+ : {}
1370
+ );
1371
+ for (let key of args) {
1222
1372
  if (insertXObjElement(obj, key, opt) !== null) count++;
1223
1373
  };
1224
1374
  return count;
1225
1375
  };
1226
1376
 
1377
+ /**
1378
+ * @typedef {Object} OPT_inselops_S
1379
+ * @property {boolean} [force=false]
1380
+ * @property {boolean} [ripOldies=false]
1381
+ */
1382
+
1227
1383
  /**
1228
1384
  * @function insertXObjEList
1229
- * @param {object}
1230
- * @param {ID_STRING}
1231
- * @param {object} [opt]
1232
- * @param {bool} [opt.force=false]
1233
- * @param {bool} [opt.ripOldies=false]
1234
- * @returns {?any}
1235
- * @throws {TypeError}
1385
+ * @param {object} obj - some object
1386
+ * @param {string} name - some child element
1387
+ * @param {OPT_inselops_S} [opt] - options
1388
+ * @returns {?(object|object[])}
1389
+ * @throws {TypeError} if first param is not an object
1236
1390
  * @description Inserts a list elements into a given object.
1237
1391
  */
1238
- function insertXObjEList(obj, name, opt){
1239
- let err = null;
1392
+ function insertXObjEList(...args) {
1393
+ let item = null;
1394
+ try {
1395
+ ({ item } = insertXObjEListEx(...args));
1396
+ } catch (err) {
1397
+ switch (err.code) {
1398
+ case XOBJ_TE_NSTR_ECODE :
1399
+ case XOBJ_TE_KNES_ECODE : {
1400
+ break;
1401
+ }
1402
+ default: {
1403
+ throw err;
1404
+ }
1405
+ };
1406
+ };
1407
+ return item;
1408
+ };
1409
+
1410
+ /**
1411
+ * @function insertXObjEListEx
1412
+ * @param {object} obj - some object
1413
+ * @param {string} name - some child element
1414
+ * @param {OPT_inselops_S} [opt] - options
1415
+ * @returns {RVAL_emodif}
1416
+ * @throws {TypeError} if first param is not an object
1417
+ * @throws {TypeError} if second param is empty string or not a string at all
1418
+ * @since 0.2.0
1419
+ * @description Inserts a list elements into a given object.
1420
+ */
1421
+ function insertXObjEListEx(obj, name, opt) {
1240
1422
  if (!isPlainObject(obj)) {
1241
- err = new TypeError(XOBJ_TE_NPOBJ_EMSG);
1423
+ const err = new TypeError(XOBJ_TE_NPOBJ_EMSG);
1242
1424
  err.code = XOBJ_TE_NPOBJ_ECODE;
1243
1425
  throw err;
1244
1426
  };
1245
- if (typeof name !== 'string') {
1246
- err = new TypeError(XOBJ_TE_NSTR_EMSG);
1247
- err.code = XOBJ_TE_NSTR_ECODE;
1248
- throw err;
1249
- };
1250
- const key = name.trim();
1251
- if (key === '') {
1252
- err = new TypeError(XOBJ_TE_KNES_EMSG);
1253
- err.code = XOBJ_TE_KNES_ECODE;
1427
+ let { isSucceed, value: key } = evalKeyName(name);
1428
+ if (!isSucceed) {
1429
+ const { code, msg } = key;
1430
+ const err = new TypeError(msg);
1431
+ err.code = code;
1254
1432
  throw err;
1255
1433
  };
1256
1434
  const _options = isPlainObject(opt) ? opt : {};
1257
1435
  let { force, ripOldies } = _options;
1258
1436
  if (typeof force !== 'boolean') force = false;
1259
1437
  if (typeof ripOldies !== 'boolean') ripOldies = false;
1260
- let item = obj[key];
1261
- let isACCEPTED = (
1262
- isNullOrUndef(item)
1263
- || (force && (ripOldies || !isArray(item)))
1264
- );
1265
- if (isACCEPTED) {
1266
- obj[key] = item = [];
1438
+ let prop = obj[key];
1439
+ isSucceed = false;
1440
+ if (
1441
+ isNullOrUndef(prop)
1442
+ || (force && (ripOldies || !isObject(prop)))
1443
+ ) {
1444
+ obj[key] = prop = [];
1445
+ isSucceed = true;
1267
1446
  } else {
1268
- isACCEPTED = isArray(item);
1269
- if (!isACCEPTED && isPlainObject(item)) {
1270
- obj[key] = item = [ item ];
1271
- isACCEPTED = true;
1447
+ if (isObject(prop)) {
1448
+ if (!isArray(prop)) prop = [ prop ];
1449
+ obj[key] = prop;
1450
+ isSucceed = true;
1272
1451
  };
1273
1452
  };
1274
- return isACCEPTED ? item : null;
1453
+ return {
1454
+ isSucceed,
1455
+ item: isSucceed ? prop : null,
1456
+ };
1275
1457
  };
1276
1458
 
1277
1459
  /**
1278
1460
  * @function insertXObjEChain
1279
- * @param {object}
1280
- * @param {ID_STRING}
1281
- * @param {...ID_STRING} args - a list of keys
1282
- * @param {object} [opt]
1461
+ * @param {object} obj - some object
1462
+ * @param {...string} name - some child element
1463
+ * @param {object} [opt] - options
1283
1464
  * @returns {?any}
1284
- * @throws {TypeError}
1465
+ * @throws {TypeError} if first param is not an object
1285
1466
  * @description Inserts a chain of an elements into a given object.
1286
1467
  */
1287
- function insertXObjEChain(obj, ...args){
1468
+ function insertXObjEChain(obj, ...args) {
1288
1469
  if (!isPlainObject(obj)) {
1289
- let err = new TypeError(XOBJ_TE_NPOBJ_EMSG);
1470
+ const err = new TypeError(XOBJ_TE_NPOBJ_EMSG);
1290
1471
  err.code = XOBJ_TE_NPOBJ_ECODE;
1291
1472
  throw err;
1292
1473
  };
1293
- const len = args.length;
1294
- const hasOpt = len > 0 && isPlainObject(args[len - 1]);
1295
- const opt = hasOpt ? args.pop() : {};
1296
- const names = readAsListS({
1297
- useTrim: true,
1298
- keepEmpty: false,
1299
- }, ...args);
1300
- let curObj = obj;
1301
- let isSUCCEED = false;
1302
- for (let key of names) {
1303
- obj = insertXObjElement(obj, key, opt);
1304
- isSUCCEED = isPlainObject(obj);
1305
- if (!isSUCCEED) break;
1306
- curObj = obj;
1307
- };
1308
- return isSUCCEED ? curObj : null;
1474
+ let result = null;
1475
+ let len = args.length;
1476
+ const opt = (
1477
+ len > 0 && isPlainObject(args[len - 1])
1478
+ ? (len--, args.pop())
1479
+ : {}
1480
+ );
1481
+ if (len > 0) {
1482
+ let parent = obj;
1483
+ let child = null;
1484
+ let isSucceed = false;
1485
+ for (let key of args) {
1486
+ child = insertXObjElement(parent, key, opt);
1487
+ isSucceed = isPlainObject(child);
1488
+ if (!isSucceed) break;
1489
+ parent = child;
1490
+ };
1491
+ result = isSucceed ? parent : null;
1492
+ };
1493
+ return result;
1309
1494
  };
1310
1495
 
1311
1496
  /***
@@ -1314,50 +1499,63 @@ function insertXObjEChain(obj, ...args){
1314
1499
 
1315
1500
  // === module exports block ===
1316
1501
 
1317
- exports.XOBJ_DEF_PARAM_TNAME = XOBJ_DEF_PARAM_TNAME;
1318
- exports.XOBJ_DEF_ATTR_TNAME = XOBJ_DEF_ATTR_TNAME;
1319
-
1320
- exports.evalXObjEName = evalXObjEName;
1321
-
1322
- exports.readXObjParamRaw = readXObjParamRaw;
1323
- exports.readXObjParam = readXObjParam;
1324
- exports.readXObjParamAsBool = readXObjParamAsBool;
1325
- exports.readXObjParamAsNum = readXObjParamAsNum;
1326
- exports.readXObjParamAsStr = readXObjParamAsStr;
1327
- exports.readXObjParamAsIndex = readXObjParamAsIndex;
1328
- exports.writeXObjParamRaw = writeXObjParamRaw;
1329
- exports.writeXObjParam = writeXObjParam;
1330
- exports.writeXObjParamAsBool = writeXObjParamAsBool;
1331
- exports.writeXObjParamAsNum = writeXObjParamAsNum;
1332
- exports.writeXObjParamAsIndex = writeXObjParamAsIndex;
1333
- exports.writeXObjParamEx = writeXObjParamEx;
1334
-
1335
- exports.readXObjAttrRaw = readXObjAttrRaw;
1336
- exports.readXObjAttr = readXObjAttr;
1337
- exports.readXObjAttrAsBool = readXObjAttrAsBool;
1338
- exports.readXObjAttrAsNum = readXObjAttrAsNum;
1339
- exports.readXObjAttrAsStr = readXObjAttrAsStr;
1340
- exports.readXObjAttrAsIndex = readXObjAttrAsIndex;
1341
- exports.writeXObjAttrRaw = writeXObjAttrRaw;
1342
- exports.writeXObjAttr = writeXObjAttr;
1343
- exports.writeXObjAttrAsBool = writeXObjAttrAsBool;
1344
- exports.writeXObjAttrAsNum = writeXObjAttrAsNum;
1345
- exports.writeXObjAttrAsIndex = writeXObjAttrAsIndex;
1346
- exports.writeXObjAttrEx = writeXObjAttrEx;
1347
-
1348
- exports.getXObjAttributes = getXObjAttributes;
1349
- exports.checkXObjAttribute = checkXObjAttribute;
1350
- exports.deleteXObjAttribute = deleteXObjAttribute;
1351
-
1352
- exports.getXObjElement = getXObjElement;
1353
- exports.insertXObjElement = insertXObjElement;
1354
- exports.addXObjElement = addXObjElement;
1355
- exports.deleteXObjElement = deleteXObjElement;
1356
- exports.deleteXObjElementEx = deleteXObjElementEx;
1357
- exports.renameXObjElement = renameXObjElement;
1358
-
1359
- exports.insertXObjElements = insertXObjElements;
1360
- exports.insertXObjEList = insertXObjEList;
1361
- exports.insertXObjEChain = insertXObjEChain;
1362
-
1363
- exports.genXObjENameDescr = genXObjENameDescr;
1502
+ module.exports.XOBJ_DEF_PARAM_TNAME = XOBJ_DEF_PARAM_TNAME;
1503
+ module.exports.XOBJ_DEF_ATTR_TNAME = XOBJ_DEF_ATTR_TNAME;
1504
+
1505
+ module.exports.readXObjParamRaw = readXObjParamRaw;
1506
+ module.exports.readXObjParam = readXObjParam;
1507
+ module.exports.readXObjParamAsBool = readXObjParamAsBool;
1508
+ module.exports.readXObjParamAsNum = readXObjParamAsNum;
1509
+ module.exports.readXObjParamEx = readXObjParamEx;
1510
+ module.exports.readXObjParamAsIndex = readXObjParamAsIndex;
1511
+ module.exports.writeXObjParamRaw = writeXObjParamRaw;
1512
+ module.exports.writeXObjParam = writeXObjParam;
1513
+ module.exports.writeXObjParamAsBool = writeXObjParamAsBool;
1514
+ module.exports.writeXObjParamAsNum = writeXObjParamAsNum;
1515
+ module.exports.writeXObjParamAsIndex = writeXObjParamAsIndex;
1516
+ module.exports.writeXObjParamEx = writeXObjParamEx;
1517
+
1518
+ module.exports.readXObjAttrRaw = readXObjAttrRaw;
1519
+ module.exports.readXObjAttr = readXObjAttr;
1520
+ module.exports.readXObjAttrAsBool = readXObjAttrAsBool;
1521
+ module.exports.readXObjAttrAsNum = readXObjAttrAsNum;
1522
+ module.exports.readXObjAttrEx = readXObjAttrEx;
1523
+ module.exports.readXObjAttrAsIndex = readXObjAttrAsIndex;
1524
+ module.exports.writeXObjAttrRaw = writeXObjAttrRaw;
1525
+ module.exports.writeXObjAttr = writeXObjAttr;
1526
+ module.exports.writeXObjAttrAsBool = writeXObjAttrAsBool;
1527
+ module.exports.writeXObjAttrAsNum = writeXObjAttrAsNum;
1528
+ module.exports.writeXObjAttrAsIndex = writeXObjAttrAsIndex;
1529
+ module.exports.writeXObjAttrEx = writeXObjAttrEx;
1530
+
1531
+ module.exports.getXObjAttributes = getXObjAttributes;
1532
+ module.exports.checkXObjAttribute = checkXObjAttribute;
1533
+ module.exports.deleteXObjAttribute = deleteXObjAttribute;
1534
+ module.exports.renameXObjAttribute = renameXObjAttribute;
1535
+
1536
+ module.exports.getXObjElement = getXObjElement;
1537
+ module.exports.addXObjElement = addXObjElement;
1538
+ module.exports.insertXObjElement = insertXObjElement;
1539
+ module.exports.insertXObjElementEx = insertXObjElementEx;
1540
+ module.exports.deleteXObjElement = deleteXObjElement;
1541
+ module.exports.deleteXObjElementEx = deleteXObjElementEx;
1542
+ module.exports.renameXObjElement = renameXObjElement;
1543
+
1544
+ module.exports.evalXObjEName = evalXObjEName;
1545
+ module.exports.insertXObjEList = insertXObjEList;
1546
+ module.exports.insertXObjEListEx = insertXObjEListEx;
1547
+
1548
+ /* inner */
1549
+ module.exports.evalKeyName = evalKeyName;
1550
+
1551
+ /* experimental */
1552
+ module.exports.genXObjENameDescr = genXObjENameDescr;
1553
+ /* experimental */
1554
+ module.exports.insertXObjElements = insertXObjElements;
1555
+ /* experimental */
1556
+ module.exports.insertXObjEChain = insertXObjEChain;
1557
+
1558
+ /** @deprecated */
1559
+ module.exports.readXObjParamAsStr = readXObjParamEx;
1560
+ /** @deprecated */
1561
+ module.exports.readXObjAttrAsStr = readXObjAttrEx;