@nejs/basic-extensions 2.21.0 → 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 (270) hide show
  1. package/.idea/markdown.xml +8 -0
  2. package/.idea/modules.xml +8 -0
  3. package/.idea/ne-basic-extensions.iml +8 -0
  4. package/.idea/vcs.xml +6 -0
  5. package/CODE_STYLE.md +393 -0
  6. package/CODING_PHILOSOPHY.md +36 -0
  7. package/DOCUMENTATION_GUIDELINES.md +221 -0
  8. package/README.md +78 -4
  9. package/dist/@nejs/basic-extensions.bundle.2.22.6.js +25 -0
  10. package/dist/@nejs/basic-extensions.bundle.2.22.6.js.map +7 -0
  11. package/dist/cjs/classes/index.cjs +11129 -0
  12. package/dist/cjs/classes/index.cjs.map +7 -0
  13. package/dist/cjs/index.cjs +15191 -0
  14. package/dist/cjs/index.cjs.map +7 -0
  15. package/dist/cjs/utils/index.cjs +3954 -0
  16. package/dist/cjs/utils/index.cjs.map +7 -0
  17. package/dist/esm/basic-extensions.mjs +25 -0
  18. package/dist/esm/basic-extensions.mjs.map +7 -0
  19. package/package.json +16 -22
  20. package/repl.bootstrap.js +4 -7
  21. package/repl.history +30 -30
  22. package/src/big.int.extension.js +171 -45
  23. package/src/classes/enumeration.js +466 -0
  24. package/src/classes/index.js +5 -1
  25. package/src/index.js +5 -1
  26. package/src/math.extension.js +73 -0
  27. package/src/number.extension.js +18 -0
  28. package/src/regular.expression.extensions.js +0 -35
  29. package/src/utils/toolkit.js +699 -516
  30. package/tests/arrayextensions.test.js +3 -3
  31. package/tests/index.test.js +3 -1
  32. package/tests/newClasses/asyncIterable.test.js +3 -3
  33. package/tests/newClasses/deferred.test.js +3 -3
  34. package/tests/newClasses/descriptor.test.js +3 -3
  35. package/tests/newClasses/iterable.test.js +3 -3
  36. package/tests/newClasses/refmap.test.js +3 -3
  37. package/tests/newClasses/refset.test.js +3 -3
  38. package/tests/objectextensions.test.js +3 -3
  39. package/tests/setextensions.test.js +3 -3
  40. package/tests/stringextensions.test.js +3 -2
  41. package/tests/utils/descriptor.utils.test.js +1 -1
  42. package/tests/utils/toolkit.test.js +429 -163
  43. package/.esdoc.json +0 -9
  44. package/.vscode/settings.json +0 -5
  45. package/bin/build +0 -27
  46. package/bin/clean +0 -14
  47. package/bin/esbuild +0 -91
  48. package/bin/fixup +0 -13
  49. package/bin/repl.basics.js +0 -584
  50. package/bin/repl.signature.js +0 -63
  51. package/bin/version +0 -100
  52. package/dist/@nejs/basic-extensions.bundle.2.21.0.js +0 -25
  53. package/dist/@nejs/basic-extensions.bundle.2.21.0.js.map +0 -7
  54. package/dist/cjs/array.extensions.d.ts +0 -39
  55. package/dist/cjs/array.extensions.js +0 -477
  56. package/dist/cjs/array.extensions.js.map +0 -1
  57. package/dist/cjs/big.int.extension.d.ts +0 -31
  58. package/dist/cjs/big.int.extension.js +0 -165
  59. package/dist/cjs/big.int.extension.js.map +0 -1
  60. package/dist/cjs/classes/asyncIterable.d.ts +0 -126
  61. package/dist/cjs/classes/asyncIterable.js +0 -209
  62. package/dist/cjs/classes/asyncIterable.js.map +0 -1
  63. package/dist/cjs/classes/deferred.d.ts +0 -146
  64. package/dist/cjs/classes/deferred.js +0 -291
  65. package/dist/cjs/classes/deferred.js.map +0 -1
  66. package/dist/cjs/classes/descriptor.d.ts +0 -334
  67. package/dist/cjs/classes/descriptor.js +0 -537
  68. package/dist/cjs/classes/descriptor.js.map +0 -1
  69. package/dist/cjs/classes/enum.d.ts +0 -50
  70. package/dist/cjs/classes/enum.js +0 -405
  71. package/dist/cjs/classes/enum.js.map +0 -1
  72. package/dist/cjs/classes/index.d.ts +0 -15
  73. package/dist/cjs/classes/index.js +0 -63
  74. package/dist/cjs/classes/index.js.map +0 -1
  75. package/dist/cjs/classes/introspector.d.ts +0 -20
  76. package/dist/cjs/classes/introspector.js +0 -130
  77. package/dist/cjs/classes/introspector.js.map +0 -1
  78. package/dist/cjs/classes/iterable.d.ts +0 -169
  79. package/dist/cjs/classes/iterable.js +0 -268
  80. package/dist/cjs/classes/iterable.js.map +0 -1
  81. package/dist/cjs/classes/param.parser.d.ts +0 -221
  82. package/dist/cjs/classes/param.parser.js +0 -242
  83. package/dist/cjs/classes/param.parser.js.map +0 -1
  84. package/dist/cjs/classes/pluggable.proxy.d.ts +0 -153
  85. package/dist/cjs/classes/pluggable.proxy.js +0 -444
  86. package/dist/cjs/classes/pluggable.proxy.js.map +0 -1
  87. package/dist/cjs/classes/property.d.ts +0 -79
  88. package/dist/cjs/classes/property.js +0 -284
  89. package/dist/cjs/classes/property.js.map +0 -1
  90. package/dist/cjs/classes/refmap.d.ts +0 -238
  91. package/dist/cjs/classes/refmap.js +0 -421
  92. package/dist/cjs/classes/refmap.js.map +0 -1
  93. package/dist/cjs/classes/refset.d.ts +0 -186
  94. package/dist/cjs/classes/refset.js +0 -370
  95. package/dist/cjs/classes/refset.js.map +0 -1
  96. package/dist/cjs/classes/symkeys.d.ts +0 -349
  97. package/dist/cjs/classes/symkeys.js +0 -510
  98. package/dist/cjs/classes/symkeys.js.map +0 -1
  99. package/dist/cjs/classes/type.d.ts +0 -56
  100. package/dist/cjs/classes/type.js +0 -405
  101. package/dist/cjs/classes/type.js.map +0 -1
  102. package/dist/cjs/function.extensions.d.ts +0 -12
  103. package/dist/cjs/function.extensions.js +0 -758
  104. package/dist/cjs/function.extensions.js.map +0 -1
  105. package/dist/cjs/global.this.d.ts +0 -2
  106. package/dist/cjs/global.this.js +0 -300
  107. package/dist/cjs/global.this.js.map +0 -1
  108. package/dist/cjs/index.d.ts +0 -31
  109. package/dist/cjs/index.js +0 -226
  110. package/dist/cjs/index.js.map +0 -1
  111. package/dist/cjs/json.extensions.d.ts +0 -2
  112. package/dist/cjs/json.extensions.js +0 -109
  113. package/dist/cjs/json.extensions.js.map +0 -1
  114. package/dist/cjs/map.extensions.d.ts +0 -3
  115. package/dist/cjs/map.extensions.js +0 -143
  116. package/dist/cjs/map.extensions.js.map +0 -1
  117. package/dist/cjs/number.extension.d.ts +0 -44
  118. package/dist/cjs/number.extension.js +0 -261
  119. package/dist/cjs/number.extension.js.map +0 -1
  120. package/dist/cjs/object.extensions.d.ts +0 -33
  121. package/dist/cjs/object.extensions.js +0 -1091
  122. package/dist/cjs/object.extensions.js.map +0 -1
  123. package/dist/cjs/package.json +0 -3
  124. package/dist/cjs/proxy.extensions.d.ts +0 -2
  125. package/dist/cjs/proxy.extensions.js +0 -207
  126. package/dist/cjs/proxy.extensions.js.map +0 -1
  127. package/dist/cjs/reflect.extensions.d.ts +0 -14
  128. package/dist/cjs/reflect.extensions.js +0 -316
  129. package/dist/cjs/reflect.extensions.js.map +0 -1
  130. package/dist/cjs/regular.expression.extensions.d.ts +0 -2
  131. package/dist/cjs/regular.expression.extensions.js +0 -423
  132. package/dist/cjs/regular.expression.extensions.js.map +0 -1
  133. package/dist/cjs/set.extensions.d.ts +0 -40
  134. package/dist/cjs/set.extensions.js +0 -355
  135. package/dist/cjs/set.extensions.js.map +0 -1
  136. package/dist/cjs/string.extensions.d.ts +0 -23
  137. package/dist/cjs/string.extensions.js +0 -704
  138. package/dist/cjs/string.extensions.js.map +0 -1
  139. package/dist/cjs/symbol.extensions.d.ts +0 -11
  140. package/dist/cjs/symbol.extensions.js +0 -735
  141. package/dist/cjs/symbol.extensions.js.map +0 -1
  142. package/dist/cjs/utils/copy.object.d.ts +0 -408
  143. package/dist/cjs/utils/copy.object.js +0 -720
  144. package/dist/cjs/utils/copy.object.js.map +0 -1
  145. package/dist/cjs/utils/descriptor.utils.d.ts +0 -298
  146. package/dist/cjs/utils/descriptor.utils.js +0 -889
  147. package/dist/cjs/utils/descriptor.utils.js.map +0 -1
  148. package/dist/cjs/utils/index.d.ts +0 -75
  149. package/dist/cjs/utils/index.js +0 -61
  150. package/dist/cjs/utils/index.js.map +0 -1
  151. package/dist/cjs/utils/stdout.d.ts +0 -742
  152. package/dist/cjs/utils/stdout.js +0 -1042
  153. package/dist/cjs/utils/stdout.js.map +0 -1
  154. package/dist/cjs/utils/toolkit.d.ts +0 -1898
  155. package/dist/cjs/utils/toolkit.js +0 -1378
  156. package/dist/cjs/utils/toolkit.js.map +0 -1
  157. package/dist/cjs/weakref.extensions.d.ts +0 -2
  158. package/dist/cjs/weakref.extensions.js +0 -19
  159. package/dist/cjs/weakref.extensions.js.map +0 -1
  160. package/dist/mjs/array.extensions.d.ts +0 -39
  161. package/dist/mjs/array.extensions.js +0 -474
  162. package/dist/mjs/array.extensions.js.map +0 -1
  163. package/dist/mjs/big.int.extension.d.ts +0 -31
  164. package/dist/mjs/big.int.extension.js +0 -162
  165. package/dist/mjs/big.int.extension.js.map +0 -1
  166. package/dist/mjs/classes/asyncIterable.d.ts +0 -126
  167. package/dist/mjs/classes/asyncIterable.js +0 -204
  168. package/dist/mjs/classes/asyncIterable.js.map +0 -1
  169. package/dist/mjs/classes/deferred.d.ts +0 -146
  170. package/dist/mjs/classes/deferred.js +0 -287
  171. package/dist/mjs/classes/deferred.js.map +0 -1
  172. package/dist/mjs/classes/descriptor.d.ts +0 -334
  173. package/dist/mjs/classes/descriptor.js +0 -533
  174. package/dist/mjs/classes/descriptor.js.map +0 -1
  175. package/dist/mjs/classes/enum.d.ts +0 -50
  176. package/dist/mjs/classes/enum.js +0 -400
  177. package/dist/mjs/classes/enum.js.map +0 -1
  178. package/dist/mjs/classes/index.d.ts +0 -15
  179. package/dist/mjs/classes/index.js +0 -46
  180. package/dist/mjs/classes/index.js.map +0 -1
  181. package/dist/mjs/classes/introspector.d.ts +0 -20
  182. package/dist/mjs/classes/introspector.js +0 -126
  183. package/dist/mjs/classes/introspector.js.map +0 -1
  184. package/dist/mjs/classes/iterable.d.ts +0 -169
  185. package/dist/mjs/classes/iterable.js +0 -263
  186. package/dist/mjs/classes/iterable.js.map +0 -1
  187. package/dist/mjs/classes/param.parser.d.ts +0 -221
  188. package/dist/mjs/classes/param.parser.js +0 -238
  189. package/dist/mjs/classes/param.parser.js.map +0 -1
  190. package/dist/mjs/classes/pluggable.proxy.d.ts +0 -153
  191. package/dist/mjs/classes/pluggable.proxy.js +0 -438
  192. package/dist/mjs/classes/pluggable.proxy.js.map +0 -1
  193. package/dist/mjs/classes/property.d.ts +0 -79
  194. package/dist/mjs/classes/property.js +0 -280
  195. package/dist/mjs/classes/property.js.map +0 -1
  196. package/dist/mjs/classes/refmap.d.ts +0 -238
  197. package/dist/mjs/classes/refmap.js +0 -417
  198. package/dist/mjs/classes/refmap.js.map +0 -1
  199. package/dist/mjs/classes/refset.d.ts +0 -186
  200. package/dist/mjs/classes/refset.js +0 -366
  201. package/dist/mjs/classes/refset.js.map +0 -1
  202. package/dist/mjs/classes/symkeys.d.ts +0 -349
  203. package/dist/mjs/classes/symkeys.js +0 -506
  204. package/dist/mjs/classes/symkeys.js.map +0 -1
  205. package/dist/mjs/classes/type.d.ts +0 -56
  206. package/dist/mjs/classes/type.js +0 -401
  207. package/dist/mjs/classes/type.js.map +0 -1
  208. package/dist/mjs/function.extensions.d.ts +0 -12
  209. package/dist/mjs/function.extensions.js +0 -755
  210. package/dist/mjs/function.extensions.js.map +0 -1
  211. package/dist/mjs/global.this.d.ts +0 -2
  212. package/dist/mjs/global.this.js +0 -264
  213. package/dist/mjs/global.this.js.map +0 -1
  214. package/dist/mjs/index.d.ts +0 -31
  215. package/dist/mjs/index.js +0 -204
  216. package/dist/mjs/index.js.map +0 -1
  217. package/dist/mjs/json.extensions.d.ts +0 -2
  218. package/dist/mjs/json.extensions.js +0 -106
  219. package/dist/mjs/json.extensions.js.map +0 -1
  220. package/dist/mjs/map.extensions.d.ts +0 -3
  221. package/dist/mjs/map.extensions.js +0 -140
  222. package/dist/mjs/map.extensions.js.map +0 -1
  223. package/dist/mjs/number.extension.d.ts +0 -44
  224. package/dist/mjs/number.extension.js +0 -258
  225. package/dist/mjs/number.extension.js.map +0 -1
  226. package/dist/mjs/object.extensions.d.ts +0 -33
  227. package/dist/mjs/object.extensions.js +0 -1088
  228. package/dist/mjs/object.extensions.js.map +0 -1
  229. package/dist/mjs/package.json +0 -3
  230. package/dist/mjs/proxy.extensions.d.ts +0 -2
  231. package/dist/mjs/proxy.extensions.js +0 -204
  232. package/dist/mjs/proxy.extensions.js.map +0 -1
  233. package/dist/mjs/reflect.extensions.d.ts +0 -14
  234. package/dist/mjs/reflect.extensions.js +0 -313
  235. package/dist/mjs/reflect.extensions.js.map +0 -1
  236. package/dist/mjs/regular.expression.extensions.d.ts +0 -2
  237. package/dist/mjs/regular.expression.extensions.js +0 -420
  238. package/dist/mjs/regular.expression.extensions.js.map +0 -1
  239. package/dist/mjs/set.extensions.d.ts +0 -40
  240. package/dist/mjs/set.extensions.js +0 -352
  241. package/dist/mjs/set.extensions.js.map +0 -1
  242. package/dist/mjs/string.extensions.d.ts +0 -23
  243. package/dist/mjs/string.extensions.js +0 -701
  244. package/dist/mjs/string.extensions.js.map +0 -1
  245. package/dist/mjs/symbol.extensions.d.ts +0 -11
  246. package/dist/mjs/symbol.extensions.js +0 -732
  247. package/dist/mjs/symbol.extensions.js.map +0 -1
  248. package/dist/mjs/utils/copy.object.d.ts +0 -408
  249. package/dist/mjs/utils/copy.object.js +0 -702
  250. package/dist/mjs/utils/copy.object.js.map +0 -1
  251. package/dist/mjs/utils/descriptor.utils.d.ts +0 -298
  252. package/dist/mjs/utils/descriptor.utils.js +0 -875
  253. package/dist/mjs/utils/descriptor.utils.js.map +0 -1
  254. package/dist/mjs/utils/index.d.ts +0 -75
  255. package/dist/mjs/utils/index.js +0 -45
  256. package/dist/mjs/utils/index.js.map +0 -1
  257. package/dist/mjs/utils/stdout.d.ts +0 -742
  258. package/dist/mjs/utils/stdout.js +0 -1037
  259. package/dist/mjs/utils/stdout.js.map +0 -1
  260. package/dist/mjs/utils/toolkit.d.ts +0 -1898
  261. package/dist/mjs/utils/toolkit.js +0 -1373
  262. package/dist/mjs/utils/toolkit.js.map +0 -1
  263. package/dist/mjs/weakref.extensions.d.ts +0 -2
  264. package/dist/mjs/weakref.extensions.js +0 -16
  265. package/dist/mjs/weakref.extensions.js.map +0 -1
  266. package/jsdoc-config.json +0 -31
  267. package/tsconfig.base.json +0 -28
  268. package/tsconfig.cjs.json +0 -8
  269. package/tsconfig.esm.json +0 -8
  270. package/vitest.config.js +0 -7
