@nejs/basic-extensions 2.8.0 → 2.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/README.md +268 -147
  2. package/bin/version +100 -0
  3. package/dist/@nejs/basic-extensions.bundle.2.10.0.js +19 -0
  4. package/dist/@nejs/basic-extensions.bundle.2.10.0.js.map +7 -0
  5. package/dist/cjs/array.extensions.js +174 -0
  6. package/dist/cjs/array.extensions.js.map +1 -1
  7. package/dist/cjs/big.int.extension.js +1 -0
  8. package/dist/cjs/big.int.extension.js.map +1 -1
  9. package/dist/cjs/classes/descriptor.js +1 -1
  10. package/dist/cjs/classes/descriptor.js.map +1 -1
  11. package/dist/cjs/classes/index.d.ts +1 -0
  12. package/dist/cjs/classes/index.js +3 -0
  13. package/dist/cjs/classes/index.js.map +1 -1
  14. package/dist/cjs/classes/iterable.d.ts +44 -0
  15. package/dist/cjs/classes/iterable.js +64 -0
  16. package/dist/cjs/classes/iterable.js.map +1 -1
  17. package/dist/cjs/classes/param.parser.d.ts +10 -10
  18. package/dist/cjs/classes/property.d.ts +86 -0
  19. package/dist/cjs/classes/property.js +284 -0
  20. package/dist/cjs/classes/property.js.map +1 -0
  21. package/dist/cjs/classes/symkeys.d.ts +68 -11
  22. package/dist/cjs/classes/symkeys.js +103 -17
  23. package/dist/cjs/classes/symkeys.js.map +1 -1
  24. package/dist/cjs/classes/type.d.ts +4 -4
  25. package/dist/cjs/function.extensions.js +1 -0
  26. package/dist/cjs/function.extensions.js.map +1 -1
  27. package/dist/cjs/global.this.js +29 -0
  28. package/dist/cjs/global.this.js.map +1 -1
  29. package/dist/cjs/index.d.ts +2 -0
  30. package/dist/cjs/index.js +18 -0
  31. package/dist/cjs/index.js.map +1 -1
  32. package/dist/cjs/json.extensions.js +22 -20
  33. package/dist/cjs/json.extensions.js.map +1 -1
  34. package/dist/cjs/map.extensions.js +1 -0
  35. package/dist/cjs/map.extensions.js.map +1 -1
  36. package/dist/cjs/number.extension.js +1 -0
  37. package/dist/cjs/number.extension.js.map +1 -1
  38. package/dist/cjs/object.extensions.d.ts +0 -29
  39. package/dist/cjs/object.extensions.js +218 -243
  40. package/dist/cjs/object.extensions.js.map +1 -1
  41. package/dist/cjs/set.extensions.js +1 -0
  42. package/dist/cjs/set.extensions.js.map +1 -1
  43. package/dist/cjs/string.extensions.js +478 -283
  44. package/dist/cjs/string.extensions.js.map +1 -1
  45. package/dist/cjs/symbol.extensions.js +500 -24
  46. package/dist/cjs/symbol.extensions.js.map +1 -1
  47. package/dist/cjs/utils/copy.object.d.ts +408 -0
  48. package/dist/cjs/utils/copy.object.js +720 -0
  49. package/dist/cjs/utils/copy.object.js.map +1 -0
  50. package/dist/cjs/utils/index.d.ts +1 -0
  51. package/dist/cjs/utils/index.js +19 -0
  52. package/dist/cjs/utils/index.js.map +1 -0
  53. package/dist/cjs/utils/toolkit.d.ts +1897 -0
  54. package/dist/cjs/utils/toolkit.js +1377 -0
  55. package/dist/cjs/utils/toolkit.js.map +1 -0
  56. package/dist/mjs/array.extensions.js +174 -0
  57. package/dist/mjs/array.extensions.js.map +1 -1
  58. package/dist/mjs/big.int.extension.js +1 -0
  59. package/dist/mjs/big.int.extension.js.map +1 -1
  60. package/dist/mjs/classes/descriptor.js +1 -1
  61. package/dist/mjs/classes/descriptor.js.map +1 -1
  62. package/dist/mjs/classes/index.d.ts +1 -0
  63. package/dist/mjs/classes/index.js +3 -0
  64. package/dist/mjs/classes/index.js.map +1 -1
  65. package/dist/mjs/classes/iterable.d.ts +44 -0
  66. package/dist/mjs/classes/iterable.js +64 -0
  67. package/dist/mjs/classes/iterable.js.map +1 -1
  68. package/dist/mjs/classes/param.parser.d.ts +10 -10
  69. package/dist/mjs/classes/property.d.ts +86 -0
  70. package/dist/mjs/classes/property.js +280 -0
  71. package/dist/mjs/classes/property.js.map +1 -0
  72. package/dist/mjs/classes/symkeys.d.ts +68 -11
  73. package/dist/mjs/classes/symkeys.js +103 -17
  74. package/dist/mjs/classes/symkeys.js.map +1 -1
  75. package/dist/mjs/classes/type.d.ts +4 -4
  76. package/dist/mjs/function.extensions.js +1 -0
  77. package/dist/mjs/function.extensions.js.map +1 -1
  78. package/dist/mjs/global.this.js +6 -0
  79. package/dist/mjs/global.this.js.map +1 -1
  80. package/dist/mjs/index.d.ts +2 -0
  81. package/dist/mjs/index.js +4 -0
  82. package/dist/mjs/index.js.map +1 -1
  83. package/dist/mjs/json.extensions.js +22 -20
  84. package/dist/mjs/json.extensions.js.map +1 -1
  85. package/dist/mjs/map.extensions.js +1 -0
  86. package/dist/mjs/map.extensions.js.map +1 -1
  87. package/dist/mjs/number.extension.js +1 -0
  88. package/dist/mjs/number.extension.js.map +1 -1
  89. package/dist/mjs/object.extensions.d.ts +0 -29
  90. package/dist/mjs/object.extensions.js +215 -239
  91. package/dist/mjs/object.extensions.js.map +1 -1
  92. package/dist/mjs/set.extensions.js +1 -0
  93. package/dist/mjs/set.extensions.js.map +1 -1
  94. package/dist/mjs/string.extensions.js +478 -283
  95. package/dist/mjs/string.extensions.js.map +1 -1
  96. package/dist/mjs/symbol.extensions.js +501 -25
  97. package/dist/mjs/symbol.extensions.js.map +1 -1
  98. package/dist/mjs/utils/copy.object.d.ts +408 -0
  99. package/dist/mjs/utils/copy.object.js +702 -0
  100. package/dist/mjs/utils/copy.object.js.map +1 -0
  101. package/dist/mjs/utils/index.d.ts +1 -0
  102. package/dist/mjs/utils/index.js +3 -0
  103. package/dist/mjs/utils/index.js.map +1 -0
  104. package/dist/mjs/utils/toolkit.d.ts +1897 -0
  105. package/dist/mjs/utils/toolkit.js +1372 -0
  106. package/dist/mjs/utils/toolkit.js.map +1 -0
  107. package/package.json +30 -38
  108. package/repl.bootstrap.js +12 -1
  109. package/src/array.extensions.js +191 -1
  110. package/src/big.int.extension.js +3 -1
  111. package/src/classes/descriptor.js +1 -1
  112. package/src/classes/index.js +4 -0
  113. package/src/classes/iterable.js +74 -0
  114. package/src/classes/property.js +333 -0
  115. package/src/classes/symkeys.js +120 -19
  116. package/src/function.extensions.js +2 -0
  117. package/src/global.this.js +8 -0
  118. package/src/index.js +5 -0
  119. package/src/json.extensions.js +21 -21
  120. package/src/map.extensions.js +3 -1
  121. package/src/number.extension.js +3 -1
  122. package/src/object.extensions.js +240 -262
  123. package/src/set.extensions.js +3 -1
  124. package/src/string.extensions.js +531 -306
  125. package/src/symbol.extensions.js +529 -25
  126. package/src/utils/copy.object.js +780 -0
  127. package/src/utils/index.js +2 -0
  128. package/src/utils/toolkit.js +1471 -0
  129. package/tests/arrayextensions.test.js +2 -0
  130. package/tests/index.test.js +1 -0
  131. package/tests/newClasses/asyncIterable.test.js +2 -0
  132. package/tests/newClasses/deferred.test.js +5 -3
  133. package/tests/newClasses/descriptor.test.js +2 -0
  134. package/tests/newClasses/iterable.test.js +2 -0
  135. package/tests/newClasses/refmap.test.js +2 -1
  136. package/tests/newClasses/refset.test.js +2 -0
  137. package/tests/objectextensions.test.js +2 -0
  138. package/tests/setextensions.test.js +2 -0
  139. package/tests/stringextensions.test.js +1 -0
  140. package/tests/utils/toolkit.test.js +223 -0
  141. package/tsconfig.base.json +1 -1
  142. package/vitest.config.js +7 -0
  143. package/dist/@nejs/basic-extensions.bundle.2.7.0.js +0 -19
  144. package/dist/@nejs/basic-extensions.bundle.2.7.0.js.map +0 -7
  145. package/docs/assets/anchor.js +0 -350
  146. package/docs/assets/bass-addons.css +0 -12
  147. package/docs/assets/bass.css +0 -544
  148. package/docs/assets/fonts/EOT/SourceCodePro-Bold.eot +0 -0
  149. package/docs/assets/fonts/EOT/SourceCodePro-Regular.eot +0 -0
  150. package/docs/assets/fonts/LICENSE.txt +0 -93
  151. package/docs/assets/fonts/OTF/SourceCodePro-Bold.otf +0 -0
  152. package/docs/assets/fonts/OTF/SourceCodePro-Regular.otf +0 -0
  153. package/docs/assets/fonts/TTF/SourceCodePro-Bold.ttf +0 -0
  154. package/docs/assets/fonts/TTF/SourceCodePro-Regular.ttf +0 -0
  155. package/docs/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff +0 -0
  156. package/docs/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff +0 -0
  157. package/docs/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff +0 -0
  158. package/docs/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff +0 -0
  159. package/docs/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2 +0 -0
  160. package/docs/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2 +0 -0
  161. package/docs/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2 +0 -0
  162. package/docs/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2 +0 -0
  163. package/docs/assets/fonts/source-code-pro.css +0 -23
  164. package/docs/assets/github.css +0 -123
  165. package/docs/assets/site.js +0 -168
  166. package/docs/assets/split.css +0 -15
  167. package/docs/assets/split.js +0 -782
  168. package/docs/assets/style.css +0 -147
  169. package/docs/index.html +0 -34965
