@magic/types 0.1.37 → 0.1.39
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 +15 -1
- package/package.json +15 -5
- package/src/deep/different.js +3 -3
- package/src/deep/equal.js +19 -10
- package/src/fns.js +83 -0
- package/src/lib.js +12 -0
- package/types/fns.d.ts +9 -0
- package/types/index.d.ts +18 -0
- package/types/lib.d.ts +18 -0
package/README.md
CHANGED
|
@@ -140,6 +140,10 @@ isIterable([]) // true
|
|
|
140
140
|
isEmail('a@b.c') // true
|
|
141
141
|
// alias isMail, is.email, is.mail
|
|
142
142
|
|
|
143
|
+
isIp('192.168.1.1') // true
|
|
144
|
+
isIp('::1') // true
|
|
145
|
+
// alias ip, is.ip, ipV4, ipV6, isIPv4, isIPv6
|
|
146
|
+
|
|
143
147
|
isNull(null) // true
|
|
144
148
|
// alias isNil, is.nil, is.null
|
|
145
149
|
|
|
@@ -402,6 +406,16 @@ update dependencies
|
|
|
402
406
|
|
|
403
407
|
- update @magic/test
|
|
404
408
|
|
|
405
|
-
##### 0.1.38
|
|
409
|
+
##### 0.1.38
|
|
410
|
+
|
|
411
|
+
- remove recursive dependencies
|
|
412
|
+
- update dependencies
|
|
413
|
+
|
|
414
|
+
##### 0.1.39
|
|
415
|
+
|
|
416
|
+
- add isIp and variants to allow ip v4 and v6 checks
|
|
417
|
+
- update dependencies
|
|
418
|
+
|
|
419
|
+
##### 0.1.40 - unreleased
|
|
406
420
|
|
|
407
421
|
...
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@magic/types",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.39",
|
|
4
4
|
"author": "Wizards & Witches",
|
|
5
5
|
"homepage": "https://github.com/magic/types",
|
|
6
6
|
"license": "AGPL-3.0",
|
|
@@ -8,6 +8,12 @@
|
|
|
8
8
|
"main": "src/index.js",
|
|
9
9
|
"types": "./types/index.d.ts",
|
|
10
10
|
"type": "module",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./src/index.js",
|
|
14
|
+
"types": "./types/index.d.ts"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
11
17
|
"scripts": {
|
|
12
18
|
"start": "t",
|
|
13
19
|
"build": "tsc && npm run format",
|
|
@@ -44,9 +50,9 @@
|
|
|
44
50
|
"@magic-modules/no-spy": "0.0.9",
|
|
45
51
|
"@magic-modules/pre": "0.0.12",
|
|
46
52
|
"@magic-themes/docs": "0.0.15",
|
|
47
|
-
"@magic/core": "0.0.
|
|
48
|
-
"@magic/format": "0.0.
|
|
49
|
-
"@magic/test": "0.3.
|
|
53
|
+
"@magic/core": "0.0.159",
|
|
54
|
+
"@magic/format": "0.0.75",
|
|
55
|
+
"@magic/test": "0.3.23",
|
|
50
56
|
"typescript": "6.0.3"
|
|
51
57
|
},
|
|
52
58
|
"keywords": [
|
|
@@ -61,6 +67,10 @@
|
|
|
61
67
|
}
|
|
62
68
|
],
|
|
63
69
|
"dependencies": {
|
|
64
|
-
"@types/node": "
|
|
70
|
+
"@types/node": "26.1.0"
|
|
71
|
+
},
|
|
72
|
+
"allowScripts": {
|
|
73
|
+
"@swc/core@1.3.41": true,
|
|
74
|
+
"canvas@3.2.3": true
|
|
65
75
|
}
|
|
66
76
|
}
|
package/src/deep/different.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { isUndefined } from '../fns.js'
|
|
2
2
|
|
|
3
3
|
import equal from './equal.js'
|
|
4
4
|
|
|
@@ -19,8 +19,8 @@ import equal from './equal.js'
|
|
|
19
19
|
* @returns {boolean | ((c: unknown) => boolean)}
|
|
20
20
|
*/
|
|
21
21
|
export const different = (a, b) => {
|
|
22
|
-
if (
|
|
23
|
-
if (
|
|
22
|
+
if (isUndefined(b)) {
|
|
23
|
+
if (isUndefined(a)) {
|
|
24
24
|
return false
|
|
25
25
|
}
|
|
26
26
|
|
package/src/deep/equal.js
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
// Written by Substack <3
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import {
|
|
4
|
+
isArray,
|
|
5
|
+
isBuffer,
|
|
6
|
+
isDate,
|
|
7
|
+
isFunction,
|
|
8
|
+
isNull,
|
|
9
|
+
isObject,
|
|
10
|
+
isObjectNative,
|
|
11
|
+
isUndefined,
|
|
12
|
+
} from '../fns.js'
|
|
4
13
|
|
|
5
14
|
/**
|
|
6
15
|
* @overload
|
|
@@ -25,15 +34,15 @@ export const equal = (a, b, options = {}) => {
|
|
|
25
34
|
const { strict = false, arrayOrderStrict = false } = options
|
|
26
35
|
|
|
27
36
|
// curry
|
|
28
|
-
if (
|
|
29
|
-
if (
|
|
37
|
+
if (isUndefined(b)) {
|
|
38
|
+
if (isUndefined(a)) {
|
|
30
39
|
return true
|
|
31
40
|
}
|
|
32
41
|
|
|
33
42
|
return c => equal(a, c)
|
|
34
43
|
}
|
|
35
44
|
|
|
36
|
-
if (
|
|
45
|
+
if (isNull(b)) {
|
|
37
46
|
return a === b
|
|
38
47
|
}
|
|
39
48
|
|
|
@@ -43,11 +52,11 @@ export const equal = (a, b, options = {}) => {
|
|
|
43
52
|
}
|
|
44
53
|
|
|
45
54
|
/* functions are handled by their toString value */
|
|
46
|
-
if (
|
|
55
|
+
if (isFunction(a) && isFunction(b)) {
|
|
47
56
|
return a.toString() === b.toString()
|
|
48
57
|
}
|
|
49
58
|
|
|
50
|
-
if (!
|
|
59
|
+
if (!isObject(a) || !isObject(b)) {
|
|
51
60
|
return a === b
|
|
52
61
|
}
|
|
53
62
|
|
|
@@ -62,12 +71,12 @@ export const equal = (a, b, options = {}) => {
|
|
|
62
71
|
}
|
|
63
72
|
|
|
64
73
|
// dates
|
|
65
|
-
if (
|
|
74
|
+
if (isDate(a)) {
|
|
66
75
|
return a.toString() === b.toString()
|
|
67
76
|
}
|
|
68
77
|
|
|
69
78
|
// buffers
|
|
70
|
-
if (
|
|
79
|
+
if (isBuffer(a) && isBuffer(b)) {
|
|
71
80
|
if (a.length !== b.length) {
|
|
72
81
|
return false
|
|
73
82
|
}
|
|
@@ -81,7 +90,7 @@ export const equal = (a, b, options = {}) => {
|
|
|
81
90
|
return true
|
|
82
91
|
}
|
|
83
92
|
|
|
84
|
-
if (
|
|
93
|
+
if (isArray(a) && isArray(b)) {
|
|
85
94
|
if (!strict && !arrayOrderStrict) {
|
|
86
95
|
a.sort()
|
|
87
96
|
b.sort()
|
|
@@ -91,7 +100,7 @@ export const equal = (a, b, options = {}) => {
|
|
|
91
100
|
return allEqual
|
|
92
101
|
}
|
|
93
102
|
|
|
94
|
-
if (
|
|
103
|
+
if (isObjectNative(a) && isObjectNative(b)) {
|
|
95
104
|
const aObj = a
|
|
96
105
|
const bObj = b
|
|
97
106
|
|
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/lib.js
CHANGED
|
@@ -315,6 +315,18 @@ export const is = /** @type {const} */ {
|
|
|
315
315
|
isLowerCase: fns.isLowerCase,
|
|
316
316
|
lowerCase: fns.isLowerCase,
|
|
317
317
|
|
|
318
|
+
isIp: fns.isIp,
|
|
319
|
+
ip: fns.isIp,
|
|
320
|
+
isIPv4: fns.isIPv4,
|
|
321
|
+
ipv4: fns.isIPv4,
|
|
322
|
+
v4: fns.isIPv4,
|
|
323
|
+
isIPv6: fns.isIPv6,
|
|
324
|
+
ipv6: fns.isIPv6,
|
|
325
|
+
v6: fns.isIPv6,
|
|
326
|
+
|
|
327
|
+
ipV4: fns.ipV4,
|
|
328
|
+
ipV6: fns.ipV6,
|
|
329
|
+
|
|
318
330
|
same: fns.isSameType,
|
|
319
331
|
sameType: fns.isSameType,
|
|
320
332
|
isSameType: fns.isSameType,
|
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
|
@@ -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
|
package/types/lib.d.ts
CHANGED
|
@@ -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
|