@@ -22,8 +22,6 @@ export const is = {
22
22
  *
23
23
  * @param {*} value - The value to check.
24
24
  * @param {*} typeOrClass - The type or class to compare against.
25
- * @param {boolean} [alreadyReversed=false] - Internal flag to prevent
26
- * infinite recursion. Not intended for external use.
27
25
  * @returns {boolean} True if the value matches the type or class,
28
26
  * false otherwise.
29
27
  *
@@ -80,10 +78,10 @@ export const is = {
80
78
  *
81
79
  * @example
82
80
  * // Returns true
83
- * is.accessorDescriptor({ get: () => 42, set: () => {} });
81
+ * is.accessorDescriptor({ get: () => 42, set: () => {} })
84
82
  *
85
83
  * // Returns false
86
- * is.accessorDescriptor({ value: 42, writable: true });
84
+ * is.accessorDescriptor({ value: 42, writable: true })
87
85
  */
88
86
  accessorDescriptor(value) {
89
87
  return !!(
@@ -91,7 +89,7 @@ export const is = {
91
89
  (value?.get || value?.set) &&
92
90
  value?.writable === undefined &&
93
91
  value?.value === undefined
94
- );
92
+ )
95
93
  },
96
94
 
97
95
  /**
@@ -101,11 +99,11 @@ export const is = {
101
99
  * @returns True if the value is an array, false otherwise.
102
100
  *
103
101
  * @example
104
- * is.array([1, 2, 3]); // true
105
- * is.array('string'); // false
102
+ * is.array([1, 2, 3]) // true
103
+ * is.array('string') // false
106
104
  */
107
105
  array(value) {
108
- return Array.isArray(value);
106
+ return Array.isArray(value)
109
107
  },
110
108
 
111
109
  /**
@@ -115,11 +113,11 @@ export const is = {
115
113
  * @returns True if the value is a bigint, false otherwise.
116
114
  *
117
115
  * @example
118
- * is.bigint(123n); // true
119
- * is.bigint(123); // false
116
+ * is.bigint(123n) // true
117
+ * is.bigint(123) // false
120
118
  */
121
119
  bigint(value) {
122
- return typeof value === "bigint" || value instanceof globalThis?.BigInt;
120
+ return typeof value === "bigint" || value instanceof globalThis?.BigInt
123
121
  },
124
122
 
125
123
  /**
@@ -131,10 +129,10 @@ export const is = {
131
129
  * @returns {boolean} True if the value is a boolean, false otherwise.
132
130
  *
133
131
  * @example
134
- * is.boolean(true); // true
135
- * is.boolean(false); // true
136
- * is.boolean(1); // false
137
- * is.boolean("true"); // false
132
+ * is.boolean(true) // true
133
+ * is.boolean(false) // true
134
+ * is.boolean(1) // false
135
+ * is.boolean("true") // false
138
136
  */
139
137
  boolean(value) {
140
138
  return [true, false].some(bool => bool === value)
@@ -151,34 +149,34 @@ export const is = {
151
149
  * `get`, or `set` function, use `is.callableDescriptor` instead.
152
150
  *
153
151
  * @example
154
- * is.callable(function() {}); // true
152
+ * is.callable(function() {}) // true
155
153
  */
156
154
  callable(object) {
157
- return this.function(object);
155
+ return this.function(object)
158
156
  },
159
157
 
160
158
  /**
161
- * Check if an object is callable. It looks to see if the object
162
- * represents a descriptor that is callable by checking object
163
- * properties named `value`, `get`, and `set`. If any three variations
159
+ * Check if an object is a callable descriptor. It looks to see if the
160
+ * object represents a descriptor that is callable by checking object
161
+ * properties named `value`, `get`, and `set`. If any of the three
164
162
  * yields a function type, true is returned.
165
163
  *
166
164
  * @param object The object to check.
167
- * @returns True if the object is callable, false otherwise.
165
+ * @returns True if the object is a callable descriptor, false otherwise.
168
166
  *
169
167
  * @example
170
- * is.callable({ get: function() {} }); // true
171
- * is.callable(123); // false
168
+ * is.callableDescriptor({ get: function() {} }) // true
169
+ * is.callableDescriptor(123) // false
172
170
  *
173
171
  * // Note the differences between these
174
- * const object = { get name() { return "Brie"; } };
175
- * const descriptor = Object.getOwnPropertyDescriptor(object, 'name');
176
- * is.callable(object); // false
177
- * is.callable(descriptor); // true
172
+ * const object = { get name() { return "Brie"; } }
173
+ * const descriptor = Object.getOwnPropertyDescriptor(object, 'name')
174
+ * is.callableDescriptor(object) // false
175
+ * is.callableDescriptor(descriptor) // true
178
176
  */
179
177
  callableDescriptor(object) {
180
- const { value, get, set } = this.shiny(object) ? object : {};
181
- return [value, get, set].some((val) => this.function(val));
178
+ const { value, get, set } = this.shiny(object) ? object : {}
179
+ return [value, get, set].some((val) => this.function(val))
182
180
  },
183
181
 
184
182
  /**
@@ -187,25 +185,25 @@ export const is = {
187
185
  * A data descriptor is an object that describes the configuration of a
188
186
  * property on an object, specifically focusing on the 'value' and
189
187
  * 'writable' attributes. The descriptor is invalid if it contains
190
- * thew accessor descriptors `get` or `set`.
188
+ * the accessor descriptors `get` or `set`.
191
189
  *
192
190
  * @param value The value to check.
193
191
  * @returns True if the value is a data descriptor, false otherwise.
194
192
  *
195
193
  * @example
196
194
  * // Returns true
197
- * is.dataDescriptor({ value: 42, writable: true });
195
+ * is.dataDescriptor({ value: 42, writable: true })
198
196
  *
199
197
  * // Returns false
200
- * is.dataDescriptor({ get: () => 42, set: () => {} });
198
+ * is.dataDescriptor({ get: () => 42, set: () => {} })
201
199
  */
202
200
  dataDescriptor(value) {
203
- return (
201
+ return !!(
204
202
  this.descriptor(value) &&
205
- (value?.value || value?.writable) &&
203
+ (value?.value !== undefined || value?.writable !== undefined) &&
206
204
  value?.get === undefined &&
207
205
  value?.set === undefined
208
- );
206
+ )
209
207
  },
210
208
 
211
209
  /**
@@ -219,21 +217,20 @@ export const is = {
219
217
  * @returns True if the value is a property descriptor, false otherwise.
220
218
  *
221
219
  * @example
222
- * is.descriptor({ configurable: true, enumerable: false }); // true
223
- * is.descriptor({ get: () => {}, set: () => {} }); // true
224
- * is.descriptor({}); // false
220
+ * is.descriptor({ configurable: true, enumerable: false }) // true
221
+ * is.descriptor({ get: () => {}, set: () => {} }) // true
222
+ * is.descriptor({}) // false
225
223
  */
226
224
  descriptor(value) {
227
225
  if (!is.object(value)) {
228
- return false;
226
+ return false
229
227
  }
230
228
 
231
-
232
- const _has = (key) => Reflect.has(value, key);
233
- const hasBase = ["configurable", "enumerable"].some((key) => _has(key));
234
- const hasData = ["value", "writable"].some((key) => _has(key));
235
- const hasAccess = ["get", "set"].some((key) => _has(key));
236
- return hasBase || hasData || hasAccess;
229
+ const _has = (key) => Reflect.has(value, key)
230
+ const hasBase = ["configurable", "enumerable"].some((key) => _has(key))
231
+ const hasData = ["value", "writable"].some((key) => _has(key))
232
+ const hasAccess = ["get", "set"].some((key) => _has(key))
233
+ return hasBase || hasData || hasAccess
237
234
  },
238
235
 
239
236
  /**
@@ -245,9 +242,9 @@ export const is = {
245
242
  * @returns {boolean} True if the value is strictly false, false otherwise.
246
243
  *
247
244
  * @example
248
- * is.false(false); // true
249
- * is.false(true); // false
250
- * is.false(0); // false
245
+ * is.false(false) // true
246
+ * is.false(true) // false
247
+ * is.false(0) // false
251
248
  */
252
249
  false(value) {
253
250
  return value === false
@@ -264,10 +261,10 @@ export const is = {
264
261
  * @returns {boolean} True if the value is falsy, false otherwise.
265
262
  *
266
263
  * @example
267
- * is.falsy(0); // true
268
- * is.falsy(""); // true
269
- * is.falsy(1); // false
270
- * is.falsy("hello"); // false
264
+ * is.falsy(0) // true
265
+ * is.falsy("") // true
266
+ * is.falsy(1) // false
267
+ * is.falsy("hello") // false
271
268
  */
272
269
  falsy(value) {
273
270
  return !!!value
@@ -282,10 +279,10 @@ export const is = {
282
279
  * @returns {boolean} True if the value is falsy, false otherwise.
283
280
  *
284
281
  * @example
285
- * is.falsey(0); // true
286
- * is.falsey(""); // true
287
- * is.falsey(1); // false
288
- * is.falsey("hello"); // false
282
+ * is.falsey(0) // true
283
+ * is.falsey("") // true
284
+ * is.falsey(1) // false
285
+ * is.falsey("hello") // false
289
286
  */
290
287
  falsey(value) {
291
288
  return this.falsy(value)
@@ -298,11 +295,11 @@ export const is = {
298
295
  * @returns True if the value is a function, false otherwise.
299
296
  *
300
297
  * @example
301
- * is.function(function() {}); // true
302
- * is.function(123); // false
298
+ * is.function(function() {}) // true
299
+ * is.function(123) // false
303
300
  */
304
301
  function(value) {
305
- return typeof value === "function" || value instanceof Function;
302
+ return typeof value === "function" || value instanceof Function
306
303
  },
307
304
 
308
305
  /**
@@ -317,13 +314,13 @@ export const is = {
317
314
  * @returns True if the value is iterable, false otherwise.
318
315
  *
319
316
  * @example
320
- * is.iterable([1, 2, 3]); // true
321
- * is.iterable('string'); // true
322
- * is.iterable(123); // false
317
+ * is.iterable([1, 2, 3]) // true
318
+ * is.iterable('string') // true
319
+ * is.iterable(123) // false
323
320
  */
324
321
  iterable(value) {
325
- const object = Object(value);
326
- return object && Reflect.has(object, Symbol.iterator);
322
+ const object = Object(value)
323
+ return object && Reflect.has(object, Symbol.iterator)
327
324
  },
328
325
 
329
326
  /**
@@ -333,12 +330,12 @@ export const is = {
333
330
  * @returns True if the value is null or undefined, false otherwise.
334
331
  *
335
332
  * @example
336
- * is.nullish(null); // true
337
- * is.nullish(undefined); // true
338
- * is.nullish('value'); // false
333
+ * is.nullish(null) // true
334
+ * is.nullish(undefined) // true
335
+ * is.nullish('value') // false
339
336
  */
340
337
  nullish(value) {
341
- return value === null || value === undefined;
338
+ return value === null || value === undefined
342
339
  },
343
340
 
344
341
  /**
@@ -348,11 +345,11 @@ export const is = {
348
345
  * @returns True if the value is a number, false otherwise.
349
346
  *
350
347
  * @example
351
- * is.number(123); // true
352
- * is.number('123'); // false
348
+ * is.number(123) // true
349
+ * is.number('123') // false
353
350
  */
354
351
  number(value) {
355
- return typeof value === "number" || value instanceof Number;
352
+ return typeof value === "number" || value instanceof Number
356
353
  },
357
354
 
358
355
  /**
@@ -362,11 +359,62 @@ export const is = {
362
359
  * @returns True if the value is an object, false otherwise.
363
360
  *
364
361
  * @example
365
- * is.object({}); // true
366
- * is.object(null); // false
362
+ * is.object({}) // true
363
+ * is.object(null) // false
367
364
  */
368
365
  object(value) {
369
- return !!(value && typeof value === "object");
366
+ return !!(value && typeof value === "object")
367
+ },
368
+
369
+ /**
370
+ * The {@link Object#entries} function returns the properties of a given
371
+ * value as an array of arrays where each element of the inner arrays is
372
+ * a valid object key (so one of {@link String}, {@link Number}, or
373
+ * {@link Symbol}) and the second element is the value of the pair which
374
+ * can be any type.
375
+ *
376
+ * This function vets this criteria and would return true for each entry
377
+ * in the returned outer array of a call to {@link Object#entries}.
378
+ *
379
+ * @param {any} value the value to test
380
+ * @returns {boolean} true if the value is a valid object entry in the
381
+ * form of `[key, value]`.
382
+ */
383
+ objectEntry(value) {
384
+ if (!(
385
+ // Must be an array
386
+ Array.isArray(value) &&
387
+
388
+ // Must have only two elements
389
+ value.length == 2 &&
390
+
391
+ // Must have its first element be string|number|symbol
392
+ (this.string(value[0]) || this.number(value[0]) || this.symbol(value[0]))
393
+ )) {
394
+ return false
395
+ }
396
+
397
+ return true
398
+ },
399
+
400
+ /**
401
+ * Check if a value is a valid object key. Valid object keys are strings,
402
+ * numbers, or symbols — the same types accepted as property keys in
403
+ * JavaScript objects.
404
+ *
405
+ * @param {*} value - The value to check.
406
+ * @returns {boolean} True if the value is a string, number, or symbol,
407
+ * false otherwise.
408
+ *
409
+ * @example
410
+ * is.objectKey('name') // true
411
+ * is.objectKey(0) // true
412
+ * is.objectKey(Symbol('id')) // true
413
+ * is.objectKey({}) // false
414
+ * is.objectKey(null) // false
415
+ */
416
+ objectKey(value) {
417
+ return this.string(value) || this.number(value) || this.symbol(value)
370
418
  },
371
419
 
372
420
  /**
@@ -380,25 +428,25 @@ export const is = {
380
428
  *
381
429
  * @example
382
430
  * // Returns true
383
- * is.primitive('hello');
431
+ * is.primitive('hello')
384
432
  *
385
433
  * // Returns true
386
- * is.primitive(123);
434
+ * is.primitive(123)
387
435
  *
388
436
  * // Returns true
389
- * is.primitive(true);
437
+ * is.primitive(true)
390
438
  *
391
439
  * // Returns true
392
- * is.primitive(123n);
440
+ * is.primitive(123n)
393
441
  *
394
442
  * // Returns true
395
- * is.primitive(Symbol('symbol'));
443
+ * is.primitive(Symbol('symbol'))
396
444
  *
397
445
  * // Returns false
398
- * is.primitive({});
446
+ * is.primitive({})
399
447
  *
400
448
  * // Returns false
401
- * is.primitive([]);
449
+ * is.primitive([])
402
450
  */
403
451
  primitive(value) {
404
452
  if (this.nullish(value))
@@ -406,7 +454,7 @@ export const is = {
406
454
 
407
455
  return ["string", "number", "boolean", "bigint", "symbol"].some(
408
456
  (type) => typeof value === type
409
- );
457
+ )
410
458
  },
411
459
 
412
460
  /**
@@ -420,12 +468,12 @@ export const is = {
420
468
  * @returns True if the value is an object or a function, false otherwise.
421
469
  *
422
470
  * @example
423
- * is.shiny({}); // true
424
- * is.shiny(function() {}); // true
425
- * is.shiny(123); // false
471
+ * is.shiny({}) // true
472
+ * is.shiny(function() {}) // true
473
+ * is.shiny(123) // false
426
474
  */
427
475
  shiny(value) {
428
- return !!(this.object(value) || this.function(value));
476
+ return !!(this.object(value) || this.function(value))
429
477
  },
430
478
 
431
479
  /**
@@ -435,11 +483,11 @@ export const is = {
435
483
  * @returns True if the value is a string, false otherwise.
436
484
  *
437
485
  * @example
438
- * is.string('hello'); // true
439
- * is.string(123); // false
486
+ * is.string('hello') // true
487
+ * is.string(123) // false
440
488
  */
441
489
  string(value) {
442
- return typeof value === "string" || value instanceof String;
490
+ return typeof value === "string" || value instanceof String
443
491
  },
444
492
 
445
493
  /**
@@ -452,11 +500,11 @@ export const is = {
452
500
  * @returns True if the value is a symbol, false otherwise.
453
501
  *
454
502
  * @example
455
- * is.symbol(Symbol('foo')); // Returns true
456
- * is.symbol('foo'); // Returns false
503
+ * is.symbol(Symbol('foo')) // Returns true
504
+ * is.symbol('foo') // Returns false
457
505
  */
458
506
  symbol(value) {
459
- return typeof value === "symbol" || value instanceof Symbol;
507
+ return typeof value === "symbol" || value instanceof Symbol
460
508
  },
461
509
 
462
510
  /**
@@ -468,9 +516,9 @@ export const is = {
468
516
  * @returns {boolean} True if the value is strictly true, false otherwise.
469
517
  *
470
518
  * @example
471
- * is.true(true); // true
472
- * is.true(false); // false
473
- * is.true(1); // false
519
+ * is.true(true) // true
520
+ * is.true(false) // false
521
+ * is.true(1) // false
474
522
  */
475
523
  true(value) {
476
524
  return value === true
@@ -487,506 +535,621 @@ export const is = {
487
535
  * @returns {boolean} True if the value is truthy, false otherwise.
488
536
  *
489
537
  * @example
490
- * is.truthy(1); // true
491
- * is.truthy("hello"); // true
492
- * is.truthy(0); // false
493
- * is.truthy(""); // false
538
+ * is.truthy(1) // true
539
+ * is.truthy("hello") // true
540
+ * is.truthy(0) // false
541
+ * is.truthy("") // false
494
542
  */
495
543
  truthy(value) {
496
544
  return !!value
497
545
  },
498
- };
546
+ }
499
547
 
500
548
  export const si = {
501
549
  /**
502
- * Checks if a value matches a specified type or class.
503
- *
504
- * This function determines if the provided value matches the specified
505
- * type or class. It supports both primitive types and class constructors.
550
+ * Inline if-then-else based on whether value matches a specified type or
551
+ * class. Delegates the condition check to {@link is#a}.
506
552
  *
507
553
  * @param {*} value - The value to check.
508
554
  * @param {*} typeOrClass - The type or class to compare against.
509
- * @param {boolean} [alreadyReversed=false] - Internal flag to prevent
510
- * infinite recursion. Not intended for external use.
511
- * @returns {boolean} True if the value matches the type or class,
512
- * false otherwise.
513
- *
514
- * @example
515
- * // Returns true
516
- * is.a(42, 'number')
517
- *
518
- * @example
519
- * // Returns true
520
- * is.a(new Date(), Date)
521
- *
522
- * @example
523
- * // Returns false
524
- * is.a('string', Number)
555
+ * @param {function|*} thenValue - Returned (or called and its result
556
+ * returned) if value matches typeOrClass.
557
+ * @param {function|*} elseValue - Returned (or called and its result
558
+ * returned) if value does not match typeOrClass.
559
+ * @returns {*} The result of thenValue if the condition is true,
560
+ * elseValue otherwise. If thenValue or elseValue is a function,
561
+ * its return value is used instead.
562
+ *
563
+ * @example
564
+ * si.a(42, 'number', 'yes', 'no') // 'yes'
565
+ * si.a('str', Number, 'yes', 'no') // 'no'
566
+ * si.a(42, 'number', () => 'computed', 'no') // 'computed'
525
567
  */
526
568
  a(value, typeOrClass, thenValue, elseValue) {
527
- const thenVal = is.function(thenValue) ? thenValue() : thenValue
528
- const elseVal = is.function(elseValue) ? elseValue() : elseValue
529
- return is.a(value, typeOrClass) ? thenValue : elseValue
569
+ return ifThenElse(is.a(value, typeOrClass), thenValue, elseValue)
530
570
  },
531
571
 
532
572
  /**
533
- * Check if a value is an accessor descriptor.
534
- *
535
- * An accessor descriptor is an object that describes the configuration of a
536
- * property on an object, specifically focusing on the 'get' and 'set'
537
- * attributes. Computed accessor descriptors are invalid if they also have
538
- * a `value` and/or `writable` property.
539
- *
540
- * @param value The value to check.
541
- * @returns True if the value is an accessor descriptor, false otherwise.
542
- *
543
- * @example
544
- * // Returns true
545
- * is.accessorDescriptor({ get: () => 42, set: () => {} });
573
+ * Inline if-then-else based on whether value is an accessor descriptor.
574
+ * Delegates the condition check to {@link is#accessorDescriptor}.
546
575
  *
547
- * // Returns false
548
- * is.accessorDescriptor({ value: 42, writable: true });
576
+ * @param {*} value - The value to check.
577
+ * @param {function|*} thenValue - Returned (or called and its result
578
+ * returned) if value is an accessor descriptor.
579
+ * @param {function|*} elseValue - Returned (or called and its result
580
+ * returned) if value is not an accessor descriptor.
581
+ * @returns {*} The result of thenValue if the condition is true,
582
+ * elseValue otherwise. If thenValue or elseValue is a function,
583
+ * its return value is used instead.
584
+ *
585
+ * @example
586
+ * si.accessorDescriptor({ get: () => 42 }, 'yes', 'no') // 'yes'
587
+ * si.accessorDescriptor({ value: 42 }, 'yes', 'no') // 'no'
588
+ * si.accessorDescriptor({ get: () => 42 }, () => 'computed', 'no') // 'computed'
549
589
  */
550
590
  accessorDescriptor(value, thenValue, elseValue) {
551
- const thenVal = is.function(thenValue) ? thenValue() : thenValue
552
- const elseVal = is.function(elseValue) ? elseValue() : elseValue
553
- return is.accessorDescriptor(value) ? thenVal : elseVal
591
+ return ifThenElse(is.accessorDescriptor(value), thenValue, elseValue)
554
592
  },
555
593
 
556
594
  /**
557
- * Check if a value is an array.
558
- *
559
- * @param value The value to check.
560
- * @returns True if the value is an array, false otherwise.
595
+ * Inline if-then-else based on whether value is an array.
596
+ * Delegates the condition check to {@link is#array}.
561
597
  *
562
- * @example
563
- * is.array([1, 2, 3]); // true
564
- * is.array('string'); // false
598
+ * @param {*} value - The value to check.
599
+ * @param {function|*} thenValue - Returned (or called and its result
600
+ * returned) if value is an array.
601
+ * @param {function|*} elseValue - Returned (or called and its result
602
+ * returned) if value is not an array.
603
+ * @returns {*} The result of thenValue if the condition is true,
604
+ * elseValue otherwise. If thenValue or elseValue is a function,
605
+ * its return value is used instead.
606
+ *
607
+ * @example
608
+ * si.array([1, 2, 3], 'yes', 'no') // 'yes'
609
+ * si.array('string', 'yes', 'no') // 'no'
610
+ * si.array([1, 2, 3], () => 'computed', 'no') // 'computed'
565
611
  */
566
612
  array(value, thenValue, elseValue) {
567
- const thenVal = is.function(thenValue) ? thenValue() : thenValue
568
- const elseVal = is.function(elseValue) ? elseValue() : elseValue
569
- return is.array(value) ? thenVal : elseVal
570
-
613
+ return ifThenElse(is.array(value), thenValue, elseValue)
571
614
  },
572
615
 
573
616
  /**
574
- * Check if a value is a bigint.
617
+ * Inline if-then-else based on whether value is a bigint.
618
+ * Delegates the condition check to {@link is#bigint}.
575
619
  *
576
- * @param value The value to check.
577
- * @returns True if the value is a bigint, false otherwise.
578
- *
579
- * @example
580
- * is.bigint(123n); // true
581
- * is.bigint(123); // false
620
+ * @param {*} value - The value to check.
621
+ * @param {function|*} thenValue - Returned (or called and its result
622
+ * returned) if value is a bigint.
623
+ * @param {function|*} elseValue - Returned (or called and its result
624
+ * returned) if value is not a bigint.
625
+ * @returns {*} The result of thenValue if the condition is true,
626
+ * elseValue otherwise. If thenValue or elseValue is a function,
627
+ * its return value is used instead.
628
+ *
629
+ * @example
630
+ * si.bigint(123n, 'yes', 'no') // 'yes'
631
+ * si.bigint(123, 'yes', 'no') // 'no'
632
+ * si.bigint(123n, () => 'computed', 'no') // 'computed'
582
633
  */
583
634
  bigint(value, thenValue, elseValue) {
584
- const thenVal = is.function(thenValue) ? thenValue() : thenValue
585
- const elseVal = is.function(elseValue) ? elseValue() : elseValue
586
- return is.bigint(value) ? thenVal : elseVal
635
+ return ifThenElse(is.bigint(value), thenValue, elseValue)
587
636
  },
588
637
 
589
638
  /**
590
- * Checks if a value is strictly a boolean (true or false).
591
- *
592
- * This method verifies if the provided value is either `true` or `false`.
639
+ * Inline if-then-else based on whether value is a boolean.
640
+ * Delegates the condition check to {@link is#boolean}.
593
641
  *
594
642
  * @param {*} value - The value to check.
595
- * @returns {boolean} True if the value is a boolean, false otherwise.
596
- *
597
- * @example
598
- * is.boolean(true); // true
599
- * is.boolean(false); // true
600
- * is.boolean(1); // false
601
- * is.boolean("true"); // false
643
+ * @param {function|*} thenValue - Returned (or called and its result
644
+ * returned) if value is a boolean.
645
+ * @param {function|*} elseValue - Returned (or called and its result
646
+ * returned) if value is not a boolean.
647
+ * @returns {*} The result of thenValue if the condition is true,
648
+ * elseValue otherwise. If thenValue or elseValue is a function,
649
+ * its return value is used instead.
650
+ *
651
+ * @example
652
+ * si.boolean(true, 'yes', 'no') // 'yes'
653
+ * si.boolean(1, 'yes', 'no') // 'no'
654
+ * si.boolean(false, () => 'computed', 'no') // 'computed'
602
655
  */
603
656
  boolean(value, thenValue, elseValue) {
604
- const thenVal = is.function(thenValue) ? thenValue() : thenValue
605
- const elseVal = is.function(elseValue) ? elseValue() : elseValue
606
- return is.boolean(value) ? thenVal : elseVal
657
+ return ifThenElse(is.boolean(value), thenValue, elseValue)
607
658
  },
608
659
 
609
660
  /**
610
- * Check if an object is callable. This function is more or less a
611
- * synonym or alias for `is.function()`.
612
- *
613
- * @param object The object to check.
614
- * @returns True if the object is callable, false otherwise.
615
- *
616
- * @note if you wish to know if a descriptor has a callable `value`,
617
- * `get`, or `set` function, use `is.callableDescriptor` instead.
618
- *
619
- * @example
620
- * is.callable(function() {}); // true
661
+ * Inline if-then-else based on whether object is callable.
662
+ * Delegates the condition check to {@link is#callable}.
663
+ *
664
+ * @param {*} object - The object to check.
665
+ * @param {function|*} thenValue - Returned (or called and its result
666
+ * returned) if object is callable.
667
+ * @param {function|*} elseValue - Returned (or called and its result
668
+ * returned) if object is not callable.
669
+ * @returns {*} The result of thenValue if the condition is true,
670
+ * elseValue otherwise. If thenValue or elseValue is a function,
671
+ * its return value is used instead.
672
+ *
673
+ * @example
674
+ * si.callable(function() {}, 'yes', 'no') // 'yes'
675
+ * si.callable(123, 'yes', 'no') // 'no'
676
+ * si.callable(function() {}, () => 'computed', 'no') // 'computed'
621
677
  */
622
678
  callable(object, thenValue, elseValue) {
623
- const thenVal = is.function(thenValue) ? thenValue() : thenValue
624
- const elseVal = is.function(elseValue) ? elseValue() : elseValue
625
- return is.callable(object) ? thenVal : elseVal
679
+ return ifThenElse(is.callable(object), thenValue, elseValue)
626
680
  },
627
681
 
628
682
  /**
629
- * Check if an object is callable. It looks to see if the object
630
- * represents a descriptor that is callable by checking object
631
- * properties named `value`, `get`, and `set`. If any three variations
632
- * yields a function type, true is returned.
633
- *
634
- * @param object The object to check.
635
- * @returns True if the object is callable, false otherwise.
636
- *
637
- * @example
638
- * is.callable({ get: function() {} }); // true
639
- * is.callable(123); // false
640
- *
641
- * // Note the differences between these
642
- * const object = { get name() { return "Brie"; } };
643
- * const descriptor = Object.getOwnPropertyDescriptor(object, 'name');
644
- * is.callable(object); // false
645
- * is.callable(descriptor); // true
683
+ * Inline if-then-else based on whether object is a callable descriptor.
684
+ * Delegates the condition check to {@link is#callableDescriptor}.
685
+ *
686
+ * @param {*} object - The object to check.
687
+ * @param {function|*} thenValue - Returned (or called and its result
688
+ * returned) if object is a callable descriptor.
689
+ * @param {function|*} elseValue - Returned (or called and its result
690
+ * returned) if object is not a callable descriptor.
691
+ * @returns {*} The result of thenValue if the condition is true,
692
+ * elseValue otherwise. If thenValue or elseValue is a function,
693
+ * its return value is used instead.
694
+ *
695
+ * @example
696
+ * si.callableDescriptor({ get: function() {} }, 'yes', 'no') // 'yes'
697
+ * si.callableDescriptor(123, 'yes', 'no') // 'no'
698
+ * si.callableDescriptor({ get: function() {} }, () => 'computed', 'no') // 'computed'
646
699
  */
647
700
  callableDescriptor(object, thenValue, elseValue) {
648
- const thenVal = is.function(thenValue) ? thenValue() : thenValue
649
- const elseVal = is.function(elseValue) ? elseValue() : elseValue
650
- return is.callableDescriptor(object) ? thenVal : elseVal
701
+ return ifThenElse(is.callableDescriptor(object), thenValue, elseValue)
651
702
  },
652
703
 
653
704
  /**
654
- * Check if a value is a data property descriptor.
655
- *
656
- * A data descriptor is an object that describes the configuration of a
657
- * property on an object, specifically focusing on the 'value' and
658
- * 'writable' attributes. The descriptor is invalid if it contains
659
- * thew accessor descriptors `get` or `set`.
660
- *
661
- * @param value The value to check.
662
- * @returns True if the value is a data descriptor, false otherwise.
663
- *
664
- * @example
665
- * // Returns true
666
- * is.dataDescriptor({ value: 42, writable: true });
705
+ * Inline if-then-else based on whether value is a data property descriptor.
706
+ * Delegates the condition check to {@link is#dataDescriptor}.
667
707
  *
668
- * // Returns false
669
- * is.dataDescriptor({ get: () => 42, set: () => {} });
708
+ * @param {*} value - The value to check.
709
+ * @param {function|*} thenValue - Returned (or called and its result
710
+ * returned) if value is a data descriptor.
711
+ * @param {function|*} elseValue - Returned (or called and its result
712
+ * returned) if value is not a data descriptor.
713
+ * @returns {*} The result of thenValue if the condition is true,
714
+ * elseValue otherwise. If thenValue or elseValue is a function,
715
+ * its return value is used instead.
716
+ *
717
+ * @example
718
+ * si.dataDescriptor({ value: 42, writable: true }, 'yes', 'no') // 'yes'
719
+ * si.dataDescriptor({ get: () => 42 }, 'yes', 'no') // 'no'
720
+ * si.dataDescriptor({ value: 42 }, () => 'computed', 'no') // 'computed'
670
721
  */
671
722
  dataDescriptor(value, thenValue, elseValue) {
672
- const thenVal = is.function(thenValue) ? thenValue() : thenValue
673
- const elseVal = is.function(elseValue) ? elseValue() : elseValue
674
- return is.dataDescriptor(value) ? thenVal : elseVal
723
+ return ifThenElse(is.dataDescriptor(value), thenValue, elseValue)
675
724
  },
676
725
 
677
726
  /**
678
- * Check if a value is a property descriptor.
679
- *
680
- * A property descriptor is an object that describes the configuration of a
681
- * property on an object. This function checks if the provided value is an
682
- * object and contains any of the standard property descriptor keys.
683
- *
684
- * @param value The value to check.
685
- * @returns True if the value is a property descriptor, false otherwise.
727
+ * Inline if-then-else based on whether value is a property descriptor.
728
+ * Delegates the condition check to {@link is#descriptor}.
686
729
  *
687
- * @example
688
- * is.descriptor({ configurable: true, enumerable: false }); // true
689
- * is.descriptor({ get: () => {}, set: () => {} }); // true
690
- * is.descriptor({}); // false
730
+ * @param {*} value - The value to check.
731
+ * @param {function|*} thenValue - Returned (or called and its result
732
+ * returned) if value is a property descriptor.
733
+ * @param {function|*} elseValue - Returned (or called and its result
734
+ * returned) if value is not a property descriptor.
735
+ * @returns {*} The result of thenValue if the condition is true,
736
+ * elseValue otherwise. If thenValue or elseValue is a function,
737
+ * its return value is used instead.
738
+ *
739
+ * @example
740
+ * si.descriptor({ configurable: true }, 'yes', 'no') // 'yes'
741
+ * si.descriptor({}, 'yes', 'no') // 'no'
742
+ * si.descriptor({ get: () => {} }, () => 'computed', 'no') // 'computed'
691
743
  */
692
744
  descriptor(value, thenValue, elseValue) {
693
- const thenVal = is.function(thenValue) ? thenValue() : thenValue
694
- const elseVal = is.function(elseValue) ? elseValue() : elseValue
695
- return is.descriptor(value) ? thenVal : elseVal
745
+ return ifThenElse(is.descriptor(value), thenValue, elseValue)
696
746
  },
697
747
 
698
748
  /**
699
- * Checks if a value is strictly false.
700
- *
701
- * This method verifies if the provided value is strictly `false`.
749
+ * Inline if-then-else based on whether value is strictly false.
750
+ * Delegates the condition check to {@link is#false}.
702
751
  *
703
752
  * @param {*} value - The value to check.
704
- * @returns {boolean} True if the value is strictly false, false otherwise.
705
- *
706
- * @example
707
- * is.false(false); // true
708
- * is.false(true); // false
709
- * is.false(0); // false
753
+ * @param {function|*} thenValue - Returned (or called and its result
754
+ * returned) if value is strictly false.
755
+ * @param {function|*} elseValue - Returned (or called and its result
756
+ * returned) if value is not strictly false.
757
+ * @returns {*} The result of thenValue if the condition is true,
758
+ * elseValue otherwise. If thenValue or elseValue is a function,
759
+ * its return value is used instead.
760
+ *
761
+ * @example
762
+ * si.false(false, 'yes', 'no') // 'yes'
763
+ * si.false(0, 'yes', 'no') // 'no'
764
+ * si.false(false, () => 'computed', 'no') // 'computed'
710
765
  */
711
766
  false(value, thenValue, elseValue) {
712
- const thenVal = is.function(thenValue) ? thenValue() : thenValue
713
- const elseVal = is.function(elseValue) ? elseValue() : elseValue
714
- return is.false(value) ? thenVal : elseVal
767
+ return ifThenElse(is.false(value), thenValue, elseValue)
715
768
  },
716
769
 
717
770
  /**
718
- * Checks if a value is falsy.
719
- *
720
- * This method converts the provided value to a boolean and returns
721
- * `true` if the value is falsy (i.e., false, 0, "", null, undefined,
722
- * or NaN).
771
+ * Inline if-then-else based on whether value is falsy.
772
+ * Delegates the condition check to {@link is#falsy}.
723
773
  *
724
774
  * @param {*} value - The value to check.
725
- * @returns {boolean} True if the value is falsy, false otherwise.
726
- *
727
- * @example
728
- * is.falsy(0); // true
729
- * is.falsy(""); // true
730
- * is.falsy(1); // false
731
- * is.falsy("hello"); // false
775
+ * @param {function|*} thenValue - Returned (or called and its result
776
+ * returned) if value is falsy.
777
+ * @param {function|*} elseValue - Returned (or called and its result
778
+ * returned) if value is not falsy.
779
+ * @returns {*} The result of thenValue if the condition is true,
780
+ * elseValue otherwise. If thenValue or elseValue is a function,
781
+ * its return value is used instead.
782
+ *
783
+ * @example
784
+ * si.falsy(0, 'yes', 'no') // 'yes'
785
+ * si.falsy(1, 'yes', 'no') // 'no'
786
+ * si.falsy('', () => 'computed', 'no') // 'computed'
732
787
  */
733
788
  falsy(value, thenValue, elseValue) {
734
- const thenVal = is.function(thenValue) ? thenValue() : thenValue
735
- const elseVal = is.function(elseValue) ? elseValue() : elseValue
736
- return is.falsy(value) ? thenVal : elseVal
789
+ return ifThenElse(is.falsy(value), thenValue, elseValue)
737
790
  },
738
791
 
739
792
  /**
740
- * Alias for the `falsy` method.
741
- *
742
- * This method is an alias for `is.falsy` and performs the same check.
793
+ * Alias for {@link si#falsy}. Inline if-then-else based on whether value
794
+ * is falsy. Delegates the condition check to {@link is#falsey}.
743
795
  *
744
796
  * @param {*} value - The value to check.
745
- * @returns {boolean} True if the value is falsy, false otherwise.
746
- *
747
- * @example
748
- * is.falsey(0); // true
749
- * is.falsey(""); // true
750
- * is.falsey(1); // false
751
- * is.falsey("hello"); // false
797
+ * @param {function|*} thenValue - Returned (or called and its result
798
+ * returned) if value is falsy.
799
+ * @param {function|*} elseValue - Returned (or called and its result
800
+ * returned) if value is not falsy.
801
+ * @returns {*} The result of thenValue if the condition is true,
802
+ * elseValue otherwise. If thenValue or elseValue is a function,
803
+ * its return value is used instead.
804
+ *
805
+ * @example
806
+ * si.falsey(0, 'yes', 'no') // 'yes'
807
+ * si.falsey(1, 'yes', 'no') // 'no'
808
+ * si.falsey('', () => 'computed', 'no') // 'computed'
752
809
  */
753
810
  falsey(value, thenValue, elseValue) {
754
- const thenVal = is.function(thenValue) ? thenValue() : thenValue
755
- const elseVal = is.function(elseValue) ? elseValue() : elseValue
756
- return is.falsey(value) ? thenVal : elseVal
811
+ return ifThenElse(is.falsey(value), thenValue, elseValue)
757
812
  },
758
813
 
759
814
  /**
760
- * Check if a value is a function.
761
- *
762
- * @param value The value to check.
763
- * @returns True if the value is a function, false otherwise.
815
+ * Inline if-then-else based on whether value is a function.
816
+ * Delegates the condition check to {@link is#function}.
764
817
  *
765
- * @example
766
- * is.function(function() {}); // true
767
- * is.function(123); // false
818
+ * @param {*} value - The value to check.
819
+ * @param {function|*} thenValue - Returned (or called and its result
820
+ * returned) if value is a function.
821
+ * @param {function|*} elseValue - Returned (or called and its result
822
+ * returned) if value is not a function.
823
+ * @returns {*} The result of thenValue if the condition is true,
824
+ * elseValue otherwise. If thenValue or elseValue is a function,
825
+ * its return value is used instead.
826
+ *
827
+ * @example
828
+ * si.function(function() {}, 'yes', 'no') // 'yes'
829
+ * si.function(123, 'yes', 'no') // 'no'
830
+ * si.function(function() {}, () => 'computed', 'no') // 'computed'
768
831
  */
769
832
  function(value, thenValue, elseValue) {
770
- const thenVal = is.function(thenValue) ? thenValue() : thenValue
771
- const elseVal = is.function(elseValue) ? elseValue() : elseValue
772
- return is.function(value) ? thenVal : elseVal
833
+ return ifThenElse(is.function(value), thenValue, elseValue)
773
834
  },
774
835
 
775
836
  /**
776
- * Check if a value is iterable. Depending on the environment, JavaScript
777
- * will permit `'string'[Symbol.iterator]()` whereas in some places, you
778
- * will need to wrap string in an object first. Since other JSVM provided
779
- * environments may or may not be leniant with this, we play it safe by
780
- * implicitly object converting values before checking for the symbol. If
781
- * a value is already an object, it will simply be passed through.
837
+ * Inline if-then-else based on whether value is iterable.
838
+ * Delegates the condition check to {@link is#iterable}.
782
839
  *
783
- * @param value The value to check.
784
- * @returns True if the value is iterable, false otherwise.
785
- *
786
- * @example
787
- * is.iterable([1, 2, 3]); // true
788
- * is.iterable('string'); // true
789
- * is.iterable(123); // false
840
+ * @param {*} value - The value to check.
841
+ * @param {function|*} thenValue - Returned (or called and its result
842
+ * returned) if value is iterable.
843
+ * @param {function|*} elseValue - Returned (or called and its result
844
+ * returned) if value is not iterable.
845
+ * @returns {*} The result of thenValue if the condition is true,
846
+ * elseValue otherwise. If thenValue or elseValue is a function,
847
+ * its return value is used instead.
848
+ *
849
+ * @example
850
+ * si.iterable([1, 2, 3], 'yes', 'no') // 'yes'
851
+ * si.iterable(123, 'yes', 'no') // 'no'
852
+ * si.iterable('string', () => 'computed', 'no') // 'computed'
790
853
  */
791
854
  iterable(value, thenValue, elseValue) {
792
- const thenVal = is.function(thenValue) ? thenValue() : thenValue
793
- const elseVal = is.function(elseValue) ? elseValue() : elseValue
794
- return is.iterable(value) ? thenVal : elseVal
855
+ return ifThenElse(is.iterable(value), thenValue, elseValue)
795
856
  },
796
857
 
797
858
  /**
798
- * Check if a value is null or undefined.
799
- *
800
- * @param value The value to check.
801
- * @returns True if the value is null or undefined, false otherwise.
859
+ * Inline if-then-else based on whether value is null or undefined.
860
+ * Delegates the condition check to {@link is#nullish}.
802
861
  *
803
- * @example
804
- * is.nullish(null); // true
805
- * is.nullish(undefined); // true
806
- * is.nullish('value'); // false
862
+ * @param {*} value - The value to check.
863
+ * @param {function|*} thenValue - Returned (or called and its result
864
+ * returned) if value is nullish.
865
+ * @param {function|*} elseValue - Returned (or called and its result
866
+ * returned) if value is not nullish.
867
+ * @returns {*} The result of thenValue if the condition is true,
868
+ * elseValue otherwise. If thenValue or elseValue is a function,
869
+ * its return value is used instead.
870
+ *
871
+ * @example
872
+ * si.nullish(null, 'yes', 'no') // 'yes'
873
+ * si.nullish('value', 'yes', 'no') // 'no'
874
+ * si.nullish(undefined, () => 'computed', 'no') // 'computed'
807
875
  */
808
876
  nullish(value, thenValue, elseValue) {
809
- const thenVal = is.function(thenValue) ? thenValue() : thenValue
810
- const elseVal = is.function(elseValue) ? elseValue() : elseValue
811
- return is.nullish(value) ? thenVal : elseVal
877
+ return ifThenElse(is.nullish(value), thenValue, elseValue)
812
878
  },
813
879
 
814
880
  /**
815
- * Check if a value is a number.
881
+ * Inline if-then-else based on whether value is a number.
882
+ * Delegates the condition check to {@link is#number}.
816
883
  *
817
- * @param value The value to check.
818
- * @returns True if the value is a number, false otherwise.
819
- *
820
- * @example
821
- * is.number(123); // true
822
- * is.number('123'); // false
884
+ * @param {*} value - The value to check.
885
+ * @param {function|*} thenValue - Returned (or called and its result
886
+ * returned) if value is a number.
887
+ * @param {function|*} elseValue - Returned (or called and its result
888
+ * returned) if value is not a number.
889
+ * @returns {*} The result of thenValue if the condition is true,
890
+ * elseValue otherwise. If thenValue or elseValue is a function,
891
+ * its return value is used instead.
892
+ *
893
+ * @example
894
+ * si.number(123, 'yes', 'no') // 'yes'
895
+ * si.number('123', 'yes', 'no') // 'no'
896
+ * si.number(123, () => 'computed', 'no') // 'computed'
823
897
  */
824
898
  number(value, thenValue, elseValue) {
825
- const thenVal = is.function(thenValue) ? thenValue() : thenValue
826
- const elseVal = is.function(elseValue) ? elseValue() : elseValue
827
- return is.number(value) ? thenVal : elseVal
899
+ return ifThenElse(is.number(value), thenValue, elseValue)
828
900
  },
829
901
 
830
902
  /**
831
- * Check if a value is an object.
832
- *
833
- * @param value The value to check.
834
- * @returns True if the value is an object, false otherwise.
903
+ * Inline if-then-else based on whether value is an object.
904
+ * Delegates the condition check to {@link is#object}.
835
905
  *
836
- * @example
837
- * is.object({}); // true
838
- * is.object(null); // false
906
+ * @param {*} value - The value to check.
907
+ * @param {function|*} thenValue - Returned (or called and its result
908
+ * returned) if value is an object.
909
+ * @param {function|*} elseValue - Returned (or called and its result
910
+ * returned) if value is not an object.
911
+ * @returns {*} The result of thenValue if the condition is true,
912
+ * elseValue otherwise. If thenValue or elseValue is a function,
913
+ * its return value is used instead.
914
+ *
915
+ * @example
916
+ * si.object({}, 'yes', 'no') // 'yes'
917
+ * si.object(null, 'yes', 'no') // 'no'
918
+ * si.object({}, () => 'computed', 'no') // 'computed'
839
919
  */
840
920
  object(value, thenValue, elseValue) {
841
- const thenVal = is.function(thenValue) ? thenValue() : thenValue
842
- const elseVal = is.function(elseValue) ? elseValue() : elseValue
843
- return is.object(value) ? thenVal : elseVal
921
+ return ifThenElse(is.object(value), thenValue, elseValue)
844
922
  },
845
923
 
846
924
  /**
847
- * Check if a value is a primitive type.
848
- *
849
- * This function determines if the provided value is one of the JavaScript
850
- * primitive types: string, number, boolean, bigint, or symbol.
851
- *
852
- * @param value The value to check.
853
- * @returns True if the value is a primitive type, false otherwise.
854
- *
855
- * @example
856
- * // Returns true
857
- * is.primitive('hello');
858
- *
859
- * // Returns true
860
- * is.primitive(123);
861
- *
862
- * // Returns true
863
- * is.primitive(true);
864
- *
865
- * // Returns true
866
- * is.primitive(123n);
867
- *
868
- * // Returns true
869
- * is.primitive(Symbol('symbol'));
925
+ * Inline if-then-else based on whether value is a valid object entry.
926
+ * Delegates the condition check to {@link is#objectEntry}.
927
+ *
928
+ * @param {any} value - The value to check.
929
+ * @param {function|*} thenValue - Returned (or called and its result
930
+ * returned) if value is a valid object entry.
931
+ * @param {function|*} elseValue - Returned (or called and its result
932
+ * returned) if value is not a valid object entry.
933
+ * @returns {*} The result of thenValue if the condition is true,
934
+ * elseValue otherwise. If thenValue or elseValue is a function,
935
+ * its return value is used instead.
936
+ *
937
+ * @example
938
+ * si.objectEntry(['key', 42], 'yes', 'no') // 'yes'
939
+ * si.objectEntry([1, 2, 3], 'yes', 'no') // 'no'
940
+ * si.objectEntry(['key', 42], () => 'computed', 'no') // 'computed'
941
+ */
942
+ objectEntry(value, thenValue, elseValue) {
943
+ return ifThenElse(is.objectEntry(value), thenValue, elseValue)
944
+ },
945
+
946
+ /**
947
+ * Inline if-then-else based on whether value is a valid object key.
948
+ * Delegates the condition check to {@link is#objectKey}.
870
949
  *
871
- * // Returns false
872
- * is.primitive({});
950
+ * @param {*} value - The value to check.
951
+ * @param {function|*} thenValue - Returned (or called and its result
952
+ * returned) if value is a valid object key.
953
+ * @param {function|*} elseValue - Returned (or called and its result
954
+ * returned) if value is not a valid object key.
955
+ * @returns {*} The result of thenValue if the condition is true,
956
+ * elseValue otherwise. If thenValue or elseValue is a function,
957
+ * its return value is used instead.
958
+ *
959
+ * @example
960
+ * si.objectKey('name', 'yes', 'no') // 'yes'
961
+ * si.objectKey({}, 'yes', 'no') // 'no'
962
+ * si.objectKey(Symbol('id'), () => 'computed', 'no') // 'computed'
963
+ */
964
+ objectKey(value, thenValue, elseValue) {
965
+ return ifThenElse(is.objectKey(value), thenValue, elseValue)
966
+ },
967
+
968
+ /**
969
+ * Inline if-then-else based on whether value is a primitive type.
970
+ * Delegates the condition check to {@link is#primitive}.
873
971
  *
874
- * // Returns false
875
- * is.primitive([]);
972
+ * @param {*} value - The value to check.
973
+ * @param {function|*} thenValue - Returned (or called and its result
974
+ * returned) if value is a primitive.
975
+ * @param {function|*} elseValue - Returned (or called and its result
976
+ * returned) if value is not a primitive.
977
+ * @returns {*} The result of thenValue if the condition is true,
978
+ * elseValue otherwise. If thenValue or elseValue is a function,
979
+ * its return value is used instead.
980
+ *
981
+ * @example
982
+ * si.primitive('hello', 'yes', 'no') // 'yes'
983
+ * si.primitive({}, 'yes', 'no') // 'no'
984
+ * si.primitive(123, () => 'computed', 'no') // 'computed'
876
985
  */
877
986
  primitive(value, thenValue, elseValue) {
878
- const thenVal = is.function(thenValue) ? thenValue() : thenValue
879
- const elseVal = is.function(elseValue) ? elseValue() : elseValue
880
- return is.primitive(value) ? thenVal : elseVal
987
+ return ifThenElse(is.primitive(value), thenValue, elseValue)
881
988
  },
882
989
 
883
990
  /**
884
- * The use of `typeof` is not a safe guarantor when it comes to Reflect
885
- * supported values. Any non-null value that returns a `typeof` either
886
- * `object` or `function` should suffice. Note that arrays return 'object'
887
- * when run through `typeof`. Shiny is clearly a reference to something
888
- * reflective and is much shorter to type. Also, Mal says shiny. :)
889
- *
890
- * @param value The value to check.
891
- * @returns True if the value is an object or a function, false otherwise.
991
+ * Inline if-then-else based on whether value is shiny (object or function).
992
+ * Delegates the condition check to {@link is#shiny}.
892
993
  *
893
- * @example
894
- * is.shiny({}); // true
895
- * is.shiny(function() {}); // true
896
- * is.shiny(123); // false
994
+ * @param {*} value - The value to check.
995
+ * @param {function|*} thenValue - Returned (or called and its result
996
+ * returned) if value is shiny.
997
+ * @param {function|*} elseValue - Returned (or called and its result
998
+ * returned) if value is not shiny.
999
+ * @returns {*} The result of thenValue if the condition is true,
1000
+ * elseValue otherwise. If thenValue or elseValue is a function,
1001
+ * its return value is used instead.
1002
+ *
1003
+ * @example
1004
+ * si.shiny({}, 'yes', 'no') // 'yes'
1005
+ * si.shiny(123, 'yes', 'no') // 'no'
1006
+ * si.shiny(function() {}, () => 'computed', 'no') // 'computed'
897
1007
  */
898
1008
  shiny(value, thenValue, elseValue) {
899
- const thenVal = is.function(thenValue) ? thenValue() : thenValue
900
- const elseVal = is.function(elseValue) ? elseValue() : elseValue
901
- return is.shiny(value) ? thenVal : elseVal
1009
+ return ifThenElse(is.shiny(value), thenValue, elseValue)
902
1010
  },
903
1011
 
904
1012
  /**
905
- * Check if a value is a string.
1013
+ * Inline if-then-else based on whether value is a string.
1014
+ * Delegates the condition check to {@link is#string}.
906
1015
  *
907
- * @param value The value to check.
908
- * @returns True if the value is a string, false otherwise.
909
- *
910
- * @example
911
- * is.string('hello'); // true
912
- * is.string(123); // false
1016
+ * @param {*} value - The value to check.
1017
+ * @param {function|*} thenValue - Returned (or called and its result
1018
+ * returned) if value is a string.
1019
+ * @param {function|*} elseValue - Returned (or called and its result
1020
+ * returned) if value is not a string.
1021
+ * @returns {*} The result of thenValue if the condition is true,
1022
+ * elseValue otherwise. If thenValue or elseValue is a function,
1023
+ * its return value is used instead.
1024
+ *
1025
+ * @example
1026
+ * si.string('hello', 'yes', 'no') // 'yes'
1027
+ * si.string(123, 'yes', 'no') // 'no'
1028
+ * si.string('hello', () => 'computed', 'no') // 'computed'
913
1029
  */
914
1030
  string(value, thenValue, elseValue) {
915
- const thenVal = is.function(thenValue) ? thenValue() : thenValue
916
- const elseVal = is.function(elseValue) ? elseValue() : elseValue
917
- return is.string(value) ? thenVal : elseVal
1031
+ return ifThenElse(is.string(value), thenValue, elseValue)
918
1032
  },
919
1033
 
920
1034
  /**
921
- * Checks if a value is a symbol.
922
- *
923
- * This function determines whether the provided value is of type
924
- * 'symbol' or an instance of the Symbol object.
925
- *
926
- * @param value - The value to check.
927
- * @returns True if the value is a symbol, false otherwise.
1035
+ * Inline if-then-else based on whether value is a symbol.
1036
+ * Delegates the condition check to {@link is#symbol}.
928
1037
  *
929
- * @example
930
- * is.symbol(Symbol('foo')); // Returns true
931
- * is.symbol('foo'); // Returns false
1038
+ * @param {*} value - The value to check.
1039
+ * @param {function|*} thenValue - Returned (or called and its result
1040
+ * returned) if value is a symbol.
1041
+ * @param {function|*} elseValue - Returned (or called and its result
1042
+ * returned) if value is not a symbol.
1043
+ * @returns {*} The result of thenValue if the condition is true,
1044
+ * elseValue otherwise. If thenValue or elseValue is a function,
1045
+ * its return value is used instead.
1046
+ *
1047
+ * @example
1048
+ * si.symbol(Symbol('foo'), 'yes', 'no') // 'yes'
1049
+ * si.symbol('foo', 'yes', 'no') // 'no'
1050
+ * si.symbol(Symbol('foo'), () => 'computed', 'no') // 'computed'
932
1051
  */
933
1052
  symbol(value, thenValue, elseValue) {
934
- const thenVal = is.function(thenValue) ? thenValue() : thenValue
935
- const elseVal = is.function(elseValue) ? elseValue() : elseValue
936
- return is.symbol(value) ? thenVal : elseVal
1053
+ return ifThenElse(is.symbol(value), thenValue, elseValue)
937
1054
  },
938
1055
 
1056
+ /**
1057
+ * Inline if-then-else using an arbitrary condition. If condition is a
1058
+ * function, it is called and its result is used as the condition; otherwise
1059
+ * the condition value is evaluated directly.
1060
+ *
1061
+ * @param {function|*} condition - The condition to evaluate. If a function,
1062
+ * it is called and its return value is used as the condition.
1063
+ * @param {function|*} thenValue - Returned (or called and its result
1064
+ * returned) if the condition is truthy.
1065
+ * @param {function|*} elseValue - Returned (or called and its result
1066
+ * returned) if the condition is falsy.
1067
+ * @returns {*} The result of thenValue if the condition is truthy,
1068
+ * elseValue otherwise. If thenValue or elseValue is a function,
1069
+ * its return value is used instead.
1070
+ *
1071
+ * @example
1072
+ * si.then(true, 'yes', 'no') // 'yes'
1073
+ * si.then(false, 'yes', 'no') // 'no'
1074
+ * si.then(() => true, 'yes', 'no') // 'yes'
1075
+ * si.then(() => false, () => 'computed', 'no') // 'no'
1076
+ */
939
1077
  then(condition, thenValue, elseValue) {
940
- const condVal = is.function(condition) ? condition() : condition
941
- const thenVal = is.function(thenValue) ? thenValue() : thenValue
942
- const elseVal = is.function(elseValue) ? elseValue() : elseValue
943
- return condVal ? thenVal : elseVal
1078
+ return ifThenElse(
1079
+ is.function(condition) ? condition() : condition,
1080
+ thenValue,
1081
+ elseValue
1082
+ )
944
1083
  },
945
1084
 
946
1085
  /**
947
- * Checks if a value is strictly true.
948
- *
949
- * This method verifies if the provided value is strictly `true`.
1086
+ * Inline if-then-else based on whether value is strictly true.
1087
+ * Delegates the condition check to {@link is#true}.
950
1088
  *
951
1089
  * @param {*} value - The value to check.
952
- * @returns {boolean} True if the value is strictly true, false otherwise.
953
- *
954
- * @example
955
- * is.true(true); // true
956
- * is.true(false); // false
957
- * is.true(1); // false
1090
+ * @param {function|*} thenValue - Returned (or called and its result
1091
+ * returned) if value is strictly true.
1092
+ * @param {function|*} elseValue - Returned (or called and its result
1093
+ * returned) if value is not strictly true.
1094
+ * @returns {*} The result of thenValue if the condition is true,
1095
+ * elseValue otherwise. If thenValue or elseValue is a function,
1096
+ * its return value is used instead.
1097
+ *
1098
+ * @example
1099
+ * si.true(true, 'yes', 'no') // 'yes'
1100
+ * si.true(1, 'yes', 'no') // 'no'
1101
+ * si.true(true, () => 'computed', 'no') // 'computed'
958
1102
  */
959
1103
  true(value, thenValue, elseValue) {
960
- const thenVal = is.function(thenValue) ? thenValue() : thenValue
961
- const elseVal = is.function(elseValue) ? elseValue() : elseValue
962
- return is.true(value) ? thenVal : elseVal
1104
+ return ifThenElse(is.true(value), thenValue, elseValue)
963
1105
  },
964
1106
 
965
1107
  /**
966
- * Checks if a value is truthy.
967
- *
968
- * This method converts the provided value to a boolean and returns
969
- * `true` if the value is truthy (i.e., not false, 0, "", null, undefined,
970
- * or NaN).
1108
+ * Inline if-then-else based on whether value is truthy.
1109
+ * Delegates the condition check to {@link is#truthy}.
971
1110
  *
972
1111
  * @param {*} value - The value to check.
973
- * @returns {boolean} True if the value is truthy, false otherwise.
974
- *
975
- * @example
976
- * is.truthy(1); // true
977
- * is.truthy("hello"); // true
978
- * is.truthy(0); // false
979
- * is.truthy(""); // false
1112
+ * @param {function|*} thenValue - Returned (or called and its result
1113
+ * returned) if value is truthy.
1114
+ * @param {function|*} elseValue - Returned (or called and its result
1115
+ * returned) if value is not truthy.
1116
+ * @returns {*} The result of thenValue if the condition is true,
1117
+ * elseValue otherwise. If thenValue or elseValue is a function,
1118
+ * its return value is used instead.
1119
+ *
1120
+ * @example
1121
+ * si.truthy(1, 'yes', 'no') // 'yes'
1122
+ * si.truthy(0, 'yes', 'no') // 'no'
1123
+ * si.truthy("hello", () => 'computed', 'no') // 'computed'
980
1124
  */
981
1125
  truthy(value, thenValue, elseValue) {
982
- const thenVal = is.function(thenValue) ? thenValue() : thenValue
983
- const elseVal = is.function(elseValue) ? elseValue() : elseValue
984
- return is.truthy(value) ? thenVal : elseVal
1126
+ return ifThenElse(is.truthy(value), thenValue, elseValue)
985
1127
  },
986
- };
987
1128
 
988
- /**
1129
+ /**
1130
+ * Inline if-then-else based on whether value is undefined.
1131
+ * Delegates the condition check to {@link is#a} with type 'undefined'.
1132
+ *
1133
+ * @param {*} value - The value to check.
1134
+ * @param {function|*} thenValue - Returned (or called and its result
1135
+ * returned) if value is undefined.
1136
+ * @param {function|*} elseValue - Returned (or called and its result
1137
+ * returned) if value is not undefined.
1138
+ * @returns {*} The result of thenValue if the condition is true,
1139
+ * elseValue otherwise. If thenValue or elseValue is a function,
1140
+ * its return value is used instead.
1141
+ *
1142
+ * @example
1143
+ * si.undefined(undefined, 'yes', 'no') // 'yes'
1144
+ * si.undefined('value', 'yes', 'no') // 'no'
1145
+ * si.undefined(undefined, () => 'computed', 'no') // 'computed'
1146
+ */
1147
+ undefined(value, thenValue, elseValue) {
1148
+ return ifThenElse(is.a(value, 'undefined'), thenValue, elseValue)
1149
+ }
1150
+ }
989
1151
 
1152
+ /**
990
1153
  * Checks if an object contains a specific key.
991
1154
  *
992
1155
  * This function determines if the provided object contains the specified key.
@@ -999,19 +1162,19 @@ export const si = {
999
1162
  *
1000
1163
  * @example
1001
1164
  * // Returns true
1002
- * has(new Map([['key', 'value']]), 'key');
1165
+ * has(new Map([['key', 'value']]), 'key')
1003
1166
  *
1004
1167
  * @example
1005
1168
  * // Returns false
1006
- * has({}, 'key');
1169
+ * has({}, 'key')
1007
1170
  */
1008
1171
  export const has = function has(object, key) {
1009
1172
  if ([Map, Set, WeakMap, WeakSet].some((i) => object instanceof i)) {
1010
- return object.has(key);
1173
+ return object.has(key)
1011
1174
  }
1012
1175
 
1013
- return is.shiny(object) && Reflect.has(object, key);
1014
- };
1176
+ return is.shiny(object) && Reflect.has(object, key)
1177
+ }
1015
1178
 
1016
1179
  Object.assign(has, {
1017
1180
  /**
@@ -1030,18 +1193,18 @@ Object.assign(has, {
1030
1193
  * // Returns true
1031
1194
  * has.all(new Map([
1032
1195
  * ['key1', 'value1'], ['key2', 'value2']
1033
- * ]), ['key1', 'key2']);
1196
+ * ]), ['key1', 'key2'])
1034
1197
  *
1035
1198
  * @example
1036
1199
  * // Returns false
1037
- * has.all({}, ['key1', 'key2']);
1200
+ * has.all({}, ['key1', 'key2'])
1038
1201
  */
1039
1202
  all(object, keys) {
1040
1203
  if (!is.shiny(object) || !is.array(keys) || !keys.length) {
1041
- return false;
1204
+ return false
1042
1205
  }
1043
1206
 
1044
- return keys.every((key) => has(object, key));
1207
+ return keys.every((key) => has(object, key))
1045
1208
  },
1046
1209
 
1047
1210
  /**
@@ -1059,18 +1222,18 @@ Object.assign(has, {
1059
1222
  *
1060
1223
  * @example
1061
1224
  * // Returns true
1062
- * has.some(new Map([['key1', 'value1'], ['key2', 'value2']]), ['key1']);
1225
+ * has.some(new Map([['key1', 'value1'], ['key2', 'value2']]), ['key1'])
1063
1226
  *
1064
1227
  * @example
1065
1228
  * // Returns false
1066
- * has.some({}, ['key1', 'key2']);
1229
+ * has.some({}, ['key1', 'key2'])
1067
1230
  */
1068
1231
  some(object, keys) {
1069
1232
  if (!is.shiny(object) || !is.array(keys) || !keys.length) {
1070
- return false;
1233
+ return false
1071
1234
  }
1072
1235
 
1073
- return keys.some((key) => has(object, key));
1236
+ return keys.some((key) => has(object, key))
1074
1237
  },
1075
1238
 
1076
1239
  /**
@@ -1110,11 +1273,11 @@ Object.assign(has, {
1110
1273
  * @returns True if the object has a custom string tag, false otherwise.
1111
1274
  *
1112
1275
  * @example
1113
- * const obj = { [Symbol.toStringTag]: 'CustomObject' };
1114
- * has.stringTag(obj); // Returns true
1276
+ * const obj = { [Symbol.toStringTag]: 'CustomObject' }
1277
+ * has.stringTag(obj) // Returns true
1115
1278
  */
1116
1279
  stringTag(object) {
1117
- return is.object(object) && has(object, Symbol.toStringTag);
1280
+ return is.object(object) && has(object, Symbol.toStringTag)
1118
1281
  },
1119
1282
 
1120
1283
  /**
@@ -1128,11 +1291,11 @@ Object.assign(has, {
1128
1291
  * false otherwise.
1129
1292
  *
1130
1293
  * @example
1131
- * const obj = { [Symbol.toPrimitive]: () => 42 };
1132
- * has.toPrimitive(obj); // Returns true
1294
+ * const obj = { [Symbol.toPrimitive]: () => 42 }
1295
+ * has.toPrimitive(obj) // Returns true
1133
1296
  */
1134
1297
  toPrimitive(object) {
1135
- return is.object(object) && has(object, Symbol.toPrimitive);
1298
+ return is.object(object) && has(object, Symbol.toPrimitive)
1136
1299
  },
1137
1300
 
1138
1301
  /**
@@ -1145,15 +1308,15 @@ Object.assign(has, {
1145
1308
  * @returns True if the object has a custom valueOf method, false otherwise.
1146
1309
  *
1147
1310
  * @example
1148
- * const obj = { valueOf: () => 42 };
1149
- * has.valueOf(obj); // Returns true
1311
+ * const obj = { valueOf: () => 42 }
1312
+ * has.valueOfFn(obj) // Returns true
1150
1313
  */
1151
1314
  valueOfFn(object) {
1152
1315
  return (
1153
- is.object(object) && has(object, "valueOf") && is.function(object.valueOf)
1154
- );
1316
+ is.object(object) && Object.hasOwn(object, "valueOf") && is.function(object.valueOf)
1317
+ )
1155
1318
  },
1156
- });
1319
+ })
1157
1320
 
1158
1321
  export const as = {
1159
1322
  /**
@@ -1164,18 +1327,18 @@ export const as = {
1164
1327
  *
1165
1328
  * @example
1166
1329
  * // Returns [1, 2, 3]
1167
- * as.array([1, 2, 3]);
1330
+ * as.array([1, 2, 3])
1168
1331
  *
1169
1332
  * @example
1170
1333
  * // Returns ['s', 't', 'r', 'i', 'n', 'g']
1171
- * as.array('string');
1334
+ * as.array('string')
1172
1335
  *
1173
1336
  * @example
1174
1337
  * // Returns undefined
1175
- * as.array(123);
1338
+ * as.array(123)
1176
1339
  */
1177
1340
  array(value) {
1178
- return (is.iterable(value) && Array.from(value)) || undefined;
1341
+ return (is.iterable(value) && Array.from(value)) || undefined
1179
1342
  },
1180
1343
 
1181
1344
  /**
@@ -1190,7 +1353,7 @@ export const as = {
1190
1353
  *
1191
1354
  * @example
1192
1355
  * // Returns { key: 'value' }
1193
- * as.object({ key: 'value' });
1356
+ * as.object({ key: 'value' })
1194
1357
  *
1195
1358
  * @example
1196
1359
  * // String instance as oppposed to primitive string
@@ -1200,10 +1363,10 @@ export const as = {
1200
1363
  *
1201
1364
  * @example
1202
1365
  * // Returns {}
1203
- * as.object(null);
1366
+ * as.object(null)
1204
1367
  */
1205
1368
  object(value) {
1206
- return Object(value);
1369
+ return Object(value)
1207
1370
  },
1208
1371
 
1209
1372
  /**
@@ -1220,29 +1383,29 @@ export const as = {
1220
1383
  *
1221
1384
  * @example
1222
1385
  * // Returns 'null'
1223
- * as.string(null);
1386
+ * as.string(null)
1224
1387
  *
1225
1388
  * @example
1226
1389
  * // Returns '123'
1227
- * as.string(123);
1390
+ * as.string(123)
1228
1391
  *
1229
1392
  * @example
1230
1393
  * // Returns 'custom'
1231
1394
  * const obj = {
1232
1395
  * [Symbol.toPrimitive](hint) {
1233
- * if (hint === 'string') return 'custom';
1234
- * return null;
1396
+ * if (hint === 'string') return 'custom'
1397
+ * return null
1235
1398
  * }
1236
- * };
1237
- * as.string(obj);
1399
+ * }
1400
+ * as.string(obj)
1238
1401
  *
1239
1402
  * @example
1240
1403
  * // Returns 'mySymbol'
1241
- * as.string(Symbol('mySymbol'), { description: true });
1404
+ * as.string(Symbol('mySymbol'), { description: true })
1242
1405
  *
1243
1406
  * @example
1244
1407
  * // Returns 'Array'
1245
- * as.string([], { stringTag: true });
1408
+ * as.string([], { stringTag: true })
1246
1409
  */
1247
1410
  string(
1248
1411
  value,
@@ -1253,47 +1416,47 @@ export const as = {
1253
1416
  ) {
1254
1417
  // Check if the value is null or undefined directly
1255
1418
  if (value === null || value === undefined) {
1256
- return String(value);
1419
+ return String(value)
1257
1420
  }
1258
1421
 
1259
1422
  if (is.symbol(value) && use?.description) {
1260
- return value.description;
1423
+ return value.description
1261
1424
  }
1262
1425
 
1263
1426
  if (has.stringTag(value) && use?.stringTag) {
1264
- return value[Symbol.toStringTag];
1427
+ return value[Symbol.toStringTag]
1265
1428
  }
1266
1429
 
1267
1430
  // Check if the value has a [Symbol.toPrimitive] method
1268
1431
  if (is.function(value?.[Symbol.toPrimitive])) {
1269
- const primitiveValue = value[Symbol.toPrimitive]("string");
1432
+ const primitiveValue = value[Symbol.toPrimitive]("string")
1270
1433
  if (is.string(primitiveValue)) {
1271
- return primitiveValue;
1434
+ return primitiveValue
1272
1435
  }
1273
1436
  }
1274
1437
 
1275
1438
  // Check if the value has a valueOf method
1276
1439
  if (is.function(value?.valueOf)) {
1277
- const valueOfValue = value.valueOf();
1440
+ const valueOfValue = value.valueOf()
1278
1441
  if (is.string(valueOfValue)) {
1279
- return valueOfValue;
1442
+ return valueOfValue
1280
1443
  }
1281
1444
  // If valueOf returns a primitive other than string, convert it to string
1282
1445
  if (!is.object(valueOfValue)) {
1283
- return String(valueOfValue);
1446
+ return String(valueOfValue)
1284
1447
  }
1285
1448
  }
1286
1449
 
1287
1450
  // Check if the value has a toString method
1288
1451
  if (is.function(value?.toString)) {
1289
- const stringValue = value.toString();
1452
+ const stringValue = value.toString()
1290
1453
  if (is.string(stringValue)) {
1291
- return stringValue;
1454
+ return stringValue
1292
1455
  }
1293
1456
  }
1294
1457
 
1295
1458
  // Fallback to String() function
1296
- return String(value);
1459
+ return String(value)
1297
1460
  },
1298
1461
 
1299
1462
  /**
@@ -1307,14 +1470,14 @@ export const as = {
1307
1470
  *
1308
1471
  * @example
1309
1472
  * // Returns '123'
1310
- * as.integerString(123.456);
1473
+ * as.integerString(123.456)
1311
1474
  *
1312
1475
  * @example
1313
1476
  * // Returns '0'
1314
- * as.integerString('0.789');
1477
+ * as.integerString('0.789')
1315
1478
  */
1316
1479
  integerString(value) {
1317
- return this.numberString(value).split(".")[0];
1480
+ return this.numberString(value).split(".")[0]
1318
1481
  },
1319
1482
 
1320
1483
  /**
@@ -1332,26 +1495,25 @@ export const as = {
1332
1495
  *
1333
1496
  * @example
1334
1497
  * // Returns '123.456'
1335
- * numberString(' 123.456abc ');
1498
+ * as.numberString(' 123.456abc ')
1336
1499
  *
1337
1500
  * @example
1338
1501
  * // Returns '-0.789'
1339
- * numberString('-0.789xyz');
1502
+ * as.numberString('-0.789xyz')
1340
1503
  */
1341
1504
  numberString(value) {
1342
1505
  // Trim the input string
1343
-
1344
1506
  const string = this.string(value)
1345
1507
  .trim()
1346
- .replace(/[^0-9.eE+-]/g, "");
1508
+ .replace(/[^0-9.eE+-]/g, "")
1347
1509
  // Use a regular expression to match a floating-point number
1348
1510
  // Allow an optional leading '+' or '-' sign, digits before and after a
1349
1511
  // single decimal point
1350
- const sanitizedStr = string.match(/^[-+]?\d*\.?\d+([eE][-+]?\d+)?/);
1512
+ const sanitizedStr = string.match(/^[-+]?\d*\.?\d+([eE][-+]?\d+)?/)
1351
1513
 
1352
1514
  // Return the sanitized string or an empty string if no valid float
1353
1515
  // was found
1354
- return sanitizedStr ? sanitizedStr[0] : "";
1516
+ return sanitizedStr ? sanitizedStr[0] : ""
1355
1517
  },
1356
1518
 
1357
1519
  /**
@@ -1365,14 +1527,14 @@ export const as = {
1365
1527
  *
1366
1528
  * @example
1367
1529
  * // Returns 123.456
1368
- * number('123.456abc');
1530
+ * as.number('123.456abc')
1369
1531
  *
1370
1532
  * @example
1371
1533
  * // Returns -0.789
1372
- * number('-0.789xyz');
1534
+ * as.number('-0.789xyz')
1373
1535
  */
1374
1536
  number(value) {
1375
- return Number(this.numberString(value));
1537
+ return Number(this.numberString(value))
1376
1538
  },
1377
1539
 
1378
1540
  /**
@@ -1386,15 +1548,15 @@ export const as = {
1386
1548
  *
1387
1549
  * @example
1388
1550
  * // Returns 123n
1389
- * bigint('123.456abc');
1551
+ * as.bigint('123.456abc')
1390
1552
  *
1391
1553
  * @example
1392
1554
  * // Returns 0n
1393
- * bigint('0.789xyz');
1555
+ * as.bigint('0.789xyz')
1394
1556
  */
1395
1557
  bigint(value) {
1396
- const BigInt = globalThis?.BigInt;
1397
- return BigInt(this.integerString(value));
1558
+ const BigInt = globalThis?.BigInt
1559
+ return BigInt(this.integerString(value))
1398
1560
  },
1399
1561
 
1400
1562
  /**
@@ -1411,35 +1573,35 @@ export const as = {
1411
1573
  *
1412
1574
  * @example
1413
1575
  * // Returns true
1414
- * is.boolean("yes")
1576
+ * as.boolean("yes")
1415
1577
  *
1416
1578
  * @example
1417
1579
  * // Returns false
1418
- * is.boolean("no")
1580
+ * as.boolean("no")
1419
1581
  *
1420
1582
  * @example
1421
1583
  * // Returns true
1422
- * is.boolean(1)
1584
+ * as.boolean(1)
1423
1585
  *
1424
1586
  * @example
1425
1587
  * // Returns false
1426
- * is.boolean(0)
1588
+ * as.boolean(0)
1427
1589
  *
1428
1590
  * @example
1429
1591
  * // Returns true
1430
- * is.boolean("true")
1592
+ * as.boolean("true")
1431
1593
  *
1432
1594
  * @example
1433
1595
  * // Returns false
1434
- * is.boolean("false")
1596
+ * as.boolean("false")
1435
1597
  *
1436
1598
  * @example
1437
1599
  * // Returns true
1438
- * is.boolean({})
1600
+ * as.boolean({})
1439
1601
  *
1440
1602
  * @example
1441
1603
  * // Returns false
1442
- * is.boolean(null)
1604
+ * as.boolean(null)
1443
1605
  */
1444
1606
  boolean(value) {
1445
1607
  switch (String(value).toLowerCase()) {
@@ -1457,7 +1619,7 @@ export const as = {
1457
1619
  return Boolean(value)
1458
1620
  }
1459
1621
  },
1460
- };
1622
+ }
1461
1623
 
1462
1624
  export function createToolkit() {
1463
1625
  return { si, is, has, as }
@@ -1470,4 +1632,25 @@ export default {
1470
1632
  si,
1471
1633
 
1472
1634
  createToolkit,
1473
- }
1635
+ }
1636
+
1637
+ function ifThenElse(condition, thenCase, elseCase) {
1638
+ if (typeof thenCase === 'undefined' && typeof elseCase === 'undefined')
1639
+ return !!condition
1640
+
1641
+ if (typeof thenCase === 'undefined')
1642
+ thenCase = condition
1643
+
1644
+ if (condition) {
1645
+ if (is.function(thenCase))
1646
+ return thenCase()
1647
+ else
1648
+ return thenCase
1649
+ }
1650
+ else {
1651
+ if (is.function(elseCase))
1652
+ return elseCase()
1653
+ else
1654
+ return elseCase
1655
+ }
1656
+ }