diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..7e0b917 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,30 @@ +module.exports = { + 'env': { + 'browser': true, + 'commonjs': false, + 'es2021': true + }, + 'extends': 'eslint:recommended', + 'parserOptions': { + 'sourceType': 'module', + 'ecmaVersion': 'latest' + }, + 'rules': { + 'indent': [ + 'error', + 2 + ], + 'linebreak-style': [ + 'error', + 'unix' + ], + 'quotes': [ + 'error', + 'single' + ], + 'semi': [ + 'error', + 'always' + ] + } +}; diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index e325df1..0000000 --- a/.eslintrc.js +++ /dev/null @@ -1,29 +0,0 @@ -module.exports = { - 'env': { - 'browser': true, - 'commonjs': true, - 'es2021': true - }, - 'extends': 'eslint:recommended', - 'parserOptions': { - 'ecmaVersion': 'latest' - }, - 'rules': { - 'indent': [ - 'error', - 2 - ], - 'linebreak-style': [ - 'error', - 'unix' - ], - 'quotes': [ - 'error', - 'single' - ], - 'semi': [ - 'error', - 'always' - ] - } -}; diff --git a/README.md b/README.md index 22e5819..25dae8c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# IP -[![](https://badge.fury.io/js/ip.svg)](https://www.npmjs.com/package/ip) +# IP +[![](https://badge.fury.io/js/ip.svg)](https://www.npmjs.com/package/ip) IP address utilities for node.js @@ -15,12 +15,12 @@ npm install ip ```shell git clone https://github.com/indutny/node-ip.git ``` - + ## Usage Get your ip address, compare ip addresses, validate ip addresses, etc. ```js -var ip = require('ip'); +import * as ip from 'ip'; ip.address() // my ip address ip.isEqual('::1', '::0:1'); // true @@ -36,10 +36,9 @@ ip.isV4Format('127.0.0.1'); // true ip.isV6Format('::ffff:127.0.0.1'); // true // operate on buffers in-place -var buf = new Buffer(128); +var buf = new Uint8Array(128); var offset = 64; ip.toBuffer('127.0.0.1', buf, offset); // [127, 0, 0, 1] at offset 64 -ip.toString(buf, offset, 4); // '127.0.0.1' // subnet information ip.subnet('192.168.1.134', '255.255.255.192') diff --git a/lib/ip.js b/lib/ip.js index 4b2adb5..ef88214 100644 --- a/lib/ip.js +++ b/lib/ip.js @@ -1,32 +1,53 @@ -const ip = exports; -const { Buffer } = require('buffer'); -const os = require('os'); +import { networkInterfaces } from 'node:os'; -ip.toBuffer = function (ip, buff, offset) { - offset = ~~offset; +/** @typedef {ReturnType} SubnetInfo */ +const ipv4Regex = /^(\d{1,3}\.){3,3}\d{1,3}$/; +const ipv6Regex = /^(::)?(((\d{1,3}\.){3}(\d{1,3}){1})?([0-9a-f]){0,4}:{0,2}){1,8}(::)?$/i; + +/** + * Encode a Uint8Array to a hex string + * + * @param {Uint8Array} array Bytes to encode to string + */ +const arr2hex = array => { + let result = ''; + for (const value of array) { + result += value.toString(16).padStart(2, '0'); + } + return result; +}; + +/** + * Convert an IP string into a Uint8array. + * + * @param {string} ip + * @param {Uint8Array} [buff] + * @param {number} [offset=0] + */ +function toBuffer(ip, buff, offset = 0) { let result; - if (this.isV4Format(ip)) { - result = buff || Buffer.alloc(offset + 4); + if (isV4Format(ip)) { + result = buff || new Uint8Array(offset + 4); ip.split(/\./g).map((byte) => { result[offset++] = parseInt(byte, 10) & 0xff; }); - } else if (this.isV6Format(ip)) { + } else if (isV6Format(ip)) { const sections = ip.split(':', 8); let i; for (i = 0; i < sections.length; i++) { - const isv4 = this.isV4Format(sections[i]); + const isv4 = isV4Format(sections[i]); let v4Buffer; if (isv4) { - v4Buffer = this.toBuffer(sections[i]); - sections[i] = v4Buffer.slice(0, 2).toString('hex'); + v4Buffer = toBuffer(sections[i]); + sections[i] = arr2hex(v4Buffer.subarray(0, 2)); } if (v4Buffer && ++i < 8) { - sections.splice(i, 0, v4Buffer.slice(2, 4).toString('hex')); + sections.splice(i, 0, arr2hex(v4Buffer.subarray(2, 4))); } } @@ -43,7 +64,7 @@ ip.toBuffer = function (ip, buff, offset) { sections.splice(...argv); } - result = buff || Buffer.alloc(offset + 16); + result = buff || new Uint8Array(offset + 16); for (i = 0; i < sections.length; i++) { const word = parseInt(sections[i], 16); result[offset++] = (word >> 8) & 0xff; @@ -56,65 +77,77 @@ ip.toBuffer = function (ip, buff, offset) { } return result; -}; - -ip.toString = function (buff, offset, length) { - offset = ~~offset; - length = length || (buff.length - offset); +} +/** + * Convert an IP buffer into a string. + * + * @param {Uint8Array} buff + */ +function toString(buff, offset = 0, length = buff.length - offset) { let result = []; + if (length === 4) { // IPv4 for (let i = 0; i < length; i++) { result.push(buff[offset + i]); } - result = result.join('.'); + return result.join('.'); } else if (length === 16) { // IPv6 for (let i = 0; i < length; i += 2) { result.push(buff.readUInt16BE(offset + i).toString(16)); } - result = result.join(':'); - result = result.replace(/(^|:)0(:0)*:0(:|$)/, '$1::$3'); - result = result.replace(/:{3,4}/, '::'); + return result.join(':') + .replace(/(^|:)0(:0)*:0(:|$)/, '$1::$3') + .replace(/:{3,4}/, '::'); } - return result; -}; - -const ipv4Regex = /^(\d{1,3}\.){3,3}\d{1,3}$/; -const ipv6Regex = /^(::)?(((\d{1,3}\.){3}(\d{1,3}){1})?([0-9a-f]){0,4}:{0,2}){1,8}(::)?$/i; + return ''; +} -ip.isV4Format = function (ip) { +/** + * Check whether an IP is a IPv4 address + * + * @param {string} ip + */ +function isV4Format(ip) { return ipv4Regex.test(ip); -}; +} -ip.isV6Format = function (ip) { +/** + * Check whether an IP is a IPv6 address + * + * @param {string} ip + */ +function isV6Format(ip) { return ipv6Regex.test(ip); -}; +} +/** + * @description Normalize the given family. + * @param {string | number} family + * @returns {string} + */ function _normalizeFamily(family) { - if (family === 4) { - return 'ipv4'; - } - if (family === 6) { - return 'ipv6'; - } - return family ? family.toLowerCase() : 'ipv4'; + return family === 4 ? 'ipv4' : + family === 6 ? 'ipv6' : + family ? family.toLowerCase() : 'ipv4'; } -ip.fromPrefixLen = function (prefixlen, family) { - if (prefixlen > 32) { - family = 'ipv6'; - } else { - family = _normalizeFamily(family); - } +/** + * Get the subnet mask from a CIDR prefix length. + * + * @param {number} prefixlen + * @param {'ipv4' | 'ipv6'} [family] + * The IP family is inferred from the prefixLength, but can be explicity + * specified as either "ipv4" or "ipv6". + */ +function fromPrefixLen(prefixlen, family) { + family = prefixlen > 32 ? 'ipv6' : _normalizeFamily(family); - let len = 4; - if (family === 'ipv6') { - len = 16; - } - const buff = Buffer.alloc(len); + const len = family === 'ipv6' ? 16 : 4; + const buff = new Uint8Array(len); for (let i = 0, n = buff.length; i < n; ++i) { let bits = 8; @@ -126,14 +159,20 @@ ip.fromPrefixLen = function (prefixlen, family) { buff[i] = ~(0xff >> bits) & 0xff; } - return ip.toString(buff); -}; + return toString(buff); +} -ip.mask = function (addr, mask) { - addr = ip.toBuffer(addr); - mask = ip.toBuffer(mask); +/** + * Get the network ID IP address from an IP address and its subnet mask. + * + * @param {string} ipAddr + * @param {string} ipMask + */ +function _mask(ipAddr, ipMask) { + const addr = toBuffer(ipAddr); + const mask = toBuffer(ipMask); - const result = Buffer.alloc(Math.max(addr.length, mask.length)); + const result = new Uint8Array(Math.max(addr.length, mask.length)); // Same protocol - do bitwise and let i; @@ -165,10 +204,15 @@ ip.mask = function (addr, mask) { result[i] = 0; } - return ip.toString(result); -}; + return toString(result); +} -ip.cidr = function (cidrString) { +/** + * Get the network ID IP address from an IP address in CIDR notation. + * + * @param {string} cidrString + */ +function cidr(cidrString) { const cidrParts = cidrString.split('/'); const addr = cidrParts[0]; @@ -176,16 +220,22 @@ ip.cidr = function (cidrString) { throw new Error(`invalid CIDR subnet: ${addr}`); } - const mask = ip.fromPrefixLen(parseInt(cidrParts[1], 10)); + const mask = fromPrefixLen(parseInt(cidrParts[1], 10)); - return ip.mask(addr, mask); -}; + return _mask(addr, mask); +} -ip.subnet = function (addr, mask) { - const networkAddress = ip.toLong(ip.mask(addr, mask)); +/** + * Get the subnet information. + * + * @param {string} ip IP address. + * @param {string} subnet Subnet address. + */ +function subnet(ip, subnet) { + const networkAddress = toLong(_mask(ip, subnet)); // Calculate the mask's length. - const maskBuffer = ip.toBuffer(mask); + const maskBuffer = toBuffer(subnet); let maskLength = 0; for (let i = 0; i < maskBuffer.length; i++) { @@ -203,26 +253,30 @@ ip.subnet = function (addr, mask) { const numberOfAddresses = 2 ** (32 - maskLength); return { - networkAddress: ip.fromLong(networkAddress), + networkAddress: fromLong(networkAddress), firstAddress: numberOfAddresses <= 2 - ? ip.fromLong(networkAddress) - : ip.fromLong(networkAddress + 1), + ? fromLong(networkAddress) + : fromLong(networkAddress + 1), lastAddress: numberOfAddresses <= 2 - ? ip.fromLong(networkAddress + numberOfAddresses - 1) - : ip.fromLong(networkAddress + numberOfAddresses - 2), - broadcastAddress: ip.fromLong(networkAddress + numberOfAddresses - 1), - subnetMask: mask, + ? fromLong(networkAddress + numberOfAddresses - 1) + : fromLong(networkAddress + numberOfAddresses - 2), + broadcastAddress: fromLong(networkAddress + numberOfAddresses - 1), + subnetMask: subnet, subnetMaskLength: maskLength, numHosts: numberOfAddresses <= 2 ? numberOfAddresses : numberOfAddresses - 2, length: numberOfAddresses, contains(other) { - return networkAddress === ip.toLong(ip.mask(other, mask)); + return networkAddress === toLong(_mask(other, subnet)); }, }; -}; +} -ip.cidrSubnet = function (cidrString) { +/** + * Get the subnet information. + * @param {string} cidrString CIDR address. + */ +function cidrSubnet(cidrString) { const cidrParts = cidrString.split('/'); const addr = cidrParts[0]; @@ -230,29 +284,41 @@ ip.cidrSubnet = function (cidrString) { throw new Error(`invalid CIDR subnet: ${addr}`); } - const mask = ip.fromPrefixLen(parseInt(cidrParts[1], 10)); + const mask = fromPrefixLen(parseInt(cidrParts[1], 10)); - return ip.subnet(addr, mask); -}; + return subnet(addr, mask); +} -ip.not = function (addr) { - const buff = ip.toBuffer(addr); +/** + * Get the bitwise inverse (NOT every octet) of an IP address or subnet mask. + * + * @param {string} ip + */ +function not(ip) { + const buff = toBuffer(ip); for (let i = 0; i < buff.length; i++) { buff[i] = 0xff ^ buff[i]; } - return ip.toString(buff); -}; + return toString(buff); +} -ip.or = function (a, b) { - a = ip.toBuffer(a); - b = ip.toBuffer(b); +/** + * Get the bitwise OR of two IP addresses + * (usually an IP address and a subnet mask). + * + * @param {string} _a + * @param {string} _b + */ +function or(_a, _b) { + const a = toBuffer(_a); + const b = toBuffer(_b); // same protocol if (a.length === b.length) { for (let i = 0; i < a.length; ++i) { a[i] |= b[i]; } - return ip.toString(a); + return toString(a); // mixed protocols } @@ -268,12 +334,18 @@ ip.or = function (a, b) { buff[i] |= other[i - offset]; } - return ip.toString(buff); -}; + return toString(buff); +} -ip.isEqual = function (a, b) { - a = ip.toBuffer(a); - b = ip.toBuffer(b); +/** + * Check two IP address are the same. + * + * @param {string} ip1 + * @param {string} ip2 + */ +function isEqual(ip1, ip2) { + let a = toBuffer(ip1); + let b = toBuffer(ip2); // Same protocol if (a.length === b.length) { @@ -285,9 +357,7 @@ ip.isEqual = function (a, b) { // Swap if (b.length === 4) { - const t = b; - b = a; - a = t; + [a, b] = [b, a]; } // a - IPv4, b - IPv6 @@ -303,35 +373,54 @@ ip.isEqual = function (a, b) { } return true; -}; +} -ip.isPrivate = function (addr) { +/** + * Check whether an IP is within a private IP address range. + * + * @param {string} ip + */ +function isPrivate(ip) { return /^(::f{4}:)?10\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i - .test(addr) - || /^(::f{4}:)?192\.168\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) + .test(ip) + || /^(::f{4}:)?192\.168\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(ip) || /^(::f{4}:)?172\.(1[6-9]|2\d|30|31)\.([0-9]{1,3})\.([0-9]{1,3})$/i - .test(addr) - || /^(::f{4}:)?127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) - || /^(::f{4}:)?169\.254\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) - || /^f[cd][0-9a-f]{2}:/i.test(addr) - || /^fe80:/i.test(addr) - || /^::1$/.test(addr) - || /^::$/.test(addr); -}; + .test(ip) + || /^(::f{4}:)?127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(ip) + || /^(::f{4}:)?169\.254\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(ip) + || /^f[cd][0-9a-f]{2}:/i.test(ip) + || /^fe80:/i.test(ip) + || /^::1$/.test(ip) + || /^::$/.test(ip); +} -ip.isPublic = function (addr) { - return !ip.isPrivate(addr); -}; +/** + * Check whether an IP is within a public IP address range + * + * @param {string} addr + */ +function isPublic(addr) { + return !isPrivate(addr); +} -ip.isLoopback = function (addr) { +/** + * Check whether an IP is a loopback address. + * @param {string} ip + */ +function isLoopback(ip) { return /^(::f{4}:)?127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/ - .test(addr) - || /^fe80::1$/.test(addr) - || /^::1$/.test(addr) - || /^::$/.test(addr); -}; + .test(ip) + || /^fe80::1$/.test(ip) + || /^::1$/.test(ip) + || /^::$/.test(ip); +} -ip.loopback = function (family) { +/** + * Get the loopback address for an IP family + * @param {string | number} [family] + * The family can be either "ipv4" or "ipv6". Default: "ipv4". + */ +function loopback(family) { // // Default to `ipv4` // @@ -342,25 +431,26 @@ ip.loopback = function (family) { } return family === 'ipv4' ? '127.0.0.1' : 'fe80::1'; -}; +} -// -// ### function address (name, family) -// #### @name {string|'public'|'private'} **Optional** Name or security -// of the network interface. -// #### @family {ipv4|ipv6} **Optional** IP family of the address (defaults -// to ipv4). -// -// Returns the address for the network interface on the current system with -// the specified `name`: -// * String: First `family` address of the interface. -// If not found see `undefined`. -// * 'public': the first public ip address of family. -// * 'private': the first private ip address of family. -// * undefined: First address with `ipv4` or loopback address `127.0.0.1`. -// -ip.address = function (name, family) { - const interfaces = os.networkInterfaces(); +/** + * Returns the address for the network interface on the current system with + * the specified `name`: + * * String: First `family` address of the interface. + * If not found see `undefined`. + * * 'public': the first public ip address of family. + * * 'private': the first private ip address of family. + * * undefined: First address with `ipv4` or loopback address `127.0.0.1`. + * + * @param {string|'public'|'private'} [name] + * The name can be any named interface, or 'public' or 'private'. + * + * @param {'ipv4'|'ipv6'|4|6} family + * The family can be either "ipv4" or "ipv6". Default: "ipv4". + * + */ +function address(name, family = 'ipv4') { + const interfaces = networkInterfaces(); // // Default to `ipv4` @@ -389,34 +479,66 @@ ip.address = function (name, family) { // const addresses = interfaces[nic].filter((details) => { details.family = _normalizeFamily(details.family); - if (details.family !== family || ip.isLoopback(details.address)) { + if (details.family !== family || isLoopback(details.address)) { return false; } if (!name) { return true; } - return name === 'public' ? ip.isPrivate(details.address) - : ip.isPublic(details.address); + return name === 'public' ? isPrivate(details.address) + : isPublic(details.address); }); return addresses.length ? addresses[0].address : undefined; }).filter(Boolean); - return !all.length ? ip.loopback(family) : all[0]; -}; + return all.length ? all[0] : loopback(family); +} -ip.toLong = function (ip) { +/** + * Convert a string IPv4 IP address to the equivalent long numeric value. + * + * @param {string} ip + */ +function toLong(ip) { let ipl = 0; ip.split('.').forEach((octet) => { ipl <<= 8; - ipl += parseInt(octet); + ipl += +octet; }); - return (ipl >>> 0); -}; + return ipl >>> 0; +} -ip.fromLong = function (ipl) { - return (`${ipl >>> 24}.${ +/** + * Convert an IPv4 IP address from its the long numeric value to a string. + * + * @param {number} ipl + */ +function fromLong(ipl) { + return `${ipl >>> 24}.${ ipl >> 16 & 255}.${ ipl >> 8 & 255}.${ - ipl & 255}`); -}; + ipl & 255}`; +} + +export { + address, + cidr, + cidrSubnet, + fromLong, + fromPrefixLen, + isEqual, + isLoopback, + isPrivate, + isPublic, + isV4Format, + isV6Format, + loopback, + _mask as mask, + not, + or, + subnet, + toBuffer, + toLong, + toString +}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index d5e964d..674ae43 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "MIT", "devDependencies": { "eslint": "^8.15.0", - "mocha": "^10.0.0" + "mocha": "^10.2.0" } }, "node_modules/@eslint/eslintrc": { @@ -53,12 +53,6 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, - "node_modules/@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, "node_modules/acorn": { "version": "8.7.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", @@ -130,9 +124,9 @@ } }, "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "dependencies": { "normalize-path": "^3.0.0", @@ -200,6 +194,18 @@ "node": ">=6" } }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -243,6 +249,17 @@ "fsevents": "~2.3.2" } }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -298,6 +315,18 @@ } } }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -579,15 +608,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/find-up/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -623,9 +643,9 @@ "dev": true }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, "optional": true, @@ -931,12 +951,11 @@ } }, "node_modules/mocha": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz", - "integrity": "sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", + "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", "dev": true, "dependencies": { - "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", "chokidar": "3.5.3", @@ -971,15 +990,13 @@ "url": "https://opencollective.com/mochajs" } }, - "node_modules/mocha/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" + "balanced-match": "^1.0.0" } }, "node_modules/mocha/node_modules/minimatch": { @@ -994,15 +1011,6 @@ "node": ">=10" } }, - "node_modules/mocha/node_modules/minimatch/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/mocha/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -1024,33 +1032,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/mocha/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -1152,6 +1133,15 @@ "node": ">=6" } }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -1236,7 +1226,7 @@ "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, "engines": { "node": ">=0.10.0" @@ -1267,10 +1257,24 @@ } }, "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, "node_modules/serialize-javascript": { "version": "6.0.0", @@ -1462,6 +1466,33 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/yargs-parser": { "version": "20.2.4", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", @@ -1486,30 +1517,6 @@ "node": ">=10" } }, - "node_modules/yargs-unparser/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs-unparser/node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -1558,12 +1565,6 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, - "@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, "acorn": { "version": "8.7.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", @@ -1611,9 +1612,9 @@ } }, "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "requires": { "normalize-path": "^3.0.0", @@ -1669,6 +1670,12 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -1695,6 +1702,17 @@ "readdirp": "~3.6.0" } }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1736,6 +1754,12 @@ "ms": "2.1.2" } }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + }, "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -1947,14 +1971,6 @@ "requires": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" - }, - "dependencies": { - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - } } }, "flat": { @@ -1986,9 +2002,9 @@ "dev": true }, "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "optional": true }, @@ -2206,12 +2222,11 @@ } }, "mocha": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz", - "integrity": "sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", + "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", "dev": true, "requires": { - "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", "chokidar": "3.5.3", @@ -2235,15 +2250,13 @@ "yargs-unparser": "2.0.0" }, "dependencies": { - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" + "balanced-match": "^1.0.0" } }, "minimatch": { @@ -2253,17 +2266,6 @@ "dev": true, "requires": { "brace-expansion": "^2.0.1" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - } } }, "ms": { @@ -2280,27 +2282,6 @@ "requires": { "has-flag": "^4.0.0" } - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } } } }, @@ -2378,6 +2359,12 @@ "callsites": "^3.0.0" } }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -2435,7 +2422,7 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, "resolve-from": { @@ -2454,9 +2441,9 @@ } }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true }, "serialize-javascript": { @@ -2601,6 +2588,27 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, "yargs-parser": { "version": "20.2.4", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", @@ -2617,20 +2625,6 @@ "decamelize": "^4.0.0", "flat": "^5.0.2", "is-plain-obj": "^2.1.0" - }, - "dependencies": { - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - } } }, "yocto-queue": { diff --git a/package.json b/package.json index f0d95e9..23111b3 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,10 @@ "main": "lib/ip", "devDependencies": { "eslint": "^8.15.0", - "mocha": "^10.0.0" + "mocha": "^10.2.0" + }, + "engines": { + "node": ">=16.0" }, "scripts": { "lint": "eslint lib/*.js test/*.js", diff --git a/test/api-test.js b/test/api-test.js index f0fd222..adc9b60 100644 --- a/test/api-test.js +++ b/test/api-test.js @@ -1,9 +1,9 @@ /* global describe, it */ -const assert = require('assert'); -const { Buffer } = require('buffer'); -const net = require('net'); -const os = require('os'); -const ip = require('..'); +import assert from 'assert'; +import { Buffer } from 'buffer'; +import net from 'net'; +import os from 'os'; +import * as ip from '../lib/ip.js'; describe('IP library for node.js', () => { describe('toBuffer()/toString() methods', () => { @@ -14,7 +14,7 @@ describe('IP library for node.js', () => { }); it('should convert to buffer IPv4 address in-place', () => { - const buf = new Buffer(128); + const buf = Buffer.alloc(128); const offset = 64; ip.toBuffer('127.0.0.1', buf, offset); assert.equal(buf.toString('hex', offset, offset + 4), '7f000001'); @@ -22,7 +22,7 @@ describe('IP library for node.js', () => { }); it('should convert to buffer IPv6 address', () => { - const buf = ip.toBuffer('::1'); + const buf = Buffer.from(ip.toBuffer('::1')); assert(/(00){15,15}01/.test(buf.toString('hex'))); assert.equal(ip.toString(buf), '::1'); assert.equal(ip.toString(ip.toBuffer('1::')), '1::'); @@ -48,15 +48,15 @@ describe('IP library for node.js', () => { }); it('should convert to buffer IPv6 mapped IPv4 address', () => { - let buf = ip.toBuffer('::ffff:127.0.0.1'); + let buf = Buffer.from(ip.toBuffer('::ffff:127.0.0.1')); assert.equal(buf.toString('hex'), '00000000000000000000ffff7f000001'); assert.equal(ip.toString(buf), '::ffff:7f00:1'); - buf = ip.toBuffer('ffff::127.0.0.1'); + buf = Buffer.from(ip.toBuffer('ffff::127.0.0.1')); assert.equal(buf.toString('hex'), 'ffff000000000000000000007f000001'); assert.equal(ip.toString(buf), 'ffff::7f00:1'); - buf = ip.toBuffer('0:0:0:0:0:ffff:127.0.0.1'); + buf = Buffer.from(ip.toBuffer('0:0:0:0:0:ffff:127.0.0.1')); assert.equal(buf.toString('hex'), '00000000000000000000ffff7f000001'); assert.equal(ip.toString(buf), '::ffff:7f00:1'); });