@nejs/basic-extensions 2.19.0 → 2.21.0

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.
Files changed (68) hide show
  1. package/bin/repl.basics.js +36 -6
  2. package/bin/repl.signature.js +63 -0
  3. package/dist/@nejs/basic-extensions.bundle.2.21.0.js +25 -0
  4. package/dist/@nejs/basic-extensions.bundle.2.21.0.js.map +7 -0
  5. package/dist/cjs/classes/descriptor.d.ts +1 -1
  6. package/dist/cjs/classes/enum.d.ts +37 -19
  7. package/dist/cjs/classes/enum.js +192 -64
  8. package/dist/cjs/classes/enum.js.map +1 -1
  9. package/dist/cjs/classes/iterable.d.ts +3 -3
  10. package/dist/cjs/classes/param.parser.d.ts +1 -7
  11. package/dist/cjs/classes/pluggable.proxy.d.ts +2 -1
  12. package/dist/cjs/classes/property.d.ts +2 -9
  13. package/dist/cjs/classes/refset.d.ts +2 -2
  14. package/dist/cjs/classes/symkeys.d.ts +1 -1
  15. package/dist/cjs/global.this.js +17 -7
  16. package/dist/cjs/global.this.js.map +1 -1
  17. package/dist/cjs/index.d.ts +8 -5
  18. package/dist/cjs/index.js +13 -8
  19. package/dist/cjs/index.js.map +1 -1
  20. package/dist/cjs/string.extensions.js +38 -0
  21. package/dist/cjs/string.extensions.js.map +1 -1
  22. package/dist/cjs/utils/copy.object.d.ts +2 -2
  23. package/dist/cjs/utils/descriptor.utils.d.ts +152 -0
  24. package/dist/cjs/utils/descriptor.utils.js +274 -13
  25. package/dist/cjs/utils/descriptor.utils.js.map +1 -1
  26. package/dist/cjs/utils/index.d.ts +15 -0
  27. package/dist/cjs/utils/index.js +9 -0
  28. package/dist/cjs/utils/index.js.map +1 -1
  29. package/dist/cjs/utils/stdout.d.ts +742 -0
  30. package/dist/cjs/utils/stdout.js +1042 -0
  31. package/dist/cjs/utils/stdout.js.map +1 -0
  32. package/dist/mjs/classes/descriptor.d.ts +1 -1
  33. package/dist/mjs/classes/enum.d.ts +37 -19
  34. package/dist/mjs/classes/enum.js +192 -65
  35. package/dist/mjs/classes/enum.js.map +1 -1
  36. package/dist/mjs/classes/iterable.d.ts +3 -3
  37. package/dist/mjs/classes/param.parser.d.ts +1 -7
  38. package/dist/mjs/classes/pluggable.proxy.d.ts +2 -1
  39. package/dist/mjs/classes/property.d.ts +2 -9
  40. package/dist/mjs/classes/refset.d.ts +2 -2
  41. package/dist/mjs/classes/symkeys.d.ts +1 -1
  42. package/dist/mjs/index.d.ts +8 -5
  43. package/dist/mjs/index.js +13 -8
  44. package/dist/mjs/index.js.map +1 -1
  45. package/dist/mjs/string.extensions.js +38 -0
  46. package/dist/mjs/string.extensions.js.map +1 -1
  47. package/dist/mjs/utils/copy.object.d.ts +2 -2
  48. package/dist/mjs/utils/descriptor.utils.d.ts +152 -0
  49. package/dist/mjs/utils/descriptor.utils.js +268 -13
  50. package/dist/mjs/utils/descriptor.utils.js.map +1 -1
  51. package/dist/mjs/utils/index.d.ts +15 -0
  52. package/dist/mjs/utils/index.js +10 -1
  53. package/dist/mjs/utils/index.js.map +1 -1
  54. package/dist/mjs/utils/stdout.d.ts +742 -0
  55. package/dist/mjs/utils/stdout.js +1037 -0
  56. package/dist/mjs/utils/stdout.js.map +1 -0
  57. package/package.json +6 -20
  58. package/repl.bootstrap.js +24 -16
  59. package/repl.history +30 -15
  60. package/src/classes/enum.js +278 -133
  61. package/src/index.js +22 -8
  62. package/src/string.extensions.js +41 -0
  63. package/src/utils/descriptor.utils.js +332 -14
  64. package/src/utils/index.js +20 -0
  65. package/src/utils/stdout.js +1151 -0
  66. package/tests/utils/descriptor.utils.test.js +130 -0
  67. package/dist/@nejs/basic-extensions.bundle.2.19.0.js +0 -19
  68. package/dist/@nejs/basic-extensions.bundle.2.19.0.js.map +0 -7
