@ygracs/xobj-lib-js 0.3.1 → 0.3.3

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.
@@ -0,0 +1,614 @@
1
+ // [v0.3.140-20260607]
2
+
3
+ // === module init block ===
4
+
5
+ const {
6
+ valueToIndex,
7
+ readAsString, readAsBoolEx, readAsNumberEx,
8
+ isArray, isObject, isPlainObject,
9
+ // * import types definitions *
10
+ IValueToStringTransformOptions,
11
+ } = require('@ygracs/bsfoc-lib-js');
12
+
13
+ const {
14
+ EvalKeyNameError,
15
+ XOBJ_ECODE_TABLE,
16
+ } = require('./xObj-errors');
17
+
18
+ const {
19
+ XOBJ_DEF_TNAMES,
20
+ } = require('./xObj-defs');
21
+
22
+ const {
23
+ evalKeyName,
24
+ getXObjElement, insertXObjElement,
25
+ // * import types definitions *
26
+ INode,
27
+ } = require('./xObj-lib');
28
+
29
+ // === module inner block ===
30
+
31
+ const {
32
+ XOBJ_TE_NSTR_ECODE,
33
+ XOBJ_TE_NPOBJ_EMSG,
34
+ XOBJ_TE_NPOBJ_ECODE,
35
+ XOBJ_TE_KNES_ECODE,
36
+ } = XOBJ_ECODE_TABLE;
37
+
38
+ const {
39
+ XOBJ_DEF_ATTR_TNAME,
40
+ } = XOBJ_DEF_TNAMES;
41
+
42
+ // === module main block ===
43
+
44
+ /**
45
+ * Extracts an attributes from a given object by its key.
46
+ * @function getXObjAttributes
47
+ * @param {INode} obj - some object
48
+ * @param {string} [key=XOBJ_DEF_ATTR_TNAME] - some key
49
+ * @returns {?INode}
50
+ * @throws {TypeError} if `obj` param is not an object
51
+ */
52
+ function getXObjAttributes(obj, key = XOBJ_DEF_ATTR_TNAME) {
53
+ let result = null;
54
+ try {
55
+ result = getXObjElement(obj, key);
56
+ } catch (err) {
57
+ switch (err.code) {
58
+ case XOBJ_TE_NSTR_ECODE :
59
+ case XOBJ_TE_KNES_ECODE : {
60
+ break;
61
+ }
62
+ default: {
63
+ throw err;
64
+ }
65
+ };
66
+ };
67
+ return isPlainObject(result) ? result : null;
68
+ };
69
+ module.exports.getXObjAttributes = getXObjAttributes;
70
+
71
+ /**
72
+ * Checks whether an attribute is exists.
73
+ * @function checkXObjAttribute
74
+ * @param {INode} obj - some object
75
+ * @param {string} attr - some attribute ID
76
+ * @param {string} [key] - some key
77
+ * @returns {boolean}
78
+ * @throws {TypeError} if `obj` param is not an object
79
+ * @throws {EvalKeyNameError} if `attr` param is not valid identifier
80
+ */
81
+ function checkXObjAttribute(obj, attr = '', key) {
82
+ /** @type {?INode} */
83
+ let node = null;
84
+ try {
85
+ node = getXObjAttributes(obj, key);
86
+ } catch (err) {
87
+ throw err;
88
+ };
89
+ if (node === null) return false;
90
+ const { isSucceed, value: name } = evalKeyName(attr, false);
91
+ if (isSucceed) {
92
+ if (name === '') return false;
93
+ return node[name] !== undefined;
94
+ } else {
95
+ const { code, msg } = name;
96
+ throw new EvalKeyNameError(msg, { code });
97
+ };
98
+ };
99
+ module.exports.checkXObjAttribute = checkXObjAttribute;
100
+
101
+ /**
102
+ * Deletes an attribute addressed by a given name.
103
+ * @function deleteXObjAttribute
104
+ * @param {INode} obj - some object
105
+ * @param {string} attr - some attribute ID
106
+ * @param {string} [key] - some key
107
+ * @returns {boolean}
108
+ * @throws {TypeError} if `obj` param is not an object
109
+ * @throws {EvalKeyNameError} if `attr` param is not valid identifier
110
+ */
111
+ function deleteXObjAttribute(obj, attr = '', key) {
112
+ /** @type {?INode} */
113
+ let node = null;
114
+ try {
115
+ node = getXObjAttributes(obj, key);
116
+ } catch (err) {
117
+ throw err;
118
+ };
119
+ if (node === null) return false;
120
+ const { isSucceed, value: name } = evalKeyName(attr, false);
121
+ if (isSucceed) {
122
+ let isSucceed = false;
123
+ if (name !== '') {
124
+ // // TODO: catch errors in strict mode
125
+ isSucceed = delete node[name];
126
+ };
127
+ return isSucceed;
128
+ } else {
129
+ const { code, msg } = name;
130
+ throw new EvalKeyNameError(msg, { code });
131
+ };
132
+ };
133
+ module.exports.deleteXObjAttribute = deleteXObjAttribute;
134
+
135
+ /**
136
+ * Renames an attribute addressed by a given name.
137
+ * @since 0.2.0
138
+ * @function renameXObjAttribute
139
+ * @param {INode} obj - some object
140
+ * @param {string} attr - some attribute ID
141
+ * @param {string} value - new attribute ID
142
+ * @param {string} [key] - some key
143
+ * @returns {boolean}
144
+ * @throws {TypeError} if `obj` param is not an object
145
+ * @throws {EvalKeyNameError} if `attr` param is not valid identifier
146
+ * @throws {EvalKeyNameError} if `value` param is not valid identifier
147
+ * @throws {EvalKeyNameError} if `key` param is not valid identifier
148
+ */
149
+ function renameXObjAttribute(obj, attr = '', value = '', key = XOBJ_DEF_ATTR_TNAME) {
150
+ if (!isPlainObject(obj)) {
151
+ throw new EvalKeyNameError(
152
+ XOBJ_TE_NPOBJ_EMSG,
153
+ { code: XOBJ_TE_NPOBJ_ECODE },
154
+ );
155
+ };
156
+ const opt = false;
157
+ const { isSucceed, value: _key } = evalKeyName(key, opt);
158
+ if (isSucceed) {
159
+ let isSucceed = false;
160
+ if (_key !== '') {
161
+ let _obj = obj[_key];
162
+ if (isPlainObject(_obj)) {
163
+ const { isSucceed: isAcceptON, value: oname } = evalKeyName(attr, opt);
164
+ if (!isAcceptON) {
165
+ const { code, msg } = oname;
166
+ throw new EvalKeyNameError(msg, { code });
167
+ };
168
+ const { isSucceed: isAcceptNN, value: nname } = evalKeyName(value, opt);
169
+ if (!isAcceptNN) {
170
+ const { code, msg } = nname;
171
+ throw new EvalKeyNameError(msg, { code });
172
+ };
173
+ if (oname !== '' && oname in _obj && nname !== '') {
174
+ if (oname !== nname) {
175
+ _obj = Object.entries(_obj);
176
+ const index = _obj.findIndex((item) => item[0] === oname);
177
+ _obj[index][0] = nname;
178
+ obj[_key] = Object.fromEntries(_obj);
179
+ };
180
+ isSucceed = true;
181
+ };
182
+ };
183
+ };
184
+ return isSucceed;
185
+ } else {
186
+ const { code, msg } = _key;
187
+ throw new EvalKeyNameError(msg, { code });
188
+ };
189
+ };
190
+ module.exports.renameXObjAttribute = renameXObjAttribute;
191
+
192
+ /**
193
+ * Extracts an attribute 'AS IS' from a given object.
194
+ * @function readXObjAttrRaw
195
+ * @param {INode} obj - some object
196
+ * @param {string} attr - some attribute
197
+ * @param {string} [key] - some key
198
+ * @returns {any}
199
+ * @throws {TypeError} if `obj` param is not an object
200
+ * @throws {EvalKeyNameError} if `attr` param is not valid identifier
201
+ */
202
+ function readXObjAttrRaw(obj, attr = '', key) {
203
+ /** @type {?INode} */
204
+ let node = null;
205
+ try {
206
+ node = getXObjAttributes(obj, key);
207
+ } catch (err) {
208
+ throw err;
209
+ };
210
+ if (node !== null) {
211
+ const { isSucceed, value: name } = evalKeyName(attr, false);
212
+ if (isSucceed) {
213
+ if (name !== '') return node[name];
214
+ } else {
215
+ const { code, msg } = name;
216
+ throw new EvalKeyNameError(msg, { code });
217
+ };
218
+ };
219
+ };
220
+ module.exports.readXObjAttrRaw = readXObjAttrRaw;
221
+
222
+ /**
223
+ * Writes a parameter into a given object.
224
+ * @function writeXObjAttrRaw
225
+ * @param {INode} obj - some object
226
+ * @param {string} attr - some attribute
227
+ * @param {any} value - some value
228
+ * @param {string} [key=XOBJ_DEF_ATTR_TNAME] - some key
229
+ * @returns {boolean}
230
+ * @throws {TypeError} if `obj` param is not an object
231
+ * @throws {EvalKeyNameError} if `attr` param is not valid identifier
232
+ */
233
+ function writeXObjAttrRaw(obj, attr = '', value, key = XOBJ_DEF_ATTR_TNAME) {
234
+ const { isSucceed, value: name } = evalKeyName(attr, false);
235
+ if (isSucceed) {
236
+ let isSucceed = false;
237
+ if (
238
+ name !== ''
239
+ && value !== undefined
240
+ && !isObject(value)
241
+ && typeof value !== 'function'
242
+ ) {
243
+ let _obj = null;
244
+ try {
245
+ const opt = { force: true, acceptIfList: true };
246
+ _obj = insertXObjElement(obj, key, opt);
247
+ } catch (err) {
248
+ throw err;
249
+ };
250
+ if (isArray(_obj)) {
251
+ // force a replacement of the old element if it's array
252
+ try {
253
+ const opt = { force: true, ripOldies: true };
254
+ _obj = insertXObjElement(obj, key, opt);
255
+ } catch (err) {
256
+ throw err;
257
+ };
258
+ };
259
+ if (_obj !== null) {
260
+ _obj[name] = value;
261
+ isSucceed = true;
262
+ };
263
+ };
264
+ return isSucceed;
265
+ } else {
266
+ const { code, msg } = name;
267
+ throw new EvalKeyNameError(msg, { code });
268
+ };
269
+ };
270
+ module.exports.writeXObjAttrRaw = writeXObjAttrRaw;
271
+
272
+ /**
273
+ * Extracts an attribute from a given object and returns it as a string.
274
+ * @function readXObjAttr
275
+ * @param {INode} obj - some object
276
+ * @param {string} attr - some attribute
277
+ * @param {string} [key] - some key
278
+ * @returns {string}
279
+ * @throws {TypeError} if `obj` param is not an object
280
+ */
281
+ function readXObjAttr(obj, attr, key) {
282
+ const opt = {
283
+ useTrim: true,
284
+ numberToString: true,
285
+ boolToString: true,
286
+ defValue: '',
287
+ };
288
+ let result = undefined;
289
+ try {
290
+ result = readXObjAttrEx(obj, attr, opt, key);
291
+ } catch (err) {
292
+ throw err;
293
+ };
294
+ return result;
295
+ };
296
+ module.exports.readXObjAttr = readXObjAttr;
297
+
298
+ /**
299
+ * Extracts an attribute from a given object and returns it as a boolean.
300
+ * @function readXObjAttrAsBool
301
+ * @param {INode} obj - some object
302
+ * @param {string} attr - some attribute
303
+ * @param {boolean} [defValue] - default value
304
+ * @param {string} [key] - some key
305
+ * @returns {boolean}
306
+ * @throws {TypeError} if `obj` param is not an object
307
+ * @see readAsBoolEx from `@ygracs/bsfoc-lib-js` on details for result
308
+ */
309
+ function readXObjAttrAsBool(obj, attr, defValue, key) {
310
+ let result = undefined;
311
+ try {
312
+ result = readXObjAttrRaw(obj, attr, key);
313
+ } catch (err) {
314
+ switch (err.code) {
315
+ case XOBJ_TE_NSTR_ECODE : {
316
+ break;
317
+ }
318
+ default: {
319
+ throw err;
320
+ }
321
+ };
322
+ };
323
+ return readAsBoolEx(result, defValue);
324
+ };
325
+ module.exports.readXObjAttrAsBool = readXObjAttrAsBool;
326
+
327
+ /**
328
+ * Extracts an attribute from a given object and returns it as a number.
329
+ * @function readXObjAttrAsNum
330
+ * @param {INode} obj - some object
331
+ * @param {string} attr - some attribute
332
+ * @param {number} [defValue] - default value
333
+ * @param {string} [key] - some key
334
+ * @returns {number}
335
+ * @throws {TypeError} if `obj` param is not an object
336
+ * @see readAsNumberEx from `@ygracs/bsfoc-lib-js` on details for result
337
+ */
338
+ function readXObjAttrAsNum(obj, attr, defValue, key) {
339
+ let result = undefined;
340
+ try {
341
+ result = readXObjAttrRaw(obj, attr, key);
342
+ } catch (err) {
343
+ switch (err.code) {
344
+ case XOBJ_TE_NSTR_ECODE : {
345
+ break;
346
+ }
347
+ default: {
348
+ throw err;
349
+ }
350
+ };
351
+ };
352
+ return readAsNumberEx(result, defValue);
353
+ };
354
+ module.exports.readXObjAttrAsNum = readXObjAttrAsNum;
355
+
356
+ /**
357
+ * Extracts an attribute from a given object and returns it as 'index' value.
358
+ * @function readXObjAttrAsIndex
359
+ * @param {INode} obj - some object
360
+ * @param {string} attr - some attribute
361
+ * @param {string} [key] - some key
362
+ * @returns {number}
363
+ * @throws {TypeError} if `obj` param is not an object
364
+ */
365
+ function readXObjAttrAsIndex(obj, attr, key) {
366
+ let result = undefined;
367
+ try {
368
+ result = readXObjAttrRaw(obj, attr, key);
369
+ } catch (err) {
370
+ switch (err.code) {
371
+ case XOBJ_TE_NSTR_ECODE : {
372
+ break;
373
+ }
374
+ default: {
375
+ throw err;
376
+ }
377
+ };
378
+ };
379
+ return valueToIndex(result);
380
+ };
381
+ module.exports.readXObjAttrAsIndex = readXObjAttrAsIndex;
382
+
383
+ /**
384
+ *
385
+ * @typedef {string} readXObjAttrOptionAsStr
386
+ * @deprecated
387
+ * @todo \[since `v0.2.1`] deprecated and will be removed
388
+ */
389
+ /**
390
+ * A virtual constant meant for support jsdoc notation:
391
+ * @type {readXObjAttrOptionAsStr}
392
+ */
393
+ module.exports.readXObjAttrOptionAsStr = '';
394
+
395
+ /**
396
+ * Extracts an attribute from a given object and returns it as a string.
397
+ * @function readXObjAttrEx
398
+ * @param {INode} obj - some object
399
+ * @param {string} attr - some attribute
400
+ * @param {readXObjAttrOptionAsStr|IValueToStringTransformOptions} [opt] - options
401
+ * @param {string} [key] - some key
402
+ * @returns {string}
403
+ * @throws {TypeError} if `obj` param is not an object
404
+ * @todo [since `v0.2.1`] deprecate use of `opt` as `string`
405
+ */
406
+ function readXObjAttrEx(obj, attr, opt, key) {
407
+ let result = undefined;
408
+ try {
409
+ result = readXObjAttrRaw(obj, attr, key);
410
+ } catch (err) {
411
+ switch (err.code) {
412
+ case XOBJ_TE_NSTR_ECODE : {
413
+ break;
414
+ }
415
+ default: {
416
+ throw err;
417
+ }
418
+ };
419
+ };
420
+ const _opt = isPlainObject(opt) ? opt : {
421
+ useTrim: true,
422
+ numberToString: true,
423
+ boolToString: true,
424
+ defValue: opt,
425
+ };
426
+ return readAsString(result, _opt);
427
+ };
428
+ module.exports.readXObjAttrEx = readXObjAttrEx;
429
+
430
+ /**
431
+ * Tries to convert a given value to a string and writes it as an attribute
432
+ * into a given object.
433
+ * @function writeXObjAttr
434
+ * @param {INode} obj - some object
435
+ * @param {string} attr - some attribute
436
+ * @param {any} value - some value
437
+ * @param {string} [key] - some key
438
+ * @returns {boolean}
439
+ * @throws {TypeError} if `obj` param is not an object
440
+ */
441
+ function writeXObjAttr(obj, attr, value, key) {
442
+ let isSucceed = false;
443
+ try {
444
+ const opt = {
445
+ useTrim: true,
446
+ numberToString: true,
447
+ boolToString: true,
448
+ defValue: '',
449
+ };
450
+ isSucceed = writeXObjAttrEx(obj, attr, value, opt, key);
451
+ } catch (err) {
452
+ throw err;
453
+ };
454
+ return isSucceed;
455
+ };
456
+ module.exports.writeXObjAttr = writeXObjAttr;
457
+
458
+ /**
459
+ * Tries to convert a given value to a boolean and writes it as an attribute
460
+ * into a given object.
461
+ * @function writeXObjAttrAsBool
462
+ * @param {INode} obj - some object
463
+ * @param {string} attr - some attribute
464
+ * @param {any} value - some value
465
+ * @param {boolean} [defValue] - default value
466
+ * @param {string} [key] - some key
467
+ * @returns {boolean}
468
+ * @throws {TypeError} if `obj` param is not an object
469
+ */
470
+ function writeXObjAttrAsBool(obj, attr, value, defValue, key) {
471
+ let isSucceed = false;
472
+ if (value !== undefined || typeof defValue === 'boolean') {
473
+ const _value = readAsBoolEx(value, defValue).toString();
474
+ try {
475
+ isSucceed = writeXObjAttrRaw(obj, attr, _value, key);
476
+ } catch (err) {
477
+ switch (err.code) {
478
+ case XOBJ_TE_NSTR_ECODE : {
479
+ break;
480
+ }
481
+ default: {
482
+ throw err;
483
+ }
484
+ };
485
+ };
486
+ };
487
+ return isSucceed;
488
+ };
489
+ module.exports.writeXObjAttrAsBool = writeXObjAttrAsBool;
490
+
491
+ /**
492
+ * Tries to convert a given value to a number and writes it as an attribute
493
+ * into a given object.
494
+ * @function writeXObjAttrAsNum
495
+ * @param {INode} obj - some object
496
+ * @param {string} attr - some attribute
497
+ * @param {any} value - some value
498
+ * @param {number} [defValue] - default value
499
+ * @param {string} [key] - some key
500
+ * @returns {boolean}
501
+ * @throws {TypeError} if `obj` param is not an object
502
+ */
503
+ function writeXObjAttrAsNum(obj, attr, value, defValue, key) {
504
+ let isSucceed = false;
505
+ if (value !== undefined || typeof defValue === 'number') {
506
+ const _value = readAsNumberEx(value, defValue).toString();
507
+ try {
508
+ isSucceed = writeXObjAttrRaw(obj, attr, _value, key);
509
+ } catch (err) {
510
+ switch (err.code) {
511
+ case XOBJ_TE_NSTR_ECODE : {
512
+ break;
513
+ }
514
+ default: {
515
+ throw err;
516
+ }
517
+ };
518
+ };
519
+ };
520
+ return isSucceed;
521
+ };
522
+ module.exports.writeXObjAttrAsNum = writeXObjAttrAsNum;
523
+
524
+ /**
525
+ * Tries to convert a given value into an 'index' value and writes it
526
+ * as an attribute into a given object.
527
+ * @function writeXObjAttrAsIndex
528
+ * @param {INode} obj - some object
529
+ * @param {string} attr - some attribute
530
+ * @param {any} value - some value
531
+ * @param {string} [key] - some key
532
+ * @returns {boolean}
533
+ * @throws {TypeError} if `obj` param is not an object
534
+ */
535
+ function writeXObjAttrAsIndex(obj, attr, value, key) {
536
+ let isSucceed = false;
537
+ if (value !== undefined) {
538
+ const _value = valueToIndex(value).toString();
539
+ try {
540
+ isSucceed = writeXObjAttrRaw(obj, attr, _value, key);
541
+ } catch (err) {
542
+ switch (err.code) {
543
+ case XOBJ_TE_NSTR_ECODE : {
544
+ break;
545
+ }
546
+ default: {
547
+ throw err;
548
+ }
549
+ };
550
+ };
551
+ };
552
+ return isSucceed;
553
+ };
554
+ module.exports.writeXObjAttrAsIndex = writeXObjAttrAsIndex;
555
+
556
+ /**
557
+ *
558
+ * @typedef {string} writeXObjAttrOptionAsStr
559
+ * @deprecated
560
+ * @todo \[since `v0.2.1`] deprecated and will be removed
561
+ */
562
+ /**
563
+ * A virtual constant meant for support jsdoc notation:
564
+ * @type {writeXObjAttrOptionAsStr}
565
+ */
566
+ module.exports.writeXObjAttrOptionAsStr = '';
567
+
568
+ /**
569
+ * Tries to convert a given value to a string and writes it as an attribute
570
+ * into a given object.
571
+ * @function writeXObjAttrEx
572
+ * @param {INode} obj - some object
573
+ * @param {string} attr - some attribute
574
+ * @param {any} value - some value
575
+ * @param {writeXObjAttrOptionAsStr|IValueToStringTransformOptions} [opt] - options
576
+ * @param {string} [key] - some key
577
+ * @returns {boolean}
578
+ * @throws {TypeError} if `obj` param is not an object
579
+ * @todo [since `v0.2.1`] deprecate use of `opt` as `string`
580
+ */
581
+ function writeXObjAttrEx(obj, attr, value, opt, key) {
582
+ let isSucceed = false;
583
+ if (value !== undefined && typeof value !== 'function') {
584
+ let _opt = opt;
585
+ if (!isPlainObject(_opt)) {
586
+ const defValue = readAsString(_opt, {
587
+ useTrim: true,
588
+ numberToString: true,
589
+ boolToString: true,
590
+ });
591
+ _opt = {
592
+ useTrim: true,
593
+ numberToString: true,
594
+ boolToString: true,
595
+ defValue,
596
+ };
597
+ };
598
+ const _value = readAsString(value, _opt);
599
+ try {
600
+ isSucceed = writeXObjAttrRaw(obj, attr, _value, key);
601
+ } catch (err) {
602
+ switch (err.code) {
603
+ case XOBJ_TE_NSTR_ECODE : {
604
+ break;
605
+ }
606
+ default: {
607
+ throw err;
608
+ }
609
+ };
610
+ };
611
+ };
612
+ return isSucceed;
613
+ };
614
+ module.exports.writeXObjAttrEx = writeXObjAttrEx;