@nejs/basic-extensions 2.20.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 +181 -56
  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 +228 -9
  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 +181 -57
  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 +222 -9
  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 -30
  60. package/src/classes/enum.js +249 -109
  61. package/src/index.js +22 -8
  62. package/src/string.extensions.js +41 -0
  63. package/src/utils/descriptor.utils.js +277 -9
  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.20.0.js +0 -19
  68. package/dist/@nejs/basic-extensions.bundle.2.20.0.js.map +0 -7
@@ -473,7 +473,7 @@ export const DescriptorUtils = {
473
473
  configurable = configurable === undefined ? true : !!configurable
474
474
  enumerable = enumerable === undefined ? true : !!enumerable
475
475
 
476
- if (valueIsDescriptor) {
476
+ if (valueIsDescriptor && !(options?.allowDescriptorValue)) {
477
477
  options = {
478
478
  writable: value?.writable ?? true,
479
479
  configurable: value?.configurable ?? true,
@@ -527,6 +527,163 @@ export const DescriptorUtils = {
527
527
  return data
528
528
  },
529
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
+
530
687
  /**
531
688
  * A function that, given a value that might be a `PropertyDescriptor`,
532
689
  * calculates a deterministic probability that the supplied value is
@@ -577,6 +734,7 @@ export const DescriptorUtils = {
577
734
  isAccessor: false,
578
735
  isData: false,
579
736
  isValid: false,
737
+ isBase: false,
580
738
  }
581
739
 
582
740
  if (!value || typeof value !== 'object' || !(value instanceof Object))
@@ -618,6 +776,9 @@ export const DescriptorUtils = {
618
776
  if (score > 0 && stats.hasDataKeys)
619
777
  stats.isData = true
620
778
 
779
+ if (stats.isValid && !(['get','set','value'].some(hasKeyFn)))
780
+ stats.isBase = true
781
+
621
782
  if (stats.isValid && stats.isData && Reflect.has(value, 'value'))
622
783
  score++
623
784
 
@@ -642,6 +803,104 @@ export const DescriptorUtils = {
642
803
  : false;
643
804
  },
644
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
+
645
904
  /**
646
905
  * Retrieves the keys associated with accessor descriptors.
647
906
  *
@@ -723,7 +982,10 @@ export const DescriptorUtils = {
723
982
  }
724
983
 
725
984
  // Destructure the functions individually...
726
- const { accessor, data, isDescriptor } = DescriptorUtils
985
+ const {
986
+ accessor, data, describe, describeMany, extract, isDescriptor,
987
+ isAccessor, isData, redescribe,
988
+ } = DescriptorUtils
727
989
 
728
990
  // ...also destructure the constants individually....
729
991
  const {
@@ -737,7 +999,13 @@ const {
737
999
  export {
738
1000
  accessor,
739
1001
  data,
1002
+ describe,
1003
+ describeMany,
1004
+ extract,
1005
+ isAccessor,
1006
+ isData,
740
1007
  isDescriptor,
1008
+ redescribe,
741
1009
 
742
1010
  kAccessorDescriptorKeys,
743
1011
  kDataDescriptorKeys,
@@ -751,7 +1019,14 @@ export default {
751
1019
 
752
1020
  accessor,
753
1021
  data,
1022
+ describe,
1023
+ describeMany,
1024
+ extract,
1025
+ isAccessor,
1026
+ isData,
754
1027
  isDescriptor,
1028
+ redescribe,
1029
+
755
1030
  kAccessorDescriptorKeys,
756
1031
  kDataDescriptorKeys,
757
1032
  kDescriptorKeys,
@@ -768,10 +1043,3 @@ function hasQuantity(quantityFn, object, keys) {
768
1043
  [quantityFn](has => has)
769
1044
  )
770
1045
  }
771
- function hasOne(object, ...keys) {
772
- return isObject(object) && (keys.flat(Infinity)
773
- .map(key => Reflect.has(object, key))
774
- .filter(has => has)
775
- .length === 1
776
- )
777
- }
@@ -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,