@ygracs/xobj-lib-js 0.3.0 → 0.3.2

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,591 @@
1
+ // [v0.3.138-20260530]
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 {object} 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 {object} 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 {object} 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 {object} 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 {object} 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 {object} 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 {object} 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 {object} 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 {object} 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 {object} 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
+ * Extracts an attribute from a given object and returns it as a string.
385
+ * @function readXObjAttrEx
386
+ * @param {object} obj - some object
387
+ * @param {string} attr - some attribute
388
+ * @param {object} [opt] - options
389
+ * @param {string} [key] - some key
390
+ * @returns {string}
391
+ * @throws {TypeError} if `obj` param is not an object
392
+ * @todo [since `v0.2.1`] deprecate use of `opt` as `string`
393
+ */
394
+ function readXObjAttrEx(obj, attr, opt, key) {
395
+ let result = undefined;
396
+ try {
397
+ result = readXObjAttrRaw(obj, attr, key);
398
+ } catch (err) {
399
+ switch (err.code) {
400
+ case XOBJ_TE_NSTR_ECODE : {
401
+ break;
402
+ }
403
+ default: {
404
+ throw err;
405
+ }
406
+ };
407
+ };
408
+ /** @type {IValueToStringTransformOptions} */
409
+ const _opt = isPlainObject(opt) ? opt : {
410
+ useTrim: true,
411
+ numberToString: true,
412
+ boolToString: true,
413
+ defValue: opt,
414
+ };
415
+ return readAsString(result, _opt);
416
+ };
417
+ module.exports.readXObjAttrEx = readXObjAttrEx;
418
+
419
+ /**
420
+ * Tries to convert a given value to a string and writes it as an attribute
421
+ * into a given object.
422
+ * @function writeXObjAttr
423
+ * @param {object} obj - some object
424
+ * @param {string} attr - some attribute
425
+ * @param {any} value - some value
426
+ * @param {string} [key] - some key
427
+ * @returns {boolean}
428
+ * @throws {TypeError} if `obj` param is not an object
429
+ */
430
+ function writeXObjAttr(obj, attr, value, key) {
431
+ let isSucceed = false;
432
+ try {
433
+ const opt = {
434
+ useTrim: true,
435
+ numberToString: true,
436
+ boolToString: true,
437
+ defValue: '',
438
+ };
439
+ isSucceed = writeXObjAttrEx(obj, attr, value, opt, key);
440
+ } catch (err) {
441
+ throw err;
442
+ };
443
+ return isSucceed;
444
+ };
445
+ module.exports.writeXObjAttr = writeXObjAttr;
446
+
447
+ /**
448
+ * Tries to convert a given value to a boolean and writes it as an attribute
449
+ * into a given object.
450
+ * @function writeXObjAttrAsBool
451
+ * @param {object} obj - some object
452
+ * @param {string} attr - some attribute
453
+ * @param {any} value - some value
454
+ * @param {boolean} [defValue] - default value
455
+ * @param {string} [key] - some key
456
+ * @returns {boolean}
457
+ * @throws {TypeError} if `obj` param is not an object
458
+ */
459
+ function writeXObjAttrAsBool(obj, attr, value, defValue, key) {
460
+ let isSucceed = false;
461
+ if (value !== undefined || typeof defValue === 'boolean') {
462
+ const _value = readAsBoolEx(value, defValue).toString();
463
+ try {
464
+ isSucceed = writeXObjAttrRaw(obj, attr, _value, key);
465
+ } catch (err) {
466
+ switch (err.code) {
467
+ case XOBJ_TE_NSTR_ECODE : {
468
+ break;
469
+ }
470
+ default: {
471
+ throw err;
472
+ }
473
+ };
474
+ };
475
+ };
476
+ return isSucceed;
477
+ };
478
+ module.exports.writeXObjAttrAsBool = writeXObjAttrAsBool;
479
+
480
+ /**
481
+ * Tries to convert a given value to a number and writes it as an attribute
482
+ * into a given object.
483
+ * @function writeXObjAttrAsNum
484
+ * @param {object} obj - some object
485
+ * @param {string} attr - some attribute
486
+ * @param {any} value - some value
487
+ * @param {number} [defValue] - default value
488
+ * @param {string} [key] - some key
489
+ * @returns {boolean}
490
+ * @throws {TypeError} if `obj` param is not an object
491
+ */
492
+ function writeXObjAttrAsNum(obj, attr, value, defValue, key) {
493
+ let isSucceed = false;
494
+ if (value !== undefined || typeof defValue === 'number') {
495
+ const _value = readAsNumberEx(value, defValue).toString();
496
+ try {
497
+ isSucceed = writeXObjAttrRaw(obj, attr, _value, key);
498
+ } catch (err) {
499
+ switch (err.code) {
500
+ case XOBJ_TE_NSTR_ECODE : {
501
+ break;
502
+ }
503
+ default: {
504
+ throw err;
505
+ }
506
+ };
507
+ };
508
+ };
509
+ return isSucceed;
510
+ };
511
+ module.exports.writeXObjAttrAsNum = writeXObjAttrAsNum;
512
+
513
+ /**
514
+ * Tries to convert a given value into an 'index' value and writes it
515
+ * as an attribute into a given object.
516
+ * @function writeXObjAttrAsIndex
517
+ * @param {object} obj - some object
518
+ * @param {string} attr - some attribute
519
+ * @param {any} value - some value
520
+ * @param {string} [key] - some key
521
+ * @returns {boolean}
522
+ * @throws {TypeError} if `obj` param is not an object
523
+ */
524
+ function writeXObjAttrAsIndex(obj, attr, value, key) {
525
+ let isSucceed = false;
526
+ if (value !== undefined) {
527
+ const _value = valueToIndex(value).toString();
528
+ try {
529
+ isSucceed = writeXObjAttrRaw(obj, attr, _value, key);
530
+ } catch (err) {
531
+ switch (err.code) {
532
+ case XOBJ_TE_NSTR_ECODE : {
533
+ break;
534
+ }
535
+ default: {
536
+ throw err;
537
+ }
538
+ };
539
+ };
540
+ };
541
+ return isSucceed;
542
+ };
543
+ module.exports.writeXObjAttrAsIndex = writeXObjAttrAsIndex;
544
+
545
+ /**
546
+ * Tries to convert a given value to a string and writes it as an attribute
547
+ * into a given object.
548
+ * @function writeXObjAttrEx
549
+ * @param {object} obj - some object
550
+ * @param {string} attr - some attribute
551
+ * @param {any} value - some value
552
+ * @param {object} [opt] - options
553
+ * @param {string} [key] - some key
554
+ * @returns {boolean}
555
+ * @throws {TypeError} if `obj` param is not an object
556
+ * @todo [since `v0.2.1`] deprecate use of `opt` as `string`
557
+ */
558
+ function writeXObjAttrEx(obj, attr, value, opt, key) {
559
+ let isSucceed = false;
560
+ if (value !== undefined && typeof value !== 'function') {
561
+ let _opt = opt;
562
+ if (!isPlainObject(_opt)) {
563
+ const defValue = readAsString(_opt, {
564
+ useTrim: true,
565
+ numberToString: true,
566
+ boolToString: true,
567
+ });
568
+ _opt = {
569
+ useTrim: true,
570
+ numberToString: true,
571
+ boolToString: true,
572
+ defValue,
573
+ };
574
+ };
575
+ const _value = readAsString(value, _opt);
576
+ try {
577
+ isSucceed = writeXObjAttrRaw(obj, attr, _value, key);
578
+ } catch (err) {
579
+ switch (err.code) {
580
+ case XOBJ_TE_NSTR_ECODE : {
581
+ break;
582
+ }
583
+ default: {
584
+ throw err;
585
+ }
586
+ };
587
+ };
588
+ };
589
+ return isSucceed;
590
+ };
591
+ module.exports.writeXObjAttrEx = writeXObjAttrEx;