@nejs/basic-extensions 2.21.5 → 2.22.6

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 (266) hide show
  1. package/README.md +78 -4
  2. package/dist/@nejs/basic-extensions.bundle.2.22.6.js +25 -0
  3. package/dist/@nejs/basic-extensions.bundle.2.22.6.js.map +7 -0
  4. package/dist/cjs/classes/index.cjs +11129 -0
  5. package/dist/cjs/classes/index.cjs.map +7 -0
  6. package/dist/cjs/index.cjs +15191 -0
  7. package/dist/cjs/index.cjs.map +7 -0
  8. package/dist/cjs/utils/index.cjs +3954 -0
  9. package/dist/cjs/utils/index.cjs.map +7 -0
  10. package/dist/esm/basic-extensions.mjs +25 -0
  11. package/dist/esm/basic-extensions.mjs.map +7 -0
  12. package/package.json +16 -22
  13. package/repl.bootstrap.js +4 -7
  14. package/repl.history +26 -26
  15. package/src/classes/enumeration.js +466 -0
  16. package/src/classes/index.js +5 -1
  17. package/src/index.js +3 -1
  18. package/src/regular.expression.extensions.js +0 -35
  19. package/src/utils/toolkit.js +699 -516
  20. package/tests/arrayextensions.test.js +3 -3
  21. package/tests/index.test.js +3 -1
  22. package/tests/newClasses/asyncIterable.test.js +3 -3
  23. package/tests/newClasses/deferred.test.js +3 -3
  24. package/tests/newClasses/descriptor.test.js +3 -3
  25. package/tests/newClasses/iterable.test.js +3 -3
  26. package/tests/newClasses/refmap.test.js +3 -3
  27. package/tests/newClasses/refset.test.js +3 -3
  28. package/tests/objectextensions.test.js +3 -3
  29. package/tests/setextensions.test.js +3 -3
  30. package/tests/stringextensions.test.js +3 -2
  31. package/tests/utils/descriptor.utils.test.js +1 -1
  32. package/tests/utils/toolkit.test.js +429 -163
  33. package/.esdoc.json +0 -9
  34. package/.vscode/settings.json +0 -5
  35. package/bin/build +0 -27
  36. package/bin/clean +0 -14
  37. package/bin/esbuild +0 -91
  38. package/bin/fixup +0 -13
  39. package/bin/repl.basics.js +0 -584
  40. package/bin/repl.signature.js +0 -63
  41. package/bin/version +0 -100
  42. package/dist/@nejs/basic-extensions.bundle.2.21.5.js +0 -25
  43. package/dist/@nejs/basic-extensions.bundle.2.21.5.js.map +0 -7
  44. package/dist/cjs/array.extensions.d.ts +0 -39
  45. package/dist/cjs/array.extensions.js +0 -477
  46. package/dist/cjs/array.extensions.js.map +0 -1
  47. package/dist/cjs/big.int.extension.d.ts +0 -31
  48. package/dist/cjs/big.int.extension.js +0 -273
  49. package/dist/cjs/big.int.extension.js.map +0 -1
  50. package/dist/cjs/classes/asyncIterable.d.ts +0 -126
  51. package/dist/cjs/classes/asyncIterable.js +0 -209
  52. package/dist/cjs/classes/asyncIterable.js.map +0 -1
  53. package/dist/cjs/classes/deferred.d.ts +0 -146
  54. package/dist/cjs/classes/deferred.js +0 -291
  55. package/dist/cjs/classes/deferred.js.map +0 -1
  56. package/dist/cjs/classes/descriptor.d.ts +0 -334
  57. package/dist/cjs/classes/descriptor.js +0 -537
  58. package/dist/cjs/classes/descriptor.js.map +0 -1
  59. package/dist/cjs/classes/enum.d.ts +0 -50
  60. package/dist/cjs/classes/enum.js +0 -405
  61. package/dist/cjs/classes/enum.js.map +0 -1
  62. package/dist/cjs/classes/index.d.ts +0 -15
  63. package/dist/cjs/classes/index.js +0 -63
  64. package/dist/cjs/classes/index.js.map +0 -1
  65. package/dist/cjs/classes/introspector.d.ts +0 -20
  66. package/dist/cjs/classes/introspector.js +0 -130
  67. package/dist/cjs/classes/introspector.js.map +0 -1
  68. package/dist/cjs/classes/iterable.d.ts +0 -169
  69. package/dist/cjs/classes/iterable.js +0 -268
  70. package/dist/cjs/classes/iterable.js.map +0 -1
  71. package/dist/cjs/classes/param.parser.d.ts +0 -221
  72. package/dist/cjs/classes/param.parser.js +0 -242
  73. package/dist/cjs/classes/param.parser.js.map +0 -1
  74. package/dist/cjs/classes/pluggable.proxy.d.ts +0 -153
  75. package/dist/cjs/classes/pluggable.proxy.js +0 -444
  76. package/dist/cjs/classes/pluggable.proxy.js.map +0 -1
  77. package/dist/cjs/classes/property.d.ts +0 -79
  78. package/dist/cjs/classes/property.js +0 -284
  79. package/dist/cjs/classes/property.js.map +0 -1
  80. package/dist/cjs/classes/refmap.d.ts +0 -238
  81. package/dist/cjs/classes/refmap.js +0 -421
  82. package/dist/cjs/classes/refmap.js.map +0 -1
  83. package/dist/cjs/classes/refset.d.ts +0 -186
  84. package/dist/cjs/classes/refset.js +0 -370
  85. package/dist/cjs/classes/refset.js.map +0 -1
  86. package/dist/cjs/classes/symkeys.d.ts +0 -349
  87. package/dist/cjs/classes/symkeys.js +0 -510
  88. package/dist/cjs/classes/symkeys.js.map +0 -1
  89. package/dist/cjs/classes/type.d.ts +0 -56
  90. package/dist/cjs/classes/type.js +0 -405
  91. package/dist/cjs/classes/type.js.map +0 -1
  92. package/dist/cjs/function.extensions.d.ts +0 -12
  93. package/dist/cjs/function.extensions.js +0 -758
  94. package/dist/cjs/function.extensions.js.map +0 -1
  95. package/dist/cjs/global.this.d.ts +0 -2
  96. package/dist/cjs/global.this.js +0 -300
  97. package/dist/cjs/global.this.js.map +0 -1
  98. package/dist/cjs/index.d.ts +0 -31
  99. package/dist/cjs/index.js +0 -228
  100. package/dist/cjs/index.js.map +0 -1
  101. package/dist/cjs/json.extensions.d.ts +0 -2
  102. package/dist/cjs/json.extensions.js +0 -109
  103. package/dist/cjs/json.extensions.js.map +0 -1
  104. package/dist/cjs/map.extensions.d.ts +0 -3
  105. package/dist/cjs/map.extensions.js +0 -143
  106. package/dist/cjs/map.extensions.js.map +0 -1
  107. package/dist/cjs/math.extension.d.ts +0 -14
  108. package/dist/cjs/math.extension.js +0 -71
  109. package/dist/cjs/math.extension.js.map +0 -1
  110. package/dist/cjs/number.extension.d.ts +0 -44
  111. package/dist/cjs/number.extension.js +0 -278
  112. package/dist/cjs/number.extension.js.map +0 -1
  113. package/dist/cjs/object.extensions.d.ts +0 -33
  114. package/dist/cjs/object.extensions.js +0 -1091
  115. package/dist/cjs/object.extensions.js.map +0 -1
  116. package/dist/cjs/package.json +0 -3
  117. package/dist/cjs/proxy.extensions.d.ts +0 -2
  118. package/dist/cjs/proxy.extensions.js +0 -207
  119. package/dist/cjs/proxy.extensions.js.map +0 -1
  120. package/dist/cjs/reflect.extensions.d.ts +0 -14
  121. package/dist/cjs/reflect.extensions.js +0 -316
  122. package/dist/cjs/reflect.extensions.js.map +0 -1
  123. package/dist/cjs/regular.expression.extensions.d.ts +0 -2
  124. package/dist/cjs/regular.expression.extensions.js +0 -423
  125. package/dist/cjs/regular.expression.extensions.js.map +0 -1
  126. package/dist/cjs/set.extensions.d.ts +0 -40
  127. package/dist/cjs/set.extensions.js +0 -355
  128. package/dist/cjs/set.extensions.js.map +0 -1
  129. package/dist/cjs/string.extensions.d.ts +0 -23
  130. package/dist/cjs/string.extensions.js +0 -704
  131. package/dist/cjs/string.extensions.js.map +0 -1
  132. package/dist/cjs/symbol.extensions.d.ts +0 -11
  133. package/dist/cjs/symbol.extensions.js +0 -735
  134. package/dist/cjs/symbol.extensions.js.map +0 -1
  135. package/dist/cjs/utils/copy.object.d.ts +0 -408
  136. package/dist/cjs/utils/copy.object.js +0 -720
  137. package/dist/cjs/utils/copy.object.js.map +0 -1
  138. package/dist/cjs/utils/descriptor.utils.d.ts +0 -298
  139. package/dist/cjs/utils/descriptor.utils.js +0 -889
  140. package/dist/cjs/utils/descriptor.utils.js.map +0 -1
  141. package/dist/cjs/utils/index.d.ts +0 -75
  142. package/dist/cjs/utils/index.js +0 -61
  143. package/dist/cjs/utils/index.js.map +0 -1
  144. package/dist/cjs/utils/stdout.d.ts +0 -742
  145. package/dist/cjs/utils/stdout.js +0 -1042
  146. package/dist/cjs/utils/stdout.js.map +0 -1
  147. package/dist/cjs/utils/toolkit.d.ts +0 -1898
  148. package/dist/cjs/utils/toolkit.js +0 -1378
  149. package/dist/cjs/utils/toolkit.js.map +0 -1
  150. package/dist/cjs/weakref.extensions.d.ts +0 -2
  151. package/dist/cjs/weakref.extensions.js +0 -19
  152. package/dist/cjs/weakref.extensions.js.map +0 -1
  153. package/dist/mjs/array.extensions.d.ts +0 -39
  154. package/dist/mjs/array.extensions.js +0 -474
  155. package/dist/mjs/array.extensions.js.map +0 -1
  156. package/dist/mjs/big.int.extension.d.ts +0 -31
  157. package/dist/mjs/big.int.extension.js +0 -270
  158. package/dist/mjs/big.int.extension.js.map +0 -1
  159. package/dist/mjs/classes/asyncIterable.d.ts +0 -126
  160. package/dist/mjs/classes/asyncIterable.js +0 -204
  161. package/dist/mjs/classes/asyncIterable.js.map +0 -1
  162. package/dist/mjs/classes/deferred.d.ts +0 -146
  163. package/dist/mjs/classes/deferred.js +0 -287
  164. package/dist/mjs/classes/deferred.js.map +0 -1
  165. package/dist/mjs/classes/descriptor.d.ts +0 -334
  166. package/dist/mjs/classes/descriptor.js +0 -533
  167. package/dist/mjs/classes/descriptor.js.map +0 -1
  168. package/dist/mjs/classes/enum.d.ts +0 -50
  169. package/dist/mjs/classes/enum.js +0 -400
  170. package/dist/mjs/classes/enum.js.map +0 -1
  171. package/dist/mjs/classes/index.d.ts +0 -15
  172. package/dist/mjs/classes/index.js +0 -46
  173. package/dist/mjs/classes/index.js.map +0 -1
  174. package/dist/mjs/classes/introspector.d.ts +0 -20
  175. package/dist/mjs/classes/introspector.js +0 -126
  176. package/dist/mjs/classes/introspector.js.map +0 -1
  177. package/dist/mjs/classes/iterable.d.ts +0 -169
  178. package/dist/mjs/classes/iterable.js +0 -263
  179. package/dist/mjs/classes/iterable.js.map +0 -1
  180. package/dist/mjs/classes/param.parser.d.ts +0 -221
  181. package/dist/mjs/classes/param.parser.js +0 -238
  182. package/dist/mjs/classes/param.parser.js.map +0 -1
  183. package/dist/mjs/classes/pluggable.proxy.d.ts +0 -153
  184. package/dist/mjs/classes/pluggable.proxy.js +0 -438
  185. package/dist/mjs/classes/pluggable.proxy.js.map +0 -1
  186. package/dist/mjs/classes/property.d.ts +0 -79
  187. package/dist/mjs/classes/property.js +0 -280
  188. package/dist/mjs/classes/property.js.map +0 -1
  189. package/dist/mjs/classes/refmap.d.ts +0 -238
  190. package/dist/mjs/classes/refmap.js +0 -417
  191. package/dist/mjs/classes/refmap.js.map +0 -1
  192. package/dist/mjs/classes/refset.d.ts +0 -186
  193. package/dist/mjs/classes/refset.js +0 -366
  194. package/dist/mjs/classes/refset.js.map +0 -1
  195. package/dist/mjs/classes/symkeys.d.ts +0 -349
  196. package/dist/mjs/classes/symkeys.js +0 -506
  197. package/dist/mjs/classes/symkeys.js.map +0 -1
  198. package/dist/mjs/classes/type.d.ts +0 -56
  199. package/dist/mjs/classes/type.js +0 -401
  200. package/dist/mjs/classes/type.js.map +0 -1
  201. package/dist/mjs/function.extensions.d.ts +0 -12
  202. package/dist/mjs/function.extensions.js +0 -755
  203. package/dist/mjs/function.extensions.js.map +0 -1
  204. package/dist/mjs/global.this.d.ts +0 -2
  205. package/dist/mjs/global.this.js +0 -264
  206. package/dist/mjs/global.this.js.map +0 -1
  207. package/dist/mjs/index.d.ts +0 -31
  208. package/dist/mjs/index.js +0 -206
  209. package/dist/mjs/index.js.map +0 -1
  210. package/dist/mjs/json.extensions.d.ts +0 -2
  211. package/dist/mjs/json.extensions.js +0 -106
  212. package/dist/mjs/json.extensions.js.map +0 -1
  213. package/dist/mjs/map.extensions.d.ts +0 -3
  214. package/dist/mjs/map.extensions.js +0 -140
  215. package/dist/mjs/map.extensions.js.map +0 -1
  216. package/dist/mjs/math.extension.d.ts +0 -14
  217. package/dist/mjs/math.extension.js +0 -68
  218. package/dist/mjs/math.extension.js.map +0 -1
  219. package/dist/mjs/number.extension.d.ts +0 -44
  220. package/dist/mjs/number.extension.js +0 -275
  221. package/dist/mjs/number.extension.js.map +0 -1
  222. package/dist/mjs/object.extensions.d.ts +0 -33
  223. package/dist/mjs/object.extensions.js +0 -1088
  224. package/dist/mjs/object.extensions.js.map +0 -1
  225. package/dist/mjs/package.json +0 -3
  226. package/dist/mjs/proxy.extensions.d.ts +0 -2
  227. package/dist/mjs/proxy.extensions.js +0 -204
  228. package/dist/mjs/proxy.extensions.js.map +0 -1
  229. package/dist/mjs/reflect.extensions.d.ts +0 -14
  230. package/dist/mjs/reflect.extensions.js +0 -313
  231. package/dist/mjs/reflect.extensions.js.map +0 -1
  232. package/dist/mjs/regular.expression.extensions.d.ts +0 -2
  233. package/dist/mjs/regular.expression.extensions.js +0 -420
  234. package/dist/mjs/regular.expression.extensions.js.map +0 -1
  235. package/dist/mjs/set.extensions.d.ts +0 -40
  236. package/dist/mjs/set.extensions.js +0 -352
  237. package/dist/mjs/set.extensions.js.map +0 -1
  238. package/dist/mjs/string.extensions.d.ts +0 -23
  239. package/dist/mjs/string.extensions.js +0 -701
  240. package/dist/mjs/string.extensions.js.map +0 -1
  241. package/dist/mjs/symbol.extensions.d.ts +0 -11
  242. package/dist/mjs/symbol.extensions.js +0 -732
  243. package/dist/mjs/symbol.extensions.js.map +0 -1
  244. package/dist/mjs/utils/copy.object.d.ts +0 -408
  245. package/dist/mjs/utils/copy.object.js +0 -702
  246. package/dist/mjs/utils/copy.object.js.map +0 -1
  247. package/dist/mjs/utils/descriptor.utils.d.ts +0 -298
  248. package/dist/mjs/utils/descriptor.utils.js +0 -875
  249. package/dist/mjs/utils/descriptor.utils.js.map +0 -1
  250. package/dist/mjs/utils/index.d.ts +0 -75
  251. package/dist/mjs/utils/index.js +0 -45
  252. package/dist/mjs/utils/index.js.map +0 -1
  253. package/dist/mjs/utils/stdout.d.ts +0 -742
  254. package/dist/mjs/utils/stdout.js +0 -1037
  255. package/dist/mjs/utils/stdout.js.map +0 -1
  256. package/dist/mjs/utils/toolkit.d.ts +0 -1898
  257. package/dist/mjs/utils/toolkit.js +0 -1373
  258. package/dist/mjs/utils/toolkit.js.map +0 -1
  259. package/dist/mjs/weakref.extensions.d.ts +0 -2
  260. package/dist/mjs/weakref.extensions.js +0 -16
  261. package/dist/mjs/weakref.extensions.js.map +0 -1
  262. package/jsdoc-config.json +0 -31
  263. package/tsconfig.base.json +0 -28
  264. package/tsconfig.cjs.json +0 -8
  265. package/tsconfig.esm.json +0 -8
  266. package/vitest.config.js +0 -7
