@open-mercato/shared 0.5.1-develop.2657.a01847a9fa → 0.5.1-develop.2663.2c29774b5b
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/dist/lib/network.js +2 -0
- package/dist/lib/network.js.map +2 -2
- package/dist/lib/version.js +1 -1
- package/dist/lib/version.js.map +1 -1
- package/package.json +1 -1
- package/src/lib/network.ts +2 -2
package/dist/lib/network.js
CHANGED
package/dist/lib/network.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/network.ts"],
|
|
4
|
-
"sourcesContent": ["import { isIP } from 'node:net'\n\nconst BLOCKED_HOSTNAMES = new Set([\n 'localhost',\n 'ip6-localhost',\n 'ip6-loopback',\n 'broadcasthost',\n])\n\nexport function isPrivateIpAddress(address: string): boolean {\n const family = isIP(address)\n if (family === 4) return isPrivateIPv4(address)\n if (family === 6) return isPrivateIPv6(address)\n return false\n}\n\nexport function isBlockedHostname(hostname: string): boolean {\n const normalized = normalizeHostname(hostname)\n if (!normalized) return true\n if (BLOCKED_HOSTNAMES.has(normalized)) return true\n if (normalized.endsWith('.localhost')) return true\n if (normalized.endsWith('.internal')) return true\n if (normalized.endsWith('.local')) return true\n return false\n}\n\nexport function isPrivateUrl(rawUrl: string): boolean {\n const urlToParse = rawUrl.replace(/\\[([0-9a-fA-F:]+)%25[^\\]]*\\]/g, '[$1]')\n let url: URL\n try {\n url = new URL(urlToParse)\n } catch {\n return false\n }\n\n const hostname = normalizeHostname(url.hostname)\n if (isBlockedHostname(hostname)) return true\n return isPrivateIpAddress(hostname)\n}\n\nfunction normalizeHostname(hostname: string): string {\n let normalized = hostname.trim().toLowerCase()\n if (normalized.startsWith('[') && normalized.endsWith(']')) {\n normalized = normalized.slice(1, -1)\n }\n while (normalized.endsWith('.')) {\n normalized = normalized.slice(0, -1)\n }\n return normalized\n}\n\
|
|
5
|
-
"mappings": "AAAA,SAAS,YAAY;AAErB,MAAM,oBAAoB,oBAAI,IAAI;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,SAAS,mBAAmB,SAA0B;AAC3D,QAAM,SAAS,KAAK,OAAO;AAC3B,MAAI,WAAW,EAAG,QAAO,cAAc,OAAO;AAC9C,MAAI,WAAW,EAAG,QAAO,cAAc,OAAO;AAC9C,SAAO;AACT;AAEO,SAAS,kBAAkB,UAA2B;AAC3D,QAAM,aAAa,kBAAkB,QAAQ;AAC7C,MAAI,CAAC,WAAY,QAAO;AACxB,MAAI,kBAAkB,IAAI,UAAU,EAAG,QAAO;AAC9C,MAAI,WAAW,SAAS,YAAY,EAAG,QAAO;AAC9C,MAAI,WAAW,SAAS,WAAW,EAAG,QAAO;AAC7C,MAAI,WAAW,SAAS,QAAQ,EAAG,QAAO;AAC1C,SAAO;AACT;AAEO,SAAS,aAAa,QAAyB;AACpD,QAAM,aAAa,OAAO,QAAQ,iCAAiC,MAAM;AACzE,MAAI;AACJ,MAAI;AACF,UAAM,IAAI,IAAI,UAAU;AAAA,EAC1B,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,kBAAkB,IAAI,QAAQ;AAC/C,MAAI,kBAAkB,QAAQ,EAAG,QAAO;AACxC,SAAO,mBAAmB,QAAQ;AACpC;AAEA,SAAS,kBAAkB,UAA0B;AACnD,MAAI,aAAa,SAAS,KAAK,EAAE,YAAY;AAC7C,MAAI,WAAW,WAAW,GAAG,KAAK,WAAW,SAAS,GAAG,GAAG;AAC1D,iBAAa,WAAW,MAAM,GAAG,EAAE;AAAA,EACrC;AACA,SAAO,WAAW,SAAS,GAAG,GAAG;AAC/B,iBAAa,WAAW,MAAM,GAAG,EAAE;AAAA,EACrC;AACA,SAAO;AACT;
|
|
4
|
+
"sourcesContent": ["import { isIP } from 'node:net'\n\nconst BLOCKED_HOSTNAMES = new Set([\n 'localhost',\n 'ip6-localhost',\n 'ip6-loopback',\n 'broadcasthost',\n])\n\nexport function isPrivateIpAddress(address: string): boolean {\n const family = isIP(address)\n if (family === 4) return isPrivateIPv4(address)\n if (family === 6) return isPrivateIPv6(address)\n return false\n}\n\nexport function isBlockedHostname(hostname: string): boolean {\n const normalized = normalizeHostname(hostname)\n if (!normalized) return true\n if (BLOCKED_HOSTNAMES.has(normalized)) return true\n if (normalized.endsWith('.localhost')) return true\n if (normalized.endsWith('.internal')) return true\n if (normalized.endsWith('.local')) return true\n return false\n}\n\nexport function isPrivateUrl(rawUrl: string): boolean {\n const urlToParse = rawUrl.replace(/\\[([0-9a-fA-F:]+)%25[^\\]]*\\]/g, '[$1]')\n let url: URL\n try {\n url = new URL(urlToParse)\n } catch {\n return false\n }\n\n const hostname = normalizeHostname(url.hostname)\n if (isBlockedHostname(hostname)) return true\n return isPrivateIpAddress(hostname)\n}\n\nfunction normalizeHostname(hostname: string): string {\n let normalized = hostname.trim().toLowerCase()\n if (normalized.startsWith('[') && normalized.endsWith(']')) {\n normalized = normalized.slice(1, -1)\n }\n while (normalized.endsWith('.')) {\n normalized = normalized.slice(0, -1)\n }\n return normalized\n}\n\nexport function isPrivateIPv4(address: string): boolean {\n const parts = address.split('.')\n if (parts.length !== 4) return false\n const octets = parts.map((part) => Number(part))\n if (octets.some((o) => !Number.isInteger(o) || o < 0 || o > 255)) return false\n\n const [a, b, c] = octets\n if (a === 0) return true\n if (a === 10) return true\n if (a === 100 && b >= 64 && b <= 127) return true\n if (a === 127) return true\n if (a === 169 && b === 254) return true\n if (a === 172 && b >= 16 && b <= 31) return true\n if (a === 192 && b === 0 && (c === 0 || c === 2)) return true\n if (a === 192 && b === 168) return true\n if (a === 198 && (b === 18 || b === 19)) return true\n if (a === 198 && b === 51 && c === 100) return true\n if (a === 203 && b === 0 && c === 113) return true\n if (a >= 224) return true\n return false\n}\n\nexport function isPrivateIPv6(address: string): boolean {\n const segments = expandIPv6(address)\n if (!segments) return false\n\n if (segments.every((segment) => segment === 0)) return true\n if (segments.slice(0, 7).every((segment) => segment === 0) && segments[7] === 1) return true\n if (isIPv4CompatibleIPv6(segments)) return true\n\n const embedded = embeddedIPv4FromIPv6(segments)\n if (embedded && isPrivateIPv4(embedded)) return true\n\n const [a] = segments\n if ((a & 0xfe00) === 0xfc00) return true\n if ((a & 0xffc0) === 0xfe80) return true\n if ((a & 0xff00) === 0xff00) return true\n return false\n}\n\nfunction expandIPv6(address: string): number[] | null {\n let normalized = address.toLowerCase()\n if (normalized.includes('.')) {\n const lastColon = normalized.lastIndexOf(':')\n if (lastColon === -1) return null\n const ipv4Segments = ipv4ToHexSegments(normalized.slice(lastColon + 1))\n if (!ipv4Segments) return null\n normalized = `${normalized.slice(0, lastColon)}:${ipv4Segments[0].toString(16)}:${ipv4Segments[1].toString(16)}`\n }\n\n const doubleColonParts = normalized.split('::')\n if (doubleColonParts.length > 2) return null\n\n const head = doubleColonParts[0] ? doubleColonParts[0].split(':') : []\n const tail = doubleColonParts[1] ? doubleColonParts[1].split(':') : []\n const headSegments = parseIPv6SegmentList(head)\n const tailSegments = parseIPv6SegmentList(tail)\n if (!headSegments || !tailSegments) return null\n\n if (doubleColonParts.length === 1) {\n return headSegments.length === 8 ? headSegments : null\n }\n\n const missing = 8 - headSegments.length - tailSegments.length\n if (missing < 1) return null\n return [\n ...headSegments,\n ...Array.from({ length: missing }, () => 0),\n ...tailSegments,\n ]\n}\n\nfunction parseIPv6SegmentList(parts: string[]): number[] | null {\n const segments: number[] = []\n for (const part of parts) {\n if (!/^[0-9a-f]{1,4}$/.test(part)) return null\n const value = Number.parseInt(part, 16)\n if (!Number.isInteger(value) || value < 0 || value > 0xffff) return null\n segments.push(value)\n }\n return segments\n}\n\nfunction ipv4ToHexSegments(address: string): [number, number] | null {\n const octets = address.split('.').map((part) => Number(part))\n if (octets.length !== 4) return null\n if (octets.some((octet) => !Number.isInteger(octet) || octet < 0 || octet > 255)) return null\n return [\n (octets[0] << 8) + octets[1],\n (octets[2] << 8) + octets[3],\n ]\n}\n\nfunction embeddedIPv4FromIPv6(segments: number[]): string | null {\n const firstFiveZero = segments.slice(0, 5).every((segment) => segment === 0)\n const isMapped = firstFiveZero && segments[5] === 0xffff\n const isNat64 = segments[0] === 0x0064\n && segments[1] === 0xff9b\n && segments.slice(2, 6).every((segment) => segment === 0)\n const isSixToFour = segments[0] === 0x2002\n\n if (isMapped || isNat64) {\n return ipv4FromHexSegments(segments[6], segments[7])\n }\n if (isSixToFour) {\n return ipv4FromHexSegments(segments[1], segments[2])\n }\n return null\n}\n\nfunction isIPv4CompatibleIPv6(segments: number[]): boolean {\n return segments.slice(0, 6).every((segment) => segment === 0)\n}\n\nfunction ipv4FromHexSegments(high: number, low: number): string {\n return [\n (high >> 8) & 0xff,\n high & 0xff,\n (low >> 8) & 0xff,\n low & 0xff,\n ].join('.')\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/lib/version.js
CHANGED
package/dist/lib/version.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/version.ts"],
|
|
4
|
-
"sourcesContent": ["// Build-time generated version\nexport const APP_VERSION = '0.5.1-develop.
|
|
4
|
+
"sourcesContent": ["// Build-time generated version\nexport const APP_VERSION = '0.5.1-develop.2663.2c29774b5b'\nexport const appVersion = APP_VERSION\n"],
|
|
5
5
|
"mappings": "AACO,MAAM,cAAc;AACpB,MAAM,aAAa;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
package/src/lib/network.ts
CHANGED
|
@@ -49,7 +49,7 @@ function normalizeHostname(hostname: string): string {
|
|
|
49
49
|
return normalized
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
function isPrivateIPv4(address: string): boolean {
|
|
52
|
+
export function isPrivateIPv4(address: string): boolean {
|
|
53
53
|
const parts = address.split('.')
|
|
54
54
|
if (parts.length !== 4) return false
|
|
55
55
|
const octets = parts.map((part) => Number(part))
|
|
@@ -71,7 +71,7 @@ function isPrivateIPv4(address: string): boolean {
|
|
|
71
71
|
return false
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
function isPrivateIPv6(address: string): boolean {
|
|
74
|
+
export function isPrivateIPv6(address: string): boolean {
|
|
75
75
|
const segments = expandIPv6(address)
|
|
76
76
|
if (!segments) return false
|
|
77
77
|
|