@@ -0,0 +1,1471 @@
1
+ const map = new Map([
2
+ ['object', Object], [Object, 'object'], ['Object', Object],
3
+ ['number', Number], [Number, 'number'], ['Number', Number],
4
+ ['string', String], [String, 'string'], ['String', String],
5
+ ['function', Function], [Function, 'function'], ['Function', Function],
6
+ ['boolean', Boolean], [Boolean, 'boolean'], ['Boolean', Boolean],
7
+ ['bigint', BigInt], [BigInt, 'bigint'], ['BigInt', BigInt],
8
+ ['symbol', Symbol], [Symbol, 'symbol'], ['Symbol', Symbol],
9
+ ['undefined', undefined], [undefined, 'undefined'],
10
+ ['null', null], [null, 'null'],
11
+ ])
12
+
13
+ /**
14
+ * Utility functions to check the type and properties of a value.
15
+ */
16
+ export const is = {
17
+ /**
18
+ * Checks if a value matches a specified type or class.
19
+ *
20
+ * This function determines if the provided value matches the specified
21
+ * type or class. It supports both primitive types and class constructors.
22
+ *
23
+ * @param {*} value - The value to check.
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
+ * @returns {boolean} True if the value matches the type or class,
28
+ * false otherwise.
29
+ *
30
+ * @example
31
+ * // Returns true
32
+ * is.a(42, 'number')
33
+ *
34
+ * @example
35
+ * // Returns true
36
+ * is.a(new Date(), Date)
37
+ *
38
+ * @example
39
+ * // Returns false
40
+ * is.a('string', Number)
41
+ */
42
+ a(value, typeOrClass) {
43
+ const valueType = typeof value
44
+ const valueTag = this.object(value) && value[Symbol.toStringTag]
45
+
46
+ if (value === typeOrClass)
47
+ return true
48
+
49
+ if (this.function(typeOrClass)) {
50
+ const typeTag = this.object(typeOrClass) && typeOrClass[Symbol.toStringTag]
51
+
52
+ if (valueTag && valueTag === typeOrClass.name)
53
+ return true
54
+
55
+ if (typeOrClass?.prototype && value instanceof typeOrClass)
56
+ return true
57
+
58
+ return map.get(valueType) === typeOrClass
59
+ }
60
+
61
+ else if (map.get(valueType)?.name === typeOrClass)
62
+ return true
63
+
64
+ else if (valueType === typeOrClass || valueTag === typeOrClass)
65
+ return true
66
+
67
+ return false
68
+ },
69
+
70
+ /**
71
+ * Check if a value is an accessor descriptor.
72
+ *
73
+ * An accessor descriptor is an object that describes the configuration of a
74
+ * property on an object, specifically focusing on the 'get' and 'set'
75
+ * attributes. Computed accessor descriptors are invalid if they also have
76
+ * a `value` and/or `writable` property.
77
+ *
78
+ * @param value The value to check.
79
+ * @returns True if the value is an accessor descriptor, false otherwise.
80
+ *
81
+ * @example
82
+ * // Returns true
83
+ * is.accessorDescriptor({ get: () => 42, set: () => {} });
84
+ *
85
+ * // Returns false
86
+ * is.accessorDescriptor({ value: 42, writable: true });
87
+ */
88
+ accessorDescriptor(value) {
89
+ return !!(
90
+ this.descriptor(value) &&
91
+ (value?.get || value?.set) &&
92
+ value?.writable === undefined &&
93
+ value?.value === undefined
94
+ );
95
+ },
96
+
97
+ /**
98
+ * Check if a value is an array.
99
+ *
100
+ * @param value The value to check.
101
+ * @returns True if the value is an array, false otherwise.
102
+ *
103
+ * @example
104
+ * is.array([1, 2, 3]); // true
105
+ * is.array('string'); // false
106
+ */
107
+ array(value) {
108
+ return Array.isArray(value);
109
+ },
110
+
111
+ /**
112
+ * Check if a value is a bigint.
113
+ *
114
+ * @param value The value to check.
115
+ * @returns True if the value is a bigint, false otherwise.
116
+ *
117
+ * @example
118
+ * is.bigint(123n); // true
119
+ * is.bigint(123); // false
120
+ */
121
+ bigint(value) {
122
+ return typeof value === "bigint" || value instanceof globalThis?.BigInt;
123
+ },
124
+
125
+ /**
126
+ * Checks if a value is strictly a boolean (true or false).
127
+ *
128
+ * This method verifies if the provided value is either `true` or `false`.
129
+ *
130
+ * @param {*} value - The value to check.
131
+ * @returns {boolean} True if the value is a boolean, false otherwise.
132
+ *
133
+ * @example
134
+ * is.boolean(true); // true
135
+ * is.boolean(false); // true
136
+ * is.boolean(1); // false
137
+ * is.boolean("true"); // false
138
+ */
139
+ boolean(value) {
140
+ return [true, false].some(bool => bool === value)
141
+ },
142
+
143
+ /**
144
+ * Check if an object is callable. This function is more or less a
145
+ * synonym or alias for `is.function()`.
146
+ *
147
+ * @param object The object to check.
148
+ * @returns True if the object is callable, false otherwise.
149
+ *
150
+ * @note if you wish to know if a descriptor has a callable `value`,
151
+ * `get`, or `set` function, use `is.callableDescriptor` instead.
152
+ *
153
+ * @example
154
+ * is.callable(function() {}); // true
155
+ */
156
+ callable(object) {
157
+ return this.function(object);
158
+ },
159
+
160
+ /**
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
164
+ * yields a function type, true is returned.
165
+ *
166
+ * @param object The object to check.
167
+ * @returns True if the object is callable, false otherwise.
168
+ *
169
+ * @example
170
+ * is.callable({ get: function() {} }); // true
171
+ * is.callable(123); // false
172
+ *
173
+ * // 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
178
+ */
179
+ callableDescriptor(object) {
180
+ const { value, get, set } = this.shiny(object) ? object : {};
181
+ return [value, get, set].some((val) => this.function(val));
182
+ },
183
+
184
+ /**
185
+ * Check if a value is a data property descriptor.
186
+ *
187
+ * A data descriptor is an object that describes the configuration of a
188
+ * property on an object, specifically focusing on the 'value' and
189
+ * 'writable' attributes. The descriptor is invalid if it contains
190
+ * thew accessor descriptors `get` or `set`.
191
+ *
192
+ * @param value The value to check.
193
+ * @returns True if the value is a data descriptor, false otherwise.
194
+ *
195
+ * @example
196
+ * // Returns true
197
+ * is.dataDescriptor({ value: 42, writable: true });
198
+ *
199
+ * // Returns false
200
+ * is.dataDescriptor({ get: () => 42, set: () => {} });
201
+ */
202
+ dataDescriptor(value) {
203
+ return (
204
+ this.descriptor(value) &&
205
+ (value?.value || value?.writable) &&
206
+ value?.get === undefined &&
207
+ value?.set === undefined
208
+ );
209
+ },
210
+
211
+ /**
212
+ * Check if a value is a property descriptor.
213
+ *
214
+ * A property descriptor is an object that describes the configuration of a
215
+ * property on an object. This function checks if the provided value is an
216
+ * object and contains any of the standard property descriptor keys.
217
+ *
218
+ * @param value The value to check.
219
+ * @returns True if the value is a property descriptor, false otherwise.
220
+ *
221
+ * @example
222
+ * is.descriptor({ configurable: true, enumerable: false }); // true
223
+ * is.descriptor({ get: () => {}, set: () => {} }); // true
224
+ * is.descriptor({}); // false
225
+ */
226
+ descriptor(value) {
227
+ if (!is.object(value)) {
228
+ return false;
229
+ }
230
+
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;
237
+ },
238
+
239
+ /**
240
+ * Checks if a value is strictly false.
241
+ *
242
+ * This method verifies if the provided value is strictly `false`.
243
+ *
244
+ * @param {*} value - The value to check.
245
+ * @returns {boolean} True if the value is strictly false, false otherwise.
246
+ *
247
+ * @example
248
+ * is.false(false); // true
249
+ * is.false(true); // false
250
+ * is.false(0); // false
251
+ */
252
+ false(value) {
253
+ return value === false
254
+ },
255
+
256
+ /**
257
+ * Checks if a value is falsy.
258
+ *
259
+ * This method converts the provided value to a boolean and returns
260
+ * `true` if the value is falsy (i.e., false, 0, "", null, undefined,
261
+ * or NaN).
262
+ *
263
+ * @param {*} value - The value to check.
264
+ * @returns {boolean} True if the value is falsy, false otherwise.
265
+ *
266
+ * @example
267
+ * is.falsy(0); // true
268
+ * is.falsy(""); // true
269
+ * is.falsy(1); // false
270
+ * is.falsy("hello"); // false
271
+ */
272
+ falsy(value) {
273
+ return !!!value
274
+ },
275
+
276
+ /**
277
+ * Alias for the `falsy` method.
278
+ *
279
+ * This method is an alias for `is.falsy` and performs the same check.
280
+ *
281
+ * @param {*} value - The value to check.
282
+ * @returns {boolean} True if the value is falsy, false otherwise.
283
+ *
284
+ * @example
285
+ * is.falsey(0); // true
286
+ * is.falsey(""); // true
287
+ * is.falsey(1); // false
288
+ * is.falsey("hello"); // false
289
+ */
290
+ falsey(value) {
291
+ return this.falsy(value)
292
+ },
293
+
294
+ /**
295
+ * Check if a value is a function.
296
+ *
297
+ * @param value The value to check.
298
+ * @returns True if the value is a function, false otherwise.
299
+ *
300
+ * @example
301
+ * is.function(function() {}); // true
302
+ * is.function(123); // false
303
+ */
304
+ function(value) {
305
+ return typeof value === "function" || value instanceof Function;
306
+ },
307
+
308
+ /**
309
+ * Check if a value is iterable. Depending on the environment, JavaScript
310
+ * will permit `'string'[Symbol.iterator]()` whereas in some places, you
311
+ * will need to wrap string in an object first. Since other JSVM provided
312
+ * environments may or may not be leniant with this, we play it safe by
313
+ * implicitly object converting values before checking for the symbol. If
314
+ * a value is already an object, it will simply be passed through.
315
+ *
316
+ * @param value The value to check.
317
+ * @returns True if the value is iterable, false otherwise.
318
+ *
319
+ * @example
320
+ * is.iterable([1, 2, 3]); // true
321
+ * is.iterable('string'); // true
322
+ * is.iterable(123); // false
323
+ */
324
+ iterable(value) {
325
+ const object = Object(value);
326
+ return object && Reflect.has(object, Symbol.iterator);
327
+ },
328
+
329
+ /**
330
+ * Check if a value is null or undefined.
331
+ *
332
+ * @param value The value to check.
333
+ * @returns True if the value is null or undefined, false otherwise.
334
+ *
335
+ * @example
336
+ * is.nullish(null); // true
337
+ * is.nullish(undefined); // true
338
+ * is.nullish('value'); // false
339
+ */
340
+ nullish(value) {
341
+ return value === null || value === undefined;
342
+ },
343
+
344
+ /**
345
+ * Check if a value is a number.
346
+ *
347
+ * @param value The value to check.
348
+ * @returns True if the value is a number, false otherwise.
349
+ *
350
+ * @example
351
+ * is.number(123); // true
352
+ * is.number('123'); // false
353
+ */
354
+ number(value) {
355
+ return typeof value === "number" || value instanceof Number;
356
+ },
357
+
358
+ /**
359
+ * Check if a value is an object.
360
+ *
361
+ * @param value The value to check.
362
+ * @returns True if the value is an object, false otherwise.
363
+ *
364
+ * @example
365
+ * is.object({}); // true
366
+ * is.object(null); // false
367
+ */
368
+ object(value) {
369
+ return !!(value && typeof value === "object");
370
+ },
371
+
372
+ /**
373
+ * Check if a value is a primitive type.
374
+ *
375
+ * This function determines if the provided value is one of the JavaScript
376
+ * primitive types: string, number, boolean, bigint, or symbol.
377
+ *
378
+ * @param value The value to check.
379
+ * @returns True if the value is a primitive type, false otherwise.
380
+ *
381
+ * @example
382
+ * // Returns true
383
+ * is.primitive('hello');
384
+ *
385
+ * // Returns true
386
+ * is.primitive(123);
387
+ *
388
+ * // Returns true
389
+ * is.primitive(true);
390
+ *
391
+ * // Returns true
392
+ * is.primitive(123n);
393
+ *
394
+ * // Returns true
395
+ * is.primitive(Symbol('symbol'));
396
+ *
397
+ * // Returns false
398
+ * is.primitive({});
399
+ *
400
+ * // Returns false
401
+ * is.primitive([]);
402
+ */
403
+ primitive(value) {
404
+ if (this.nullish(value))
405
+ return true
406
+
407
+ return ["string", "number", "boolean", "bigint", "symbol"].some(
408
+ (type) => typeof value === type
409
+ );
410
+ },
411
+
412
+ /**
413
+ * The use of `typeof` is not a safe guarantor when it comes to Reflect
414
+ * supported values. Any non-null value that returns a `typeof` either
415
+ * `object` or `function` should suffice. Note that arrays return 'object'
416
+ * when run through `typeof`. Shiny is clearly a reference to something
417
+ * reflective and is much shorter to type. Also, Mal says shiny. :)
418
+ *
419
+ * @param value The value to check.
420
+ * @returns True if the value is an object or a function, false otherwise.
421
+ *
422
+ * @example
423
+ * is.shiny({}); // true
424
+ * is.shiny(function() {}); // true
425
+ * is.shiny(123); // false
426
+ */
427
+ shiny(value) {
428
+ return !!(this.object(value) || this.function(value));
429
+ },
430
+
431
+ /**
432
+ * Check if a value is a string.
433
+ *
434
+ * @param value The value to check.
435
+ * @returns True if the value is a string, false otherwise.
436
+ *
437
+ * @example
438
+ * is.string('hello'); // true
439
+ * is.string(123); // false
440
+ */
441
+ string(value) {
442
+ return typeof value === "string" || value instanceof String;
443
+ },
444
+
445
+ /**
446
+ * Checks if a value is a symbol.
447
+ *
448
+ * This function determines whether the provided value is of type
449
+ * 'symbol' or an instance of the Symbol object.
450
+ *
451
+ * @param value - The value to check.
452
+ * @returns True if the value is a symbol, false otherwise.
453
+ *
454
+ * @example
455
+ * is.symbol(Symbol('foo')); // Returns true
456
+ * is.symbol('foo'); // Returns false
457
+ */
458
+ symbol(value) {
459
+ return typeof value === "symbol" || value instanceof Symbol;
460
+ },
461
+
462
+ /**
463
+ * Checks if a value is strictly true.
464
+ *
465
+ * This method verifies if the provided value is strictly `true`.
466
+ *
467
+ * @param {*} value - The value to check.
468
+ * @returns {boolean} True if the value is strictly true, false otherwise.
469
+ *
470
+ * @example
471
+ * is.true(true); // true
472
+ * is.true(false); // false
473
+ * is.true(1); // false
474
+ */
475
+ true(value) {
476
+ return value === true
477
+ },
478
+
479
+ /**
480
+ * Checks if a value is truthy.
481
+ *
482
+ * This method converts the provided value to a boolean and returns
483
+ * `true` if the value is truthy (i.e., not false, 0, "", null, undefined,
484
+ * or NaN).
485
+ *
486
+ * @param {*} value - The value to check.
487
+ * @returns {boolean} True if the value is truthy, false otherwise.
488
+ *
489
+ * @example
490
+ * is.truthy(1); // true
491
+ * is.truthy("hello"); // true
492
+ * is.truthy(0); // false
493
+ * is.truthy(""); // false
494
+ */
495
+ truthy(value) {
496
+ return !!value
497
+ },
498
+ };
499
+
500
+ export const si = {
501
+ /**
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.
506
+ *
507
+ * @param {*} value - The value to check.
508
+ * @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)
525
+ */
526
+ 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
530
+ },
531
+
532
+ /**
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: () => {} });
546
+ *
547
+ * // Returns false
548
+ * is.accessorDescriptor({ value: 42, writable: true });
549
+ */
550
+ 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
554
+ },
555
+
556
+ /**
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.
561
+ *
562
+ * @example
563
+ * is.array([1, 2, 3]); // true
564
+ * is.array('string'); // false
565
+ */
566
+ 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
+
571
+ },
572
+
573
+ /**
574
+ * Check if a value is a bigint.
575
+ *
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
582
+ */
583
+ 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
587
+ },
588
+
589
+ /**
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`.
593
+ *
594
+ * @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
602
+ */
603
+ 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
607
+ },
608
+
609
+ /**
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
621
+ */
622
+ 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
626
+ },
627
+
628
+ /**
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
646
+ */
647
+ 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
651
+ },
652
+
653
+ /**
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 });
667
+ *
668
+ * // Returns false
669
+ * is.dataDescriptor({ get: () => 42, set: () => {} });
670
+ */
671
+ 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
675
+ },
676
+
677
+ /**
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.
686
+ *
687
+ * @example
688
+ * is.descriptor({ configurable: true, enumerable: false }); // true
689
+ * is.descriptor({ get: () => {}, set: () => {} }); // true
690
+ * is.descriptor({}); // false
691
+ */
692
+ 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
696
+ },
697
+
698
+ /**
699
+ * Checks if a value is strictly false.
700
+ *
701
+ * This method verifies if the provided value is strictly `false`.
702
+ *
703
+ * @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
710
+ */
711
+ 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
715
+ },
716
+
717
+ /**
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).
723
+ *
724
+ * @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
732
+ */
733
+ 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
737
+ },
738
+
739
+ /**
740
+ * Alias for the `falsy` method.
741
+ *
742
+ * This method is an alias for `is.falsy` and performs the same check.
743
+ *
744
+ * @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
752
+ */
753
+ 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
757
+ },
758
+
759
+ /**
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.
764
+ *
765
+ * @example
766
+ * is.function(function() {}); // true
767
+ * is.function(123); // false
768
+ */
769
+ 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
773
+ },
774
+
775
+ /**
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.
782
+ *
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
790
+ */
791
+ 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
795
+ },
796
+
797
+ /**
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.
802
+ *
803
+ * @example
804
+ * is.nullish(null); // true
805
+ * is.nullish(undefined); // true
806
+ * is.nullish('value'); // false
807
+ */
808
+ 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
812
+ },
813
+
814
+ /**
815
+ * Check if a value is a number.
816
+ *
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
823
+ */
824
+ 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
828
+ },
829
+
830
+ /**
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.
835
+ *
836
+ * @example
837
+ * is.object({}); // true
838
+ * is.object(null); // false
839
+ */
840
+ 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
844
+ },
845
+
846
+ /**
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'));
870
+ *
871
+ * // Returns false
872
+ * is.primitive({});
873
+ *
874
+ * // Returns false
875
+ * is.primitive([]);
876
+ */
877
+ 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
881
+ },
882
+
883
+ /**
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.
892
+ *
893
+ * @example
894
+ * is.shiny({}); // true
895
+ * is.shiny(function() {}); // true
896
+ * is.shiny(123); // false
897
+ */
898
+ 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
902
+ },
903
+
904
+ /**
905
+ * Check if a value is a string.
906
+ *
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
913
+ */
914
+ 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
918
+ },
919
+
920
+ /**
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.
928
+ *
929
+ * @example
930
+ * is.symbol(Symbol('foo')); // Returns true
931
+ * is.symbol('foo'); // Returns false
932
+ */
933
+ 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
937
+ },
938
+
939
+ 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
944
+ },
945
+
946
+ /**
947
+ * Checks if a value is strictly true.
948
+ *
949
+ * This method verifies if the provided value is strictly `true`.
950
+ *
951
+ * @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
958
+ */
959
+ 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
963
+ },
964
+
965
+ /**
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).
971
+ *
972
+ * @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
980
+ */
981
+ 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
985
+ },
986
+ };
987
+
988
+ /**
989
+
990
+ * Checks if an object contains a specific key.
991
+ *
992
+ * This function determines if the provided object contains the specified key.
993
+ * It supports various types of objects including Map, Set, WeakMap, and
994
+ * WeakSet. For other objects, it uses the Reflect API to check for the key.
995
+ *
996
+ * @param object The object to check.
997
+ * @param key The key to look for in the object.
998
+ * @returns True if the object contains the key, false otherwise.
999
+ *
1000
+ * @example
1001
+ * // Returns true
1002
+ * has(new Map([['key', 'value']]), 'key');
1003
+ *
1004
+ * @example
1005
+ * // Returns false
1006
+ * has({}, 'key');
1007
+ */
1008
+ export const has = function has(object, key) {
1009
+ if ([Map, Set, WeakMap, WeakSet].some((i) => object instanceof i)) {
1010
+ return object.has(key);
1011
+ }
1012
+
1013
+ return is.shiny(object) && Reflect.has(object, key);
1014
+ };
1015
+
1016
+ Object.assign(has, {
1017
+ /**
1018
+ * Checks if an object contains all specified keys.
1019
+ *
1020
+ * This function determines if the provided object contains all the keys
1021
+ * specified in the keys array. It supports various types of objects
1022
+ * including Map, Set, WeakMap, and WeakSet. For other objects, it uses
1023
+ * the Reflect API to check for the keys.
1024
+ *
1025
+ * @param object The object to check.
1026
+ * @param keys The array of keys to look for in the object.
1027
+ * @returns True if the object contains all the keys, false otherwise.
1028
+ *
1029
+ * @example
1030
+ * // Returns true
1031
+ * has.all(new Map([
1032
+ * ['key1', 'value1'], ['key2', 'value2']
1033
+ * ]), ['key1', 'key2']);
1034
+ *
1035
+ * @example
1036
+ * // Returns false
1037
+ * has.all({}, ['key1', 'key2']);
1038
+ */
1039
+ all(object, keys) {
1040
+ if (!is.shiny(object) || !is.array(keys) || !keys.length) {
1041
+ return false;
1042
+ }
1043
+
1044
+ return keys.every((key) => has(object, key));
1045
+ },
1046
+
1047
+ /**
1048
+ * Checks if an object contains at least one of the specified keys.
1049
+ *
1050
+ * This function determines if the provided object contains at least one
1051
+ * of the keys specified in the keys array. It supports various types of
1052
+ * objects including Map, Set, WeakMap, and WeakSet. For other objects,
1053
+ * it uses the Reflect API to check for the keys.
1054
+ *
1055
+ * @param object The object to check.
1056
+ * @param keys The array of keys to look for in the object.
1057
+ * @returns True if the object contains at least one of the keys, false
1058
+ * otherwise.
1059
+ *
1060
+ * @example
1061
+ * // Returns true
1062
+ * has.some(new Map([['key1', 'value1'], ['key2', 'value2']]), ['key1']);
1063
+ *
1064
+ * @example
1065
+ * // Returns false
1066
+ * has.some({}, ['key1', 'key2']);
1067
+ */
1068
+ some(object, keys) {
1069
+ if (!is.shiny(object) || !is.array(keys) || !keys.length) {
1070
+ return false;
1071
+ }
1072
+
1073
+ return keys.some((key) => has(object, key));
1074
+ },
1075
+
1076
+ /**
1077
+ * Checks if an object has a 'prototype' property.
1078
+ *
1079
+ * This function is one way to determine if a supplied function is a big
1080
+ * arrow function or not. Regular functions and class functions, both
1081
+ * static and instance level, all have prototypes. Only big arrow functions
1082
+ * do not.
1083
+ *
1084
+ * @param {Object} object - The object to check.
1085
+ * @returns {boolean} True if the object has a 'prototype' property,
1086
+ * false otherwise.
1087
+ *
1088
+ * @example
1089
+ * // Returns true
1090
+ * has.prototype(function() {})
1091
+ *
1092
+ * @example
1093
+ * // Returns false
1094
+ * has.prototype(() => {})
1095
+ * has.prototype(5)
1096
+ * has.prototype(true)
1097
+ */
1098
+ prototype(object) {
1099
+ // Shiny objects work with calls to Reflect.has
1100
+ return is.shiny(object) && has(object, 'prototype')
1101
+ },
1102
+
1103
+ /**
1104
+ * Checks if an object has a custom string tag.
1105
+ *
1106
+ * This method determines if the object has a Symbol.toStringTag property,
1107
+ * which is used to customize the behavior of Object.prototype.toString().
1108
+ *
1109
+ * @param object - The object to check.
1110
+ * @returns True if the object has a custom string tag, false otherwise.
1111
+ *
1112
+ * @example
1113
+ * const obj = { [Symbol.toStringTag]: 'CustomObject' };
1114
+ * has.stringTag(obj); // Returns true
1115
+ */
1116
+ stringTag(object) {
1117
+ return is.object(object) && has(object, Symbol.toStringTag);
1118
+ },
1119
+
1120
+ /**
1121
+ * Checks if an object has a custom toPrimitive method.
1122
+ *
1123
+ * This method determines if the object has a Symbol.toPrimitive property,
1124
+ * which is used to convert an object to a primitive value.
1125
+ *
1126
+ * @param object - The object to check.
1127
+ * @returns True if the object has a custom toPrimitive method,
1128
+ * false otherwise.
1129
+ *
1130
+ * @example
1131
+ * const obj = { [Symbol.toPrimitive]: () => 42 };
1132
+ * has.toPrimitive(obj); // Returns true
1133
+ */
1134
+ toPrimitive(object) {
1135
+ return is.object(object) && has(object, Symbol.toPrimitive);
1136
+ },
1137
+
1138
+ /**
1139
+ * Checks if an object has a custom valueOf method.
1140
+ *
1141
+ * This method determines if the object has a valueOf property that is a
1142
+ * function, which is used to convert an object to a primitive value.
1143
+ *
1144
+ * @param object - The object to check.
1145
+ * @returns True if the object has a custom valueOf method, false otherwise.
1146
+ *
1147
+ * @example
1148
+ * const obj = { valueOf: () => 42 };
1149
+ * has.valueOf(obj); // Returns true
1150
+ */
1151
+ valueOfFn(object) {
1152
+ return (
1153
+ is.object(object) && has(object, "valueOf") && is.function(object.valueOf)
1154
+ );
1155
+ },
1156
+ });
1157
+
1158
+ export const as = {
1159
+ /**
1160
+ * Converts a value to an array if it is iterable.
1161
+ *
1162
+ * @param value The value to convert.
1163
+ * @returns The converted array if the value is iterable, otherwise undefined.
1164
+ *
1165
+ * @example
1166
+ * // Returns [1, 2, 3]
1167
+ * as.array([1, 2, 3]);
1168
+ *
1169
+ * @example
1170
+ * // Returns ['s', 't', 'r', 'i', 'n', 'g']
1171
+ * as.array('string');
1172
+ *
1173
+ * @example
1174
+ * // Returns undefined
1175
+ * as.array(123);
1176
+ */
1177
+ array(value) {
1178
+ return (is.iterable(value) && Array.from(value)) || undefined;
1179
+ },
1180
+
1181
+ /**
1182
+ * Converts a value to an object. If the supplied value is a primitive
1183
+ * value, in many cases, this will convert it to an object instance of
1184
+ * that type. Numbers, strings, symbols, and big integers, all have
1185
+ * object instance variants. Wrapping them in a call to `Object()` will
1186
+ * convert the primitive into this instance variant.
1187
+ *
1188
+ * @param value The value to convert.
1189
+ * @returns The converted object.
1190
+ *
1191
+ * @example
1192
+ * // Returns { key: 'value' }
1193
+ * as.object({ key: 'value' });
1194
+ *
1195
+ * @example
1196
+ * // String instance as oppposed to primitive string
1197
+ * typeof as.object('string') // 'object'
1198
+ * as.object('string') instanceof String // true
1199
+ * 'string' instanceof String // false
1200
+ *
1201
+ * @example
1202
+ * // Returns {}
1203
+ * as.object(null);
1204
+ */
1205
+ object(value) {
1206
+ return Object(value);
1207
+ },
1208
+
1209
+ /**
1210
+ * Converts a given value to a string. This function handles various types
1211
+ * of values, including null, undefined, objects with custom
1212
+ * [Symbol.toPrimitive] methods, and objects with toString or valueOf
1213
+ * methods.
1214
+ *
1215
+ * @param value The value to convert to a string.
1216
+ * @param use Optional configuration object:
1217
+ * - description: If true, returns the description of a Symbol.
1218
+ * - stringTag: If true, returns the [Symbol.toStringTag] value if present.
1219
+ * @returns The string representation of the value.
1220
+ *
1221
+ * @example
1222
+ * // Returns 'null'
1223
+ * as.string(null);
1224
+ *
1225
+ * @example
1226
+ * // Returns '123'
1227
+ * as.string(123);
1228
+ *
1229
+ * @example
1230
+ * // Returns 'custom'
1231
+ * const obj = {
1232
+ * [Symbol.toPrimitive](hint) {
1233
+ * if (hint === 'string') return 'custom';
1234
+ * return null;
1235
+ * }
1236
+ * };
1237
+ * as.string(obj);
1238
+ *
1239
+ * @example
1240
+ * // Returns 'mySymbol'
1241
+ * as.string(Symbol('mySymbol'), { description: true });
1242
+ *
1243
+ * @example
1244
+ * // Returns 'Array'
1245
+ * as.string([], { stringTag: true });
1246
+ */
1247
+ string(
1248
+ value,
1249
+ use = {
1250
+ description: false,
1251
+ stringTag: false,
1252
+ }
1253
+ ) {
1254
+ // Check if the value is null or undefined directly
1255
+ if (value === null || value === undefined) {
1256
+ return String(value);
1257
+ }
1258
+
1259
+ if (is.symbol(value) && use?.description) {
1260
+ return value.description;
1261
+ }
1262
+
1263
+ if (has.stringTag(value) && use?.stringTag) {
1264
+ return value[Symbol.toStringTag];
1265
+ }
1266
+
1267
+ // Check if the value has a [Symbol.toPrimitive] method
1268
+ if (is.function(value?.[Symbol.toPrimitive])) {
1269
+ const primitiveValue = value[Symbol.toPrimitive]("string");
1270
+ if (is.string(primitiveValue)) {
1271
+ return primitiveValue;
1272
+ }
1273
+ }
1274
+
1275
+ // Check if the value has a valueOf method
1276
+ if (is.function(value?.valueOf)) {
1277
+ const valueOfValue = value.valueOf();
1278
+ if (is.string(valueOfValue)) {
1279
+ return valueOfValue;
1280
+ }
1281
+ // If valueOf returns a primitive other than string, convert it to string
1282
+ if (!is.object(valueOfValue)) {
1283
+ return String(valueOfValue);
1284
+ }
1285
+ }
1286
+
1287
+ // Check if the value has a toString method
1288
+ if (is.function(value?.toString)) {
1289
+ const stringValue = value.toString();
1290
+ if (is.string(stringValue)) {
1291
+ return stringValue;
1292
+ }
1293
+ }
1294
+
1295
+ // Fallback to String() function
1296
+ return String(value);
1297
+ },
1298
+
1299
+ /**
1300
+ * Converts a given value to a string representing an integer.
1301
+ *
1302
+ * This method first converts the value to a number string and then extracts
1303
+ * the integer part by splitting the string at the decimal point.
1304
+ *
1305
+ * @param value The value to convert to an integer string.
1306
+ * @returns The integer part of the value as a string.
1307
+ *
1308
+ * @example
1309
+ * // Returns '123'
1310
+ * as.integerString(123.456);
1311
+ *
1312
+ * @example
1313
+ * // Returns '0'
1314
+ * as.integerString('0.789');
1315
+ */
1316
+ integerString(value) {
1317
+ return this.numberString(value).split(".")[0];
1318
+ },
1319
+
1320
+ /**
1321
+ * Converts a given value to a string representing a number.
1322
+ *
1323
+ * This method first converts the value to a string, trims any whitespace,
1324
+ * and removes any non-numeric characters except for '.', 'e', 'E', '+',
1325
+ * and '-'. It then uses a regular expression to match a floating-point
1326
+ * number, allowing an optional leading '+' or '-' sign, digits before
1327
+ * and after a single decimal point.
1328
+ *
1329
+ * @param value The value to convert to a number string.
1330
+ * @returns The sanitized number string or an empty string if no valid
1331
+ * float was found.
1332
+ *
1333
+ * @example
1334
+ * // Returns '123.456'
1335
+ * numberString(' 123.456abc ');
1336
+ *
1337
+ * @example
1338
+ * // Returns '-0.789'
1339
+ * numberString('-0.789xyz');
1340
+ */
1341
+ numberString(value) {
1342
+ // Trim the input string
1343
+
1344
+ const string = this.string(value)
1345
+ .trim()
1346
+ .replace(/[^0-9.eE+-]/g, "");
1347
+ // Use a regular expression to match a floating-point number
1348
+ // Allow an optional leading '+' or '-' sign, digits before and after a
1349
+ // single decimal point
1350
+ const sanitizedStr = string.match(/^[-+]?\d*\.?\d+([eE][-+]?\d+)?/);
1351
+
1352
+ // Return the sanitized string or an empty string if no valid float
1353
+ // was found
1354
+ return sanitizedStr ? sanitizedStr[0] : "";
1355
+ },
1356
+
1357
+ /**
1358
+ * Converts a given value to a number.
1359
+ *
1360
+ * This method uses the `numberString` method to sanitize the input value
1361
+ * and then converts it to a number.
1362
+ *
1363
+ * @param value The value to convert to a number.
1364
+ * @returns The numeric representation of the value.
1365
+ *
1366
+ * @example
1367
+ * // Returns 123.456
1368
+ * number('123.456abc');
1369
+ *
1370
+ * @example
1371
+ * // Returns -0.789
1372
+ * number('-0.789xyz');
1373
+ */
1374
+ number(value) {
1375
+ return Number(this.numberString(value));
1376
+ },
1377
+
1378
+ /**
1379
+ * Converts a given value to a bigint.
1380
+ *
1381
+ * This method uses the `integerString` method to sanitize the input value
1382
+ * and then converts it to a bigint.
1383
+ *
1384
+ * @param value The value to convert to a bigint.
1385
+ * @returns The bigint representation of the value.
1386
+ *
1387
+ * @example
1388
+ * // Returns 123n
1389
+ * bigint('123.456abc');
1390
+ *
1391
+ * @example
1392
+ * // Returns 0n
1393
+ * bigint('0.789xyz');
1394
+ */
1395
+ bigint(value) {
1396
+ const BigInt = globalThis?.BigInt;
1397
+ return BigInt(this.integerString(value));
1398
+ },
1399
+
1400
+ /**
1401
+ * Converts a given value to a boolean.
1402
+ *
1403
+ * This method takes a value, converts it to a string, and then checks
1404
+ * if it matches common representations of boolean values. It returns
1405
+ * `true` for "1", "yes", and "true" (case insensitive), and `false`
1406
+ * for "0", "no", and "false" (case insensitive). For any other values,
1407
+ * it returns the boolean representation of the value.
1408
+ *
1409
+ * @param {*} value - The value to convert to a boolean.
1410
+ * @returns {boolean} The boolean representation of the value.
1411
+ *
1412
+ * @example
1413
+ * // Returns true
1414
+ * is.boolean("yes")
1415
+ *
1416
+ * @example
1417
+ * // Returns false
1418
+ * is.boolean("no")
1419
+ *
1420
+ * @example
1421
+ * // Returns true
1422
+ * is.boolean(1)
1423
+ *
1424
+ * @example
1425
+ * // Returns false
1426
+ * is.boolean(0)
1427
+ *
1428
+ * @example
1429
+ * // Returns true
1430
+ * is.boolean("true")
1431
+ *
1432
+ * @example
1433
+ * // Returns false
1434
+ * is.boolean("false")
1435
+ *
1436
+ * @example
1437
+ * // Returns true
1438
+ * is.boolean({})
1439
+ *
1440
+ * @example
1441
+ * // Returns false
1442
+ * is.boolean(null)
1443
+ */
1444
+ boolean(value) {
1445
+ switch (String(value).toLowerCase()) {
1446
+ case "1":
1447
+ case "yes":
1448
+ case "true":
1449
+ return true
1450
+
1451
+ case "0":
1452
+ case "no":
1453
+ case "false":
1454
+ return false
1455
+
1456
+ default:
1457
+ return Boolean(value)
1458
+ }
1459
+ },
1460
+ };
1461
+
1462
+ export function createToolkit() {
1463
+ return { si, is, has, as }
1464
+ }
1465
+
1466
+ export default {
1467
+ is,
1468
+ si,
1469
+ has,
1470
+ as,
1471
+ }