@@ -0,0 +1,3954 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/utils/index.js
20
+ var index_exports = {};
21
+ __export(index_exports, {
22
+ COPropertyHandler: () => COPropertyHandler,
23
+ DescriptorUtils: () => DescriptorUtils,
24
+ FlexiblyHiddenHandler: () => FlexiblyHiddenHandler,
25
+ FlexiblyVisibleHandler: () => FlexiblyVisibleHandler,
26
+ ImmutablyHiddenHandler: () => ImmutablyHiddenHandler,
27
+ ImmutablyVisibleHandler: () => ImmutablyVisibleHandler,
28
+ MutablyHiddenHandler: () => MutablyHiddenHandler,
29
+ MutablyVisibleHandler: () => MutablyVisibleHandler,
30
+ SC: () => SC,
31
+ StdoutGlobalPatches: () => StdoutGlobalPatches,
32
+ StringConsole: () => StringConsole,
33
+ StringConsoleExtension: () => StringConsoleExtension,
34
+ VisibilityKeys: () => VisibilityKeys,
35
+ VisibilityScopeHandler: () => VisibilityScopeHandler,
36
+ accessor: () => accessor,
37
+ as: () => as,
38
+ captureStdout: () => captureStdout,
39
+ copyObject: () => copyObject,
40
+ createToolkit: () => createToolkit,
41
+ customCopyObject: () => customCopyObject,
42
+ data: () => data,
43
+ default: () => index_default,
44
+ describe: () => describe,
45
+ describeMany: () => describeMany,
46
+ extract: () => extract,
47
+ has: () => has,
48
+ is: () => is,
49
+ isAccessor: () => isAccessor,
50
+ isData: () => isData,
51
+ isDescriptor: () => isDescriptor,
52
+ kAccessorDescriptorKeys: () => kAccessorDescriptorKeys,
53
+ kDataDescriptorKeys: () => kDataDescriptorKeys,
54
+ kDescriptorKeys: () => kDescriptorKeys,
55
+ kSharedDescriptorKeys: () => kSharedDescriptorKeys,
56
+ kVisibilityKeys: () => kVisibilityKeys,
57
+ makeTransducer: () => makeTransducer,
58
+ redescribe: () => redescribe,
59
+ si: () => si,
60
+ transduceFrom: () => transduceFrom,
61
+ transduceFromCOHandler: () => transduceFromCOHandler,
62
+ tryIgnore: () => tryIgnore
63
+ });
64
+ module.exports = __toCommonJS(index_exports);
65
+
66
+ // src/utils/copy.object.js
67
+ function tryIgnore(code) {
68
+ try {
69
+ return code();
70
+ } catch (ignore) {
71
+ return void 0;
72
+ }
73
+ }
74
+ function transduceFrom(array, transform, into = {}) {
75
+ if (typeof transform !== "function") {
76
+ return into;
77
+ }
78
+ return array.reduce((accumulator, element) => {
79
+ const { key, value } = transform?.(element) ?? {};
80
+ if (key && value) {
81
+ accumulator[key] = value;
82
+ }
83
+ return accumulator;
84
+ }, into);
85
+ }
86
+ function transduceFromCOHandler(element) {
87
+ const result = {};
88
+ if (element instanceof COPropertyHandler) {
89
+ result.key = element.property;
90
+ result.value = element;
91
+ }
92
+ return result;
93
+ }
94
+ function makeTransducer(array, transform) {
95
+ return transduceFrom.bind(null, array, transform);
96
+ }
97
+ var COPropertyHandler = class _COPropertyHandler {
98
+ /**
99
+ * The name of the property this handler is responsible for.
100
+ * @type {string|undefined}
101
+ */
102
+ property = void 0;
103
+ /**
104
+ * The property handler. When provided and invoked, it will receive
105
+ * a the property name of the value being handled, the current
106
+ * descriptor to transform, and the object into which values are
107
+ * currently being copied into.
108
+ *
109
+ * The result must be a COPropertyHandler response type, which can
110
+ * be made with {@link COPropertyHandler.makeResponse} and which
111
+ * can be validated with {@link COPropertyHandler.isResponse}.
112
+ *
113
+ * The handler should have the following parameters
114
+ * - {string} property - The name of the property being handled.
115
+ * - {Object} curDescriptor - The property descriptor to handle.
116
+ * - {Object} destination - The destination object into which
117
+ * properties are being copied.
118
+ *
119
+ * An should return
120
+ * - {Object} a `COPropertyHandler.Response` type object which
121
+ * can be made with {@link COPropertyHandler.makeResponse}.
122
+ *
123
+ * @type {function|undefined}
124
+ */
125
+ handler = void 0;
126
+ /**
127
+ * Creates a new COPropertyHandler instance.
128
+ * @param {string} [property] - The name of the property to handle.
129
+ * @param {function} [handler] - The function to handle the property
130
+ * descriptor.
131
+ */
132
+ constructor(property2, handler) {
133
+ Object.assign(this, { property: property2, handler });
134
+ }
135
+ /**
136
+ * Handles a property descriptor using the registered handler function.
137
+ * @param {string} property - The name of the property being handled.
138
+ * @param {Object} descriptor - The property descriptor to handle.
139
+ * @returns {Object} The resulting property descriptor after handling.
140
+ */
141
+ handle(property2, descriptor, destination) {
142
+ if (this.handler) {
143
+ return _COPropertyHandler.defaultHandle(
144
+ property2,
145
+ descriptor,
146
+ this.handler
147
+ );
148
+ }
149
+ return descriptor;
150
+ }
151
+ /**
152
+ * The default property descriptor handler.
153
+ *
154
+ * @param {string} property - The name of the property being handled.
155
+ * @param {Object} curDescriptor - The property descriptor to handle.
156
+ * @param {Object} destination - The destination object into which
157
+ * properties are being copied.
158
+ * @param {function} handler - The function to handle the property
159
+ * descriptor.
160
+ * @returns {Object} a `COPropertyHandler.Response` type object which
161
+ * can be made with {@link COPropertyHandler.makeResponse}.
162
+ */
163
+ static defaultHandle(property2, curDescriptor, destination, handler) {
164
+ if (typeof handler === "function") {
165
+ try {
166
+ const {
167
+ descriptor,
168
+ flow
169
+ } = handler(property2, curDescriptor, destination);
170
+ return this.makeResponse(descriptor, flow);
171
+ } catch (ignore) {
172
+ }
173
+ }
174
+ return this.makeResponse(curDescriptor);
175
+ }
176
+ /**
177
+ * Creates a COPropertyHandler response object.
178
+ *
179
+ * @param {Object} descriptor - The property descriptor.
180
+ * @param {string} [flow=COPropertyHandler.kNoChange] - The flow control
181
+ * directive. Must be one of the values from
182
+ * {@link COPropertyHandler.flowTypes} if provided.
183
+ * @returns {COPropertyHandler.Response} The response object.
184
+ * @example
185
+ * COPropertyHandler.makeResponse({ value: 42, writable: false })
186
+ * // => {
187
+ * // newDescriptor: { value: 42, writable: false },
188
+ * // flow: 'nochange'
189
+ * // }
190
+ */
191
+ static makeResponse(descriptor, flow) {
192
+ return {
193
+ newDescriptor: descriptor,
194
+ flow: flow ?? this.kNoChange,
195
+ get [Symbol.toStringTag]() {
196
+ return "COPropertyHandler.Response";
197
+ }
198
+ };
199
+ }
200
+ /**
201
+ * Checks if a value is a valid COPropertyHandler response object.
202
+ * @param {*} value - The value to check.
203
+ * @returns {boolean} `true` if the value is a response object, `false`
204
+ * otherwise.
205
+ * @example
206
+ * COPropertyHandler.isResponse({
207
+ * newDescriptor: { value: 42 },
208
+ * flow: 'nochange'
209
+ * })
210
+ * // => true
211
+ */
212
+ static isResponse(value) {
213
+ return value && typeof value === "object" && value[Symbol.toStringTag] === "COPropertyHandler.Response";
214
+ }
215
+ /**
216
+ * The flow control directive indicating no change in flow.
217
+ * @type {string}
218
+ */
219
+ static get kNoChange() {
220
+ return "nochange";
221
+ }
222
+ /**
223
+ * The flow control directive indicating to continue the loop.
224
+ * @type {string}
225
+ */
226
+ static get kContinue() {
227
+ return "continue";
228
+ }
229
+ /**
230
+ * The flow control directive indicating to break the loop.
231
+ * @type {string}
232
+ */
233
+ static get kBreak() {
234
+ return "break";
235
+ }
236
+ /**
237
+ * An array of all valid flow control directive values.
238
+ * @type {string[]}
239
+ */
240
+ static get flowTypes() {
241
+ return [this.kNoChange, this.kContinue, this.kBreak];
242
+ }
243
+ /**
244
+ * An object mapping flow control directive values to their
245
+ * corresponding string representations.
246
+ * @type {Object.<string, string>}
247
+ */
248
+ static get flowEnum() {
249
+ return {
250
+ [this.kNoChange]: this.kNoChange,
251
+ [this.kContinue]: this.kContinue,
252
+ [this.kBreak]: this.kBreak
253
+ };
254
+ }
255
+ };
256
+ function kVisibilityKeys() {
257
+ const keys = {
258
+ get mutablyHidden() {
259
+ return Symbol.for(JSON.stringify({
260
+ enumerable: false,
261
+ configurable: true
262
+ }));
263
+ },
264
+ get mutablyVisible() {
265
+ return Symbol.for(JSON.stringify({
266
+ enumerable: true,
267
+ configurable: true
268
+ }));
269
+ },
270
+ get immutablyHidden() {
271
+ return Symbol.for(JSON.stringify({
272
+ enumerable: false,
273
+ configurable: false
274
+ }));
275
+ },
276
+ get immutablyVisible() {
277
+ return Symbol.for(JSON.stringify({
278
+ enumerable: true,
279
+ configurable: false
280
+ }));
281
+ },
282
+ get flexiblyHidden() {
283
+ return Symbol.for(JSON.stringify({
284
+ enumerable: false,
285
+ configurable: false,
286
+ writable: true
287
+ }));
288
+ },
289
+ get flexiblyVisible() {
290
+ return Symbol.for(JSON.stringify({
291
+ enumerable: true,
292
+ configurable: false,
293
+ writable: true
294
+ }));
295
+ }
296
+ };
297
+ const enumerated = {
298
+ mutablyHidden: keys.mutablyHidden,
299
+ mutablyVisible: keys.mutablyVisible,
300
+ immutablyHidden: keys.immutablyHidden,
301
+ immutablyVisible: keys.immutablyVisible,
302
+ flexiblyHidden: keys.flexiblyHidden,
303
+ flexiblyVisible: keys.flexiblyVisible
304
+ };
305
+ function* keyGenerator() {
306
+ for (const key of Object.keys(enumerated)) {
307
+ yield key;
308
+ }
309
+ }
310
+ function* symbolGenerator() {
311
+ for (const value of Object.values(enumerated)) {
312
+ yield value;
313
+ }
314
+ }
315
+ function* entryGenerator() {
316
+ for (const entry of Object.entries(enumerated)) {
317
+ yield entry;
318
+ }
319
+ }
320
+ function* descriptorGenertor() {
321
+ for (const [key, value] of entryGenerator()) {
322
+ yield [key, JSON.parse(value.description)];
323
+ }
324
+ }
325
+ Object.defineProperties(keys, {
326
+ enumeration: { get() {
327
+ return enumerated;
328
+ }, enumerable: false },
329
+ keys: { get() {
330
+ return keyGenerator();
331
+ }, enumerable: false },
332
+ symbols: { get() {
333
+ return symbolGenerator();
334
+ }, enumerable: false },
335
+ entries: { get() {
336
+ return entryGenerator();
337
+ }, enumerable: false },
338
+ descriptors: { get() {
339
+ return descriptorGenertor();
340
+ }, enumerable: false },
341
+ descriptorFor: {
342
+ value(symbol) {
343
+ try {
344
+ return JSON.parse(symbol.description);
345
+ } catch (ignored) {
346
+ }
347
+ return void 0;
348
+ },
349
+ enumerable: false
350
+ },
351
+ [Symbol.iterator]: { get() {
352
+ return symbolGenerator();
353
+ } }
354
+ });
355
+ return keys;
356
+ }
357
+ var VisibilityKeys = kVisibilityKeys();
358
+ var VisibilityScopeHandler = class extends COPropertyHandler {
359
+ overrides = void 0;
360
+ /**
361
+ * Creates a new VisibilityScopeHandler instance.
362
+ *
363
+ * @constructor
364
+ * @param {symbol} visibilityKey - The visibility key to use for handling
365
+ * property descriptors.
366
+ */
367
+ constructor(visibilityKey) {
368
+ super(visibilityKey, (property2, descriptor, dest, source) => {
369
+ let data2 = descriptor?.value;
370
+ if (!descriptor || typeof descriptor.value !== "object") {
371
+ return COPropertyHandler.makeResponse(descriptor, "nochange");
372
+ }
373
+ if (!data2 && (descriptor?.get || descriptor?.set)) {
374
+ const newDescriptor = this.applyOverridesTo(descriptor);
375
+ return COPropertyHandler.makeResponse(newDescriptor, "nochange");
376
+ }
377
+ data2 = customCopyObject({ deep: false }, {}, data2 ?? {});
378
+ this.walkAndApply(data2);
379
+ descriptor.value = data2;
380
+ return COPropertyHandler.makeResponse(descriptor, "continue");
381
+ });
382
+ tryIgnore(() => this.overrides = JSON.parse(property.description));
383
+ }
384
+ applyOverridesTo(existingDescriptor, overwrite = false) {
385
+ const allowed = ["value", "get", "set", "writable", "configurable", "enumerable"];
386
+ const output = overwrite ? existingDescriptor : { ...existingDescriptor };
387
+ for (let [key, value] of Object.entries(this.overrides ?? {})) {
388
+ if (!~allowed.indexOf(key)) {
389
+ continue;
390
+ }
391
+ if (!(["get", "set"].some((k) => k === key) && ["undefined", "function"].some((t) => typeof value === t))) {
392
+ continue;
393
+ }
394
+ if (!(["enumerable", "configurable", "writable"].some((k) => k === key) && typeof value !== "boolean")) {
395
+ value = !!value;
396
+ }
397
+ delete output[key];
398
+ output[key] = value;
399
+ }
400
+ return output;
401
+ }
402
+ walkAndApply(to) {
403
+ Reflect.ownKeys(to).forEach((key) => {
404
+ tryIgnore(() => {
405
+ let result = Object.getOwnPropertyDescriptor(to, key);
406
+ this.applyOverridesTo(result, true);
407
+ Object.defineProperty(to, key, result);
408
+ });
409
+ });
410
+ }
411
+ };
412
+ var MutablyVisibleHandler = class extends VisibilityScopeHandler {
413
+ constructor() {
414
+ super(VisibilityKeys.mutablyVisible);
415
+ }
416
+ static get shared() {
417
+ return this.#singleton ?? (this.#singleton = new this());
418
+ }
419
+ static #singleton;
420
+ };
421
+ var MutablyHiddenHandler = class extends VisibilityScopeHandler {
422
+ constructor() {
423
+ super(VisibilityKeys.mutablyHidden);
424
+ }
425
+ static get shared() {
426
+ return this.#singleton ?? (this.#singleton = new this());
427
+ }
428
+ static #singleton;
429
+ };
430
+ var ImmutablyVisibleHandler = class extends VisibilityScopeHandler {
431
+ constructor() {
432
+ super(VisibilityKeys.immutablyVisible);
433
+ }
434
+ static get shared() {
435
+ return this.#singleton ?? (this.#singleton = new this());
436
+ }
437
+ static #singleton;
438
+ };
439
+ var ImmutablyHiddenHandler = class extends VisibilityScopeHandler {
440
+ constructor() {
441
+ super(VisibilityKeys.immutablyHidden);
442
+ }
443
+ static get shared() {
444
+ return this.#singleton ?? (this.#singleton = new this());
445
+ }
446
+ static #singleton;
447
+ };
448
+ var FlexiblyVisibleHandler = class extends VisibilityScopeHandler {
449
+ constructor() {
450
+ super(VisibilityKeys.flexiblyVisible);
451
+ }
452
+ static get shared() {
453
+ return this.#singleton ?? (this.#singleton = new this());
454
+ }
455
+ static #singleton;
456
+ };
457
+ var FlexiblyHiddenHandler = class extends VisibilityScopeHandler {
458
+ constructor() {
459
+ super(VisibilityKeys.flexiblyHidden);
460
+ }
461
+ static get shared() {
462
+ return this.#singleton ?? (this.#singleton = new this());
463
+ }
464
+ static #singleton;
465
+ };
466
+ Object.defineProperties(COPropertyHandler, {
467
+ MutablyHiddenHandler: { get() {
468
+ return MutablyHiddenHandler.shared;
469
+ } },
470
+ MutablyVisibleHandler: { get() {
471
+ return MutablyVisibleHandler.shared;
472
+ } },
473
+ ImmutablyHiddenHandler: { get() {
474
+ return ImmutablyHiddenHandler.shared;
475
+ } },
476
+ ImmutablyVisibleHandler: { get() {
477
+ return ImmutablyVisibleHandler.shared;
478
+ } },
479
+ FlexiblyHiddenHandler: { get() {
480
+ return FlexiblyHiddenHandler.shared;
481
+ } },
482
+ FlexiblyVisibleHandler: { get() {
483
+ return FlexiblyVisibleHandler.shared;
484
+ } },
485
+ handlers: {
486
+ value: [
487
+ MutablyHiddenHandler,
488
+ MutablyVisibleHandler,
489
+ ImmutablyHiddenHandler,
490
+ ImmutablyVisibleHandler,
491
+ FlexiblyHiddenHandler,
492
+ FlexiblyVisibleHandler
493
+ ].map((klass) => klass.shared),
494
+ configurable: true,
495
+ enumerable: true
496
+ }
497
+ });
498
+ function copyObject(deep, destination, ...sources) {
499
+ const options = {
500
+ deep: deep || false,
501
+ propertyHandlers: COPropertyHandler?.handlers ?? []
502
+ };
503
+ return customCopyObject(options, destination, ...sources);
504
+ }
505
+ function customCopyObject(_options, _destination, ..._sources) {
506
+ const visited = /* @__PURE__ */ new Set();
507
+ const [options, destination, sources] = ccoParseArgs(
508
+ _options,
509
+ _destination,
510
+ ..._sources
511
+ );
512
+ let { deep } = options;
513
+ for (const source of sources) {
514
+ if (source === null || typeof source !== "object" || visited.has(source)) {
515
+ continue;
516
+ }
517
+ visited.add(source);
518
+ const keys = Reflect.ownKeys(source);
519
+ for (let key of keys) {
520
+ let descriptor;
521
+ try {
522
+ descriptor = Object.getOwnPropertyDescriptor(source, key);
523
+ } catch (err) {
524
+ console.warn(`Failed to get descriptor for key "${key}": ${err}`);
525
+ continue;
526
+ }
527
+ const isDataDesc = Reflect.has(descriptor, "value");
528
+ const keyedValue = descriptor?.value;
529
+ const conditionsMet = [
530
+ isDataDesc,
531
+ keyedValue,
532
+ typeof keyedValue === "object",
533
+ !visited.has(keyedValue)
534
+ ].every((condition) => condition);
535
+ if (conditionsMet) {
536
+ visited.add(keyedValue);
537
+ const prototype = Object.getPrototypeOf(keyedValue);
538
+ const descriptors = Object.getOwnPropertyDescriptors(keyedValue);
539
+ const replacement = Object.create(prototype, descriptors);
540
+ descriptor.value = deep ? customCopyObject(options, replacement, keyedValue) : replacement;
541
+ }
542
+ try {
543
+ Object.defineProperty(destination, key, descriptor);
544
+ } catch (err) {
545
+ console.error(`Failed to define property "${key}": ${err}`);
546
+ }
547
+ }
548
+ }
549
+ return destination;
550
+ }
551
+ function ccoParseArgs(options, destination, ...sources) {
552
+ let { deep = true, propertyHandlers = [] } = options;
553
+ deep = !!deep;
554
+ propertyHandlers = (Array.isArray(propertyHandlers) ? propertyHandlers : [propertyHandlers]).filter((element) => element instanceof COPropertyHandler);
555
+ const transducer = makeTransducer(propertyHandlers, transduceFromCOHandler);
556
+ propertyHandlers = transducer({});
557
+ options = { deep, propertyHandlers };
558
+ sources = sources.filter((source) => source && typeof source === "object");
559
+ if (!destination) {
560
+ destination = {};
561
+ }
562
+ return [options, destination, sources];
563
+ }
564
+
565
+ // src/utils/stdout.js
566
+ var import_extension = require("@nejs/extension");
567
+ function captureStdout(callback, args = [], thisArg = console) {
568
+ let captured = "";
569
+ const originalWrite = process.stdout.write;
570
+ if (typeof callback !== "function") {
571
+ let newArgs = [callback];
572
+ if (thisArg) {
573
+ newArgs.push(thisArg);
574
+ }
575
+ newArgs = newArgs.concat(args);
576
+ callback = function() {
577
+ console.log(...newArgs);
578
+ };
579
+ thisArg = console;
580
+ args = [];
581
+ }
582
+ process.stdout.write = (chunk, encoding, callback2) => {
583
+ captured += chunk;
584
+ };
585
+ try {
586
+ callback.apply(thisArg, args);
587
+ } finally {
588
+ process.stdout.write = originalWrite;
589
+ }
590
+ return captured.substring(0, captured.length - 1);
591
+ }
592
+ var StringConsole = class _StringConsole {
593
+ /**
594
+ * @type {Array}
595
+ * @description
596
+ * The buffer array is used to store captured console output. It is
597
+ * initialized as an empty array and can be populated with strings
598
+ * representing console messages. This buffer serves as a temporary
599
+ * storage for output that can be manipulated or inspected later.
600
+ *
601
+ * @example
602
+ * const console = new StringConsole()
603
+ * console.buffer.push('Hello, World!')
604
+ * console.buffer // ['Hello, World!']
605
+ */
606
+ buffer = [];
607
+ /**
608
+ * The last index of the buffer when capture began. This number should be
609
+ * set to `NaN` when not in use.
610
+ *
611
+ * @type {number|NaN}
612
+ */
613
+ capturedAt = NaN;
614
+ /**
615
+ * If this is `true`, all "logged" output will be captured in an ever
616
+ * growing buffer.
617
+ *
618
+ * @type {boolean}
619
+ * @see {@link StringConsole.buffer}
620
+ */
621
+ captureOutput = true;
622
+ /**
623
+ * @typedef {
624
+ * Int8Array|Int16Array|Int32Array|Float32Array|Float64Array
625
+ * } TypedArray
626
+ */
627
+ /**
628
+ * @typedef {(
629
+ * chunk: string|Buffer|TypedArray|DataView,
630
+ * encoding: string|null,
631
+ * callback: ()=>{}
632
+ * )=>boolean} StringConsoleRecorder
633
+ * @property {boolean} [Symbol.for('StringConsole.recorder')]
634
+ */
635
+ /**
636
+ * The recorder function is what is subsituted for the `process.stdout.write`
637
+ * function whenever we need to temporarily capture the output of data bound
638
+ * for the bidirectional read-write stream, `stdout`.
639
+ *
640
+ * @type {StringConsoleRecorder}
641
+ * @param {string|Buffer|TypedArray|DataView|any} chunk Optional data to
642
+ * write. For streams not operating in object mode, chunk must be a
643
+ * {@link String}, {@link Buffer}, {@link Int8Array}, {@link Int16Array},
644
+ * {@link Int32Array}, {@link Float32Array}, {@link Float64Array} or
645
+ * {@link DataView}. For object mode streams, chunk may be any JavaScript
646
+ * value other than `null`.
647
+ * @param {string|null} encoding the encoding, if chunk is a string.
648
+ * Default: `'utf8'`
649
+ * @param {Function} callback callback for when this chunk of data is
650
+ * flushed.
651
+ *
652
+ * @returns {boolean} false if the stream wishes for the calling code to
653
+ * wait for the 'drain' event to be emitted before continuing to write
654
+ * additional data; otherwise true.
655
+ */
656
+ recorder = Object.defineProperty(
657
+ function recorder(chunk, encoding, callback) {
658
+ this.buffer.push(chunk);
659
+ },
660
+ Symbol.for(`StringConsole.recorder`),
661
+ { value: true, configurable: true }
662
+ );
663
+ /**
664
+ * Initializes a new instance of the StringConsole class.
665
+ *
666
+ * @param {string|string[]} [initialContents] - The initial contents to
667
+ * populate the buffer. If an array is provided, it will be used directly
668
+ * as the buffer. If a single string is provided, it will be converted
669
+ * to a string and added to the buffer.
670
+ *
671
+ * @example
672
+ * const console1 = new StringConsole('Hello')
673
+ * console1.buffer // ['Hello']
674
+ *
675
+ * const console2 = new StringConsole(['Hello', 'World'])
676
+ * console2.buffer // ['Hello', 'World']
677
+ */
678
+ constructor(captureOutput = true, initialContents = void 0) {
679
+ this.recorder = this.recorder.bind(this);
680
+ if (Array.isArray(initialContents))
681
+ this.buffer = initialContents;
682
+ else if (initialContents)
683
+ this.buffer.push(String(initialContents));
684
+ }
685
+ /**
686
+ * Clears the buffer by removing all elements.
687
+ *
688
+ * This method utilizes the `splice` function to remove all elements
689
+ * from the buffer array, effectively resetting it to an empty state.
690
+ * This is useful when you want to discard all previously captured
691
+ * console output and start fresh.
692
+ *
693
+ * @returns {StringConsole} `this` to allow for calling `clear()`
694
+ * before immediately invoking a console method.
695
+ *
696
+ * @example
697
+ * const console = new StringConsole(['Hello', 'World'])
698
+ * console.clear()
699
+ * console.buffer // []
700
+ */
701
+ clear() {
702
+ this.buffer.splice(0, this.buffer.length);
703
+ return this;
704
+ }
705
+ /**
706
+ * Checks if the console output is currently being captured.
707
+ *
708
+ * This method determines if the `process.stdout.write` function has been
709
+ * overridden to capture console output by checking for the presence of
710
+ * a specific symbol.
711
+ *
712
+ * @returns {boolean} True if capturing is active, false otherwise.
713
+ *
714
+ * @example
715
+ * const stringConsole = new StringConsole()
716
+ * stringConsole.startCapture()
717
+ * console.log(stringConsole.isCapturing()) // Stores 'true' in the buffer
718
+ */
719
+ isCapturing() {
720
+ return Reflect.has(
721
+ process.stdout.write,
722
+ Symbol.for("StringConsole.recorder")
723
+ );
724
+ }
725
+ /**
726
+ * Starts capturing console output.
727
+ *
728
+ * This method overrides the `process.stdout.write` function with a custom
729
+ * recorder function to capture all console output.
730
+ *
731
+ * @returns {number} the last index of the buffer in its current state or
732
+ * 0 if it is empty
733
+ *
734
+ * @example
735
+ * const stringConsole = new StringConsole()
736
+ * stringConsole.startCapture()
737
+ * console.log('This will be stored in stringConsole.buffer')
738
+ */
739
+ startCapture() {
740
+ if (this.captureOutput === false)
741
+ this.buffer = [];
742
+ process.stdout.write = this.recorder;
743
+ process.stderr.write = this.recorder;
744
+ this.capturedAt = this.buffer.length ? this.buffer.length : 0;
745
+ return this.capturedAt;
746
+ }
747
+ /**
748
+ * An object containing two properties covering the captured content
749
+ * while `process.stdout.write` was swapped. It should contain the
750
+ * range of line indicies as well as the content as an array of strings
751
+ *
752
+ * @typedef {object} StringConsoleCapturedOutput
753
+ * @property {number[]} range an array of two numbers, a starting index
754
+ * and an ending index. This value will be [NaN,NaN] if this instance
755
+ * has indicated that storing captured output is disabled.
756
+ * @property {string[]} lines an array of strings of captured output
757
+ * that occurred in between calls to {@link ~startCapture} and then
758
+ * ending call to {@link ~stopCapture}
759
+ */
760
+ /**
761
+ * Stops capturing console output.
762
+ *
763
+ * This method restores the original `process.stdout.write` function,
764
+ * ceasing the capture of console output.
765
+ *
766
+ * @returns {StringConsoleCapturedOutput} the range of indices capturing
767
+ * the lines of the buffer that have been added since capturing was
768
+ * started.
769
+ *
770
+ * @example
771
+ * const stringConsole = new StringConsole()
772
+ * stringConsole.startCapture()
773
+ * console.log('This will be stored in stringConsole.buffer')
774
+ * stringConsole.stopCapture()
775
+ * console.log('This will not be captured')
776
+ */
777
+ stopCapture() {
778
+ const range = [this.capturedAt || 0, this.buffer.length - 1];
779
+ const lines = this.buffer.slice(range[0], range[1] + 1);
780
+ if (this.captureOutput === false)
781
+ this.buffer = [];
782
+ process.stdout.write = _StringConsole[Symbol.for("process.stdout.write")];
783
+ process.stderr.write = _StringConsole[Symbol.for("process.stderr.write")];
784
+ this.capturedAt = NaN;
785
+ return { range, lines };
786
+ }
787
+ /**
788
+ * Joins the StringConsole output as a single string. By default, each entry
789
+ * captured so far is joined on a new line. Pass a different joiner such as
790
+ * an empty string or a whitespace character, as examples, to change the
791
+ * output string.
792
+ *
793
+ * @param {string} joinOn the string to join the output buffer on, defaults
794
+ * to a new line character
795
+ * @returns a single string of contatenated entries so far to this buffer.
796
+ */
797
+ toString(joinOn = "") {
798
+ return this.buffer.join(joinOn);
799
+ }
800
+ /**
801
+ * Captures formatted debug messages as though they'd been printed. The
802
+ * resulting output that would have been printed is stored in the buffer
803
+ * as well as being returned.
804
+ *
805
+ * This method formats the provided arguments with color coding specific
806
+ * to the 'debug' level as though `console.debug` were used. The output
807
+ * is captured and stored in the buffer for later inspection, but not
808
+ * actually printed to the standard output.
809
+ *
810
+ * @param {any[]} args - The arguments to be log captured. These can be
811
+ * of any type and will be formatted with color coding without being logged.
812
+ *
813
+ * @returns {string} The captured console output as a string.
814
+ *
815
+ * @example
816
+ * const stringConsole = new StringConsole()
817
+ * stringConsole.debug('[debug]', 'message')
818
+ * stringConsole.buffer // Contains the captured messages so far as an array
819
+ */
820
+ debug(...args) {
821
+ args = this.constructor.colorArgs("debug", args);
822
+ this.startCapture();
823
+ console.debug(...args);
824
+ return this.stopCapture().lines.join("\n");
825
+ }
826
+ /**
827
+ * Captures formatted error messages as though they'd been printed. The
828
+ * resulting output that would have been printed is stored in the buffer
829
+ * as well as being returned.
830
+ *
831
+ * This method formats the provided arguments with color coding specific
832
+ * to the 'error' level as though `console.error` were used. The output
833
+ * is captured and stored in the buffer for later inspection, but not
834
+ * actually printed to the standard output.
835
+ *
836
+ * @param {any[]} args - The arguments to be log captured. These can be
837
+ * of any type and will be formatted with color coding without being logged.
838
+ *
839
+ * @returns {string} The captured console output as a string.
840
+ *
841
+ * @example
842
+ * const stringConsole = new StringConsole()
843
+ * stringConsole.error('[error]', 'message')
844
+ * stringConsole.buffer // Contains the captured messages so far as an array
845
+ */
846
+ error(...args) {
847
+ args = this.constructor.colorArgs("error", args);
848
+ this.startCapture();
849
+ console.error(...args);
850
+ return this.stopCapture().lines.join("\n");
851
+ }
852
+ /**
853
+ * Groups console output under a specified group name and captures the
854
+ * output. No content will actually be logged to the console, just
855
+ * the output that normally would be is formatted in a string and returned
856
+ * instead.
857
+ *
858
+ * This method allows you to format multiple messages under a single
859
+ * group name. It captures the output of each invocation and stores it in
860
+ * a buffer. The captured output is returned as a single string.
861
+ *
862
+ * @param {string} groupName - The name of the group under which the
863
+ * messages will be logged.
864
+ * @param {...Array} invocations - An array of invocations where each
865
+ * invocation is an array. The first element is the log level (e.g.,
866
+ * 'log', 'info'), and the remaining elements are the arguments to be
867
+ * logged.
868
+ *
869
+ * @returns {string} The captured console output as a string.
870
+ *
871
+ * @example
872
+ * const console = new StringConsole()
873
+ * const output = console.group('MyGroup',
874
+ * ['log', 'Hello'],
875
+ * ['warn', 'Warning!']
876
+ * )
877
+ *
878
+ * console.buffer // Contains the captured group output
879
+ */
880
+ group(groupName, ...invocations) {
881
+ const commands = ["log", "info", "warn", "error", "debug", "trace"];
882
+ const buffer = [];
883
+ invocations = invocations.filter((i) => commands.includes(i?.[0]));
884
+ if (groupName)
885
+ groupName = this.constructor.style(groupName, ["underline", "bold"]);
886
+ else
887
+ groupName = this.constructor.style("grouped", ["underline", "bold"]);
888
+ this.startCapture();
889
+ console.group(groupName);
890
+ for (const invocation of invocations) {
891
+ if (!Array.isArray(invocation) || invocation.length < 2)
892
+ continue;
893
+ const [level, ...args] = invocation;
894
+ console[level](...this.constructor.colorArgs(level, args));
895
+ }
896
+ console.groupEnd(groupName);
897
+ return this.stopCapture().lines.join("");
898
+ }
899
+ /**
900
+ * Captures formatted info messages as though they'd been printed. The
901
+ * resulting output that would have been printed is stored in the buffer
902
+ * as well as being returned.
903
+ *
904
+ * This method formats the provided arguments with color coding specific
905
+ * to the 'info' level as though `console.info` were used. The output
906
+ * is captured and stored in the buffer for later inspection, but not
907
+ * actually printed to the standard output.
908
+ *
909
+ * @param {any[]} args - The arguments to be log captured. These can be
910
+ * of any type and will be formatted with color coding without being logged.
911
+ *
912
+ * @returns {string} The captured console output as a string.
913
+ *
914
+ * @example
915
+ * const stringConsole = new StringConsole()
916
+ * stringConsole.info('[info]', 'message')
917
+ * stringConsole.buffer // Contains the captured messages so far as an array
918
+ */
919
+ info(...args) {
920
+ args = this.constructor.colorArgs("info", args);
921
+ this.startCapture();
922
+ console.info(...args);
923
+ return this.stopCapture().lines.join("\n");
924
+ }
925
+ /**
926
+ * Captures formatted log messages as though they'd been printed. The
927
+ * resulting output that would have been printed is stored in the buffer
928
+ * as well as being returned.
929
+ *
930
+ * This method formats the provided arguments with color coding specific
931
+ * to the 'log' level as though `console.log` were used. The output
932
+ * is captured and stored in the buffer for later inspection, but not
933
+ * actually printed to the standard output.
934
+ *
935
+ * @param {any[]} args - The arguments to be log captured. These can be
936
+ * of any type and will be formatted with color coding without being logged.
937
+ *
938
+ * @returns {string} The captured console output as a string.
939
+ *
940
+ * @example
941
+ * const stringConsole = new StringConsole()
942
+ * stringConsole.log('[log]', 'message')
943
+ * stringConsole.buffer // Contains the captured messages so far as an array
944
+ */
945
+ log(...args) {
946
+ args = this.constructor.colorArgs("log", args);
947
+ this.startCapture();
948
+ console.log(...args);
949
+ return this.stopCapture().lines.join("\n");
950
+ }
951
+ /**
952
+ * Captures formatted trace messages as though they'd been printed. The
953
+ * resulting output that would have been printed is stored in the buffer
954
+ * as well as being returned.
955
+ *
956
+ * This method formats the provided arguments with color coding specific
957
+ * to the 'trace' level as though `console.trace` were used. The output
958
+ * is captured and stored in the buffer for later inspection, but not
959
+ * actually printed to the standard output.
960
+ *
961
+ * @param {any[]} args - The arguments to be log captured. These can be
962
+ * of any type and will be formatted with color coding without being logged.
963
+ *
964
+ * @returns {string} The captured console output as a string.
965
+ *
966
+ * @example
967
+ * const stringConsole = new StringConsole()
968
+ * stringConsole.trace('[trace]', 'message')
969
+ * stringConsole.buffer // Contains the captured messages so far as an array
970
+ */
971
+ trace(...args) {
972
+ args = this.constructor.colorArgs("trace", args);
973
+ this.startCapture();
974
+ console.trace(...args);
975
+ return this.stopCapture().lines.join("\n");
976
+ }
977
+ /**
978
+ * Captures formatted warn messages as though they'd been printed. The
979
+ * resulting output that would have been printed is stored in the buffer
980
+ * as well as being returned.
981
+ *
982
+ * This method formats the provided arguments with color coding specific
983
+ * to the 'warn' level as though `console.warn` were used. The output
984
+ * is captured and stored in the buffer for later inspection, but not
985
+ * actually printed to the standard output.
986
+ *
987
+ * @param {any[]} args - The arguments to be log captured. These can be
988
+ * of any type and will be formatted with color coding without being logged.
989
+ *
990
+ * @returns {string} The captured console output as a string.
991
+ *
992
+ * @example
993
+ * const stringConsole = new StringConsole()
994
+ * stringConsole.warn('[warn]', 'message')
995
+ * stringConsole.buffer // Contains the captured messages so far as an array
996
+ */
997
+ warn(...args) {
998
+ args = this.constructor.colorArgs("warn", args);
999
+ this.startCapture();
1000
+ console.warn(...args);
1001
+ return this.stopCapture().lines.join("\n");
1002
+ }
1003
+ /**
1004
+ * Captures a single line of text that would be logged to the console if
1005
+ * the console function of the same name were to be invoked. The string
1006
+ * is formatted according to the log colors, or any pre-existing colors as
1007
+ * those are untouched. After formatting, the string is returned.
1008
+ *
1009
+ * @param {...*} args the arguments to be logged. These can be of any
1010
+ * type and will be passed to the underlying console's method of the same
1011
+ * name.
1012
+ *
1013
+ * @returns {string}
1014
+ *
1015
+ * @example
1016
+ * const string = StringConsole.debug('[debug]: %o', someVariable)
1017
+ */
1018
+ static debug(...args) {
1019
+ return this.#console.clear().debug(...args);
1020
+ }
1021
+ /**
1022
+ * Captures a single line of text that would be logged to the console if
1023
+ * the console function of the same name were to be invoked. The string
1024
+ * is formatted according to the log colors, or any pre-existing colors as
1025
+ * those are untouched. After formatting, the string is returned.
1026
+ *
1027
+ * @param {...*} args the arguments to be logged. These can be of any
1028
+ * type and will be passed to the underlying console's method of the same
1029
+ * name.
1030
+ *
1031
+ * @returns {string}
1032
+ *
1033
+ * @example
1034
+ * const string = StringConsole.error('[error]: %o', someVariable)
1035
+ */
1036
+ static error(...args) {
1037
+ return this.#console.clear().error(...args);
1038
+ }
1039
+ /**
1040
+ * Groups console output under a specified group name and captures the
1041
+ * output. No content will actually be logged to the console, just
1042
+ * the output that normally would be is formatted in a string and returned
1043
+ * instead.
1044
+ *
1045
+ * This method allows you to format multiple messages under a single
1046
+ * group name. It captures the output of each invocation and stores it in
1047
+ * a buffer. The captured output is returned as a single string.
1048
+ *
1049
+ * @param {string} groupName - The name of the group under which the
1050
+ * messages will be logged.
1051
+ * @param {...Array} invocations - An array of invocations where each
1052
+ * invocation is an array. The first element is the log level (e.g.,
1053
+ * 'log', 'info'), and the remaining elements are the arguments to be
1054
+ * logged.
1055
+ *
1056
+ * @returns {string} The captured console output as a string.
1057
+ *
1058
+ * @example
1059
+ * const console = new StringConsole()
1060
+ * const output = console.group('MyGroup',
1061
+ * ['log', 'Hello'],
1062
+ * ['warn', 'Warning!']
1063
+ * )
1064
+ *
1065
+ * console.buffer // Contains the captured group output
1066
+ */
1067
+ static group(groupName, ...invocations) {
1068
+ return this.#console.clear().group(groupName, ...invocations);
1069
+ }
1070
+ /**
1071
+ * Captures a single line of text that would be logged to the console if
1072
+ * the console function of the same name were to be invoked. The string
1073
+ * is formatted according to the log colors, or any pre-existing colors as
1074
+ * those are untouched. After formatting, the string is returned.
1075
+ *
1076
+ * @param {...*} args the arguments to be logged. These can be of any
1077
+ * type and will be passed to the underlying console's method of the same
1078
+ * name.
1079
+ *
1080
+ * @returns {string}
1081
+ *
1082
+ * @example
1083
+ * const string = StringConsole.info('[info]: %o', someVariable)
1084
+ */
1085
+ static info(...args) {
1086
+ return this.#console.clear().info(...args);
1087
+ }
1088
+ /**
1089
+ * Captures a single line of text that would be logged to the console if
1090
+ * the console function of the same name were to be invoked. The string
1091
+ * is formatted according to the log colors, or any pre-existing colors as
1092
+ * those are untouched. After formatting, the string is returned.
1093
+ *
1094
+ * @param {...*} args the arguments to be logged. These can be of any
1095
+ * type and will be passed to the underlying console's method of the same
1096
+ * name.
1097
+ *
1098
+ * @returns {string}
1099
+ *
1100
+ * @example
1101
+ * const string = StringConsole.log('[log]: %o', someVariable)
1102
+ */
1103
+ static log(...args) {
1104
+ return this.#console.clear().log(...args);
1105
+ }
1106
+ /**
1107
+ * Captures a single line of text that would be logged to the console if
1108
+ * the console function of the same name were to be invoked. The string
1109
+ * is formatted according to the log colors, or any pre-existing colors as
1110
+ * those are untouched. After formatting, the string is returned.
1111
+ *
1112
+ * @param {...*} args the arguments to be logged. These can be of any
1113
+ * type and will be passed to the underlying console's method of the same
1114
+ * name.
1115
+ *
1116
+ * @returns {string}
1117
+ *
1118
+ * @example
1119
+ * const string = StringConsole.trace('[trace]: %o', someVariable)
1120
+ */
1121
+ static trace(...args) {
1122
+ return this.#console.clear().trace(...args);
1123
+ }
1124
+ /**
1125
+ * Captures a single line of text that would be logged to the console if
1126
+ * the console function of the same name were to be invoked. The string
1127
+ * is formatted according to the log colors, or any pre-existing colors as
1128
+ * those are untouched. After formatting, the string is returned.
1129
+ *
1130
+ * @param {...*} args the arguments to be logged. These can be of any
1131
+ * type and will be passed to the underlying console's method of the same
1132
+ * name.
1133
+ *
1134
+ * @returns {string}
1135
+ *
1136
+ * @example
1137
+ * const string = StringConsole.warn('[warn]: %o', someVariable)
1138
+ */
1139
+ static warn(...args) {
1140
+ return this.#console.clear().warn(...args);
1141
+ }
1142
+ /**
1143
+ * Internal instance of {@link StringConsole} used for static logging
1144
+ * methods.
1145
+ *
1146
+ * @type {StringConsole}
1147
+ */
1148
+ static #console = new _StringConsole(false);
1149
+ /**
1150
+ * A static map defining color codes for console output. Each color is
1151
+ * associated with an array containing two numbers, which represent
1152
+ * the ANSI escape codes for styling text in the terminal.
1153
+ *
1154
+ * The first number in the array is the suffix code for the standard
1155
+ * color, while the second number suffix code to undo the color. These
1156
+ * codes are useless without the pen prefix code.
1157
+ *
1158
+ * @type {Map<string, number[]>}
1159
+ * @see {@link StringConsole.pens}
1160
+ *
1161
+ * @example
1162
+ * // Accessing the color codes for 'red'
1163
+ * const redCodes = StringConsole.colors.get('red')
1164
+ * const fgCodes = StringConsole.pens.get('foreground')
1165
+ * const prefix = `\x1b[${fgCodes[0]}${redCodes[0]}m`
1166
+ * const suffix = `\x1b[${fgCodes[1]}${redCodes[1]}m`
1167
+ * // Outputs: "Text" in red but "!!" in the default color
1168
+ * console.log(`${prefix}Text!!${suffix}`)
1169
+ *
1170
+ * @description
1171
+ * This map is used to apply color coding to console messages, enhancing
1172
+ * readability and providing visual cues for different log levels.
1173
+ */
1174
+ static colors = /* @__PURE__ */ new Map([
1175
+ ["black", [0, 9]],
1176
+ ["red", [1, 9]],
1177
+ ["green", [2, 9]],
1178
+ ["yellow", [3, 9]],
1179
+ ["blue", [4, 9]],
1180
+ ["magenta", [5, 9]],
1181
+ ["cyan", [6, 9]],
1182
+ ["white", [7, 9]]
1183
+ ]);
1184
+ /**
1185
+ * A static map defining the color schemes for different logging levels.
1186
+ * Each log level is associated with an array of color styles that are
1187
+ * applied to the console output for that level.
1188
+ *
1189
+ * The available log levels and their corresponding color styles are:
1190
+ * - 'log': White
1191
+ * - 'info': Cyan
1192
+ * - 'warn': Yellow
1193
+ * - 'error': Red
1194
+ * - 'trace': Magenta
1195
+ * - 'debug': Bold Yellow
1196
+ *
1197
+ * @type {Map<string, string[]>}
1198
+ *
1199
+ * @example
1200
+ * const logColor = StringConsole.levels.get('log') // ['white']
1201
+ * const errorColor = StringConsole.levels.get('error') // ['red']
1202
+ */
1203
+ static levels = Object.defineProperties(/* @__PURE__ */ new Map([
1204
+ ["log", ["white"]],
1205
+ ["info", ["cyan"]],
1206
+ ["warn", ["yellow"]],
1207
+ ["error", ["red"]],
1208
+ ["trace", ["magenta"]],
1209
+ ["debug", ["bold", "yellow"]]
1210
+ ]), {
1211
+ color: {
1212
+ value: function color(key) {
1213
+ for (const value of this.get(key)) {
1214
+ if (_StringConsole.colors.has(value)) {
1215
+ return _StringConsole.colors.get(value);
1216
+ }
1217
+ }
1218
+ return _StringConsole.colors.get("white");
1219
+ },
1220
+ configurable: true
1221
+ },
1222
+ styles: {
1223
+ value: function styles(key) {
1224
+ const styles2 = [];
1225
+ for (const value of this.get(key)) {
1226
+ if (_StringConsole.styles.has(value)) {
1227
+ styles2.push(_StringConsole.styles.get(value));
1228
+ }
1229
+ }
1230
+ return styles2;
1231
+ },
1232
+ configurable: true
1233
+ }
1234
+ });
1235
+ /**
1236
+ * A static map defining the ANSI escape codes for different pen styles
1237
+ * used in console output. Each pen style is associated with an array
1238
+ * containing two numbers: the first for setting the style and the second
1239
+ * for resetting it.
1240
+ *
1241
+ * The available pen styles and their corresponding ANSI codes are:
1242
+ * - 'foreground': [3, 3] - Standard foreground color
1243
+ * - 'background': [4, 4] - Standard background color
1244
+ * - 'bright.foreground': [9, 3] - Bright foreground color
1245
+ * - 'bright.background': [10, 4] - Bright background color
1246
+ *
1247
+ * These are prefixes for both enabling and disabling. Normally a red color
1248
+ * is represented using SGR (Select Graphic Rendition) codes like \x1b[31m
1249
+ * for the foreground and \x1b[39m to return to normal color. So the 3
1250
+ * determines a foreground prefix for starting and stopping (the 3's in 31
1251
+ * and 39). Background prefixes are usually 4. These change for bright
1252
+ * colors which use 9 and 3, and 10 and 4, respectively.
1253
+ *
1254
+ * @type {Map<string, number[]>}
1255
+ *
1256
+ * @example
1257
+ * // [3, 3]
1258
+ * const foregroundPen = StringConsole.pens.get('foreground')
1259
+ *
1260
+ * // [10, 4]
1261
+ * const brightBackgroundPen = StringConsole.pens.get('bright.background')
1262
+ */
1263
+ static pens = /* @__PURE__ */ new Map([
1264
+ ["foreground", [3, 3]],
1265
+ ["background", [4, 4]],
1266
+ ["bright.foreground", [9, 3]],
1267
+ ["bright.background", [10, 4]]
1268
+ ]);
1269
+ /**
1270
+ * A static map defining ANSI escape codes for various text styles used
1271
+ * in console output. Each style is associated with an array containing
1272
+ * two escape codes: one for enabling the style and one for disabling it.
1273
+ *
1274
+ * The available styles and their corresponding ANSI codes are:
1275
+ * - 'reset': Resets all styles to default.
1276
+ * - 'blink': Enables blinking text.
1277
+ * - 'bold': Makes text bold.
1278
+ * - 'conceal': Conceals text.
1279
+ * - 'dim': Dims the text.
1280
+ * - 'italics': Italicizes the text.
1281
+ * - 'negative': Inverts the foreground and background colors.
1282
+ * - 'strike': Strikes through the text.
1283
+ * - 'underline': Underlines the text.
1284
+ *
1285
+ * @type {Map<string, string[]>}
1286
+ *
1287
+ * @example
1288
+ * const boldStyle = StringConsole.styles.get('bold')
1289
+ * // ['\x1b[1m', '\x1b[22m']
1290
+ */
1291
+ static styles = /* @__PURE__ */ new Map([
1292
+ ["reset", ["\x1B[0m"]],
1293
+ ["blink", ["\x1B[5m", "\x1B[25m"]],
1294
+ ["bold", ["\x1B[1m", "\x1B[22m"]],
1295
+ ["conceal", ["\x1B[8m", "\x1B[28m"]],
1296
+ ["dim", ["\x1B[2m", "\x1B[22m"]],
1297
+ ["italics", ["\x1B[3m", "\x1B[23m"]],
1298
+ ["negative", ["\x1B[7m", "\x1B[27m"]],
1299
+ ["strike", ["\x1B[9m", "\x1B[29m"]],
1300
+ ["underline", ["\x1B[4m", "\x1B[24m"]]
1301
+ ]);
1302
+ /**
1303
+ * Applies ANSI color codes to a given string based on specified options.
1304
+ * This method checks if the string already contains color codes or if
1305
+ * the input is not a string, in which case it returns the original input.
1306
+ * Otherwise, it formats the string with the specified color and pen
1307
+ * options.
1308
+ *
1309
+ * @param {string} string - The string to be colorized.
1310
+ * @param {Object} [options] - Configuration options for colorization.
1311
+ * @param {string} [options.level] - The log level determining
1312
+ * which colors to apply.
1313
+ * @param {number[]} [options.rgb8] a single color code where 0 - 7, for
1314
+ * the 'standard' colors specified by the SGR sequences 30 to 37; 8-15 are
1315
+ * high intensity or bright colors,
1316
+ * @param {number[]} [options.rgb24] An array of three values, ordered, red,
1317
+ * green and then blue. The values should range from 0 to 255.
1318
+ * @param {string|string[]} [options.styles] defaulting to an empty array, if
1319
+ * supplied with a single known style {@link ~styles}, or an array of them.
1320
+ * @param {string} [options.pen='foreground'] - The pen type for color
1321
+ * application, either 'foreground' or 'background'.
1322
+ * @param {Array} [options.buffer=[]] - An array to prepend to the
1323
+ * formatted string.
1324
+ * @param {Array} [options.before=[]] - An array of strings to prepend
1325
+ * before the main string.
1326
+ * @param {Array} [options.after=[]] - An array of strings to append
1327
+ * after the main string. 16 - 231, for the colors in the 6 × 6 × 6 cube
1328
+ * defined by 16 + 36 × r + 6 × g + b (0 ≤ r, g, b ≤ 5); 232-255:
1329
+ * grayscale from dark to light in 24 steps.
1330
+ *
1331
+ * @returns {string} The colorized string with ANSI codes applied.
1332
+ *
1333
+ * @example
1334
+ * const coloredString = StringConsole.color('Hello', {
1335
+ * level: 'info',
1336
+ * pen: 'bright.foreground'
1337
+ * })
1338
+ * console.log(coloredString)
1339
+ */
1340
+ static color(string, options = {
1341
+ level: void 0,
1342
+ color: void 0,
1343
+ pen: "foreground",
1344
+ rgb8: void 0,
1345
+ rgb24: [186, 186, 186],
1346
+ styles: [],
1347
+ buffer: [],
1348
+ before: [],
1349
+ after: []
1350
+ }) {
1351
+ const { colors: Colors, styles: Styles, pens: Pens, levels: Levels } = this;
1352
+ let useColors = void 0;
1353
+ let useRGB = false;
1354
+ let styles = [];
1355
+ const pens = this.pens.get(options?.pen ?? "foreground");
1356
+ const [p0, p1] = pens;
1357
+ if (options?.styles) {
1358
+ if (Array.isArray(options.styles))
1359
+ styles = options.styles.filter((s) => Styles.has(s)).map((s) => Styles.get(s));
1360
+ else if (typeof options.styles === "string" && Styles.has(options.styles))
1361
+ styles = Styles.get(options.styles);
1362
+ }
1363
+ if (options?.level && Levels.has(options.level)) {
1364
+ useColors = Levels.color(options.level);
1365
+ const addlStyles = Levels.styles(options.level);
1366
+ if (addlStyles.length)
1367
+ styles = styles.concat(addlStyles);
1368
+ } else if (options?.color && Colors.has(options.color))
1369
+ useColors = Colors.get(options.color);
1370
+ else if (options?.rgb24 && Array.isArray(options.rgb24)) {
1371
+ useColors = [`\x1B[${p0}8;2;${options.rgb24.join(";")};m`, `\x1B[${p1}9m`];
1372
+ useRGB = true;
1373
+ } else if (options?.rgb8 && typeof options.rgb8 === "number") {
1374
+ useColors = [`\x1B[${p0}8;5;${options.rgb8}m`, `\x1B[${p1}9m`];
1375
+ useRGB = true;
1376
+ } else useColors = [9, 9];
1377
+ const [c0, c1] = useRGB ? useColors : useColors?.map((c, i) => `\x1B[${pens[i]}${c}m`) ?? [`\x1B[39;49m`];
1378
+ if (this.hasColor(string)) return string;
1379
+ if (typeof string !== "string") return string;
1380
+ if (string instanceof String) string = String(string);
1381
+ if (!useColors) return string;
1382
+ if (options?.buffer && !Array.isArray(options.buffer))
1383
+ options.buffer = [String(options.buffer)];
1384
+ if (options?.before && !Array.isArray(options.before))
1385
+ options.before = [String(options.before)];
1386
+ if (options?.after && !Array.isArray(options.after))
1387
+ options.after = [String(options.after)];
1388
+ const buffer = [].concat(options?.buffer ?? []);
1389
+ const before = [].concat(options?.before ?? []);
1390
+ const after = [].concat(options?.after ?? []);
1391
+ if (c0)
1392
+ before.push(c0);
1393
+ if (c1)
1394
+ after.push(c1);
1395
+ for (const style of styles) {
1396
+ if (style?.[0])
1397
+ before.push(style[0]);
1398
+ if (style?.[1])
1399
+ after.push(style[1]);
1400
+ }
1401
+ return [...buffer, before.join(""), string, after.join("")].join("");
1402
+ }
1403
+ /**
1404
+ * Applies color formatting to each argument based on the specified log level.
1405
+ *
1406
+ * This method processes an array of arguments, applying color formatting
1407
+ * to each one according to the provided log level. The color formatting
1408
+ * is determined by the `color` method, which uses the log level to
1409
+ * select the appropriate color scheme.
1410
+ *
1411
+ * @param {string} level - The log level that determines the color scheme
1412
+ * to be applied. Common levels include 'log', 'info', 'warn', 'error',
1413
+ * etc.
1414
+ * @param {Array} args - An array of arguments to be formatted. Each
1415
+ * argument will be processed individually to apply the color formatting.
1416
+ *
1417
+ * @returns {Array} A new array containing the formatted arguments with
1418
+ * color applied.
1419
+ *
1420
+ * @example
1421
+ * const formattedArgs = StringConsole.colorArgs(
1422
+ * 'info',
1423
+ * ['Message 1', 'Message 2']
1424
+ * )
1425
+ * // formattedArgs will contain the messages with 'info' level
1426
+ * // color formatting
1427
+ */
1428
+ static colorArgs(level, args) {
1429
+ const newArgs = [];
1430
+ if (args === null || args === void 0 || !Array.isArray(args))
1431
+ return args;
1432
+ for (const arg of args) {
1433
+ newArgs.push(this.color(arg, { level }));
1434
+ }
1435
+ return newArgs;
1436
+ }
1437
+ /**
1438
+ * Determines if a given string contains ANSI color codes.
1439
+ *
1440
+ * This method checks for the presence of ANSI escape codes in the
1441
+ * provided string, which are used for color formatting in terminal
1442
+ * outputs. The presence of these codes indicates that the string
1443
+ * has color formatting applied.
1444
+ *
1445
+ * @param {string} string - The string to be checked for ANSI color codes.
1446
+ *
1447
+ * @returns {boolean} Returns true if the string contains ANSI color codes,
1448
+ * otherwise false.
1449
+ *
1450
+ * @example
1451
+ * const hasColor = StringConsole.hasColor('\x1b[31mRed Text\x1b[0m')
1452
+ * // hasColor will be true
1453
+ *
1454
+ * const noColor = StringConsole.hasColor('Plain Text')
1455
+ * // noColor will be false
1456
+ */
1457
+ static hasColor(string) {
1458
+ return string.includes("\x1B[");
1459
+ }
1460
+ /**
1461
+ * Applies a series of styles to a given string using ANSI escape codes.
1462
+ *
1463
+ * This method takes a string and an array of style names or style arrays,
1464
+ * and applies the corresponding ANSI escape codes to the string. The
1465
+ * styles are defined in the `styles` map, which associates style names
1466
+ * with their respective ANSI codes.
1467
+ *
1468
+ * @param {string} string - The string to which styles will be applied.
1469
+ * @param {string|string[]} styles - A style name or an array of style
1470
+ * names/arrays to be applied. Each style can be a string that matches
1471
+ * a key in the `styles` map or an array containing ANSI codes.
1472
+ *
1473
+ * @returns {string} The styled string with ANSI escape codes applied.
1474
+ *
1475
+ * @example
1476
+ * const styledText = StringConsole.style('Hello', ['bold', 'underline'])
1477
+ * // styledText will have 'Hello' with bold and underline styles
1478
+ */
1479
+ static style(string, styles) {
1480
+ const before = [];
1481
+ const after = [];
1482
+ const buffer = [];
1483
+ if (typeof styles === "string" && this.styles.has(styles)) {
1484
+ styles = [styles];
1485
+ }
1486
+ for (const style of styles) {
1487
+ let group = [];
1488
+ if (this.styles.has(style))
1489
+ group = this.styles.get(style);
1490
+ else if (Array.isArray(style) && style.length >= 1)
1491
+ group = style;
1492
+ if (group?.[0])
1493
+ before.push(group?.[0]);
1494
+ if (group?.[1])
1495
+ after.push(group?.[1]);
1496
+ }
1497
+ return [before.join(""), string, after.join("")].join("");
1498
+ }
1499
+ static {
1500
+ Object.defineProperties(_StringConsole, {
1501
+ [Symbol.for("process.stdout.write")]: {
1502
+ value: Object.defineProperties(process.stdout.write, {
1503
+ [Symbol.for("original")]: { value: true, configurable: true },
1504
+ isOriginal: { get() {
1505
+ return true;
1506
+ }, configurable: true }
1507
+ }),
1508
+ configurable: true
1509
+ },
1510
+ [Symbol.for("process.stderr.write")]: {
1511
+ value: Object.defineProperties(process.stderr.write, {
1512
+ [Symbol.for("original")]: { value: true, configurable: true },
1513
+ isOriginal: { get() {
1514
+ return true;
1515
+ }, configurable: true }
1516
+ }),
1517
+ configurable: true
1518
+ }
1519
+ });
1520
+ if (!Reflect.has(_StringConsole, "writer")) {
1521
+ Object.defineProperties(_StringConsole, {
1522
+ writer: {
1523
+ value: _StringConsole[Symbol.for("process.stdout.write")],
1524
+ configurable: true
1525
+ },
1526
+ errorWriter: {
1527
+ value: _StringConsole[Symbol.for("process.stderr.write")],
1528
+ configurable: true
1529
+ }
1530
+ });
1531
+ }
1532
+ }
1533
+ };
1534
+ var SC = StringConsole;
1535
+ var StringConsoleExtension = new import_extension.Extension(StringConsole);
1536
+ var StdoutGlobalPatches = new import_extension.Patch(globalThis, {
1537
+ [import_extension.Patch.kMutablyHidden]: {
1538
+ captureStdout
1539
+ }
1540
+ });
1541
+
1542
+ // src/utils/toolkit.js
1543
+ var map = /* @__PURE__ */ new Map([
1544
+ ["object", Object],
1545
+ [Object, "object"],
1546
+ ["Object", Object],
1547
+ ["number", Number],
1548
+ [Number, "number"],
1549
+ ["Number", Number],
1550
+ ["string", String],
1551
+ [String, "string"],
1552
+ ["String", String],
1553
+ ["function", Function],
1554
+ [Function, "function"],
1555
+ ["Function", Function],
1556
+ ["boolean", Boolean],
1557
+ [Boolean, "boolean"],
1558
+ ["Boolean", Boolean],
1559
+ ["bigint", BigInt],
1560
+ [BigInt, "bigint"],
1561
+ ["BigInt", BigInt],
1562
+ ["symbol", Symbol],
1563
+ [Symbol, "symbol"],
1564
+ ["Symbol", Symbol],
1565
+ ["undefined", void 0],
1566
+ [void 0, "undefined"],
1567
+ ["null", null],
1568
+ [null, "null"]
1569
+ ]);
1570
+ var is = {
1571
+ /**
1572
+ * Checks if a value matches a specified type or class.
1573
+ *
1574
+ * This function determines if the provided value matches the specified
1575
+ * type or class. It supports both primitive types and class constructors.
1576
+ *
1577
+ * @param {*} value - The value to check.
1578
+ * @param {*} typeOrClass - The type or class to compare against.
1579
+ * @returns {boolean} True if the value matches the type or class,
1580
+ * false otherwise.
1581
+ *
1582
+ * @example
1583
+ * // Returns true
1584
+ * is.a(42, 'number')
1585
+ *
1586
+ * @example
1587
+ * // Returns true
1588
+ * is.a(new Date(), Date)
1589
+ *
1590
+ * @example
1591
+ * // Returns false
1592
+ * is.a('string', Number)
1593
+ */
1594
+ a(value, typeOrClass) {
1595
+ const valueType = typeof value;
1596
+ const valueTag = this.object(value) && value[Symbol.toStringTag];
1597
+ if (value === typeOrClass)
1598
+ return true;
1599
+ if (this.function(typeOrClass)) {
1600
+ const typeTag = this.object(typeOrClass) && typeOrClass[Symbol.toStringTag];
1601
+ if (valueTag && valueTag === typeOrClass.name)
1602
+ return true;
1603
+ if (typeOrClass?.prototype && value instanceof typeOrClass)
1604
+ return true;
1605
+ return map.get(valueType) === typeOrClass;
1606
+ } else if (map.get(valueType)?.name === typeOrClass)
1607
+ return true;
1608
+ else if (valueType === typeOrClass || valueTag === typeOrClass)
1609
+ return true;
1610
+ return false;
1611
+ },
1612
+ /**
1613
+ * Check if a value is an accessor descriptor.
1614
+ *
1615
+ * An accessor descriptor is an object that describes the configuration of a
1616
+ * property on an object, specifically focusing on the 'get' and 'set'
1617
+ * attributes. Computed accessor descriptors are invalid if they also have
1618
+ * a `value` and/or `writable` property.
1619
+ *
1620
+ * @param value The value to check.
1621
+ * @returns True if the value is an accessor descriptor, false otherwise.
1622
+ *
1623
+ * @example
1624
+ * // Returns true
1625
+ * is.accessorDescriptor({ get: () => 42, set: () => {} })
1626
+ *
1627
+ * // Returns false
1628
+ * is.accessorDescriptor({ value: 42, writable: true })
1629
+ */
1630
+ accessorDescriptor(value) {
1631
+ return !!(this.descriptor(value) && (value?.get || value?.set) && value?.writable === void 0 && value?.value === void 0);
1632
+ },
1633
+ /**
1634
+ * Check if a value is an array.
1635
+ *
1636
+ * @param value The value to check.
1637
+ * @returns True if the value is an array, false otherwise.
1638
+ *
1639
+ * @example
1640
+ * is.array([1, 2, 3]) // true
1641
+ * is.array('string') // false
1642
+ */
1643
+ array(value) {
1644
+ return Array.isArray(value);
1645
+ },
1646
+ /**
1647
+ * Check if a value is a bigint.
1648
+ *
1649
+ * @param value The value to check.
1650
+ * @returns True if the value is a bigint, false otherwise.
1651
+ *
1652
+ * @example
1653
+ * is.bigint(123n) // true
1654
+ * is.bigint(123) // false
1655
+ */
1656
+ bigint(value) {
1657
+ return typeof value === "bigint" || value instanceof globalThis?.BigInt;
1658
+ },
1659
+ /**
1660
+ * Checks if a value is strictly a boolean (true or false).
1661
+ *
1662
+ * This method verifies if the provided value is either `true` or `false`.
1663
+ *
1664
+ * @param {*} value - The value to check.
1665
+ * @returns {boolean} True if the value is a boolean, false otherwise.
1666
+ *
1667
+ * @example
1668
+ * is.boolean(true) // true
1669
+ * is.boolean(false) // true
1670
+ * is.boolean(1) // false
1671
+ * is.boolean("true") // false
1672
+ */
1673
+ boolean(value) {
1674
+ return [true, false].some((bool) => bool === value);
1675
+ },
1676
+ /**
1677
+ * Check if an object is callable. This function is more or less a
1678
+ * synonym or alias for `is.function()`.
1679
+ *
1680
+ * @param object The object to check.
1681
+ * @returns True if the object is callable, false otherwise.
1682
+ *
1683
+ * @note if you wish to know if a descriptor has a callable `value`,
1684
+ * `get`, or `set` function, use `is.callableDescriptor` instead.
1685
+ *
1686
+ * @example
1687
+ * is.callable(function() {}) // true
1688
+ */
1689
+ callable(object) {
1690
+ return this.function(object);
1691
+ },
1692
+ /**
1693
+ * Check if an object is a callable descriptor. It looks to see if the
1694
+ * object represents a descriptor that is callable by checking object
1695
+ * properties named `value`, `get`, and `set`. If any of the three
1696
+ * yields a function type, true is returned.
1697
+ *
1698
+ * @param object The object to check.
1699
+ * @returns True if the object is a callable descriptor, false otherwise.
1700
+ *
1701
+ * @example
1702
+ * is.callableDescriptor({ get: function() {} }) // true
1703
+ * is.callableDescriptor(123) // false
1704
+ *
1705
+ * // Note the differences between these
1706
+ * const object = { get name() { return "Brie"; } }
1707
+ * const descriptor = Object.getOwnPropertyDescriptor(object, 'name')
1708
+ * is.callableDescriptor(object) // false
1709
+ * is.callableDescriptor(descriptor) // true
1710
+ */
1711
+ callableDescriptor(object) {
1712
+ const { value, get, set } = this.shiny(object) ? object : {};
1713
+ return [value, get, set].some((val) => this.function(val));
1714
+ },
1715
+ /**
1716
+ * Check if a value is a data property descriptor.
1717
+ *
1718
+ * A data descriptor is an object that describes the configuration of a
1719
+ * property on an object, specifically focusing on the 'value' and
1720
+ * 'writable' attributes. The descriptor is invalid if it contains
1721
+ * the accessor descriptors `get` or `set`.
1722
+ *
1723
+ * @param value The value to check.
1724
+ * @returns True if the value is a data descriptor, false otherwise.
1725
+ *
1726
+ * @example
1727
+ * // Returns true
1728
+ * is.dataDescriptor({ value: 42, writable: true })
1729
+ *
1730
+ * // Returns false
1731
+ * is.dataDescriptor({ get: () => 42, set: () => {} })
1732
+ */
1733
+ dataDescriptor(value) {
1734
+ return !!(this.descriptor(value) && (value?.value !== void 0 || value?.writable !== void 0) && value?.get === void 0 && value?.set === void 0);
1735
+ },
1736
+ /**
1737
+ * Check if a value is a property descriptor.
1738
+ *
1739
+ * A property descriptor is an object that describes the configuration of a
1740
+ * property on an object. This function checks if the provided value is an
1741
+ * object and contains any of the standard property descriptor keys.
1742
+ *
1743
+ * @param value The value to check.
1744
+ * @returns True if the value is a property descriptor, false otherwise.
1745
+ *
1746
+ * @example
1747
+ * is.descriptor({ configurable: true, enumerable: false }) // true
1748
+ * is.descriptor({ get: () => {}, set: () => {} }) // true
1749
+ * is.descriptor({}) // false
1750
+ */
1751
+ descriptor(value) {
1752
+ if (!is.object(value)) {
1753
+ return false;
1754
+ }
1755
+ const _has = (key) => Reflect.has(value, key);
1756
+ const hasBase = ["configurable", "enumerable"].some((key) => _has(key));
1757
+ const hasData = ["value", "writable"].some((key) => _has(key));
1758
+ const hasAccess = ["get", "set"].some((key) => _has(key));
1759
+ return hasBase || hasData || hasAccess;
1760
+ },
1761
+ /**
1762
+ * Checks if a value is strictly false.
1763
+ *
1764
+ * This method verifies if the provided value is strictly `false`.
1765
+ *
1766
+ * @param {*} value - The value to check.
1767
+ * @returns {boolean} True if the value is strictly false, false otherwise.
1768
+ *
1769
+ * @example
1770
+ * is.false(false) // true
1771
+ * is.false(true) // false
1772
+ * is.false(0) // false
1773
+ */
1774
+ false(value) {
1775
+ return value === false;
1776
+ },
1777
+ /**
1778
+ * Checks if a value is falsy.
1779
+ *
1780
+ * This method converts the provided value to a boolean and returns
1781
+ * `true` if the value is falsy (i.e., false, 0, "", null, undefined,
1782
+ * or NaN).
1783
+ *
1784
+ * @param {*} value - The value to check.
1785
+ * @returns {boolean} True if the value is falsy, false otherwise.
1786
+ *
1787
+ * @example
1788
+ * is.falsy(0) // true
1789
+ * is.falsy("") // true
1790
+ * is.falsy(1) // false
1791
+ * is.falsy("hello") // false
1792
+ */
1793
+ falsy(value) {
1794
+ return !!!value;
1795
+ },
1796
+ /**
1797
+ * Alias for the `falsy` method.
1798
+ *
1799
+ * This method is an alias for `is.falsy` and performs the same check.
1800
+ *
1801
+ * @param {*} value - The value to check.
1802
+ * @returns {boolean} True if the value is falsy, false otherwise.
1803
+ *
1804
+ * @example
1805
+ * is.falsey(0) // true
1806
+ * is.falsey("") // true
1807
+ * is.falsey(1) // false
1808
+ * is.falsey("hello") // false
1809
+ */
1810
+ falsey(value) {
1811
+ return this.falsy(value);
1812
+ },
1813
+ /**
1814
+ * Check if a value is a function.
1815
+ *
1816
+ * @param value The value to check.
1817
+ * @returns True if the value is a function, false otherwise.
1818
+ *
1819
+ * @example
1820
+ * is.function(function() {}) // true
1821
+ * is.function(123) // false
1822
+ */
1823
+ function(value) {
1824
+ return typeof value === "function" || value instanceof Function;
1825
+ },
1826
+ /**
1827
+ * Check if a value is iterable. Depending on the environment, JavaScript
1828
+ * will permit `'string'[Symbol.iterator]()` whereas in some places, you
1829
+ * will need to wrap string in an object first. Since other JSVM provided
1830
+ * environments may or may not be leniant with this, we play it safe by
1831
+ * implicitly object converting values before checking for the symbol. If
1832
+ * a value is already an object, it will simply be passed through.
1833
+ *
1834
+ * @param value The value to check.
1835
+ * @returns True if the value is iterable, false otherwise.
1836
+ *
1837
+ * @example
1838
+ * is.iterable([1, 2, 3]) // true
1839
+ * is.iterable('string') // true
1840
+ * is.iterable(123) // false
1841
+ */
1842
+ iterable(value) {
1843
+ const object = Object(value);
1844
+ return object && Reflect.has(object, Symbol.iterator);
1845
+ },
1846
+ /**
1847
+ * Check if a value is null or undefined.
1848
+ *
1849
+ * @param value The value to check.
1850
+ * @returns True if the value is null or undefined, false otherwise.
1851
+ *
1852
+ * @example
1853
+ * is.nullish(null) // true
1854
+ * is.nullish(undefined) // true
1855
+ * is.nullish('value') // false
1856
+ */
1857
+ nullish(value) {
1858
+ return value === null || value === void 0;
1859
+ },
1860
+ /**
1861
+ * Check if a value is a number.
1862
+ *
1863
+ * @param value The value to check.
1864
+ * @returns True if the value is a number, false otherwise.
1865
+ *
1866
+ * @example
1867
+ * is.number(123) // true
1868
+ * is.number('123') // false
1869
+ */
1870
+ number(value) {
1871
+ return typeof value === "number" || value instanceof Number;
1872
+ },
1873
+ /**
1874
+ * Check if a value is an object.
1875
+ *
1876
+ * @param value The value to check.
1877
+ * @returns True if the value is an object, false otherwise.
1878
+ *
1879
+ * @example
1880
+ * is.object({}) // true
1881
+ * is.object(null) // false
1882
+ */
1883
+ object(value) {
1884
+ return !!(value && typeof value === "object");
1885
+ },
1886
+ /**
1887
+ * The {@link Object#entries} function returns the properties of a given
1888
+ * value as an array of arrays where each element of the inner arrays is
1889
+ * a valid object key (so one of {@link String}, {@link Number}, or
1890
+ * {@link Symbol}) and the second element is the value of the pair which
1891
+ * can be any type.
1892
+ *
1893
+ * This function vets this criteria and would return true for each entry
1894
+ * in the returned outer array of a call to {@link Object#entries}.
1895
+ *
1896
+ * @param {any} value the value to test
1897
+ * @returns {boolean} true if the value is a valid object entry in the
1898
+ * form of `[key, value]`.
1899
+ */
1900
+ objectEntry(value) {
1901
+ if (!// Must be an array
1902
+ (Array.isArray(value) && // Must have only two elements
1903
+ value.length == 2 && // Must have its first element be string|number|symbol
1904
+ (this.string(value[0]) || this.number(value[0]) || this.symbol(value[0])))) {
1905
+ return false;
1906
+ }
1907
+ return true;
1908
+ },
1909
+ /**
1910
+ * Check if a value is a valid object key. Valid object keys are strings,
1911
+ * numbers, or symbols — the same types accepted as property keys in
1912
+ * JavaScript objects.
1913
+ *
1914
+ * @param {*} value - The value to check.
1915
+ * @returns {boolean} True if the value is a string, number, or symbol,
1916
+ * false otherwise.
1917
+ *
1918
+ * @example
1919
+ * is.objectKey('name') // true
1920
+ * is.objectKey(0) // true
1921
+ * is.objectKey(Symbol('id')) // true
1922
+ * is.objectKey({}) // false
1923
+ * is.objectKey(null) // false
1924
+ */
1925
+ objectKey(value) {
1926
+ return this.string(value) || this.number(value) || this.symbol(value);
1927
+ },
1928
+ /**
1929
+ * Check if a value is a primitive type.
1930
+ *
1931
+ * This function determines if the provided value is one of the JavaScript
1932
+ * primitive types: string, number, boolean, bigint, or symbol.
1933
+ *
1934
+ * @param value The value to check.
1935
+ * @returns True if the value is a primitive type, false otherwise.
1936
+ *
1937
+ * @example
1938
+ * // Returns true
1939
+ * is.primitive('hello')
1940
+ *
1941
+ * // Returns true
1942
+ * is.primitive(123)
1943
+ *
1944
+ * // Returns true
1945
+ * is.primitive(true)
1946
+ *
1947
+ * // Returns true
1948
+ * is.primitive(123n)
1949
+ *
1950
+ * // Returns true
1951
+ * is.primitive(Symbol('symbol'))
1952
+ *
1953
+ * // Returns false
1954
+ * is.primitive({})
1955
+ *
1956
+ * // Returns false
1957
+ * is.primitive([])
1958
+ */
1959
+ primitive(value) {
1960
+ if (this.nullish(value))
1961
+ return true;
1962
+ return ["string", "number", "boolean", "bigint", "symbol"].some(
1963
+ (type) => typeof value === type
1964
+ );
1965
+ },
1966
+ /**
1967
+ * The use of `typeof` is not a safe guarantor when it comes to Reflect
1968
+ * supported values. Any non-null value that returns a `typeof` either
1969
+ * `object` or `function` should suffice. Note that arrays return 'object'
1970
+ * when run through `typeof`. Shiny is clearly a reference to something
1971
+ * reflective and is much shorter to type. Also, Mal says shiny. :)
1972
+ *
1973
+ * @param value The value to check.
1974
+ * @returns True if the value is an object or a function, false otherwise.
1975
+ *
1976
+ * @example
1977
+ * is.shiny({}) // true
1978
+ * is.shiny(function() {}) // true
1979
+ * is.shiny(123) // false
1980
+ */
1981
+ shiny(value) {
1982
+ return !!(this.object(value) || this.function(value));
1983
+ },
1984
+ /**
1985
+ * Check if a value is a string.
1986
+ *
1987
+ * @param value The value to check.
1988
+ * @returns True if the value is a string, false otherwise.
1989
+ *
1990
+ * @example
1991
+ * is.string('hello') // true
1992
+ * is.string(123) // false
1993
+ */
1994
+ string(value) {
1995
+ return typeof value === "string" || value instanceof String;
1996
+ },
1997
+ /**
1998
+ * Checks if a value is a symbol.
1999
+ *
2000
+ * This function determines whether the provided value is of type
2001
+ * 'symbol' or an instance of the Symbol object.
2002
+ *
2003
+ * @param value - The value to check.
2004
+ * @returns True if the value is a symbol, false otherwise.
2005
+ *
2006
+ * @example
2007
+ * is.symbol(Symbol('foo')) // Returns true
2008
+ * is.symbol('foo') // Returns false
2009
+ */
2010
+ symbol(value) {
2011
+ return typeof value === "symbol" || value instanceof Symbol;
2012
+ },
2013
+ /**
2014
+ * Checks if a value is strictly true.
2015
+ *
2016
+ * This method verifies if the provided value is strictly `true`.
2017
+ *
2018
+ * @param {*} value - The value to check.
2019
+ * @returns {boolean} True if the value is strictly true, false otherwise.
2020
+ *
2021
+ * @example
2022
+ * is.true(true) // true
2023
+ * is.true(false) // false
2024
+ * is.true(1) // false
2025
+ */
2026
+ true(value) {
2027
+ return value === true;
2028
+ },
2029
+ /**
2030
+ * Checks if a value is truthy.
2031
+ *
2032
+ * This method converts the provided value to a boolean and returns
2033
+ * `true` if the value is truthy (i.e., not false, 0, "", null, undefined,
2034
+ * or NaN).
2035
+ *
2036
+ * @param {*} value - The value to check.
2037
+ * @returns {boolean} True if the value is truthy, false otherwise.
2038
+ *
2039
+ * @example
2040
+ * is.truthy(1) // true
2041
+ * is.truthy("hello") // true
2042
+ * is.truthy(0) // false
2043
+ * is.truthy("") // false
2044
+ */
2045
+ truthy(value) {
2046
+ return !!value;
2047
+ }
2048
+ };
2049
+ var si = {
2050
+ /**
2051
+ * Inline if-then-else based on whether value matches a specified type or
2052
+ * class. Delegates the condition check to {@link is#a}.
2053
+ *
2054
+ * @param {*} value - The value to check.
2055
+ * @param {*} typeOrClass - The type or class to compare against.
2056
+ * @param {function|*} thenValue - Returned (or called and its result
2057
+ * returned) if value matches typeOrClass.
2058
+ * @param {function|*} elseValue - Returned (or called and its result
2059
+ * returned) if value does not match typeOrClass.
2060
+ * @returns {*} The result of thenValue if the condition is true,
2061
+ * elseValue otherwise. If thenValue or elseValue is a function,
2062
+ * its return value is used instead.
2063
+ *
2064
+ * @example
2065
+ * si.a(42, 'number', 'yes', 'no') // 'yes'
2066
+ * si.a('str', Number, 'yes', 'no') // 'no'
2067
+ * si.a(42, 'number', () => 'computed', 'no') // 'computed'
2068
+ */
2069
+ a(value, typeOrClass, thenValue, elseValue) {
2070
+ return ifThenElse(is.a(value, typeOrClass), thenValue, elseValue);
2071
+ },
2072
+ /**
2073
+ * Inline if-then-else based on whether value is an accessor descriptor.
2074
+ * Delegates the condition check to {@link is#accessorDescriptor}.
2075
+ *
2076
+ * @param {*} value - The value to check.
2077
+ * @param {function|*} thenValue - Returned (or called and its result
2078
+ * returned) if value is an accessor descriptor.
2079
+ * @param {function|*} elseValue - Returned (or called and its result
2080
+ * returned) if value is not an accessor descriptor.
2081
+ * @returns {*} The result of thenValue if the condition is true,
2082
+ * elseValue otherwise. If thenValue or elseValue is a function,
2083
+ * its return value is used instead.
2084
+ *
2085
+ * @example
2086
+ * si.accessorDescriptor({ get: () => 42 }, 'yes', 'no') // 'yes'
2087
+ * si.accessorDescriptor({ value: 42 }, 'yes', 'no') // 'no'
2088
+ * si.accessorDescriptor({ get: () => 42 }, () => 'computed', 'no') // 'computed'
2089
+ */
2090
+ accessorDescriptor(value, thenValue, elseValue) {
2091
+ return ifThenElse(is.accessorDescriptor(value), thenValue, elseValue);
2092
+ },
2093
+ /**
2094
+ * Inline if-then-else based on whether value is an array.
2095
+ * Delegates the condition check to {@link is#array}.
2096
+ *
2097
+ * @param {*} value - The value to check.
2098
+ * @param {function|*} thenValue - Returned (or called and its result
2099
+ * returned) if value is an array.
2100
+ * @param {function|*} elseValue - Returned (or called and its result
2101
+ * returned) if value is not an array.
2102
+ * @returns {*} The result of thenValue if the condition is true,
2103
+ * elseValue otherwise. If thenValue or elseValue is a function,
2104
+ * its return value is used instead.
2105
+ *
2106
+ * @example
2107
+ * si.array([1, 2, 3], 'yes', 'no') // 'yes'
2108
+ * si.array('string', 'yes', 'no') // 'no'
2109
+ * si.array([1, 2, 3], () => 'computed', 'no') // 'computed'
2110
+ */
2111
+ array(value, thenValue, elseValue) {
2112
+ return ifThenElse(is.array(value), thenValue, elseValue);
2113
+ },
2114
+ /**
2115
+ * Inline if-then-else based on whether value is a bigint.
2116
+ * Delegates the condition check to {@link is#bigint}.
2117
+ *
2118
+ * @param {*} value - The value to check.
2119
+ * @param {function|*} thenValue - Returned (or called and its result
2120
+ * returned) if value is a bigint.
2121
+ * @param {function|*} elseValue - Returned (or called and its result
2122
+ * returned) if value is not a bigint.
2123
+ * @returns {*} The result of thenValue if the condition is true,
2124
+ * elseValue otherwise. If thenValue or elseValue is a function,
2125
+ * its return value is used instead.
2126
+ *
2127
+ * @example
2128
+ * si.bigint(123n, 'yes', 'no') // 'yes'
2129
+ * si.bigint(123, 'yes', 'no') // 'no'
2130
+ * si.bigint(123n, () => 'computed', 'no') // 'computed'
2131
+ */
2132
+ bigint(value, thenValue, elseValue) {
2133
+ return ifThenElse(is.bigint(value), thenValue, elseValue);
2134
+ },
2135
+ /**
2136
+ * Inline if-then-else based on whether value is a boolean.
2137
+ * Delegates the condition check to {@link is#boolean}.
2138
+ *
2139
+ * @param {*} value - The value to check.
2140
+ * @param {function|*} thenValue - Returned (or called and its result
2141
+ * returned) if value is a boolean.
2142
+ * @param {function|*} elseValue - Returned (or called and its result
2143
+ * returned) if value is not a boolean.
2144
+ * @returns {*} The result of thenValue if the condition is true,
2145
+ * elseValue otherwise. If thenValue or elseValue is a function,
2146
+ * its return value is used instead.
2147
+ *
2148
+ * @example
2149
+ * si.boolean(true, 'yes', 'no') // 'yes'
2150
+ * si.boolean(1, 'yes', 'no') // 'no'
2151
+ * si.boolean(false, () => 'computed', 'no') // 'computed'
2152
+ */
2153
+ boolean(value, thenValue, elseValue) {
2154
+ return ifThenElse(is.boolean(value), thenValue, elseValue);
2155
+ },
2156
+ /**
2157
+ * Inline if-then-else based on whether object is callable.
2158
+ * Delegates the condition check to {@link is#callable}.
2159
+ *
2160
+ * @param {*} object - The object to check.
2161
+ * @param {function|*} thenValue - Returned (or called and its result
2162
+ * returned) if object is callable.
2163
+ * @param {function|*} elseValue - Returned (or called and its result
2164
+ * returned) if object is not callable.
2165
+ * @returns {*} The result of thenValue if the condition is true,
2166
+ * elseValue otherwise. If thenValue or elseValue is a function,
2167
+ * its return value is used instead.
2168
+ *
2169
+ * @example
2170
+ * si.callable(function() {}, 'yes', 'no') // 'yes'
2171
+ * si.callable(123, 'yes', 'no') // 'no'
2172
+ * si.callable(function() {}, () => 'computed', 'no') // 'computed'
2173
+ */
2174
+ callable(object, thenValue, elseValue) {
2175
+ return ifThenElse(is.callable(object), thenValue, elseValue);
2176
+ },
2177
+ /**
2178
+ * Inline if-then-else based on whether object is a callable descriptor.
2179
+ * Delegates the condition check to {@link is#callableDescriptor}.
2180
+ *
2181
+ * @param {*} object - The object to check.
2182
+ * @param {function|*} thenValue - Returned (or called and its result
2183
+ * returned) if object is a callable descriptor.
2184
+ * @param {function|*} elseValue - Returned (or called and its result
2185
+ * returned) if object is not a callable descriptor.
2186
+ * @returns {*} The result of thenValue if the condition is true,
2187
+ * elseValue otherwise. If thenValue or elseValue is a function,
2188
+ * its return value is used instead.
2189
+ *
2190
+ * @example
2191
+ * si.callableDescriptor({ get: function() {} }, 'yes', 'no') // 'yes'
2192
+ * si.callableDescriptor(123, 'yes', 'no') // 'no'
2193
+ * si.callableDescriptor({ get: function() {} }, () => 'computed', 'no') // 'computed'
2194
+ */
2195
+ callableDescriptor(object, thenValue, elseValue) {
2196
+ return ifThenElse(is.callableDescriptor(object), thenValue, elseValue);
2197
+ },
2198
+ /**
2199
+ * Inline if-then-else based on whether value is a data property descriptor.
2200
+ * Delegates the condition check to {@link is#dataDescriptor}.
2201
+ *
2202
+ * @param {*} value - The value to check.
2203
+ * @param {function|*} thenValue - Returned (or called and its result
2204
+ * returned) if value is a data descriptor.
2205
+ * @param {function|*} elseValue - Returned (or called and its result
2206
+ * returned) if value is not a data descriptor.
2207
+ * @returns {*} The result of thenValue if the condition is true,
2208
+ * elseValue otherwise. If thenValue or elseValue is a function,
2209
+ * its return value is used instead.
2210
+ *
2211
+ * @example
2212
+ * si.dataDescriptor({ value: 42, writable: true }, 'yes', 'no') // 'yes'
2213
+ * si.dataDescriptor({ get: () => 42 }, 'yes', 'no') // 'no'
2214
+ * si.dataDescriptor({ value: 42 }, () => 'computed', 'no') // 'computed'
2215
+ */
2216
+ dataDescriptor(value, thenValue, elseValue) {
2217
+ return ifThenElse(is.dataDescriptor(value), thenValue, elseValue);
2218
+ },
2219
+ /**
2220
+ * Inline if-then-else based on whether value is a property descriptor.
2221
+ * Delegates the condition check to {@link is#descriptor}.
2222
+ *
2223
+ * @param {*} value - The value to check.
2224
+ * @param {function|*} thenValue - Returned (or called and its result
2225
+ * returned) if value is a property descriptor.
2226
+ * @param {function|*} elseValue - Returned (or called and its result
2227
+ * returned) if value is not a property descriptor.
2228
+ * @returns {*} The result of thenValue if the condition is true,
2229
+ * elseValue otherwise. If thenValue or elseValue is a function,
2230
+ * its return value is used instead.
2231
+ *
2232
+ * @example
2233
+ * si.descriptor({ configurable: true }, 'yes', 'no') // 'yes'
2234
+ * si.descriptor({}, 'yes', 'no') // 'no'
2235
+ * si.descriptor({ get: () => {} }, () => 'computed', 'no') // 'computed'
2236
+ */
2237
+ descriptor(value, thenValue, elseValue) {
2238
+ return ifThenElse(is.descriptor(value), thenValue, elseValue);
2239
+ },
2240
+ /**
2241
+ * Inline if-then-else based on whether value is strictly false.
2242
+ * Delegates the condition check to {@link is#false}.
2243
+ *
2244
+ * @param {*} value - The value to check.
2245
+ * @param {function|*} thenValue - Returned (or called and its result
2246
+ * returned) if value is strictly false.
2247
+ * @param {function|*} elseValue - Returned (or called and its result
2248
+ * returned) if value is not strictly false.
2249
+ * @returns {*} The result of thenValue if the condition is true,
2250
+ * elseValue otherwise. If thenValue or elseValue is a function,
2251
+ * its return value is used instead.
2252
+ *
2253
+ * @example
2254
+ * si.false(false, 'yes', 'no') // 'yes'
2255
+ * si.false(0, 'yes', 'no') // 'no'
2256
+ * si.false(false, () => 'computed', 'no') // 'computed'
2257
+ */
2258
+ false(value, thenValue, elseValue) {
2259
+ return ifThenElse(is.false(value), thenValue, elseValue);
2260
+ },
2261
+ /**
2262
+ * Inline if-then-else based on whether value is falsy.
2263
+ * Delegates the condition check to {@link is#falsy}.
2264
+ *
2265
+ * @param {*} value - The value to check.
2266
+ * @param {function|*} thenValue - Returned (or called and its result
2267
+ * returned) if value is falsy.
2268
+ * @param {function|*} elseValue - Returned (or called and its result
2269
+ * returned) if value is not falsy.
2270
+ * @returns {*} The result of thenValue if the condition is true,
2271
+ * elseValue otherwise. If thenValue or elseValue is a function,
2272
+ * its return value is used instead.
2273
+ *
2274
+ * @example
2275
+ * si.falsy(0, 'yes', 'no') // 'yes'
2276
+ * si.falsy(1, 'yes', 'no') // 'no'
2277
+ * si.falsy('', () => 'computed', 'no') // 'computed'
2278
+ */
2279
+ falsy(value, thenValue, elseValue) {
2280
+ return ifThenElse(is.falsy(value), thenValue, elseValue);
2281
+ },
2282
+ /**
2283
+ * Alias for {@link si#falsy}. Inline if-then-else based on whether value
2284
+ * is falsy. Delegates the condition check to {@link is#falsey}.
2285
+ *
2286
+ * @param {*} value - The value to check.
2287
+ * @param {function|*} thenValue - Returned (or called and its result
2288
+ * returned) if value is falsy.
2289
+ * @param {function|*} elseValue - Returned (or called and its result
2290
+ * returned) if value is not falsy.
2291
+ * @returns {*} The result of thenValue if the condition is true,
2292
+ * elseValue otherwise. If thenValue or elseValue is a function,
2293
+ * its return value is used instead.
2294
+ *
2295
+ * @example
2296
+ * si.falsey(0, 'yes', 'no') // 'yes'
2297
+ * si.falsey(1, 'yes', 'no') // 'no'
2298
+ * si.falsey('', () => 'computed', 'no') // 'computed'
2299
+ */
2300
+ falsey(value, thenValue, elseValue) {
2301
+ return ifThenElse(is.falsey(value), thenValue, elseValue);
2302
+ },
2303
+ /**
2304
+ * Inline if-then-else based on whether value is a function.
2305
+ * Delegates the condition check to {@link is#function}.
2306
+ *
2307
+ * @param {*} value - The value to check.
2308
+ * @param {function|*} thenValue - Returned (or called and its result
2309
+ * returned) if value is a function.
2310
+ * @param {function|*} elseValue - Returned (or called and its result
2311
+ * returned) if value is not a function.
2312
+ * @returns {*} The result of thenValue if the condition is true,
2313
+ * elseValue otherwise. If thenValue or elseValue is a function,
2314
+ * its return value is used instead.
2315
+ *
2316
+ * @example
2317
+ * si.function(function() {}, 'yes', 'no') // 'yes'
2318
+ * si.function(123, 'yes', 'no') // 'no'
2319
+ * si.function(function() {}, () => 'computed', 'no') // 'computed'
2320
+ */
2321
+ function(value, thenValue, elseValue) {
2322
+ return ifThenElse(is.function(value), thenValue, elseValue);
2323
+ },
2324
+ /**
2325
+ * Inline if-then-else based on whether value is iterable.
2326
+ * Delegates the condition check to {@link is#iterable}.
2327
+ *
2328
+ * @param {*} value - The value to check.
2329
+ * @param {function|*} thenValue - Returned (or called and its result
2330
+ * returned) if value is iterable.
2331
+ * @param {function|*} elseValue - Returned (or called and its result
2332
+ * returned) if value is not iterable.
2333
+ * @returns {*} The result of thenValue if the condition is true,
2334
+ * elseValue otherwise. If thenValue or elseValue is a function,
2335
+ * its return value is used instead.
2336
+ *
2337
+ * @example
2338
+ * si.iterable([1, 2, 3], 'yes', 'no') // 'yes'
2339
+ * si.iterable(123, 'yes', 'no') // 'no'
2340
+ * si.iterable('string', () => 'computed', 'no') // 'computed'
2341
+ */
2342
+ iterable(value, thenValue, elseValue) {
2343
+ return ifThenElse(is.iterable(value), thenValue, elseValue);
2344
+ },
2345
+ /**
2346
+ * Inline if-then-else based on whether value is null or undefined.
2347
+ * Delegates the condition check to {@link is#nullish}.
2348
+ *
2349
+ * @param {*} value - The value to check.
2350
+ * @param {function|*} thenValue - Returned (or called and its result
2351
+ * returned) if value is nullish.
2352
+ * @param {function|*} elseValue - Returned (or called and its result
2353
+ * returned) if value is not nullish.
2354
+ * @returns {*} The result of thenValue if the condition is true,
2355
+ * elseValue otherwise. If thenValue or elseValue is a function,
2356
+ * its return value is used instead.
2357
+ *
2358
+ * @example
2359
+ * si.nullish(null, 'yes', 'no') // 'yes'
2360
+ * si.nullish('value', 'yes', 'no') // 'no'
2361
+ * si.nullish(undefined, () => 'computed', 'no') // 'computed'
2362
+ */
2363
+ nullish(value, thenValue, elseValue) {
2364
+ return ifThenElse(is.nullish(value), thenValue, elseValue);
2365
+ },
2366
+ /**
2367
+ * Inline if-then-else based on whether value is a number.
2368
+ * Delegates the condition check to {@link is#number}.
2369
+ *
2370
+ * @param {*} value - The value to check.
2371
+ * @param {function|*} thenValue - Returned (or called and its result
2372
+ * returned) if value is a number.
2373
+ * @param {function|*} elseValue - Returned (or called and its result
2374
+ * returned) if value is not a number.
2375
+ * @returns {*} The result of thenValue if the condition is true,
2376
+ * elseValue otherwise. If thenValue or elseValue is a function,
2377
+ * its return value is used instead.
2378
+ *
2379
+ * @example
2380
+ * si.number(123, 'yes', 'no') // 'yes'
2381
+ * si.number('123', 'yes', 'no') // 'no'
2382
+ * si.number(123, () => 'computed', 'no') // 'computed'
2383
+ */
2384
+ number(value, thenValue, elseValue) {
2385
+ return ifThenElse(is.number(value), thenValue, elseValue);
2386
+ },
2387
+ /**
2388
+ * Inline if-then-else based on whether value is an object.
2389
+ * Delegates the condition check to {@link is#object}.
2390
+ *
2391
+ * @param {*} value - The value to check.
2392
+ * @param {function|*} thenValue - Returned (or called and its result
2393
+ * returned) if value is an object.
2394
+ * @param {function|*} elseValue - Returned (or called and its result
2395
+ * returned) if value is not an object.
2396
+ * @returns {*} The result of thenValue if the condition is true,
2397
+ * elseValue otherwise. If thenValue or elseValue is a function,
2398
+ * its return value is used instead.
2399
+ *
2400
+ * @example
2401
+ * si.object({}, 'yes', 'no') // 'yes'
2402
+ * si.object(null, 'yes', 'no') // 'no'
2403
+ * si.object({}, () => 'computed', 'no') // 'computed'
2404
+ */
2405
+ object(value, thenValue, elseValue) {
2406
+ return ifThenElse(is.object(value), thenValue, elseValue);
2407
+ },
2408
+ /**
2409
+ * Inline if-then-else based on whether value is a valid object entry.
2410
+ * Delegates the condition check to {@link is#objectEntry}.
2411
+ *
2412
+ * @param {any} value - The value to check.
2413
+ * @param {function|*} thenValue - Returned (or called and its result
2414
+ * returned) if value is a valid object entry.
2415
+ * @param {function|*} elseValue - Returned (or called and its result
2416
+ * returned) if value is not a valid object entry.
2417
+ * @returns {*} The result of thenValue if the condition is true,
2418
+ * elseValue otherwise. If thenValue or elseValue is a function,
2419
+ * its return value is used instead.
2420
+ *
2421
+ * @example
2422
+ * si.objectEntry(['key', 42], 'yes', 'no') // 'yes'
2423
+ * si.objectEntry([1, 2, 3], 'yes', 'no') // 'no'
2424
+ * si.objectEntry(['key', 42], () => 'computed', 'no') // 'computed'
2425
+ */
2426
+ objectEntry(value, thenValue, elseValue) {
2427
+ return ifThenElse(is.objectEntry(value), thenValue, elseValue);
2428
+ },
2429
+ /**
2430
+ * Inline if-then-else based on whether value is a valid object key.
2431
+ * Delegates the condition check to {@link is#objectKey}.
2432
+ *
2433
+ * @param {*} value - The value to check.
2434
+ * @param {function|*} thenValue - Returned (or called and its result
2435
+ * returned) if value is a valid object key.
2436
+ * @param {function|*} elseValue - Returned (or called and its result
2437
+ * returned) if value is not a valid object key.
2438
+ * @returns {*} The result of thenValue if the condition is true,
2439
+ * elseValue otherwise. If thenValue or elseValue is a function,
2440
+ * its return value is used instead.
2441
+ *
2442
+ * @example
2443
+ * si.objectKey('name', 'yes', 'no') // 'yes'
2444
+ * si.objectKey({}, 'yes', 'no') // 'no'
2445
+ * si.objectKey(Symbol('id'), () => 'computed', 'no') // 'computed'
2446
+ */
2447
+ objectKey(value, thenValue, elseValue) {
2448
+ return ifThenElse(is.objectKey(value), thenValue, elseValue);
2449
+ },
2450
+ /**
2451
+ * Inline if-then-else based on whether value is a primitive type.
2452
+ * Delegates the condition check to {@link is#primitive}.
2453
+ *
2454
+ * @param {*} value - The value to check.
2455
+ * @param {function|*} thenValue - Returned (or called and its result
2456
+ * returned) if value is a primitive.
2457
+ * @param {function|*} elseValue - Returned (or called and its result
2458
+ * returned) if value is not a primitive.
2459
+ * @returns {*} The result of thenValue if the condition is true,
2460
+ * elseValue otherwise. If thenValue or elseValue is a function,
2461
+ * its return value is used instead.
2462
+ *
2463
+ * @example
2464
+ * si.primitive('hello', 'yes', 'no') // 'yes'
2465
+ * si.primitive({}, 'yes', 'no') // 'no'
2466
+ * si.primitive(123, () => 'computed', 'no') // 'computed'
2467
+ */
2468
+ primitive(value, thenValue, elseValue) {
2469
+ return ifThenElse(is.primitive(value), thenValue, elseValue);
2470
+ },
2471
+ /**
2472
+ * Inline if-then-else based on whether value is shiny (object or function).
2473
+ * Delegates the condition check to {@link is#shiny}.
2474
+ *
2475
+ * @param {*} value - The value to check.
2476
+ * @param {function|*} thenValue - Returned (or called and its result
2477
+ * returned) if value is shiny.
2478
+ * @param {function|*} elseValue - Returned (or called and its result
2479
+ * returned) if value is not shiny.
2480
+ * @returns {*} The result of thenValue if the condition is true,
2481
+ * elseValue otherwise. If thenValue or elseValue is a function,
2482
+ * its return value is used instead.
2483
+ *
2484
+ * @example
2485
+ * si.shiny({}, 'yes', 'no') // 'yes'
2486
+ * si.shiny(123, 'yes', 'no') // 'no'
2487
+ * si.shiny(function() {}, () => 'computed', 'no') // 'computed'
2488
+ */
2489
+ shiny(value, thenValue, elseValue) {
2490
+ return ifThenElse(is.shiny(value), thenValue, elseValue);
2491
+ },
2492
+ /**
2493
+ * Inline if-then-else based on whether value is a string.
2494
+ * Delegates the condition check to {@link is#string}.
2495
+ *
2496
+ * @param {*} value - The value to check.
2497
+ * @param {function|*} thenValue - Returned (or called and its result
2498
+ * returned) if value is a string.
2499
+ * @param {function|*} elseValue - Returned (or called and its result
2500
+ * returned) if value is not a string.
2501
+ * @returns {*} The result of thenValue if the condition is true,
2502
+ * elseValue otherwise. If thenValue or elseValue is a function,
2503
+ * its return value is used instead.
2504
+ *
2505
+ * @example
2506
+ * si.string('hello', 'yes', 'no') // 'yes'
2507
+ * si.string(123, 'yes', 'no') // 'no'
2508
+ * si.string('hello', () => 'computed', 'no') // 'computed'
2509
+ */
2510
+ string(value, thenValue, elseValue) {
2511
+ return ifThenElse(is.string(value), thenValue, elseValue);
2512
+ },
2513
+ /**
2514
+ * Inline if-then-else based on whether value is a symbol.
2515
+ * Delegates the condition check to {@link is#symbol}.
2516
+ *
2517
+ * @param {*} value - The value to check.
2518
+ * @param {function|*} thenValue - Returned (or called and its result
2519
+ * returned) if value is a symbol.
2520
+ * @param {function|*} elseValue - Returned (or called and its result
2521
+ * returned) if value is not a symbol.
2522
+ * @returns {*} The result of thenValue if the condition is true,
2523
+ * elseValue otherwise. If thenValue or elseValue is a function,
2524
+ * its return value is used instead.
2525
+ *
2526
+ * @example
2527
+ * si.symbol(Symbol('foo'), 'yes', 'no') // 'yes'
2528
+ * si.symbol('foo', 'yes', 'no') // 'no'
2529
+ * si.symbol(Symbol('foo'), () => 'computed', 'no') // 'computed'
2530
+ */
2531
+ symbol(value, thenValue, elseValue) {
2532
+ return ifThenElse(is.symbol(value), thenValue, elseValue);
2533
+ },
2534
+ /**
2535
+ * Inline if-then-else using an arbitrary condition. If condition is a
2536
+ * function, it is called and its result is used as the condition; otherwise
2537
+ * the condition value is evaluated directly.
2538
+ *
2539
+ * @param {function|*} condition - The condition to evaluate. If a function,
2540
+ * it is called and its return value is used as the condition.
2541
+ * @param {function|*} thenValue - Returned (or called and its result
2542
+ * returned) if the condition is truthy.
2543
+ * @param {function|*} elseValue - Returned (or called and its result
2544
+ * returned) if the condition is falsy.
2545
+ * @returns {*} The result of thenValue if the condition is truthy,
2546
+ * elseValue otherwise. If thenValue or elseValue is a function,
2547
+ * its return value is used instead.
2548
+ *
2549
+ * @example
2550
+ * si.then(true, 'yes', 'no') // 'yes'
2551
+ * si.then(false, 'yes', 'no') // 'no'
2552
+ * si.then(() => true, 'yes', 'no') // 'yes'
2553
+ * si.then(() => false, () => 'computed', 'no') // 'no'
2554
+ */
2555
+ then(condition, thenValue, elseValue) {
2556
+ return ifThenElse(
2557
+ is.function(condition) ? condition() : condition,
2558
+ thenValue,
2559
+ elseValue
2560
+ );
2561
+ },
2562
+ /**
2563
+ * Inline if-then-else based on whether value is strictly true.
2564
+ * Delegates the condition check to {@link is#true}.
2565
+ *
2566
+ * @param {*} value - The value to check.
2567
+ * @param {function|*} thenValue - Returned (or called and its result
2568
+ * returned) if value is strictly true.
2569
+ * @param {function|*} elseValue - Returned (or called and its result
2570
+ * returned) if value is not strictly true.
2571
+ * @returns {*} The result of thenValue if the condition is true,
2572
+ * elseValue otherwise. If thenValue or elseValue is a function,
2573
+ * its return value is used instead.
2574
+ *
2575
+ * @example
2576
+ * si.true(true, 'yes', 'no') // 'yes'
2577
+ * si.true(1, 'yes', 'no') // 'no'
2578
+ * si.true(true, () => 'computed', 'no') // 'computed'
2579
+ */
2580
+ true(value, thenValue, elseValue) {
2581
+ return ifThenElse(is.true(value), thenValue, elseValue);
2582
+ },
2583
+ /**
2584
+ * Inline if-then-else based on whether value is truthy.
2585
+ * Delegates the condition check to {@link is#truthy}.
2586
+ *
2587
+ * @param {*} value - The value to check.
2588
+ * @param {function|*} thenValue - Returned (or called and its result
2589
+ * returned) if value is truthy.
2590
+ * @param {function|*} elseValue - Returned (or called and its result
2591
+ * returned) if value is not truthy.
2592
+ * @returns {*} The result of thenValue if the condition is true,
2593
+ * elseValue otherwise. If thenValue or elseValue is a function,
2594
+ * its return value is used instead.
2595
+ *
2596
+ * @example
2597
+ * si.truthy(1, 'yes', 'no') // 'yes'
2598
+ * si.truthy(0, 'yes', 'no') // 'no'
2599
+ * si.truthy("hello", () => 'computed', 'no') // 'computed'
2600
+ */
2601
+ truthy(value, thenValue, elseValue) {
2602
+ return ifThenElse(is.truthy(value), thenValue, elseValue);
2603
+ },
2604
+ /**
2605
+ * Inline if-then-else based on whether value is undefined.
2606
+ * Delegates the condition check to {@link is#a} with type 'undefined'.
2607
+ *
2608
+ * @param {*} value - The value to check.
2609
+ * @param {function|*} thenValue - Returned (or called and its result
2610
+ * returned) if value is undefined.
2611
+ * @param {function|*} elseValue - Returned (or called and its result
2612
+ * returned) if value is not undefined.
2613
+ * @returns {*} The result of thenValue if the condition is true,
2614
+ * elseValue otherwise. If thenValue or elseValue is a function,
2615
+ * its return value is used instead.
2616
+ *
2617
+ * @example
2618
+ * si.undefined(undefined, 'yes', 'no') // 'yes'
2619
+ * si.undefined('value', 'yes', 'no') // 'no'
2620
+ * si.undefined(undefined, () => 'computed', 'no') // 'computed'
2621
+ */
2622
+ undefined(value, thenValue, elseValue) {
2623
+ return ifThenElse(is.a(value, "undefined"), thenValue, elseValue);
2624
+ }
2625
+ };
2626
+ var has = function has2(object, key) {
2627
+ if ([Map, Set, WeakMap, WeakSet].some((i) => object instanceof i)) {
2628
+ return object.has(key);
2629
+ }
2630
+ return is.shiny(object) && Reflect.has(object, key);
2631
+ };
2632
+ Object.assign(has, {
2633
+ /**
2634
+ * Checks if an object contains all specified keys.
2635
+ *
2636
+ * This function determines if the provided object contains all the keys
2637
+ * specified in the keys array. It supports various types of objects
2638
+ * including Map, Set, WeakMap, and WeakSet. For other objects, it uses
2639
+ * the Reflect API to check for the keys.
2640
+ *
2641
+ * @param object The object to check.
2642
+ * @param keys The array of keys to look for in the object.
2643
+ * @returns True if the object contains all the keys, false otherwise.
2644
+ *
2645
+ * @example
2646
+ * // Returns true
2647
+ * has.all(new Map([
2648
+ * ['key1', 'value1'], ['key2', 'value2']
2649
+ * ]), ['key1', 'key2'])
2650
+ *
2651
+ * @example
2652
+ * // Returns false
2653
+ * has.all({}, ['key1', 'key2'])
2654
+ */
2655
+ all(object, keys) {
2656
+ if (!is.shiny(object) || !is.array(keys) || !keys.length) {
2657
+ return false;
2658
+ }
2659
+ return keys.every((key) => has(object, key));
2660
+ },
2661
+ /**
2662
+ * Checks if an object contains at least one of the specified keys.
2663
+ *
2664
+ * This function determines if the provided object contains at least one
2665
+ * of the keys specified in the keys array. It supports various types of
2666
+ * objects including Map, Set, WeakMap, and WeakSet. For other objects,
2667
+ * it uses the Reflect API to check for the keys.
2668
+ *
2669
+ * @param object The object to check.
2670
+ * @param keys The array of keys to look for in the object.
2671
+ * @returns True if the object contains at least one of the keys, false
2672
+ * otherwise.
2673
+ *
2674
+ * @example
2675
+ * // Returns true
2676
+ * has.some(new Map([['key1', 'value1'], ['key2', 'value2']]), ['key1'])
2677
+ *
2678
+ * @example
2679
+ * // Returns false
2680
+ * has.some({}, ['key1', 'key2'])
2681
+ */
2682
+ some(object, keys) {
2683
+ if (!is.shiny(object) || !is.array(keys) || !keys.length) {
2684
+ return false;
2685
+ }
2686
+ return keys.some((key) => has(object, key));
2687
+ },
2688
+ /**
2689
+ * Checks if an object has a 'prototype' property.
2690
+ *
2691
+ * This function is one way to determine if a supplied function is a big
2692
+ * arrow function or not. Regular functions and class functions, both
2693
+ * static and instance level, all have prototypes. Only big arrow functions
2694
+ * do not.
2695
+ *
2696
+ * @param {Object} object - The object to check.
2697
+ * @returns {boolean} True if the object has a 'prototype' property,
2698
+ * false otherwise.
2699
+ *
2700
+ * @example
2701
+ * // Returns true
2702
+ * has.prototype(function() {})
2703
+ *
2704
+ * @example
2705
+ * // Returns false
2706
+ * has.prototype(() => {})
2707
+ * has.prototype(5)
2708
+ * has.prototype(true)
2709
+ */
2710
+ prototype(object) {
2711
+ return is.shiny(object) && has(object, "prototype");
2712
+ },
2713
+ /**
2714
+ * Checks if an object has a custom string tag.
2715
+ *
2716
+ * This method determines if the object has a Symbol.toStringTag property,
2717
+ * which is used to customize the behavior of Object.prototype.toString().
2718
+ *
2719
+ * @param object - The object to check.
2720
+ * @returns True if the object has a custom string tag, false otherwise.
2721
+ *
2722
+ * @example
2723
+ * const obj = { [Symbol.toStringTag]: 'CustomObject' }
2724
+ * has.stringTag(obj) // Returns true
2725
+ */
2726
+ stringTag(object) {
2727
+ return is.object(object) && has(object, Symbol.toStringTag);
2728
+ },
2729
+ /**
2730
+ * Checks if an object has a custom toPrimitive method.
2731
+ *
2732
+ * This method determines if the object has a Symbol.toPrimitive property,
2733
+ * which is used to convert an object to a primitive value.
2734
+ *
2735
+ * @param object - The object to check.
2736
+ * @returns True if the object has a custom toPrimitive method,
2737
+ * false otherwise.
2738
+ *
2739
+ * @example
2740
+ * const obj = { [Symbol.toPrimitive]: () => 42 }
2741
+ * has.toPrimitive(obj) // Returns true
2742
+ */
2743
+ toPrimitive(object) {
2744
+ return is.object(object) && has(object, Symbol.toPrimitive);
2745
+ },
2746
+ /**
2747
+ * Checks if an object has a custom valueOf method.
2748
+ *
2749
+ * This method determines if the object has a valueOf property that is a
2750
+ * function, which is used to convert an object to a primitive value.
2751
+ *
2752
+ * @param object - The object to check.
2753
+ * @returns True if the object has a custom valueOf method, false otherwise.
2754
+ *
2755
+ * @example
2756
+ * const obj = { valueOf: () => 42 }
2757
+ * has.valueOfFn(obj) // Returns true
2758
+ */
2759
+ valueOfFn(object) {
2760
+ return is.object(object) && Object.hasOwn(object, "valueOf") && is.function(object.valueOf);
2761
+ }
2762
+ });
2763
+ var as = {
2764
+ /**
2765
+ * Converts a value to an array if it is iterable.
2766
+ *
2767
+ * @param value The value to convert.
2768
+ * @returns The converted array if the value is iterable, otherwise undefined.
2769
+ *
2770
+ * @example
2771
+ * // Returns [1, 2, 3]
2772
+ * as.array([1, 2, 3])
2773
+ *
2774
+ * @example
2775
+ * // Returns ['s', 't', 'r', 'i', 'n', 'g']
2776
+ * as.array('string')
2777
+ *
2778
+ * @example
2779
+ * // Returns undefined
2780
+ * as.array(123)
2781
+ */
2782
+ array(value) {
2783
+ return is.iterable(value) && Array.from(value) || void 0;
2784
+ },
2785
+ /**
2786
+ * Converts a value to an object. If the supplied value is a primitive
2787
+ * value, in many cases, this will convert it to an object instance of
2788
+ * that type. Numbers, strings, symbols, and big integers, all have
2789
+ * object instance variants. Wrapping them in a call to `Object()` will
2790
+ * convert the primitive into this instance variant.
2791
+ *
2792
+ * @param value The value to convert.
2793
+ * @returns The converted object.
2794
+ *
2795
+ * @example
2796
+ * // Returns { key: 'value' }
2797
+ * as.object({ key: 'value' })
2798
+ *
2799
+ * @example
2800
+ * // String instance as oppposed to primitive string
2801
+ * typeof as.object('string') // 'object'
2802
+ * as.object('string') instanceof String // true
2803
+ * 'string' instanceof String // false
2804
+ *
2805
+ * @example
2806
+ * // Returns {}
2807
+ * as.object(null)
2808
+ */
2809
+ object(value) {
2810
+ return Object(value);
2811
+ },
2812
+ /**
2813
+ * Converts a given value to a string. This function handles various types
2814
+ * of values, including null, undefined, objects with custom
2815
+ * [Symbol.toPrimitive] methods, and objects with toString or valueOf
2816
+ * methods.
2817
+ *
2818
+ * @param value The value to convert to a string.
2819
+ * @param use Optional configuration object:
2820
+ * - description: If true, returns the description of a Symbol.
2821
+ * - stringTag: If true, returns the [Symbol.toStringTag] value if present.
2822
+ * @returns The string representation of the value.
2823
+ *
2824
+ * @example
2825
+ * // Returns 'null'
2826
+ * as.string(null)
2827
+ *
2828
+ * @example
2829
+ * // Returns '123'
2830
+ * as.string(123)
2831
+ *
2832
+ * @example
2833
+ * // Returns 'custom'
2834
+ * const obj = {
2835
+ * [Symbol.toPrimitive](hint) {
2836
+ * if (hint === 'string') return 'custom'
2837
+ * return null
2838
+ * }
2839
+ * }
2840
+ * as.string(obj)
2841
+ *
2842
+ * @example
2843
+ * // Returns 'mySymbol'
2844
+ * as.string(Symbol('mySymbol'), { description: true })
2845
+ *
2846
+ * @example
2847
+ * // Returns 'Array'
2848
+ * as.string([], { stringTag: true })
2849
+ */
2850
+ string(value, use = {
2851
+ description: false,
2852
+ stringTag: false
2853
+ }) {
2854
+ if (value === null || value === void 0) {
2855
+ return String(value);
2856
+ }
2857
+ if (is.symbol(value) && use?.description) {
2858
+ return value.description;
2859
+ }
2860
+ if (has.stringTag(value) && use?.stringTag) {
2861
+ return value[Symbol.toStringTag];
2862
+ }
2863
+ if (is.function(value?.[Symbol.toPrimitive])) {
2864
+ const primitiveValue = value[Symbol.toPrimitive]("string");
2865
+ if (is.string(primitiveValue)) {
2866
+ return primitiveValue;
2867
+ }
2868
+ }
2869
+ if (is.function(value?.valueOf)) {
2870
+ const valueOfValue = value.valueOf();
2871
+ if (is.string(valueOfValue)) {
2872
+ return valueOfValue;
2873
+ }
2874
+ if (!is.object(valueOfValue)) {
2875
+ return String(valueOfValue);
2876
+ }
2877
+ }
2878
+ if (is.function(value?.toString)) {
2879
+ const stringValue = value.toString();
2880
+ if (is.string(stringValue)) {
2881
+ return stringValue;
2882
+ }
2883
+ }
2884
+ return String(value);
2885
+ },
2886
+ /**
2887
+ * Converts a given value to a string representing an integer.
2888
+ *
2889
+ * This method first converts the value to a number string and then extracts
2890
+ * the integer part by splitting the string at the decimal point.
2891
+ *
2892
+ * @param value The value to convert to an integer string.
2893
+ * @returns The integer part of the value as a string.
2894
+ *
2895
+ * @example
2896
+ * // Returns '123'
2897
+ * as.integerString(123.456)
2898
+ *
2899
+ * @example
2900
+ * // Returns '0'
2901
+ * as.integerString('0.789')
2902
+ */
2903
+ integerString(value) {
2904
+ return this.numberString(value).split(".")[0];
2905
+ },
2906
+ /**
2907
+ * Converts a given value to a string representing a number.
2908
+ *
2909
+ * This method first converts the value to a string, trims any whitespace,
2910
+ * and removes any non-numeric characters except for '.', 'e', 'E', '+',
2911
+ * and '-'. It then uses a regular expression to match a floating-point
2912
+ * number, allowing an optional leading '+' or '-' sign, digits before
2913
+ * and after a single decimal point.
2914
+ *
2915
+ * @param value The value to convert to a number string.
2916
+ * @returns The sanitized number string or an empty string if no valid
2917
+ * float was found.
2918
+ *
2919
+ * @example
2920
+ * // Returns '123.456'
2921
+ * as.numberString(' 123.456abc ')
2922
+ *
2923
+ * @example
2924
+ * // Returns '-0.789'
2925
+ * as.numberString('-0.789xyz')
2926
+ */
2927
+ numberString(value) {
2928
+ const string = this.string(value).trim().replace(/[^0-9.eE+-]/g, "");
2929
+ const sanitizedStr = string.match(/^[-+]?\d*\.?\d+([eE][-+]?\d+)?/);
2930
+ return sanitizedStr ? sanitizedStr[0] : "";
2931
+ },
2932
+ /**
2933
+ * Converts a given value to a number.
2934
+ *
2935
+ * This method uses the `numberString` method to sanitize the input value
2936
+ * and then converts it to a number.
2937
+ *
2938
+ * @param value The value to convert to a number.
2939
+ * @returns The numeric representation of the value.
2940
+ *
2941
+ * @example
2942
+ * // Returns 123.456
2943
+ * as.number('123.456abc')
2944
+ *
2945
+ * @example
2946
+ * // Returns -0.789
2947
+ * as.number('-0.789xyz')
2948
+ */
2949
+ number(value) {
2950
+ return Number(this.numberString(value));
2951
+ },
2952
+ /**
2953
+ * Converts a given value to a bigint.
2954
+ *
2955
+ * This method uses the `integerString` method to sanitize the input value
2956
+ * and then converts it to a bigint.
2957
+ *
2958
+ * @param value The value to convert to a bigint.
2959
+ * @returns The bigint representation of the value.
2960
+ *
2961
+ * @example
2962
+ * // Returns 123n
2963
+ * as.bigint('123.456abc')
2964
+ *
2965
+ * @example
2966
+ * // Returns 0n
2967
+ * as.bigint('0.789xyz')
2968
+ */
2969
+ bigint(value) {
2970
+ const BigInt2 = globalThis?.BigInt;
2971
+ return BigInt2(this.integerString(value));
2972
+ },
2973
+ /**
2974
+ * Converts a given value to a boolean.
2975
+ *
2976
+ * This method takes a value, converts it to a string, and then checks
2977
+ * if it matches common representations of boolean values. It returns
2978
+ * `true` for "1", "yes", and "true" (case insensitive), and `false`
2979
+ * for "0", "no", and "false" (case insensitive). For any other values,
2980
+ * it returns the boolean representation of the value.
2981
+ *
2982
+ * @param {*} value - The value to convert to a boolean.
2983
+ * @returns {boolean} The boolean representation of the value.
2984
+ *
2985
+ * @example
2986
+ * // Returns true
2987
+ * as.boolean("yes")
2988
+ *
2989
+ * @example
2990
+ * // Returns false
2991
+ * as.boolean("no")
2992
+ *
2993
+ * @example
2994
+ * // Returns true
2995
+ * as.boolean(1)
2996
+ *
2997
+ * @example
2998
+ * // Returns false
2999
+ * as.boolean(0)
3000
+ *
3001
+ * @example
3002
+ * // Returns true
3003
+ * as.boolean("true")
3004
+ *
3005
+ * @example
3006
+ * // Returns false
3007
+ * as.boolean("false")
3008
+ *
3009
+ * @example
3010
+ * // Returns true
3011
+ * as.boolean({})
3012
+ *
3013
+ * @example
3014
+ * // Returns false
3015
+ * as.boolean(null)
3016
+ */
3017
+ boolean(value) {
3018
+ switch (String(value).toLowerCase()) {
3019
+ case "1":
3020
+ case "yes":
3021
+ case "true":
3022
+ return true;
3023
+ case "0":
3024
+ case "no":
3025
+ case "false":
3026
+ return false;
3027
+ default:
3028
+ return Boolean(value);
3029
+ }
3030
+ }
3031
+ };
3032
+ function createToolkit() {
3033
+ return { si, is, has, as };
3034
+ }
3035
+ function ifThenElse(condition, thenCase, elseCase) {
3036
+ if (typeof thenCase === "undefined" && typeof elseCase === "undefined")
3037
+ return !!condition;
3038
+ if (typeof thenCase === "undefined")
3039
+ thenCase = condition;
3040
+ if (condition) {
3041
+ if (is.function(thenCase))
3042
+ return thenCase();
3043
+ else
3044
+ return thenCase;
3045
+ } else {
3046
+ if (is.function(elseCase))
3047
+ return elseCase();
3048
+ else
3049
+ return elseCase;
3050
+ }
3051
+ }
3052
+
3053
+ // src/utils/descriptor.utils.js
3054
+ var DescriptorUtils = {
3055
+ /**
3056
+ * Creates an accessor descriptor object
3057
+ *
3058
+ * This function has multiple possible overloads
3059
+ *
3060
+ * ```markdown
3061
+ * _**zeroFn** is a function that takes no parameters_
3062
+ * _**oneFn** is a function that takes a single parameter_
3063
+ * _**oneOrNone** is a either a function that takes a single parameter or nullish_
3064
+ * _**nonFn** is any value that is not a function_
3065
+ * _**nullish** is either null or undefined_
3066
+ * _**...** means configurable?, enumerable?, storage?, key? liaison? as
3067
+ * subsequent following parameters in that order_
3068
+ *
3069
+ * **accessor()**
3070
+ * creates a storage backed accessor that is both read and write.
3071
+ * The storage object will be a provided empty object with the key
3072
+ * being 'value'. Configurable and enumerable flags will be set to
3073
+ * `true`.
3074
+ *
3075
+ * **accessor(options)**
3076
+ * this single argument variant of accessor() consists of a single
3077
+ * options object. If neither `get` nor `set` are provided, a
3078
+ * storage backed read-write accessor with undefined as the initial
3079
+ * value will be constructed.
3080
+ *
3081
+ * **accessor(nonFn)**
3082
+ * **accessor(any, true, options?)**
3083
+ * **accessor(any, true, ...)**
3084
+ * supplying only a non-function only parameter or any value and the
3085
+ * value `true` as the second parameter, you will get a read-write
3086
+ * accessor stored in the default or specified storage. The resultant
3087
+ * initial value will be whatever is provided as the first parameter.
3088
+ * See options to customize `configurable`, `enumerable`, `storage`,
3089
+ * `key` and the `liaison` factory function.
3090
+ *
3091
+ * **accessor(any, false, options?)**
3092
+ * **accessor(any, false, ...)**
3093
+ * supplying only a non-function only parameter or any value and the
3094
+ * value `false` as the second parameter, you will get a read-only
3095
+ * getter stored in the default or specified storage. The resultant
3096
+ * value will be whatever is provided as the first parameter.
3097
+ * See options to customize `configurable`, `enumerable`, `storage`,
3098
+ * `key` and the `liaison` factory function.
3099
+ *
3100
+ * **accessor(zeroFn)**
3101
+ * **accessor(zeroFn, nullish, options?)**
3102
+ * **accessor(zeroFn, nullish, ...)**
3103
+ * creates a generic read-only accessor with the first no-argument
3104
+ * function parameter being the getter and either null or undefined
3105
+ * for the setter. Either an options object or the manually ordered
3106
+ * parameters can optionally follow if a nullish value for setter
3107
+ * is provided.
3108
+ *
3109
+ * **accessor(zeroFn, oneOrNone, options?)**
3110
+ * **accessor(zeroFn, oneOrNone, ...)**
3111
+ * creates a generic read-write accessor with the first no-argument
3112
+ * function parameter being the getter and the second single-argument
3113
+ * function parameter being the setter. Either an options object or
3114
+ * the manually ordered parameters can optionally follow.
3115
+ *
3116
+ * **accessor(oneFn, oneFn, options?)**
3117
+ * **accessor(oneFn, oneFn, ...)**
3118
+ * this special variant of the accessor() invocation, allows a single
3119
+ * argument getter and setter factory to be supplied. These will
3120
+ * automatically be invoked with the specified or default storage
3121
+ * object. The result of the getter factory should be a no argument
3122
+ * function. And the result of the setter factory should be a single
3123
+ * argument function. The options for `liaison` and `key` will be
3124
+ * ignored and should be handled specifically in the factory
3125
+ * functions to suit your own use case.
3126
+ * ```
3127
+ *
3128
+ * Options are an object oriented way of supplying the alternate
3129
+ * flags to the data descriptor. They are
3130
+ *
3131
+ * • `get` - only referenced when an options object is the only parameter
3132
+ * • `set` - only referenced when an options object is the only parameter
3133
+ * • `configurable` - if true, the descriptor of the object that this
3134
+ * accessor descriptor represents can be redefined at later time by
3135
+ * subsequent calls to {@link Object.defineProperty} or
3136
+ * {@link Object.defineProperties}
3137
+ * • `enumerable` - if true, enumeration over the object this
3138
+ * descriptor is applied to, will show the property
3139
+ * represented by this descriptor. See the associated MDN
3140
+ * page regarding this {@link PropertyDescriptor} if you
3141
+ * want to know more.
3142
+ * • `storage` - an object, usually {@link Object} or {@link Map} or
3143
+ * nullish if unused
3144
+ * • `key` - a {@link PropertyKey} of your choosing or the default
3145
+ * string `"value"`
3146
+ * • `bind` - true if you wish to have the `storage` object bound as
3147
+ * the `thisObj` for both the `get` and `set` functions when
3148
+ * storage is used. **note* this will not work if you supply a
3149
+ * big arrow function for the accessor function in question. This
3150
+ * defaults to `false`.
3151
+ * • `liaison` - an optional factory function that must return an
3152
+ * object with two properties. The first is a `get()` function that
3153
+ * returns a value and the second is a `set(value)` function that
3154
+ * stores a value. The factory function receives `storage` and
3155
+ * `key`, in that order. The default uses {@link Map.get} and
3156
+ * {@link Map.set} if the storage is an instance of {@link Map}.
3157
+ * Otherwise, the typical `object[key]` format is used if the
3158
+ * storage object is an instanceof {@link Object}
3159
+ *
3160
+ * @param {(object|any)?} value the JavaScript value representing
3161
+ * this descriptor's value or an options object if it is the
3162
+ * only parameter.
3163
+ * @param {(object|boolean)?} optionsOrConfigurable true or false if
3164
+ * you wish the `configurable` flag to be set. Optionally supply an
3165
+ * object with one of the supported options to configure the run
3166
+ * of the function.
3167
+ * @param {boolean?} enumerable true or false if you wish to
3168
+ * configure the `.enumerable` property of the descriptor
3169
+ * @param {object?} storage an object upon which data storage should
3170
+ * be written to and read from. Defaults to an empty {@link Object}
3171
+ * when storage is needed and not supplied via this parameter or
3172
+ * an options object.
3173
+ * @param {PropertyKey?} key the key used to store content on the
3174
+ * storage object.
3175
+ * @param {(object, PropertyKey) => { get: ()=>any, set: (v)=>void}} liaison
3176
+ * an optional function that, given a storage object and property key,
3177
+ * returns an object with a no argument `get()` function that returns
3178
+ * the value on the storage object with a given key and a single argument
3179
+ * `set(value)` function that stores a new value using the property key
3180
+ * on the supplied storage object. This exists because access to a
3181
+ * {@link Map} and {@link Object} values are handled differently. If you
3182
+ * need support for some other class than `Map` or `Object` then you
3183
+ * should provide a liaison function to define access.
3184
+ *
3185
+ * @returns {PropertyDescriptor}
3186
+ *
3187
+ * @see {@link PropertyDescriptor}
3188
+ * @note More info on this can be found at the
3189
+ * [MDN Object.defineProperty/ies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty)
3190
+ * page
3191
+ *
3192
+ * @type {Function & { keys: string[] }}
3193
+ */
3194
+ get accessor() {
3195
+ function accessor2(get, set, optionsOrConfigurable = true, enumerable = true, storage, key = "value", liaison) {
3196
+ const count = arguments.length;
3197
+ const storageKeys = ["storage", "key", "liaison", "initial", "bind"];
3198
+ const optionKeys = [
3199
+ // accessor functions
3200
+ "get",
3201
+ "set",
3202
+ // descriptor flags
3203
+ "configurable",
3204
+ "enumerable",
3205
+ // storage configuration keys
3206
+ ...storageKeys
3207
+ ];
3208
+ const has3 = (object, key2) => isObject(object) && Reflect.has(object, key2);
3209
+ const isOpts = (object) => optionKeys.some((key2) => has3(object, key2));
3210
+ let configurable = !!optionsOrConfigurable;
3211
+ let initial = void 0;
3212
+ let bind = false;
3213
+ let options = {};
3214
+ if (count === 1 && isObject(get) && hasSome(get, ...optionKeys)) {
3215
+ options = { ...get };
3216
+ ({ get, set } = get);
3217
+ }
3218
+ if (isObject(optionsOrConfigurable) || isObject(set)) {
3219
+ options = isObject(set) && count === 2 ? { ...set } : { ...optionsOrConfigurable };
3220
+ ({ configurable, enumerable, storage, key, bind, initial } = options);
3221
+ }
3222
+ liaison = options?.liaison ?? liaison ?? ((storage2, key2) => ({
3223
+ get() {
3224
+ if (storage2 instanceof Map)
3225
+ return storage2.get(key2);
3226
+ else if (isObject(storage2))
3227
+ return storage2[key2];
3228
+ },
3229
+ set(value) {
3230
+ if (storage2 instanceof Map)
3231
+ storage2.set(key2, value);
3232
+ else if (isObject(storage2))
3233
+ storage2[key2] = value;
3234
+ }
3235
+ }));
3236
+ configurable = configurable ?? true;
3237
+ enumerable = enumerable ?? true;
3238
+ key = key ?? "value";
3239
+ bind = bind ?? false;
3240
+ const nullish = (value) => value === null || value === void 0;
3241
+ const nonFn = (value) => !nullish(value) && typeof value !== "function";
3242
+ const yesFn = (value) => typeof value === "function";
3243
+ const zeroFn = (value) => yesFn(value) && value.length === 0;
3244
+ const oneFn = (value) => yesFn(value) && value.length === 1;
3245
+ const isTrue = (value) => value === true;
3246
+ const isFalse = (value) => value === false;
3247
+ const addRefs = (fn, value) => Object.defineProperties(fn, {
3248
+ storage: { value, configurable: true, enumerable: false },
3249
+ key: { value: key, configurable: true, enumerable: false }
3250
+ });
3251
+ if (count === 0 || !get && !set) {
3252
+ storage = { [key]: initial };
3253
+ const _ = liaison(storage, key);
3254
+ get = addRefs(function() {
3255
+ return _.get();
3256
+ }, storage);
3257
+ set = addRefs(function(value) {
3258
+ _.set(value);
3259
+ }, storage);
3260
+ return { get, set, configurable, enumerable };
3261
+ }
3262
+ if (count === 1 && oneFn(get)) {
3263
+ set = false;
3264
+ }
3265
+ if (count === 1 && nonFn(get) || (isTrue(set) || isFalse(set))) {
3266
+ const skipSet = isFalse(set);
3267
+ if (!storage || !(storage instanceof Map) || !isObject(storage)) {
3268
+ storage = {};
3269
+ }
3270
+ const _ = liaison(storage, key);
3271
+ _.set(get);
3272
+ let _get = function() {
3273
+ return _.get();
3274
+ };
3275
+ let _set = function(value) {
3276
+ _.set(value);
3277
+ };
3278
+ if (bind) {
3279
+ _get = _get.bind(storage);
3280
+ _set = _set.bind(storage);
3281
+ }
3282
+ get = addRefs(_get, storage);
3283
+ set = addRefs(_set, storage);
3284
+ if (skipSet) {
3285
+ set = void 0;
3286
+ }
3287
+ return { get, set, configurable, enumerable };
3288
+ }
3289
+ if (zeroFn(get) && !set || zeroFn(get) && oneFn(set)) {
3290
+ const descriptor = { get, set, configurable, enumerable };
3291
+ if (isObject(options) && Reflect.has(options, "initial"))
3292
+ descriptor.set(initial);
3293
+ return descriptor;
3294
+ }
3295
+ if (oneFn(get) && oneFn(set)) {
3296
+ storage = storage || {};
3297
+ let _get = get(storage);
3298
+ let _set = set(storage);
3299
+ if (bind) {
3300
+ _get = _get.bind(storage);
3301
+ _set = _set.bind(storage);
3302
+ }
3303
+ return {
3304
+ get: addRefs(_get, storage),
3305
+ set: addRefs(_set, storage),
3306
+ configurable,
3307
+ enumerable
3308
+ };
3309
+ }
3310
+ return { get, set, configurable, enumerable };
3311
+ }
3312
+ Object.defineProperty(accessor2, "keys", {
3313
+ get() {
3314
+ return Object.defineProperties(
3315
+ ["get", "set", "configurable", "enumerable"],
3316
+ {
3317
+ from: {
3318
+ value: function extractKeysFrom(object) {
3319
+ const response = {
3320
+ get: void 0,
3321
+ set: void 0,
3322
+ configurable: void 0,
3323
+ enumerable: void 0
3324
+ };
3325
+ if (!object || !(object instanceof Object))
3326
+ return response;
3327
+ for (const key of DescriptorUtils.accessor.keys) {
3328
+ if (Reflect.has(object, key))
3329
+ response[key] = object[key];
3330
+ }
3331
+ },
3332
+ writable: false,
3333
+ configurable: false,
3334
+ enumerable: false
3335
+ }
3336
+ }
3337
+ );
3338
+ },
3339
+ configurable: true,
3340
+ enumerable: false
3341
+ });
3342
+ return accessor2;
3343
+ },
3344
+ /**
3345
+ * Creates a data descriptor object
3346
+ *
3347
+ * This function has multiple possible overloads
3348
+ *
3349
+ * ```markdown
3350
+ * **data()**
3351
+ * creates a data descriptor with a value of `undefined` that
3352
+ * is writable, configurable and enumerable.
3353
+ *
3354
+ * **data(options)**
3355
+ * if the only parameter is an object and that object contains
3356
+ * at least a `.value` property, this funtion will return a
3357
+ * data descriptor with the associated values. This variant
3358
+ * is useful if you want to extract the normal data descriptor
3359
+ * properties: value, writable, configurable and/or enumerable
3360
+ * from an object that has properties with these names, in
3361
+ * addition to other properties or functions. Note that if you
3362
+ * wish for the value of the descriptor to be an object that
3363
+ * also contains a `.value` property, use `data({value: obj})`
3364
+ * instead.
3365
+ *
3366
+ * **data(value)**
3367
+ * **data(value, options?)**
3368
+ * creates a data descriptor from the supplied `value`,
3369
+ * optionally augmented by additional `options`. The defaults
3370
+ * for this writable, configurable and enumerable values set
3371
+ * to `true`
3372
+ *
3373
+ * **data(value, writable?, configurable?, enumerable?)**
3374
+ * if writable, configurable or enumerable or true or false
3375
+ * then this function creates a data descriptor with those
3376
+ * flags and the supplied value (there's no real reason to
3377
+ * invoke this function if you're supplying all four values)
3378
+ * ```
3379
+ *
3380
+ * Options are an object oriented way of supplying the alternate
3381
+ * flags to the data descriptor. They are
3382
+ *
3383
+ * • `value` - only referenced when an options object is the
3384
+ * only parameter
3385
+ * • `writable` - true if the value represented by this data
3386
+ * descriptor can be reassigned a new value.
3387
+ * • `configurable` - if true, the descriptor of the object
3388
+ * that this data descriptor represents can be redefined at
3389
+ * later time by subsequent calls to `Object.defineProperty`
3390
+ * or `Object.defineProperties`. If `.configurable` is true
3391
+ * this can be done even if `.writable` is set to false
3392
+ * • `enumerable` - if true, enumeration over the object this
3393
+ * descriptor is applied to, will show the property
3394
+ * represented by this descriptor. See the associated MDN
3395
+ * page regarding this `PropertyDescriptor` if you want to
3396
+ * know more.
3397
+ *
3398
+ * @param {(object|any)?} value the JavaScript value representing
3399
+ * this descriptor's value or an options object if it is the
3400
+ * only parameter.
3401
+ * @param {(object|boolean)?} optionsOrWritable true or false if
3402
+ * you wish the writable flag to be set. Optionally supply an
3403
+ * object with one of the supported options to configure the run
3404
+ * of the function.
3405
+ * @param {boolean?} configurable true or false if you wish to
3406
+ * configure the `.configurable` property of the descriptor
3407
+ * @param {boolean?} enumerable true or false if you wish to
3408
+ * configure the `.enumerable` property of the descriptor
3409
+ * @returns {PropertyDescriptor}
3410
+ *
3411
+ * @note More info on this can be found at the
3412
+ * [MDN Object.defineProperty/ies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty)
3413
+ * page
3414
+ *
3415
+ * @type {Function & { keys: string[] }}
3416
+ */
3417
+ get data() {
3418
+ function data2(value, optionsOrWritable, configurable, enumerable) {
3419
+ const count = arguments.length;
3420
+ let valueIsDescriptor = false;
3421
+ if (count === 0) {
3422
+ return {
3423
+ value: void 0,
3424
+ writable: true,
3425
+ configurable: true,
3426
+ enumerable: true
3427
+ };
3428
+ }
3429
+ if (count === 1) {
3430
+ const stats = DescriptorUtils.isDescriptor(value, true);
3431
+ if (stats.isValid && stats.isData) {
3432
+ valueIsDescriptor = true;
3433
+ }
3434
+ }
3435
+ let writable = optionsOrWritable === void 0 ? true : !!optionsOrWritable;
3436
+ let options = typeof optionsOrWritable === "boolean" ? {} : Object(optionsOrWritable);
3437
+ configurable = configurable === void 0 ? true : !!configurable;
3438
+ enumerable = enumerable === void 0 ? true : !!enumerable;
3439
+ if (valueIsDescriptor && !options?.allowDescriptorValue) {
3440
+ options = {
3441
+ writable: value?.writable ?? true,
3442
+ configurable: value?.configurable ?? true,
3443
+ enumerable: value?.enumerable ?? true
3444
+ };
3445
+ value = value?.value;
3446
+ }
3447
+ if (options) {
3448
+ ({ writable, configurable, enumerable } = {
3449
+ ...{ writable, configurable, enumerable },
3450
+ ...options
3451
+ });
3452
+ }
3453
+ return { value, writable, configurable, enumerable };
3454
+ }
3455
+ Object.defineProperty(data2, "keys", {
3456
+ value: Object.defineProperties(
3457
+ ["value", "writable", "configurable", "enumerable"],
3458
+ {
3459
+ from: {
3460
+ value: function extractKeysFrom(object) {
3461
+ const response = {
3462
+ value: void 0,
3463
+ writable: void 0,
3464
+ configurable: void 0,
3465
+ enumerable: void 0
3466
+ };
3467
+ if (!object || !(object instanceof Object))
3468
+ return response;
3469
+ for (const key of DescriptorUtils.data.keys) {
3470
+ if (Reflect.has(object, key))
3471
+ response[key] = object[key];
3472
+ }
3473
+ },
3474
+ writable: false,
3475
+ configurable: false,
3476
+ enumerable: false
3477
+ }
3478
+ }
3479
+ ),
3480
+ writable: false,
3481
+ configurable: true,
3482
+ enumerable: false
3483
+ });
3484
+ return data2;
3485
+ },
3486
+ describe(object, key, value, detectDescriptorValues = true) {
3487
+ const { isAccessor: isAccessor2, isData: isData2, data: data2 } = DescriptorUtils;
3488
+ if (!(object && object instanceof Object))
3489
+ return void 0;
3490
+ if (!["string", "number", "symbol"].includes(typeof key))
3491
+ return void 0;
3492
+ if (detectDescriptorValues && isAccessor2(value) || isData2(value)) {
3493
+ return Object.defineProperty(object, key, value);
3494
+ } else {
3495
+ return Object.defineProperty(object, key, data2(value));
3496
+ }
3497
+ },
3498
+ describeMany(object, keyValues, detectDescriptorValues = true) {
3499
+ const { isAccessor: isAccessor2, isData: isData2, isDescriptor: isDescriptor2, data: data2, describe: describe2 } = DescriptorUtils;
3500
+ const isKey = (k) => ["string", "number", "symbol"].includes(typeof k);
3501
+ let map2 = void 0;
3502
+ if (Array.isArray(keyValues)) {
3503
+ map2 = new Map(keyValues.filter((keyValue) => {
3504
+ return typeof keyValue === "function" && keyValue.length === 2;
3505
+ }));
3506
+ } else if (keyValues instanceof Map) {
3507
+ map2 = keyValues;
3508
+ } else if (keyValues instanceof Object) {
3509
+ const descriptors = Object.getOwnPropertyDescriptors(keyValues);
3510
+ map2 = new Object.entries(descriptors);
3511
+ } else {
3512
+ return [];
3513
+ }
3514
+ for (const [key, value] of map2) {
3515
+ if (detectDescriptorValues) {
3516
+ if (isDescriptor2(key)) {
3517
+ }
3518
+ }
3519
+ }
3520
+ const accessorBase = { enumerable: true, configurable: true };
3521
+ const dataBase = { writable: true, ...accessorBase };
3522
+ const extractBase = (descriptor) => {
3523
+ if (isAccessor2(descriptor)) {
3524
+ const { configurable, enumerable } = descriptor;
3525
+ return { configurable, enumerable };
3526
+ } else if (isData2(descriptor)) {
3527
+ const { writable, configurable, enumerable } = descriptor;
3528
+ return { writable, configurable, enumerable };
3529
+ }
3530
+ return void 0;
3531
+ };
3532
+ for (const [key, value] of map2.entries()) {
3533
+ const descriptor = detectDescriptorValues && isDescriptor2(value) ? value : data2(value, dataBase);
3534
+ }
3535
+ },
3536
+ extract(fromObject, keysToExtract, defaultIfMissing = void 0, extractDescriptors = false) {
3537
+ const { data: data2 } = DescriptorUtils;
3538
+ const output = {};
3539
+ if (!fromObject || typeof fromObject !== "object")
3540
+ return output;
3541
+ if (!Array.isArray(keysToExtract))
3542
+ keysToExtract = [keysToExtract];
3543
+ for (const key of keysToExtract) {
3544
+ let descriptor = Object.getOwnPropertyDescriptor(fromObject, key);
3545
+ if (!descriptor)
3546
+ descriptor = data2(defaultIfMissing);
3547
+ if (extractDescriptors)
3548
+ descriptor.value = data2(descriptor, { allowDescriptorValue: true });
3549
+ Object.defineProperty(output, key, descriptor);
3550
+ }
3551
+ return output;
3552
+ },
3553
+ /**
3554
+ * Determines if a given value is an accessor descriptor.
3555
+ *
3556
+ * An accessor descriptor is a property descriptor that defines
3557
+ * getter and/or setter functions for a property. This function
3558
+ * checks the validity of the descriptor and whether it qualifies
3559
+ * as an accessor.
3560
+ *
3561
+ * @param {Object} value - The descriptor object to evaluate.
3562
+ * @param {boolean} [strict=true] - If true, performs a strict
3563
+ * validation of the descriptor.
3564
+ * @returns {boolean} Returns true if the descriptor is valid and
3565
+ * is an accessor descriptor, otherwise false.
3566
+ *
3567
+ * @example
3568
+ * // Example usage:
3569
+ * const descriptor = { get: () => 42, set: (val) => {} }
3570
+ * const result = DescriptorUtils.isAccessor(descriptor)
3571
+ * console.log(result) // Outputs: true
3572
+ */
3573
+ isAccessor(value, strict = true) {
3574
+ const stats = DescriptorUtils.isDescriptor(value, true, strict);
3575
+ return stats.isValid && stats.isAccessor;
3576
+ },
3577
+ /**
3578
+ * Checks if a given value is a data descriptor.
3579
+ *
3580
+ * A data descriptor is a property descriptor that defines a value
3581
+ * and optionally a writable attribute for a property. This function
3582
+ * evaluates the descriptor's validity and whether it qualifies as
3583
+ * a data descriptor.
3584
+ *
3585
+ * @param {Object} value - The descriptor object to evaluate.
3586
+ * @param {boolean} [strict=true] - If true, performs a strict
3587
+ * validation of the descriptor.
3588
+ * @returns {boolean} Returns true if the descriptor is valid and
3589
+ * is a data descriptor, otherwise false.
3590
+ *
3591
+ * @example
3592
+ * // Example usage:
3593
+ * const descriptor = { value: 42, writable: true }
3594
+ * const result = DescriptorUtils.isData(descriptor)
3595
+ * console.log(result) // Outputs: true
3596
+ */
3597
+ isData(value, strict = true) {
3598
+ const stats = DescriptorUtils.isDescriptor(value, true, strict);
3599
+ return stats.isValid && stats.isData;
3600
+ },
3601
+ /**
3602
+ * A function that, given a value that might be a `PropertyDescriptor`,
3603
+ * calculates a deterministic probability that the supplied value is
3604
+ * an object that either is a `PropertyDescriptor` or that can function
3605
+ * as one.
3606
+ *
3607
+ * @param {unknown} value a JavaScript value that might be a
3608
+ * `PropertyDescriptor` type.
3609
+ * @param {boolean?} returnStats if this value is true, instead of returning
3610
+ * a determined boolean value indicating the supplied value might be a
3611
+ * `PropertyDescriptor`, an object containing the determined flags and score
3612
+ * the led to the determination instead is returned.
3613
+ * @param {boolean?} strict if this value is `true`, which is the default,
3614
+ * then the function will not allow descriptor compatible objects, rather it
3615
+ * will only return true if the object has keys that belong in a descriptor
3616
+ * and do not form an invalid combination.
3617
+ * @returns {IsDescriptorResponse} if `returnStats` is `true`
3618
+ * an object of type {@link IsDescriptorStats} is returned. This object
3619
+ * will have a lot of {@link Boolean} flags pertaining to the `true`/`false`
3620
+ * evaluation. If `returnStats` is `false`, then a boolean value denoting
3621
+ * whether or not the value is a {@link PropertyDescriptor} is returned
3622
+ * instead. This is effectively the same as the `isValid` parameter from the
3623
+ * stats block.
3624
+ */
3625
+ isDescriptor(value, returnStats = false, strict = true) {
3626
+ const areBools = (...props) => props.flat().every(
3627
+ (prop) => boolTypes.includes(typeof value[prop])
3628
+ );
3629
+ const areFuncs = (...props) => props.flat().every(
3630
+ (prop) => funcTypes.includes(typeof value[prop])
3631
+ );
3632
+ const hasKeyFn = (property2) => Reflect.has(value, property2);
3633
+ const isOfType = (type) => (element) => typeof element === type;
3634
+ const baseProps = ["configurable", "enumerable"];
3635
+ const dataProps = ["value", "writable"];
3636
+ const accessorProps = ["get", "set"];
3637
+ const anyDescProps = [...baseProps, ...dataProps, ...accessorProps];
3638
+ const boolTypes = ["undefined", "boolean"];
3639
+ const funcTypes = ["undefined", "function"];
3640
+ const stats = {
3641
+ confidence: 0,
3642
+ hasAccessorKeys: false,
3643
+ hasBaseDescriptorKeys: false,
3644
+ hasDataKeys: false,
3645
+ isAccessor: false,
3646
+ isData: false,
3647
+ isValid: false,
3648
+ isBase: false
3649
+ };
3650
+ if (!value || typeof value !== "object" || !(value instanceof Object))
3651
+ return returnStats ? stats : false;
3652
+ let score = 0;
3653
+ if (value && typeof value === "object") {
3654
+ const objKeys = Reflect.ownKeys(value);
3655
+ const nonDescKeys = objKeys.filter((k) => !anyDescProps.includes(k));
3656
+ if (strict && nonDescKeys.length)
3657
+ return false;
3658
+ if (objKeys.length <= 4)
3659
+ score++;
3660
+ stats.hasAccessorKeys = accessorProps.some(hasKeyFn) && areFuncs(accessorProps);
3661
+ stats.hasDataKeys = dataProps.some(hasKeyFn) && areBools("writable");
3662
+ stats.hasBaseDescriptorKeys = baseProps.some(hasKeyFn) && areBools(baseProps);
3663
+ if (stats.hasBaseDescriptorKeys)
3664
+ score++;
3665
+ if (stats.hasAccessorKeys || stats.hasDataKeys)
3666
+ score++;
3667
+ if (score > 0)
3668
+ stats.isValid = true;
3669
+ if (score > 0 && stats.hasAccessorKeys)
3670
+ stats.isAccessor = true;
3671
+ if (score > 0 && stats.hasDataKeys)
3672
+ stats.isData = true;
3673
+ if (stats.isValid && !["get", "set", "value"].some(hasKeyFn))
3674
+ stats.isBase = true;
3675
+ if (stats.isValid && stats.isData && Reflect.has(value, "value"))
3676
+ score++;
3677
+ else if (stats.isValid && stats.isAccessor) {
3678
+ if ([value?.get, value?.set].some(isOfType("function")))
3679
+ score++;
3680
+ }
3681
+ if (stats.hasAccessorKeys && stats.hasDataKeys) {
3682
+ score = 0;
3683
+ stats.isValid = false;
3684
+ }
3685
+ stats.confidence = parseFloat(score / 4);
3686
+ }
3687
+ if (returnStats)
3688
+ return stats;
3689
+ return score >= 0 ? true : false;
3690
+ },
3691
+ /**
3692
+ * Redefines a property on an object with new descriptors and options.
3693
+ * This function allows renaming, aliasing, and redefining property
3694
+ * descriptors such as configurable, enumerable, writable, get, and set.
3695
+ *
3696
+ * @param {Object} object - The target object whose property is to be
3697
+ * redefined.
3698
+ * @param {string|symbol} key - The key of the property to redefine.
3699
+ * @param {Object} as - An object containing new property descriptors.
3700
+ * @param {Object} [options] - Optional settings for renaming and aliasing.
3701
+ * @param {string|symbol} [options.rename] - New key name for the property.
3702
+ * @param {Array<string|symbol>} [options.alsoAs] - Additional aliases for
3703
+ * the property.
3704
+ * @param {Object} [options.moveTo] optionally move the descriptor from this
3705
+ * object to another.
3706
+ * @returns {any} the result of `object[key]` in its final state
3707
+ *
3708
+ * @example
3709
+ * const obj = { a: 1 }
3710
+ * redescribe(obj, 'a', { writable: false }, { rename: 'b', alsoAs: ['c'] })
3711
+ * console.log(obj.b) // Outputs: 1
3712
+ * console.log(obj.c) // Outputs: 1
3713
+ */
3714
+ redescribe(object, key, as2, options) {
3715
+ const { isAccessor: isAccessor2, isData: isData2 } = DescriptorUtils;
3716
+ const ifThen = (condition, fn, ...args) => condition && fn(...args);
3717
+ const isBool = (value) => typeof value === "boolean" || value instanceof Boolean;
3718
+ const isFunction = (value) => typeof value === "function";
3719
+ const isObject2 = (value) => value && value instanceof Object;
3720
+ const isDefined = (value, key2) => isObject2(value) && Reflect.has(value, key2);
3721
+ const isObjectKey = (v) => ["string", "number", "symbol"].includes(typeof v);
3722
+ const define = (key2, values) => Object.defineProperty(object, key2, values);
3723
+ const assign = (object2, ...values) => Object.assign(object2, ...values);
3724
+ const isAnObject = isObject2(object);
3725
+ let asIsObject = isObject2(as2);
3726
+ const descriptor = isAnObject && Object.getOwnPropertyDescriptor(object, key);
3727
+ const aliases = [];
3728
+ if (descriptor && !asIsObject) {
3729
+ asIsObject = true;
3730
+ as2 = {};
3731
+ }
3732
+ if (isObject2(options)) {
3733
+ if (isDefined(options, "rename")) {
3734
+ const successfulDelete = delete object[key];
3735
+ if (successfulDelete)
3736
+ key = options.rename;
3737
+ }
3738
+ if (isDefined(options, "alsoAs")) {
3739
+ if (Array.isArray(options.alsoAs)) {
3740
+ for (const value of options.alsoAs.filter((v) => isObjectKey(v)))
3741
+ aliases.push(value);
3742
+ } else if (isObjectKey(options.alsoAs)) {
3743
+ aliases.push(options.alsoAs);
3744
+ }
3745
+ }
3746
+ if (isDefined(options, "moveTo")) {
3747
+ ifThen(isObject2(options.moveTo), () => object = options.moveTo);
3748
+ }
3749
+ }
3750
+ if (isAnObject && asIsObject) {
3751
+ let { configurable, enumerable, writable, get, set, value } = as2;
3752
+ if (isAccessor2(descriptor)) {
3753
+ ifThen(isFunction(get), () => assign(descriptor, { get }));
3754
+ ifThen(isFunction(set), () => assign(descriptor, { set }));
3755
+ }
3756
+ ifThen(isBool(writable) && isData2(descriptor), () => {
3757
+ assign(descriptor, {
3758
+ writable,
3759
+ value: isDefined(as2, "value") ? value : descriptor.value
3760
+ });
3761
+ });
3762
+ ifThen(isBool(configurable), () => assign(descriptor, { configurable }));
3763
+ ifThen(isBool(enumerable), () => assign(descriptor, { enumerable }));
3764
+ define(key, descriptor);
3765
+ for (const alias of aliases) {
3766
+ define(alias, descriptor);
3767
+ }
3768
+ return object[key];
3769
+ }
3770
+ },
3771
+ /**
3772
+ * Retrieves the keys associated with accessor descriptors.
3773
+ *
3774
+ * Accessor descriptors are property descriptors that define
3775
+ * getter and/or setter functions for a property.
3776
+ *
3777
+ * @type {string[]}
3778
+ *
3779
+ * @example
3780
+ * // Example usage:
3781
+ * const keys = DescriptorUtils.kAccessorDescriptorKeys
3782
+ * console.log(keys) // Output: ['get', 'set']
3783
+ */
3784
+ get kAccessorDescriptorKeys() {
3785
+ return ["get", "set"];
3786
+ },
3787
+ /**
3788
+ * Retrieves the keys associated with data descriptors.
3789
+ *
3790
+ * Data descriptors are property descriptors that define a value
3791
+ * and optionally a writable attribute for a property.
3792
+ *
3793
+ * @type {string[]}
3794
+ *
3795
+ * @example
3796
+ * // Example usage:
3797
+ * const keys = DescriptorUtils.kDataDescriptorKeys
3798
+ * console.log(keys) // Output: ['value', 'writable']
3799
+ */
3800
+ get kDataDescriptorKeys() {
3801
+ return ["value", "writable"];
3802
+ },
3803
+ /**
3804
+ * Retrieves the keys associated with shared descriptors.
3805
+ *
3806
+ * Shared descriptors are property descriptors that define
3807
+ * common attributes for a property, such as whether the
3808
+ * property is configurable or enumerable.
3809
+ *
3810
+ * @type {string[]}
3811
+ *
3812
+ * @example
3813
+ * // Example usage:
3814
+ * const keys = DescriptorUtils.kSharedDescriptorKeys
3815
+ * console.log(keys) // Output: ['configurable', 'enumerable']
3816
+ */
3817
+ get kSharedDescriptorKeys() {
3818
+ return ["configurable", "enumerable"];
3819
+ },
3820
+ /**
3821
+ * Retrieves all descriptor keys, combining accessor, data, and shared
3822
+ * descriptor keys.
3823
+ *
3824
+ * This getter method aggregates keys from accessor descriptors,
3825
+ * data descriptors, and shared descriptors into a single array.
3826
+ * This can be useful when you need to validate or inspect all
3827
+ * possible descriptor keys.
3828
+ *
3829
+ * @type {string[]}
3830
+ *
3831
+ * @example
3832
+ * // Example usage:
3833
+ * const allKeys = DescriptorUtils.kDescriptorKeys
3834
+ * console.log(allKeys)
3835
+ * // Output: [
3836
+ * // 'get', 'set', 'value', 'writable', 'configurable', 'enumerable'
3837
+ * // ]
3838
+ */
3839
+ get kDescriptorKeys() {
3840
+ return [
3841
+ ...this.kAccessorDescriptorKeys,
3842
+ ...this.kDataDescriptorKeys,
3843
+ ...this.kSharedDescriptorKeys
3844
+ ];
3845
+ }
3846
+ };
3847
+ var {
3848
+ accessor,
3849
+ data,
3850
+ describe,
3851
+ describeMany,
3852
+ extract,
3853
+ isDescriptor,
3854
+ isAccessor,
3855
+ isData,
3856
+ redescribe
3857
+ } = DescriptorUtils;
3858
+ var {
3859
+ kAccessorDescriptorKeys,
3860
+ kDataDescriptorKeys,
3861
+ kDescriptorKeys,
3862
+ kSharedDescriptorKeys
3863
+ } = DescriptorUtils;
3864
+ function isObject(o) {
3865
+ return o && typeof o === "object";
3866
+ }
3867
+ function hasSome(object, ...keys) {
3868
+ return hasQuantity("some", object, keys);
3869
+ }
3870
+ function hasQuantity(quantityFn, object, keys) {
3871
+ return isObject(object) && keys.flat(Infinity).map((key) => Reflect.has(object, key))[quantityFn]((has3) => has3);
3872
+ }
3873
+
3874
+ // src/utils/index.js
3875
+ var index_default = {
3876
+ COPropertyHandler,
3877
+ FlexiblyHiddenHandler,
3878
+ FlexiblyVisibleHandler,
3879
+ ImmutablyHiddenHandler,
3880
+ ImmutablyVisibleHandler,
3881
+ MutablyHiddenHandler,
3882
+ MutablyVisibleHandler,
3883
+ StdoutGlobalPatches,
3884
+ StringConsole,
3885
+ VisibilityKeys,
3886
+ VisibilityScopeHandler,
3887
+ as,
3888
+ has,
3889
+ is,
3890
+ si,
3891
+ accessor,
3892
+ captureStdout,
3893
+ copyObject,
3894
+ createToolkit,
3895
+ customCopyObject,
3896
+ data,
3897
+ describe,
3898
+ describeMany,
3899
+ extract,
3900
+ isDescriptor,
3901
+ makeTransducer,
3902
+ redescribe,
3903
+ transduceFrom,
3904
+ transduceFromCOHandler,
3905
+ tryIgnore,
3906
+ kAccessorDescriptorKeys,
3907
+ kDataDescriptorKeys,
3908
+ kDescriptorKeys,
3909
+ kVisibilityKeys
3910
+ };
3911
+ // Annotate the CommonJS export names for ESM import in node:
3912
+ 0 && (module.exports = {
3913
+ COPropertyHandler,
3914
+ DescriptorUtils,
3915
+ FlexiblyHiddenHandler,
3916
+ FlexiblyVisibleHandler,
3917
+ ImmutablyHiddenHandler,
3918
+ ImmutablyVisibleHandler,
3919
+ MutablyHiddenHandler,
3920
+ MutablyVisibleHandler,
3921
+ SC,
3922
+ StdoutGlobalPatches,
3923
+ StringConsole,
3924
+ StringConsoleExtension,
3925
+ VisibilityKeys,
3926
+ VisibilityScopeHandler,
3927
+ accessor,
3928
+ as,
3929
+ captureStdout,
3930
+ copyObject,
3931
+ createToolkit,
3932
+ customCopyObject,
3933
+ data,
3934
+ describe,
3935
+ describeMany,
3936
+ extract,
3937
+ has,
3938
+ is,
3939
+ isAccessor,
3940
+ isData,
3941
+ isDescriptor,
3942
+ kAccessorDescriptorKeys,
3943
+ kDataDescriptorKeys,
3944
+ kDescriptorKeys,
3945
+ kSharedDescriptorKeys,
3946
+ kVisibilityKeys,
3947
+ makeTransducer,
3948
+ redescribe,
3949
+ si,
3950
+ transduceFrom,
3951
+ transduceFromCOHandler,
3952
+ tryIgnore
3953
+ });
3954
+ //# sourceMappingURL=index.cjs.map