@magic/types 0.1.38 → 0.1.40
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.
- package/README.md +151 -25
- package/package.json +10 -9
- package/src/deep/index.js +2 -2
- package/src/fns.js +83 -0
- package/src/index.js +1 -0
- package/src/lib.js +117 -1
- package/types/fns.d.ts +9 -0
- package/types/index.d.ts +20 -1
- package/types/lib.d.ts +28 -1
package/README.md
CHANGED
|
@@ -45,6 +45,19 @@ import is from '@magic/types'
|
|
|
45
45
|
is.array([]) // true
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
+
##### import deep
|
|
49
|
+
|
|
50
|
+
```javascript
|
|
51
|
+
import { deep } from '@magic/types'
|
|
52
|
+
|
|
53
|
+
deep.isDeepEqual([1, 2, 3], [1, 2, 3]) // true
|
|
54
|
+
// also: deep.deepEqual, deep.deepEq, is.isDeepEqual
|
|
55
|
+
deep.isDeepDifferent([1, 2, 3], [1, 2, 3]) // false
|
|
56
|
+
// also: deep.deepDifferent, deep.deepDiff, is.isDeepDifferent
|
|
57
|
+
deep.isEqual([1, 2, 3], [1, 2, 3]) // true
|
|
58
|
+
// also: is.deep.isEqual, is.deep.equal, is.deep.eq
|
|
59
|
+
```
|
|
60
|
+
|
|
48
61
|
##### functions
|
|
49
62
|
|
|
50
63
|
```javascript
|
|
@@ -52,13 +65,20 @@ is.array([]) // true
|
|
|
52
65
|
// comparisons
|
|
53
66
|
|
|
54
67
|
// test a value for multiple types
|
|
55
|
-
is(ele, ...types)
|
|
56
|
-
// alias is.
|
|
68
|
+
is.is(ele, ...types)
|
|
69
|
+
// alias is.type, is.testType, is.types, test
|
|
57
70
|
|
|
58
71
|
// test if a value is not of a type
|
|
59
72
|
not(ele, ...types)
|
|
60
73
|
// alias is.neq, isNeq, isNot
|
|
61
74
|
|
|
75
|
+
// not (and is.not) is also a namespace with negated versions of every check:
|
|
76
|
+
is.not.array([]) // false
|
|
77
|
+
is.not.len.eq('abc', 'def') // false
|
|
78
|
+
is.not.case.upper('lowercase') // true
|
|
79
|
+
is.not.deep.eq([1], [1]) // false
|
|
80
|
+
is.not.ip.v4('192.168.1.1') // false
|
|
81
|
+
|
|
62
82
|
isSameType('string', 'string')
|
|
63
83
|
// alias isSame, is.same, is.sameType
|
|
64
84
|
|
|
@@ -74,7 +94,7 @@ isBoolean(true) // true
|
|
|
74
94
|
isDefined(undefined) //false
|
|
75
95
|
// alias isDef, is.defined, is.def
|
|
76
96
|
|
|
77
|
-
isUndefined(undefined) //
|
|
97
|
+
isUndefined(undefined) //true
|
|
78
98
|
// alias isUndef, is.undefined, is.undef
|
|
79
99
|
|
|
80
100
|
isFunction(() => {}) // true
|
|
@@ -84,7 +104,7 @@ isAsyncFunction(async () => {}) // true
|
|
|
84
104
|
// alias isAsyncFunc, isAsyncFn, is.asyncFunction, is.asyncFunc, is.asyncFn
|
|
85
105
|
|
|
86
106
|
isGeneratorFunction(* () => {}) // true
|
|
87
|
-
// alias isGeneratorFunc,
|
|
107
|
+
// alias isGeneratorFunc, isGeneratorFn, isGenerator, is.generatorFunction, is.generatorFunc, is.generatorFn, generator, generatorFn, generatorFunc, generatorFunction
|
|
88
108
|
|
|
89
109
|
isNumber(1) // true
|
|
90
110
|
// alias isNum, is.number, is.num
|
|
@@ -98,21 +118,41 @@ isFloat(1.1) // true
|
|
|
98
118
|
isObject({}) // true
|
|
99
119
|
// alias isObj, is.object, is.obj
|
|
100
120
|
|
|
121
|
+
isObjectNative({}) // true
|
|
122
|
+
isObjectNative([]) // false
|
|
123
|
+
// alias is.objectNative
|
|
124
|
+
|
|
101
125
|
isString('') // true
|
|
102
126
|
// alias isStr, is.string, is.str
|
|
103
127
|
|
|
104
128
|
isRGBAObject({ r: 1, g: 1, b: 1, a: 1 }) // true
|
|
105
129
|
// alias isRGBA, is.rgbaObject, is.rgba
|
|
106
130
|
|
|
107
|
-
isRGBObject
|
|
131
|
+
isRGBObject({ r: 1, g: 1, b: 1 }) // true
|
|
108
132
|
// alias isRGB, is.rgbObject, is.rgb
|
|
109
133
|
|
|
134
|
+
isRGBValue({ r: 1, g: 1, b: 1 }) // true
|
|
135
|
+
// alias isRGBObject, is.rgbValue
|
|
136
|
+
|
|
137
|
+
isRGBAValue({ r: 1, g: 1, b: 1, a: 1 }) // true
|
|
138
|
+
// alias isRGBAObject, is.rgbaValue
|
|
139
|
+
|
|
110
140
|
isHexColor('#333') // true
|
|
111
141
|
// alias isHex, is.hex, is.hexColor
|
|
112
142
|
|
|
143
|
+
isHexColor3('#333') // true
|
|
144
|
+
isHexColor4('#3333') // true
|
|
145
|
+
isHexColor6('#333333') // true
|
|
146
|
+
isHexColor8('#33333333') // true
|
|
147
|
+
// aliases is.hex3, is.hexColor3, is.hex4, is.hexColor4, is.hex6, is.hexColor6, is.hex8, is.hexColor8
|
|
148
|
+
|
|
113
149
|
isHexAlphaColor('#3333') // true
|
|
114
150
|
// alias isHexa, is.hexa, is.hexAlphaColor
|
|
115
151
|
|
|
152
|
+
isHexAlphaColor4('#3333') // true
|
|
153
|
+
isHexAlphaColor8('#33333333') // true
|
|
154
|
+
// aliases is.hexa4, is.hexAlphaColor4, is.hexa8, is.hexAlphaColor8
|
|
155
|
+
|
|
116
156
|
isColor('#444') // true
|
|
117
157
|
// alias isCol, is.color, is.col
|
|
118
158
|
|
|
@@ -135,52 +175,89 @@ isError(new Error('')) // true
|
|
|
135
175
|
// alias isErr, is.error, is.err
|
|
136
176
|
|
|
137
177
|
isIterable([]) // true
|
|
138
|
-
// alias is.iterable
|
|
178
|
+
// alias is.iterable, is.iter, isIter
|
|
139
179
|
|
|
140
180
|
isEmail('a@b.c') // true
|
|
141
181
|
// alias isMail, is.email, is.mail
|
|
142
182
|
|
|
183
|
+
isIP('192.168.1.1') // true
|
|
184
|
+
isIP('::1') // true
|
|
185
|
+
// alias ip, is.ip, isIp, isIP
|
|
186
|
+
|
|
187
|
+
isIp('192.168.1.1') // true
|
|
188
|
+
isIp('::1') // true
|
|
189
|
+
// alias ip, is.ip
|
|
190
|
+
|
|
191
|
+
isIp.v4('192.168.1.1') // true
|
|
192
|
+
isIp.v6('::1') // true
|
|
193
|
+
|
|
194
|
+
isIPv4('192.168.1.1') // true
|
|
195
|
+
// aliases ipV4, is.ipV4, is.ipv4, is.v4
|
|
196
|
+
|
|
197
|
+
isIPv6('::1') // true
|
|
198
|
+
// aliases ipV6, is.ipV6, is.ipv6, is.v6
|
|
199
|
+
|
|
200
|
+
isMap(new Map()) // true
|
|
201
|
+
// alias is.map, is.map, map
|
|
202
|
+
|
|
203
|
+
isSet(new Set()) // true
|
|
204
|
+
// alias is.set, is.set, set
|
|
205
|
+
|
|
206
|
+
isWeakMap(new WeakMap()) // true
|
|
207
|
+
// alias is.weakMap, is.weakMap, weakMap
|
|
208
|
+
|
|
209
|
+
isWeakSet(new WeakSet()) // true
|
|
210
|
+
// alias is.weakSet, is.weakSet, weakSet
|
|
211
|
+
|
|
143
212
|
isNull(null) // true
|
|
144
213
|
// alias isNil, is.nil, is.null
|
|
145
214
|
|
|
146
215
|
isUndefinedOrNull(undefined || null) // true
|
|
147
216
|
// alias is.undefinedOrNull, is.undefinedOrNil, is.undefOrNull, is.undefOrNil
|
|
148
217
|
|
|
149
|
-
isBuffer(
|
|
218
|
+
isBuffer(Buffer.from('test')) // true
|
|
150
219
|
// alias isBuff, is.buffer, is.buff
|
|
151
220
|
|
|
152
|
-
isPromise(new Promise()) // true
|
|
221
|
+
isPromise(new Promise(r => r())) // true
|
|
153
222
|
// alias is.promise, isThenable, isThen, is.thenable, is.then
|
|
154
223
|
|
|
155
|
-
//
|
|
156
|
-
|
|
224
|
+
// (call with a function's arguments object)
|
|
225
|
+
(function () {
|
|
226
|
+
isArguments(arguments) // true
|
|
227
|
+
})()
|
|
157
228
|
// alias isArgs, is.arguments, is.args
|
|
158
229
|
|
|
159
230
|
isUUID(uuid) // true
|
|
160
231
|
// alias is.uuid
|
|
161
232
|
|
|
162
|
-
|
|
163
|
-
// alias is.type
|
|
233
|
+
isType(42, 'number') // true
|
|
234
|
+
// alias is.type, is.testType, isType
|
|
164
235
|
|
|
165
|
-
test(42, ['string', 'object']) // false
|
|
236
|
+
is.test(42, ['string', 'object']) // false
|
|
166
237
|
// alias is.types
|
|
167
238
|
|
|
168
|
-
|
|
239
|
+
is.eq('abc', 'def') // true
|
|
169
240
|
// alias is.eq
|
|
241
|
+
// is.eq compares lengths, see "length" section below
|
|
170
242
|
|
|
171
|
-
isNot = isNeq = is.not(42, '
|
|
243
|
+
isNot = isNeq = is.not(42, 'string') // true
|
|
172
244
|
// alias is.neq
|
|
173
245
|
|
|
174
|
-
isDeepEqual([1, 2, 3], [1, 2, 3]) // true
|
|
246
|
+
deep.isDeepEqual([1, 2, 3], [1, 2, 3]) // true
|
|
175
247
|
// alias is.deep.eq, is.deep.equal
|
|
176
|
-
|
|
248
|
+
// also deep.deepEqual, deep.deepEq, is.isDeepEqual
|
|
249
|
+
deep.isDeepDifferent([1, 2, 3], [1, 2, 3]) // false
|
|
177
250
|
// alias is.deep.diff, is.deep.different
|
|
251
|
+
// also deep.deepDifferent, deep.deepDiff, is.isDeepDifferent
|
|
252
|
+
|
|
253
|
+
deep.isDifferent([1, 2, 3], [1, 2, 3]) // false
|
|
254
|
+
// alias is.deep.isDifferent, is.deep.different, is.deep.diff
|
|
178
255
|
|
|
179
|
-
isDeepEqual([1, 2, 3], [3, 2, 1]) // true
|
|
180
|
-
isDeepEqual([1, 2, 3], [3, 2, 1], { strict: true }) // false
|
|
256
|
+
deep.isDeepEqual([1, 2, 3], [3, 2, 1]) // true
|
|
257
|
+
deep.isDeepEqual([1, 2, 3], [3, 2, 1], { strict: true }) // false
|
|
181
258
|
|
|
182
|
-
isDeepEqual({a: 1, b: 2, c: 3 }, { c: 3, b: 2, a: 1 }) // true
|
|
183
|
-
isDeepEqual({a: 1, b: 2, c: 3 }, { c: 3, b: 2, a: 1 }, { strict: true }) // false
|
|
259
|
+
deep.isDeepEqual({a: 1, b: 2, c: 3 }, { c: 3, b: 2, a: 1 }) // true
|
|
260
|
+
deep.isDeepEqual({a: 1, b: 2, c: 3 }, { c: 3, b: 2, a: 1 }, { strict: true }) // false
|
|
184
261
|
|
|
185
262
|
isEvery([1, 2, 3], 'number') // true
|
|
186
263
|
isEvery([1, 2, 3], is.number) // true
|
|
@@ -190,7 +267,7 @@ isSome([1, 'str', {}], 'number') // true
|
|
|
190
267
|
isSome([1, 'str', {}], is.number) // true
|
|
191
268
|
// alias is.some
|
|
192
269
|
|
|
193
|
-
isSymbol(Symbol('testing)) // true
|
|
270
|
+
isSymbol(Symbol('testing')) // true
|
|
194
271
|
// alias is.symbol, is.sym
|
|
195
272
|
|
|
196
273
|
isNone([1, 2, 3], 'string') // true
|
|
@@ -205,10 +282,10 @@ isCase('lowercase', 'low') // true
|
|
|
205
282
|
// alias is.case
|
|
206
283
|
|
|
207
284
|
isUpperCase('UPPERCASE') // true
|
|
208
|
-
// alias is.case.upper,
|
|
285
|
+
// alias is.case.upper, isCase.upper
|
|
209
286
|
|
|
210
287
|
isLowerCase('lowercase') // true
|
|
211
|
-
// alias is.case.lower,
|
|
288
|
+
// alias is.case.lower, isCase.lower
|
|
212
289
|
|
|
213
290
|
isMergeableObject({}) // true
|
|
214
291
|
// alias is.mergeable, is.mergeableObject, isMergeable
|
|
@@ -217,9 +294,47 @@ const mod = await import('path/to/file')
|
|
|
217
294
|
isModule(mod) // true
|
|
218
295
|
// alias is.module
|
|
219
296
|
|
|
297
|
+
isComparable(1) // true
|
|
298
|
+
isComparable('str') // true
|
|
299
|
+
isComparable(true) // true
|
|
300
|
+
isComparable({}) // false
|
|
301
|
+
// aliases is.comparable, is.Comparable
|
|
302
|
+
|
|
220
303
|
isOwnProp({ test: undefined }, 'test') // true
|
|
221
304
|
// alias isOwnProperty, is.ownProperty, is.ownProp, is.prop
|
|
222
305
|
|
|
306
|
+
// length
|
|
307
|
+
|
|
308
|
+
// get the length of a string, array, map, set, regexp, or object
|
|
309
|
+
// numbers return themselves
|
|
310
|
+
getLength('test') // 4
|
|
311
|
+
getLength([1, 2, 3]) // 3
|
|
312
|
+
getLength(new Set([1, 2])) // 2
|
|
313
|
+
getLength(123) // 123
|
|
314
|
+
// aliases is.len, is.count, is.length, is.ln
|
|
315
|
+
|
|
316
|
+
// compare lengths, both arguments can be anything with a length
|
|
317
|
+
// these can also be curried: is.gt('abcd')('ab') // true
|
|
318
|
+
is.eq('abc', 'def') // true
|
|
319
|
+
is.gt('abcd', 'ab') // true
|
|
320
|
+
is.gte('abc', 'ab') // true
|
|
321
|
+
is.lt('ab', 'abc') // true
|
|
322
|
+
is.lte('abc', 'abc') // true
|
|
323
|
+
// aliases is.equal, is.greater, is.bigger, is.greaterequal, is.biggerequal,
|
|
324
|
+
// is.gteq, is.lower, is.smaller, is.lowerequal, is.smallerequal, is.lteq
|
|
325
|
+
|
|
326
|
+
isLengthEqual('abc', 3) // true
|
|
327
|
+
isLengthGreater('abc', 2) // true
|
|
328
|
+
isLengthGreaterOrEqual('ab', 2) // true
|
|
329
|
+
isLengthSmaller('ab', 3) // true
|
|
330
|
+
isLengthSmallerOrEqual('abc', 3) // true
|
|
331
|
+
// aliases is.isLengthEqual, is.isLengthGreater, is.isLengthGreaterOrEqual,
|
|
332
|
+
// is.isLengthSmaller, is.isLengthSmallerOrEqual
|
|
333
|
+
|
|
334
|
+
compareCount('abc', 3) // true
|
|
335
|
+
|
|
336
|
+
// the length functions also exist as methods on the length checks:
|
|
337
|
+
is.len.eq('abc', 'def') // true
|
|
223
338
|
```
|
|
224
339
|
|
|
225
340
|
#### Changelog
|
|
@@ -407,6 +522,17 @@ update dependencies
|
|
|
407
522
|
- remove recursive dependencies
|
|
408
523
|
- update dependencies
|
|
409
524
|
|
|
410
|
-
##### 0.1.39
|
|
525
|
+
##### 0.1.39
|
|
526
|
+
|
|
527
|
+
- add isIp and variants to allow ip v4 and v6 checks
|
|
528
|
+
- update dependencies
|
|
529
|
+
|
|
530
|
+
##### 0.1.40
|
|
531
|
+
|
|
532
|
+
- add is.not negations of all type functions
|
|
533
|
+
- update docs
|
|
534
|
+
- update dependencies
|
|
535
|
+
|
|
536
|
+
##### 0.1.41 - unreleased
|
|
411
537
|
|
|
412
538
|
...
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@magic/types",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.40",
|
|
4
4
|
"author": "Wizards & Witches",
|
|
5
5
|
"homepage": "https://github.com/magic/types",
|
|
6
6
|
"license": "AGPL-3.0",
|
|
@@ -27,7 +27,8 @@
|
|
|
27
27
|
"format": "f -w --exclude docs",
|
|
28
28
|
"format:check": "f --exclude docs",
|
|
29
29
|
"calls": "calls",
|
|
30
|
-
"lint": "tsc --noEmit"
|
|
30
|
+
"lint": "tsc --noEmit",
|
|
31
|
+
"lint:test": "tsc --noEmit -p tsconfig.test.json"
|
|
31
32
|
},
|
|
32
33
|
"engines": {
|
|
33
34
|
"node": ">=18"
|
|
@@ -50,10 +51,10 @@
|
|
|
50
51
|
"@magic-modules/no-spy": "0.0.9",
|
|
51
52
|
"@magic-modules/pre": "0.0.12",
|
|
52
53
|
"@magic-themes/docs": "0.0.15",
|
|
53
|
-
"@magic/core": "0.0.
|
|
54
|
-
"@magic/format": "0.0.
|
|
55
|
-
"@magic/test": "0.3.
|
|
56
|
-
"typescript": "
|
|
54
|
+
"@magic/core": "0.0.160",
|
|
55
|
+
"@magic/format": "0.0.75",
|
|
56
|
+
"@magic/test": "0.3.32",
|
|
57
|
+
"typescript": "npm:@typescript/typescript6"
|
|
57
58
|
},
|
|
58
59
|
"keywords": [
|
|
59
60
|
"magic",
|
|
@@ -67,10 +68,10 @@
|
|
|
67
68
|
}
|
|
68
69
|
],
|
|
69
70
|
"dependencies": {
|
|
70
|
-
"@types/node": "26.
|
|
71
|
+
"@types/node": "26.6.3"
|
|
71
72
|
},
|
|
72
73
|
"allowScripts": {
|
|
73
|
-
"@
|
|
74
|
-
"
|
|
74
|
+
"canvas@3.2.3": true,
|
|
75
|
+
"@swc/core@1.15.46": true
|
|
75
76
|
}
|
|
76
77
|
}
|
package/src/deep/index.js
CHANGED
package/src/fns.js
CHANGED
|
@@ -631,3 +631,86 @@ export const isModule = s => Object.prototype.toString.call(s) === '[object Modu
|
|
|
631
631
|
export const isCase = (s, c = 'up') => (c === 'up' ? isUpperCase(s) : isLowerCase(s))
|
|
632
632
|
isCase.upper = isUpperCase
|
|
633
633
|
isCase.lower = isLowerCase
|
|
634
|
+
|
|
635
|
+
/**
|
|
636
|
+
* Check if a value is a valid IPv4 address
|
|
637
|
+
* @param {unknown} a - value to check
|
|
638
|
+
* @returns {boolean} - true if value is an IPv4 address
|
|
639
|
+
*/
|
|
640
|
+
export const isIPv4 = a => {
|
|
641
|
+
if (!isString(a)) return false
|
|
642
|
+
const parts = a.split('.')
|
|
643
|
+
if (parts.length !== 4) return false
|
|
644
|
+
return parts.every(part => {
|
|
645
|
+
const num = Number(part)
|
|
646
|
+
return /^(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])$/.test(part) && String(num) === part
|
|
647
|
+
})
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* Check if a value is a valid IPv6 address
|
|
652
|
+
* @param {unknown} a - value to check
|
|
653
|
+
* @returns {boolean} - true if value is an IPv6 address
|
|
654
|
+
*/
|
|
655
|
+
export const isIPv6 = a => {
|
|
656
|
+
if (!isString(a)) {
|
|
657
|
+
return false
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
const str = a.toLowerCase()
|
|
661
|
+
|
|
662
|
+
// Handle IPv4-mapped IPv6 (::ffff:192.168.1.1)
|
|
663
|
+
if (str.includes('.')) {
|
|
664
|
+
const lastColon = str.lastIndexOf(':')
|
|
665
|
+
const ipv4Part = str.slice(lastColon + 1)
|
|
666
|
+
if (!isIPv4(ipv4Part)) {
|
|
667
|
+
return false
|
|
668
|
+
}
|
|
669
|
+
const beforeIpv4 = str.slice(0, lastColon)
|
|
670
|
+
// Should be ::ffff: or similar, and rest should be empty or valid hex
|
|
671
|
+
const colonCount = beforeIpv4.split(':').length - 1
|
|
672
|
+
return colonCount <= 2 && (beforeIpv4 === '::ffff' || beforeIpv4 === ':' || beforeIpv4 === '')
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
// Handle :: compression
|
|
676
|
+
const doubleColon = str.indexOf('::')
|
|
677
|
+
if (doubleColon !== -1) {
|
|
678
|
+
const parts = str.split('::')
|
|
679
|
+
if (parts.length !== 2) {
|
|
680
|
+
return false
|
|
681
|
+
}
|
|
682
|
+
const leftParts = parts[0] ? parts[0].split(':') : []
|
|
683
|
+
const rightParts = parts[1] ? parts[1].split(':') : []
|
|
684
|
+
const totalGroups = leftParts.length + rightParts.length
|
|
685
|
+
if (totalGroups > 7) {
|
|
686
|
+
return false
|
|
687
|
+
}
|
|
688
|
+
const emptyParts =
|
|
689
|
+
leftParts.filter(p => p === '').length + rightParts.filter(p => p === '').length
|
|
690
|
+
if (emptyParts > 1) {
|
|
691
|
+
return false
|
|
692
|
+
}
|
|
693
|
+
const allValid = [...leftParts, ...rightParts].every(p => p === '' || /^[0-9a-f]{1,4}$/.test(p))
|
|
694
|
+
return allValid
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
// Full form: 8 groups of 1-4 hex digits
|
|
698
|
+
const parts = str.split(':')
|
|
699
|
+
if (parts.length !== 8) {
|
|
700
|
+
return false
|
|
701
|
+
}
|
|
702
|
+
return parts.every(part => /^[0-9a-f]{1,4}$/.test(part))
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
/**
|
|
706
|
+
* Check if a value is a valid IP address (v4 or v6)
|
|
707
|
+
* @param {unknown} a - value to check
|
|
708
|
+
* @returns {boolean} - true if value is an IP address
|
|
709
|
+
*/
|
|
710
|
+
export const isIp = a => isIPv4(a) || isIPv6(a)
|
|
711
|
+
isIp.v4 = isIPv4
|
|
712
|
+
isIp.v6 = isIPv6
|
|
713
|
+
|
|
714
|
+
export const ipV4 = isIPv4
|
|
715
|
+
|
|
716
|
+
export const ipV6 = isIPv6
|
package/src/index.js
CHANGED
package/src/lib.js
CHANGED
|
@@ -30,6 +30,16 @@ import * as deep from './deep/index.js'
|
|
|
30
30
|
* }} EnhancedLengthFunction
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* The `is.not` namespace: the original `isNot` check function, extended at
|
|
35
|
+
* runtime (by `addNotFunctions`) with a negated version of every `is.*` check
|
|
36
|
+
* and their nested sub-checks (e.g. `.upper`, `.eq`, `.v4`, `deep`). Each
|
|
37
|
+
* added property is either a negated check function or an object of them.
|
|
38
|
+
* @typedef {((e: unknown, ...types: string[]) => boolean) & {
|
|
39
|
+
* [key: string]: any
|
|
40
|
+
* }} NotNamespace
|
|
41
|
+
*/
|
|
42
|
+
|
|
33
43
|
// Create enhanced length functions with comparison methods
|
|
34
44
|
const lengthFunctions = {
|
|
35
45
|
eq: fns.isLengthEqual,
|
|
@@ -126,7 +136,7 @@ export const is = /** @type {const} */ {
|
|
|
126
136
|
empty: fns.isEmpty,
|
|
127
137
|
|
|
128
138
|
isNot: fns.isNot,
|
|
129
|
-
not: fns.isNot,
|
|
139
|
+
not: /** @type {NotNamespace} */ (fns.isNot),
|
|
130
140
|
isNeq: fns.isNot,
|
|
131
141
|
neq: fns.isNot,
|
|
132
142
|
|
|
@@ -315,6 +325,18 @@ export const is = /** @type {const} */ {
|
|
|
315
325
|
isLowerCase: fns.isLowerCase,
|
|
316
326
|
lowerCase: fns.isLowerCase,
|
|
317
327
|
|
|
328
|
+
isIp: fns.isIp,
|
|
329
|
+
ip: fns.isIp,
|
|
330
|
+
isIPv4: fns.isIPv4,
|
|
331
|
+
ipv4: fns.isIPv4,
|
|
332
|
+
v4: fns.isIPv4,
|
|
333
|
+
isIPv6: fns.isIPv6,
|
|
334
|
+
ipv6: fns.isIPv6,
|
|
335
|
+
v6: fns.isIPv6,
|
|
336
|
+
|
|
337
|
+
ipV4: fns.ipV4,
|
|
338
|
+
ipV6: fns.ipV6,
|
|
339
|
+
|
|
318
340
|
same: fns.isSameType,
|
|
319
341
|
sameType: fns.isSameType,
|
|
320
342
|
isSameType: fns.isSameType,
|
|
@@ -331,4 +353,98 @@ export const is = /** @type {const} */ {
|
|
|
331
353
|
...deep,
|
|
332
354
|
}
|
|
333
355
|
|
|
356
|
+
/**
|
|
357
|
+
* Negation helper: creates a function that returns the logical NOT of fn
|
|
358
|
+
* @param {any} fn - function to negate
|
|
359
|
+
* @returns {(...args: any[]) => boolean} - negated function
|
|
360
|
+
*/
|
|
361
|
+
const negate =
|
|
362
|
+
fn =>
|
|
363
|
+
(...args) =>
|
|
364
|
+
!fn(...args)
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Add negated functions to the existing is.not namespace
|
|
368
|
+
* @param {any} obj - source object (the is namespace)
|
|
369
|
+
* @param {any} target - target object (the is.not namespace)
|
|
370
|
+
*/
|
|
371
|
+
const addNotFunctions = (obj, target) => {
|
|
372
|
+
// Skip certain properties that shouldn't be copied
|
|
373
|
+
const skipKeys = new Set(['length', 'name', 'prototype', 'caller', 'callee', 'arguments'])
|
|
374
|
+
|
|
375
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
376
|
+
if (key === 'not' || skipKeys.has(key)) continue
|
|
377
|
+
if (fns.isFunction(value)) {
|
|
378
|
+
target[key] = negate(value)
|
|
379
|
+
// Handle function sub-properties (e.g., isCase.upper, isIp.v4)
|
|
380
|
+
if (value.upper) {
|
|
381
|
+
target[key].upper = negate(value.upper)
|
|
382
|
+
}
|
|
383
|
+
if (value.lower) {
|
|
384
|
+
target[key].lower = negate(value.lower)
|
|
385
|
+
}
|
|
386
|
+
if (value.v4) {
|
|
387
|
+
target[key].v4 = negate(value.v4)
|
|
388
|
+
}
|
|
389
|
+
if (value.v6) {
|
|
390
|
+
target[key].v6 = negate(value.v6)
|
|
391
|
+
}
|
|
392
|
+
// Handle all length comparison functions
|
|
393
|
+
if (value.eq) {
|
|
394
|
+
target[key].eq = negate(value.eq)
|
|
395
|
+
}
|
|
396
|
+
if (value.equal) {
|
|
397
|
+
target[key].equal = negate(value.equal)
|
|
398
|
+
}
|
|
399
|
+
if (value.gt) {
|
|
400
|
+
target[key].gt = negate(value.gt)
|
|
401
|
+
}
|
|
402
|
+
if (value.bigger) {
|
|
403
|
+
target[key].bigger = negate(value.bigger)
|
|
404
|
+
}
|
|
405
|
+
if (value.biggerequal) {
|
|
406
|
+
target[key].biggerequal = negate(value.biggerequal)
|
|
407
|
+
}
|
|
408
|
+
if (value.greater) {
|
|
409
|
+
target[key].greater = negate(value.greater)
|
|
410
|
+
}
|
|
411
|
+
if (value.greaterequal) {
|
|
412
|
+
target[key].greaterequal = negate(value.greaterequal)
|
|
413
|
+
}
|
|
414
|
+
if (value.gte) {
|
|
415
|
+
target[key].gte = negate(value.gte)
|
|
416
|
+
}
|
|
417
|
+
if (value.gteq) {
|
|
418
|
+
target[key].gteq = negate(value.gteq)
|
|
419
|
+
}
|
|
420
|
+
if (value.lower) {
|
|
421
|
+
target[key].lower = negate(value.lower)
|
|
422
|
+
}
|
|
423
|
+
if (value.smaller) {
|
|
424
|
+
target[key].smaller = negate(value.smaller)
|
|
425
|
+
}
|
|
426
|
+
if (value.lt) {
|
|
427
|
+
target[key].lt = negate(value.lt)
|
|
428
|
+
}
|
|
429
|
+
if (value.lowerequal) {
|
|
430
|
+
target[key].lowerequal = negate(value.lowerequal)
|
|
431
|
+
}
|
|
432
|
+
if (value.smallerequal) {
|
|
433
|
+
target[key].smallerequal = negate(value.smallerequal)
|
|
434
|
+
}
|
|
435
|
+
if (value.lte) {
|
|
436
|
+
target[key].lte = negate(value.lte)
|
|
437
|
+
}
|
|
438
|
+
if (value.lteq) {
|
|
439
|
+
target[key].lteq = negate(value.lteq)
|
|
440
|
+
}
|
|
441
|
+
} else if (fns.isObjectNative(value)) {
|
|
442
|
+
target[key] = {}
|
|
443
|
+
addNotFunctions(value, target[key])
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
addNotFunctions(is, is.not)
|
|
449
|
+
|
|
334
450
|
export default is
|
package/types/fns.d.ts
CHANGED
|
@@ -173,3 +173,12 @@ export const isCase: ((s: unknown, c?: 'up' | 'down') => boolean) & {
|
|
|
173
173
|
upper: (s: unknown) => boolean
|
|
174
174
|
lower: (s: unknown) => boolean
|
|
175
175
|
}
|
|
176
|
+
export function isIPv4(a: unknown): boolean
|
|
177
|
+
export function isIPv6(a: unknown): boolean
|
|
178
|
+
export function isIp(a: unknown): boolean
|
|
179
|
+
export namespace isIp {
|
|
180
|
+
export { isIPv4 as v4 }
|
|
181
|
+
export { isIPv6 as v6 }
|
|
182
|
+
}
|
|
183
|
+
export function ipV4(a: unknown): boolean
|
|
184
|
+
export function ipV6(a: unknown): boolean
|
package/types/index.d.ts
CHANGED
|
@@ -234,7 +234,7 @@ export const is: {
|
|
|
234
234
|
isEmpty: (e: unknown) => boolean
|
|
235
235
|
empty: (e: unknown) => boolean
|
|
236
236
|
isNot: (e: unknown, ...types: string[]) => boolean
|
|
237
|
-
not: (
|
|
237
|
+
not: import('./lib.js').NotNamespace
|
|
238
238
|
isNeq: (e: unknown, ...types: string[]) => boolean
|
|
239
239
|
neq: (e: unknown, ...types: string[]) => boolean
|
|
240
240
|
isArray: (e: unknown) => e is unknown[]
|
|
@@ -495,6 +495,24 @@ export const is: {
|
|
|
495
495
|
upperCase: (s: unknown) => s is string
|
|
496
496
|
isLowerCase: (s: unknown) => s is string
|
|
497
497
|
lowerCase: (s: unknown) => s is string
|
|
498
|
+
isIp: {
|
|
499
|
+
(a: unknown): boolean
|
|
500
|
+
v4: (a: unknown) => boolean
|
|
501
|
+
v6: (a: unknown) => boolean
|
|
502
|
+
}
|
|
503
|
+
ip: {
|
|
504
|
+
(a: unknown): boolean
|
|
505
|
+
v4: (a: unknown) => boolean
|
|
506
|
+
v6: (a: unknown) => boolean
|
|
507
|
+
}
|
|
508
|
+
isIPv4: (a: unknown) => boolean
|
|
509
|
+
ipv4: (a: unknown) => boolean
|
|
510
|
+
v4: (a: unknown) => boolean
|
|
511
|
+
isIPv6: (a: unknown) => boolean
|
|
512
|
+
ipv6: (a: unknown) => boolean
|
|
513
|
+
v6: (a: unknown) => boolean
|
|
514
|
+
ipV4: (a: unknown) => boolean
|
|
515
|
+
ipV6: (a: unknown) => boolean
|
|
498
516
|
same: (a: unknown, b: unknown) => boolean
|
|
499
517
|
sameType: (a: unknown, b: unknown) => boolean
|
|
500
518
|
isSameType: (a: unknown, b: unknown) => boolean
|
|
@@ -751,4 +769,5 @@ export const is: {
|
|
|
751
769
|
(a: unknown): (c: unknown) => boolean
|
|
752
770
|
}
|
|
753
771
|
}
|
|
772
|
+
export const not: import('./lib.js').NotNamespace
|
|
754
773
|
export default is
|
package/types/lib.d.ts
CHANGED
|
@@ -232,7 +232,7 @@ export const is: {
|
|
|
232
232
|
isEmpty: (e: unknown) => boolean
|
|
233
233
|
empty: (e: unknown) => boolean
|
|
234
234
|
isNot: (e: unknown, ...types: string[]) => boolean
|
|
235
|
-
not:
|
|
235
|
+
not: NotNamespace
|
|
236
236
|
isNeq: (e: unknown, ...types: string[]) => boolean
|
|
237
237
|
neq: (e: unknown, ...types: string[]) => boolean
|
|
238
238
|
isArray: (e: unknown) => e is unknown[]
|
|
@@ -493,6 +493,24 @@ export const is: {
|
|
|
493
493
|
upperCase: (s: unknown) => s is string
|
|
494
494
|
isLowerCase: (s: unknown) => s is string
|
|
495
495
|
lowerCase: (s: unknown) => s is string
|
|
496
|
+
isIp: {
|
|
497
|
+
(a: unknown): boolean
|
|
498
|
+
v4: (a: unknown) => boolean
|
|
499
|
+
v6: (a: unknown) => boolean
|
|
500
|
+
}
|
|
501
|
+
ip: {
|
|
502
|
+
(a: unknown): boolean
|
|
503
|
+
v4: (a: unknown) => boolean
|
|
504
|
+
v6: (a: unknown) => boolean
|
|
505
|
+
}
|
|
506
|
+
isIPv4: (a: unknown) => boolean
|
|
507
|
+
ipv4: (a: unknown) => boolean
|
|
508
|
+
v4: (a: unknown) => boolean
|
|
509
|
+
isIPv6: (a: unknown) => boolean
|
|
510
|
+
ipv6: (a: unknown) => boolean
|
|
511
|
+
v6: (a: unknown) => boolean
|
|
512
|
+
ipV4: (a: unknown) => boolean
|
|
513
|
+
ipV6: (a: unknown) => boolean
|
|
496
514
|
same: (a: unknown, b: unknown) => boolean
|
|
497
515
|
sameType: (a: unknown, b: unknown) => boolean
|
|
498
516
|
isSameType: (a: unknown, b: unknown) => boolean
|
|
@@ -769,4 +787,13 @@ export type EnhancedLengthFunction = typeof fns.getLength & {
|
|
|
769
787
|
lte: LengthComparison
|
|
770
788
|
lteq: LengthComparison
|
|
771
789
|
}
|
|
790
|
+
/**
|
|
791
|
+
* The `is.not` namespace: the original `isNot` check function, extended at
|
|
792
|
+
* runtime (by `addNotFunctions`) with a negated version of every `is.*` check
|
|
793
|
+
* and their nested sub-checks (e.g. `.upper`, `.eq`, `.v4`, `deep`). Each
|
|
794
|
+
* added property is either a negated check function or an object of them.
|
|
795
|
+
*/
|
|
796
|
+
export type NotNamespace = ((e: unknown, ...types: string[]) => boolean) & {
|
|
797
|
+
[key: string]: any
|
|
798
|
+
}
|
|
772
799
|
import * as fns from './fns.js'
|