@open-condo/miniapp-utils
Version:
A set of helper functions / components / hooks used to build new condo apps fast
454 lines (447 loc) • 14 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/helpers/ip/index.ts
var ip_exports = {};
__export(ip_exports, {
IPv4: () => ipv4_exports,
IPv6: () => ipv6_exports,
check: () => check,
createChecker: () => createChecker3,
isIP: () => isIP,
isIPv4: () => isIPv4,
isIPv4MappedAddress: () => isIPv4MappedAddress2,
isIPv6: () => isIPv6,
isInSubnet: () => isInSubnet3,
isLocalhost: () => isLocalhost3,
isPrivate: () => isPrivate3,
isReserved: () => isReserved3,
isSpecial: () => isSpecial3
});
module.exports = __toCommonJS(ip_exports);
// src/helpers/ip/ipv4.ts
var ipv4_exports = {};
__export(ipv4_exports, {
createChecker: () => createChecker,
isInSubnet: () => isInSubnet,
isLocalhost: () => isLocalhost,
isPrivate: () => isPrivate,
isReserved: () => isReserved,
isSpecial: () => isSpecial
});
// src/helpers/ip/ranges.ts
var ranges_default = {
/** localhost IP ranges */
localhost: {
/** the localhost address ranges for IPv4 */
ipv4: ["127.0.0.0/8"],
/** the localhost address ranges for IPv6 */
ipv6: ["::1/128"]
},
/** private IP ranges */
private: {
/** private address ranges for IPv4 */
ipv4: [
"10.0.0.0/8",
// RFC 1918
"172.16.0.0/12",
// RFC 1918
"192.168.0.0/16"
// RFC 1918
],
/** private address ranges for IPv6 */
ipv6: [
"fe80::/10",
// link-local address
"fc00::/7"
// unique local address (ULA)
]
},
/** reserved IP ranges */
reserved: {
/** reserved address ranges for IPv4 */
ipv4: [
"0.0.0.0/8",
// broadcast "this"
"100.64.0.0/10",
// carrier-grade NAT
"169.254.0.0/16",
// DHCP fallback
"192.0.0.0/24",
// IANA Special Purpose Address Registry
"192.0.2.0/24",
// TEST-NET-1 for documentation examples
"192.88.99.0/24",
// deprecated 6to4 anycast relays
"198.18.0.0/15",
// for testing inter-network comms between two subnets
"198.51.100.0/24",
// TEST-NET-2 for documentation examples
"203.0.113.0/24",
// TEST-NET-3 for documentation examples
"224.0.0.0/4",
// multicast
"240.0.0.0/4",
// reserved unspecified
"255.255.255.255/32"
// limited broadcast address
],
/** reserved address ranges for IPv6 */
ipv6: [
"::/128",
// unspecified address
"64:ff9b::/96",
// IPv4/IPv6 translation
"100::/64",
// discard prefix
"2001::/32",
// Teredo tunneling
"2001:10::/28",
// deprecated
"2001:20::/28",
// ORCHIDv2
"2001:db8::/32",
// for documentation and examples
"2002::/16",
// 6to4
"ff00::/8"
// multicast
]
}
};
// src/helpers/ip/utils.ts
var v4Seg = "(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])";
var v4Str = `(${v4Seg}[.]){3}${v4Seg}`;
var IPv4Reg = new RegExp(`^${v4Str}$`);
var v6Seg = "(?:[0-9a-fA-F]{1,4})";
var IPv6Reg = new RegExp(
`^((?:${v6Seg}:){7}(?:${v6Seg}|:)|(?:${v6Seg}:){6}(?:${v4Str}|:${v6Seg}|:)|(?:${v6Seg}:){5}(?::${v4Str}|(:${v6Seg}){1,2}|:)|(?:${v6Seg}:){4}(?:(:${v6Seg}){0,1}:${v4Str}|(:${v6Seg}){1,3}|:)|(?:${v6Seg}:){3}(?:(:${v6Seg}){0,2}:${v4Str}|(:${v6Seg}){1,4}|:)|(?:${v6Seg}:){2}(?:(:${v6Seg}){0,3}:${v4Str}|(:${v6Seg}){1,5}|:)|(?:${v6Seg}:){1}(?:(:${v6Seg}){0,4}:${v4Str}|(:${v6Seg}){1,6}|:)|(?::((?::${v6Seg}){0,5}:${v4Str}|(?::${v6Seg}){1,7}|:)))(%[0-9a-zA-Z]{1,})?$`
);
function isIPv4(s) {
return IPv4Reg.test(s);
}
function isIPv6(s) {
return IPv6Reg.test(s);
}
function isIP(s) {
if (isIPv4(s)) return 4;
if (isIPv6(s)) return 6;
return 0;
}
// src/helpers/ip/ipv4.ts
function ipv4ToLong(ip) {
if (!isIPv4(ip)) {
throw new Error(`not a valid IPv4 address: ${ip}`);
}
const octets = ip.split(".");
return (parseInt(octets[0], 10) << 24) + (parseInt(octets[1], 10) << 16) + (parseInt(octets[2], 10) << 8) + parseInt(octets[3], 10) >>> 0;
}
function createLongChecker(subnet) {
const [subnetAddress, prefixLengthString] = subnet.split("/");
const prefixLength = parseInt(prefixLengthString, 10);
if (!subnetAddress || !Number.isInteger(prefixLength)) {
throw new Error(`not a valid IPv4 subnet: ${subnet}`);
}
if (prefixLength < 0 || prefixLength > 32) {
throw new Error(`not a valid IPv4 prefix length: ${prefixLength} (from ${subnet})`);
}
const subnetLong = ipv4ToLong(subnetAddress);
return (addressLong) => {
if (prefixLength === 0) {
return true;
}
const subnetPrefix = subnetLong >> 32 - prefixLength;
const addressPrefix = addressLong >> 32 - prefixLength;
return subnetPrefix === addressPrefix;
};
}
function createChecker(subnetOrSubnets) {
if (Array.isArray(subnetOrSubnets)) {
const checks = subnetOrSubnets.map((subnet) => createLongChecker(subnet));
return (address) => {
const addressLong = ipv4ToLong(address);
return checks.some((check3) => check3(addressLong));
};
}
const check2 = createLongChecker(subnetOrSubnets);
return (address) => {
const addressLong = ipv4ToLong(address);
return check2(addressLong);
};
}
function isInSubnet(address, subnetOrSubnets) {
return createChecker(subnetOrSubnets)(address);
}
var specialNetsCache = {};
function isPrivate(address) {
if (!("private" in specialNetsCache)) {
specialNetsCache["private"] = createChecker(ranges_default.private.ipv4);
}
return specialNetsCache["private"](address);
}
function isLocalhost(address) {
if (!("localhost" in specialNetsCache)) {
specialNetsCache["localhost"] = createChecker(ranges_default.localhost.ipv4);
}
return specialNetsCache["localhost"](address);
}
function isReserved(address) {
if (!("reserved" in specialNetsCache)) {
specialNetsCache["reserved"] = createChecker(ranges_default.reserved.ipv4);
}
return specialNetsCache["reserved"](address);
}
function isSpecial(address) {
if (!("special" in specialNetsCache)) {
specialNetsCache["special"] = createChecker([
...ranges_default.private.ipv4,
...ranges_default.localhost.ipv4,
...ranges_default.reserved.ipv4
]);
}
return specialNetsCache["special"](address);
}
// src/helpers/ip/ipv6.ts
var ipv6_exports = {};
__export(ipv6_exports, {
createChecker: () => createChecker2,
extractMappedIpv4: () => extractMappedIpv4,
isIPv4MappedAddress: () => isIPv4MappedAddress,
isInSubnet: () => isInSubnet2,
isLocalhost: () => isLocalhost2,
isPrivate: () => isPrivate2,
isReserved: () => isReserved2,
isSpecial: () => isSpecial2
});
var dot = /\./;
var mappedIpv4 = /^(.+:ffff:)(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?:%.+)?$/;
var colon = /:/;
var doubleColon = /::/;
function mappedIpv4ToIpv6(ip) {
const matches = ip.match(mappedIpv4);
if (!matches || !isIPv4(matches[2])) {
throw new Error(`not a mapped IPv4 address: ${ip}`);
}
const prefix = matches[1];
const ipv4 = matches[2];
const parts = ipv4.split(dot).map((x) => parseInt(x, 10));
const segment7 = ((parts[0] << 8) + parts[1]).toString(16);
const segment8 = ((parts[2] << 8) + parts[3]).toString(16);
return `${prefix}${segment7}:${segment8}`;
}
function extractMappedIpv4(ip) {
const matches = ip.match(mappedIpv4);
if (!matches || !isIPv4(matches[2])) {
throw new Error(`not a mapped IPv4 address: ${ip}`);
}
return matches[2];
}
function getIpv6Segments(ip) {
if (!isIPv6(ip)) {
throw new Error(`not a valid IPv6 address: ${ip}`);
}
if (dot.test(ip)) {
return getIpv6Segments(mappedIpv4ToIpv6(ip));
}
const [beforeChunk, afterChunk] = ip.split(doubleColon);
const beforeParts = beforeChunk && beforeChunk.split(colon) || [];
const afterParts = afterChunk && afterChunk.split(colon) || [];
const missingSegments = new Array(8 - (beforeParts.length + afterParts.length));
return beforeParts.concat(missingSegments, afterParts);
}
function isInSubnet2(address, subnetOrSubnets) {
return createChecker2(subnetOrSubnets)(address);
}
function createChecker2(subnetOrSubnets) {
if (Array.isArray(subnetOrSubnets)) {
const checks = subnetOrSubnets.map((subnet) => createSegmentChecker(subnet));
return (address) => {
const segments = getIpv6Segments(address);
return checks.some((check3) => check3(segments));
};
}
const check2 = createSegmentChecker(subnetOrSubnets);
return (address) => {
const segments = getIpv6Segments(address);
return check2(segments);
};
}
function createSegmentChecker(subnet) {
const [subnetAddress, prefixLengthString] = subnet.split("/");
const prefixLength = parseInt(prefixLengthString, 10);
if (!subnetAddress || !Number.isInteger(prefixLength)) {
throw new Error(`not a valid IPv6 CIDR subnet: ${subnet}`);
}
if (prefixLength < 0 || prefixLength > 128) {
throw new Error(`not a valid IPv6 prefix length: ${prefixLength} (from ${subnet})`);
}
const subnetSegments = getIpv6Segments(subnetAddress);
return (addressSegments) => {
for (let i = 0; i < 8; ++i) {
const bitCount = Math.min(prefixLength - i * 16, 16);
if (bitCount <= 0) {
break;
}
const subnetPrefix = (subnetSegments[i] && parseInt(subnetSegments[i], 16) || 0) >> 16 - bitCount;
const addressPrefix = (addressSegments[i] && parseInt(addressSegments[i], 16) || 0) >> 16 - bitCount;
if (subnetPrefix !== addressPrefix) {
return false;
}
}
return true;
};
}
var specialNetsCache2 = {};
function isPrivate2(address) {
if (!("private" in specialNetsCache2)) {
specialNetsCache2["private"] = createChecker2(ranges_default.private.ipv6);
}
return specialNetsCache2["private"](address);
}
function isLocalhost2(address) {
if (!("localhost" in specialNetsCache2)) {
specialNetsCache2["localhost"] = createChecker2(ranges_default.localhost.ipv6);
}
return specialNetsCache2["localhost"](address);
}
function isIPv4MappedAddress(address) {
if (!("mapped" in specialNetsCache2)) {
specialNetsCache2["mapped"] = createChecker2("::ffff:0:0/96");
}
if (specialNetsCache2["mapped"](address)) {
const matches = address.match(mappedIpv4);
return Boolean(matches && isIPv4(matches[2]));
}
return false;
}
function isReserved2(address) {
if (!("reserved" in specialNetsCache2)) {
specialNetsCache2["reserved"] = createChecker2(ranges_default.reserved.ipv6);
}
return specialNetsCache2["reserved"](address);
}
function isSpecial2(address) {
if (!("special" in specialNetsCache2)) {
specialNetsCache2["special"] = createChecker2([
...ranges_default.private.ipv6,
...ranges_default.localhost.ipv6,
...ranges_default.reserved.ipv6
]);
}
return specialNetsCache2["special"](address);
}
// src/helpers/ip/index.ts
function isInSubnet3(address, subnetOrSubnets) {
return createChecker3(subnetOrSubnets)(address);
}
function createChecker3(subnetOrSubnets) {
if (!Array.isArray(subnetOrSubnets)) {
return createChecker3([subnetOrSubnets]);
}
const subnetsByVersion = subnetOrSubnets.reduce(
(acc, subnet) => {
const ip = subnet.split("/")[0];
acc[isIP(ip)].push(subnet);
return acc;
},
{ 0: [], 4: [], 6: [] }
);
if (subnetsByVersion[0].length !== 0) {
throw new Error(`some subnets are not valid IP addresses: ${subnetsByVersion[0]}`);
}
const check4 = createChecker(subnetsByVersion[4]);
const check6 = createChecker2(subnetsByVersion[6]);
return (address) => {
if (!isIP(address)) {
throw new Error(`not a valid IPv4 or IPv6 address: ${address}`);
}
if (isIPv6(address) && isIPv4MappedAddress(address)) {
return check6(address) || check4(extractMappedIpv4(address));
}
if (isIPv6(address)) {
return check6(address);
} else {
return check4(address);
}
};
}
function isPrivate3(address) {
if (isIPv6(address)) {
if (isIPv4MappedAddress(address)) {
return isPrivate(extractMappedIpv4(address));
}
return isPrivate2(address);
} else {
return isPrivate(address);
}
}
function isLocalhost3(address) {
if (isIPv6(address)) {
if (isIPv4MappedAddress(address)) {
return isLocalhost(extractMappedIpv4(address));
}
return isLocalhost2(address);
} else {
return isLocalhost(address);
}
}
function isIPv4MappedAddress2(address) {
if (isIPv6(address)) {
return isIPv4MappedAddress(address);
} else {
return false;
}
}
function isReserved3(address) {
if (isIPv6(address)) {
if (isIPv4MappedAddress(address)) {
return isReserved(extractMappedIpv4(address));
}
return isReserved2(address);
} else {
return isReserved(address);
}
}
function isSpecial3(address) {
if (isIPv6(address)) {
if (isIPv4MappedAddress(address)) {
return isSpecial(extractMappedIpv4(address));
}
return isSpecial2(address);
} else {
return isSpecial(address);
}
}
var check = isInSubnet3;
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
IPv4,
IPv6,
check,
createChecker,
isIP,
isIPv4,
isIPv4MappedAddress,
isIPv6,
isInSubnet,
isLocalhost,
isPrivate,
isReserved,
isSpecial
});
//# sourceMappingURL=index.js.map