@@ -335,7 +335,32 @@ export const DescriptorUtils = {
335
335
  }
336
336
 
337
337
  Object.defineProperty(accessor, 'keys', {
338
- get() { return ['get', 'set', 'configurable', 'enumerable'] },
338
+ get() { return Object.defineProperties(
339
+ ['get', 'set', 'configurable', 'enumerable'],
340
+ {
341
+ from: {
342
+ value: function extractKeysFrom(object) {
343
+ const response = {
344
+ get: undefined,
345
+ set: undefined,
346
+ configurable: undefined,
347
+ enumerable: undefined,
348
+ }
349
+
350
+ if (!object || !(object instanceof Object))
351
+ return response
352
+
353
+ for (const key of DescriptorUtils.accessor.keys) {
354
+ if (Reflect.has(object, key))
355
+ response[key] = object[key]
356
+ }
357
+ },
358
+ writable: false,
359
+ configurable: false,
360
+ enumerable: false
361
+ }
362
+ }
363
+ ) },
339
364
  configurable: true,
340
365
  enumerable: false,
341
366
  })
@@ -448,7 +473,7 @@ export const DescriptorUtils = {
448
473
  configurable = configurable === undefined ? true : !!configurable
449
474
  enumerable = enumerable === undefined ? true : !!enumerable
450
475
 
451
- if (valueIsDescriptor) {
476
+ if (valueIsDescriptor && !(options?.allowDescriptorValue)) {
452
477
  options = {
453
478
  writable: value?.writable ?? true,
454
479
  configurable: value?.configurable ?? true,
@@ -468,7 +493,32 @@ export const DescriptorUtils = {
468
493
  }
469
494
 
470
495
  Object.defineProperty(data, 'keys', {
471
- value: ['value', 'writable', 'configurable', 'enumerable'],
496
+ value: Object.defineProperties(
497
+ ['value', 'writable', 'configurable', 'enumerable'],
498
+ {
499
+ from: {
500
+ value: function extractKeysFrom(object) {
501
+ const response = {
502
+ value: undefined,
503
+ writable: undefined,
504
+ configurable: undefined,
505
+ enumerable: undefined,
506
+ }
507
+
508
+ if (!object || !(object instanceof Object))
509
+ return response
510
+
511
+ for (const key of DescriptorUtils.data.keys) {
512
+ if (Reflect.has(object, key))
513
+ response[key] = object[key]
514
+ }
515
+ },
516
+ writable: false,
517
+ configurable: false,
518
+ enumerable: false,
519
+ }
520
+ }
521
+ ),
472
522
  writable: false,
473
523
  configurable: true,
474
524
  enumerable: false
@@ -477,6 +527,163 @@ export const DescriptorUtils = {
477
527
  return data
478
528
  },
479
529
 
530
+ describe(object, key, value, detectDescriptorValues = true) {
531
+ const { isAccessor, isData, data } = DescriptorUtils
532
+
533
+ if (!(object && object instanceof Object))
534
+ return undefined
535
+
536
+ if (!(['string', 'number', 'symbol'].includes(typeof key)))
537
+ return undefined
538
+
539
+ if (detectDescriptorValues && isAccessor(value) || isData(value)) {
540
+ return Object.defineProperty(object, key, value)
541
+ }
542
+ else {
543
+ return Object.defineProperty(object, key, data(value))
544
+ }
545
+ },
546
+
547
+ describeMany(object, keyValues, detectDescriptorValues = true) {
548
+ const { isAccessor, isData, isDescriptor, data, describe } = DescriptorUtils
549
+ const isKey = k => ['string', 'number', 'symbol'].includes(typeof k)
550
+
551
+ let map = undefined
552
+
553
+ if (Array.isArray(keyValues)) {
554
+ map = new Map(keyValues.filter(keyValue => {
555
+ return typeof keyValue === 'function' && keyValue.length === 2
556
+ }))
557
+ }
558
+ else if (keyValues instanceof Map) {
559
+ map = keyValues
560
+ }
561
+ else if (keyValues instanceof Object) {
562
+ const descriptors = Object.getOwnPropertyDescriptors(keyValues)
563
+ map = new Object.entries(descriptors)
564
+ }
565
+ else {
566
+ return []
567
+ }
568
+
569
+ for (const [key, value] of map) {
570
+ if (detectDescriptorValues) {
571
+ if (isDescriptor(key)) {
572
+
573
+ }
574
+ }
575
+ }
576
+
577
+ const accessorBase = { enumerable: true, configurable: true }
578
+ const dataBase = { writable: true, ...accessorBase }
579
+ const extractBase = descriptor => {
580
+ if (isAccessor(descriptor)) {
581
+ const { configurable, enumerable } = descriptor
582
+ return { configurable, enumerable }
583
+ }
584
+ else if (isData(descriptor)) {
585
+ const { writable, configurable, enumerable } = descriptor
586
+ return { writable, configurable, enumerable }
587
+ }
588
+ return undefined
589
+ }
590
+
591
+ // convert all map entries to
592
+ // [baseDescriptor, {key: value, key: value, ...}]
593
+ // unless detectDescriptorValues == false in which case
594
+ // [dataBase, { key: value, key: value, etc... }]
595
+ // ... dropping all non-isKey(key) values
596
+
597
+ for (const [key, value] of map.entries()) {
598
+ const descriptor = (detectDescriptorValues && isDescriptor(value)
599
+ ? value
600
+ : data(value, dataBase)
601
+ )
602
+
603
+ }
604
+
605
+ },
606
+
607
+ extract(
608
+ fromObject,
609
+ keysToExtract,
610
+ defaultIfMissing = undefined,
611
+ extractDescriptors = false
612
+ ) {
613
+ const { data } = DescriptorUtils
614
+ const output = { }
615
+
616
+ if (!fromObject || typeof fromObject !== 'object')
617
+ return output
618
+
619
+ if (!Array.isArray(keysToExtract))
620
+ keysToExtract = [keysToExtract]
621
+
622
+ for (const key of keysToExtract) {
623
+ let descriptor = Object.getOwnPropertyDescriptor(fromObject, key)
624
+
625
+ if (!descriptor)
626
+ descriptor = data(defaultIfMissing)
627
+
628
+ if (extractDescriptors)
629
+ descriptor.value = data(descriptor, { allowDescriptorValue: true })
630
+
631
+ Object.defineProperty(output, key, descriptor)
632
+ }
633
+
634
+ return output
635
+ },
636
+
637
+ /**
638
+ * Determines if a given value is an accessor descriptor.
639
+ *
640
+ * An accessor descriptor is a property descriptor that defines
641
+ * getter and/or setter functions for a property. This function
642
+ * checks the validity of the descriptor and whether it qualifies
643
+ * as an accessor.
644
+ *
645
+ * @param {Object} value - The descriptor object to evaluate.
646
+ * @param {boolean} [strict=true] - If true, performs a strict
647
+ * validation of the descriptor.
648
+ * @returns {boolean} Returns true if the descriptor is valid and
649
+ * is an accessor descriptor, otherwise false.
650
+ *
651
+ * @example
652
+ * // Example usage:
653
+ * const descriptor = { get: () => 42, set: (val) => {} }
654
+ * const result = DescriptorUtils.isAccessor(descriptor)
655
+ * console.log(result) // Outputs: true
656
+ */
657
+ isAccessor(value, strict = true) {
658
+ const stats = DescriptorUtils.isDescriptor(value, true, strict)
659
+ return stats.isValid && stats.isAccessor
660
+ },
661
+
662
+ /**
663
+ * Checks if a given value is a data descriptor.
664
+ *
665
+ * A data descriptor is a property descriptor that defines a value
666
+ * and optionally a writable attribute for a property. This function
667
+ * evaluates the descriptor's validity and whether it qualifies as
668
+ * a data descriptor.
669
+ *
670
+ * @param {Object} value - The descriptor object to evaluate.
671
+ * @param {boolean} [strict=true] - If true, performs a strict
672
+ * validation of the descriptor.
673
+ * @returns {boolean} Returns true if the descriptor is valid and
674
+ * is a data descriptor, otherwise false.
675
+ *
676
+ * @example
677
+ * // Example usage:
678
+ * const descriptor = { value: 42, writable: true }
679
+ * const result = DescriptorUtils.isData(descriptor)
680
+ * console.log(result) // Outputs: true
681
+ */
682
+ isData(value, strict = true) {
683
+ const stats = DescriptorUtils.isDescriptor(value, true, strict)
684
+ return stats.isValid && stats.isData
685
+ },
686
+
480
687
  /**
481
688
  * A function that, given a value that might be a `PropertyDescriptor`,
482
689
  * calculates a deterministic probability that the supplied value is
@@ -502,9 +709,6 @@ export const DescriptorUtils = {
502
709
  * stats block.
503
710
  */
504
711
  isDescriptor(value, returnStats = false, strict = true) {
505
- if (!value || typeof value !== 'object' || !(value instanceof Object))
506
- return false
507
-
508
712
  const areBools = (...props) => props.flat().every(
509
713
  prop => boolTypes.includes(typeof value[prop])
510
714
  );
@@ -530,8 +734,12 @@ export const DescriptorUtils = {
530
734
  isAccessor: false,
531
735
  isData: false,
532
736
  isValid: false,
737
+ isBase: false,
533
738
  }
534
739
 
740
+ if (!value || typeof value !== 'object' || !(value instanceof Object))
741
+ return returnStats ? stats : false;
742
+
535
743
  let score = 0
536
744
 
537
745
  if (value && typeof value === 'object') {
@@ -568,6 +776,9 @@ export const DescriptorUtils = {
568
776
  if (score > 0 && stats.hasDataKeys)
569
777
  stats.isData = true
570
778
 
779
+ if (stats.isValid && !(['get','set','value'].some(hasKeyFn)))
780
+ stats.isBase = true
781
+
571
782
  if (stats.isValid && stats.isData && Reflect.has(value, 'value'))
572
783
  score++
573
784
 
@@ -592,6 +803,104 @@ export const DescriptorUtils = {
592
803
  : false;
593
804
  },
594
805
 
806
+ /**
807
+ * Redefines a property on an object with new descriptors and options.
808
+ * This function allows renaming, aliasing, and redefining property
809
+ * descriptors such as configurable, enumerable, writable, get, and set.
810
+ *
811
+ * @param {Object} object - The target object whose property is to be
812
+ * redefined.
813
+ * @param {string|symbol} key - The key of the property to redefine.
814
+ * @param {Object} as - An object containing new property descriptors.
815
+ * @param {Object} [options] - Optional settings for renaming and aliasing.
816
+ * @param {string|symbol} [options.rename] - New key name for the property.
817
+ * @param {Array<string|symbol>} [options.alsoAs] - Additional aliases for
818
+ * the property.
819
+ * @param {Object} [options.moveTo] optionally move the descriptor from this
820
+ * object to another.
821
+ * @returns {any} the result of `object[key]` in its final state
822
+ *
823
+ * @example
824
+ * const obj = { a: 1 }
825
+ * redescribe(obj, 'a', { writable: false }, { rename: 'b', alsoAs: ['c'] })
826
+ * console.log(obj.b) // Outputs: 1
827
+ * console.log(obj.c) // Outputs: 1
828
+ */
829
+ redescribe(object, key, as, options) {
830
+ const { isAccessor, isData } = DescriptorUtils
831
+
832
+ const ifThen = (condition, fn, ...args) => condition && fn(...args)
833
+ const isBool = value => typeof value === 'boolean' || value instanceof Boolean
834
+ const isFunction = value => typeof value === 'function'
835
+ const isObject = value => value && value instanceof Object
836
+ const isDefined = (value, key) => isObject(value) && Reflect.has(value, key)
837
+ const isObjectKey = v => ['string', 'number', 'symbol'].includes(typeof v)
838
+ const define = (key, values) => Object.defineProperty(object, key, values)
839
+ const assign = (object, ...values) => Object.assign(object, ...values)
840
+
841
+ const isAnObject = isObject(object)
842
+ let asIsObject = isObject(as)
843
+ const descriptor = isAnObject && Object.getOwnPropertyDescriptor(object, key)
844
+ const aliases = []
845
+
846
+ if (descriptor && !asIsObject) {
847
+ asIsObject = true
848
+ as = {}
849
+ }
850
+
851
+ if (isObject(options)) {
852
+ if (isDefined(options, 'rename')) {
853
+ const successfulDelete = delete object[key]
854
+
855
+ if (successfulDelete)
856
+ key = options.rename
857
+ }
858
+
859
+ if (isDefined(options, 'alsoAs')) {
860
+ if (Array.isArray(options.alsoAs)) {
861
+ for (const value of options.alsoAs.filter(v => isObjectKey(v)))
862
+ aliases.push(value)
863
+ }
864
+ else if (isObjectKey(options.alsoAs)) {
865
+ aliases.push(options.alsoAs)
866
+ }
867
+ }
868
+
869
+ if (isDefined(options, 'moveTo')) {
870
+ ifThen(isObject(options.moveTo), () => (object = options.moveTo))
871
+ }
872
+ }
873
+
874
+ if (isAnObject && asIsObject) {
875
+ let { configurable, enumerable, writable, get, set, value } = as
876
+
877
+ if (isAccessor(descriptor)) {
878
+ ifThen(isFunction(get), () => assign(descriptor, { get }))
879
+ ifThen(isFunction(set), () => assign(descriptor, { set }))
880
+ }
881
+
882
+ ifThen(isBool(writable) && isData(descriptor), () => {
883
+ assign(descriptor, {
884
+ writable,
885
+ value: isDefined(as, 'value')
886
+ ? value
887
+ : descriptor.value,
888
+ })
889
+ })
890
+
891
+ ifThen(isBool(configurable), () => assign(descriptor, { configurable }))
892
+ ifThen(isBool(enumerable), () => assign(descriptor, { enumerable }))
893
+
894
+ define(key, descriptor)
895
+
896
+ for (const alias of aliases) {
897
+ define(alias, descriptor)
898
+ }
899
+
900
+ return object[key]
901
+ }
902
+ },
903
+
595
904
  /**
596
905
  * Retrieves the keys associated with accessor descriptors.
597
906
  *
@@ -673,7 +982,10 @@ export const DescriptorUtils = {
673
982
  }
674
983
 
675
984
  // Destructure the functions individually...
676
- const { accessor, data, isDescriptor } = DescriptorUtils
985
+ const {
986
+ accessor, data, describe, describeMany, extract, isDescriptor,
987
+ isAccessor, isData, redescribe,
988
+ } = DescriptorUtils
677
989
 
678
990
  // ...also destructure the constants individually....
679
991
  const {
@@ -687,7 +999,13 @@ const {
687
999
  export {
688
1000
  accessor,
689
1001
  data,
1002
+ describe,
1003
+ describeMany,
1004
+ extract,
1005
+ isAccessor,
1006
+ isData,
690
1007
  isDescriptor,
1008
+ redescribe,
691
1009
 
692
1010
  kAccessorDescriptorKeys,
693
1011
  kDataDescriptorKeys,
@@ -701,7 +1019,14 @@ export default {
701
1019
 
702
1020
  accessor,
703
1021
  data,
1022
+ describe,
1023
+ describeMany,
1024
+ extract,
1025
+ isAccessor,
1026
+ isData,
704
1027
  isDescriptor,
1028
+ redescribe,
1029
+
705
1030
  kAccessorDescriptorKeys,
706
1031
  kDataDescriptorKeys,
707
1032
  kDescriptorKeys,
@@ -718,10 +1043,3 @@ function hasQuantity(quantityFn, object, keys) {
718
1043
  [quantityFn](has => has)
719
1044
  )
720
1045
  }
721
- function hasOne(object, ...keys) {
722
- return isObject(object) && (keys.flat(Infinity)
723
- .map(key => Reflect.has(object, key))
724
- .filter(has => has)
725
- .length === 1
726
- )
727
- }
@@ -20,6 +20,15 @@ import {
20
20
  kVisibilityKeys,
21
21
  } from './copy.object.js'
22
22
 
23
+ export * from './stdout.js'
24
+ import {
25
+ StringConsole,
26
+ StringConsoleExtension,
27
+ StdoutGlobalPatches,
28
+
29
+ captureStdout,
30
+ } from './stdout.js'
31
+
23
32
  export * from './toolkit.js'
24
33
  import {
25
34
  as,
@@ -34,7 +43,11 @@ export * from './descriptor.utils.js'
34
43
  import {
35
44
  accessor,
36
45
  data,
46
+ describe,
47
+ describeMany,
48
+ extract,
37
49
  isDescriptor,
50
+ redescribe,
38
51
  kAccessorDescriptorKeys,
39
52
  kDataDescriptorKeys,
40
53
  kDescriptorKeys
@@ -48,6 +61,8 @@ export default {
48
61
  ImmutablyVisibleHandler,
49
62
  MutablyHiddenHandler,
50
63
  MutablyVisibleHandler,
64
+ StdoutGlobalPatches,
65
+ StringConsole,
51
66
  VisibilityKeys,
52
67
  VisibilityScopeHandler,
53
68
 
@@ -57,12 +72,17 @@ export default {
57
72
  si,
58
73
 
59
74
  accessor,
75
+ captureStdout,
60
76
  copyObject,
61
77
  createToolkit,
62
78
  customCopyObject,
63
79
  data,
80
+ describe,
81
+ describeMany,
82
+ extract,
64
83
  isDescriptor,
65
84
  makeTransducer,
85
+ redescribe,
66
86
  transduceFrom,
67
87
  transduceFromCOHandler,
68
88
  tryIgnore,