From 1cfa26a923da6a62f5a9fa2b7dd700624a9269d3 Mon Sep 17 00:00:00 2001 From: Beau Gunderson Date: Fri, 18 Sep 2020 17:50:37 -0700 Subject: [PATCH] reformat --- .eslintignore | 2 +- .eslintrc.js | 23 +- ip-address.ts | 2 +- lib/common.ts | 13 +- lib/ipv4.ts | 127 ++++---- lib/ipv6.ts | 460 ++++++++++++++--------------- lib/v6/constants.ts | 8 +- lib/v6/helpers.ts | 68 +++-- lib/v6/regular-expressions.ts | 57 ++-- package-lock.json | 43 +++ package.json | 1 + test/address-test.js | 90 +++--- test/functionality-v4-test.js | 153 +++++----- test/functionality-v6-test.js | 524 +++++++++++++++++----------------- 14 files changed, 807 insertions(+), 764 deletions(-) diff --git a/.eslintignore b/.eslintignore index 1eae0cf..763301f 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,2 +1,2 @@ dist/ -node_modules/ +node_modules/ \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js index b30194f..24fb079 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -8,13 +8,7 @@ module.exports = { parser: '@typescript-eslint/parser', - plugins: [ - 'filenames', - 'import', - 'prettier', - 'sort-imports-es6-autofix', - '@typescript-eslint', - ], + plugins: ['filenames', 'import', 'prettier', 'sort-imports-es6-autofix', '@typescript-eslint'], extends: ['airbnb', 'prettier'], @@ -75,19 +69,6 @@ module.exports = { }, ], - // JSX - 'jsx-a11y/anchor-is-valid': 'off', - 'jsx-a11y/click-events-have-key-events': 'off', - 'jsx-a11y/href-no-hash': 'off', - 'jsx-a11y/img-has-alt': 'off', - 'jsx-a11y/label-has-associated-control': 'off', - 'jsx-a11y/label-has-for': 'off', - 'jsx-a11y/no-noninteractive-element-interactions': 'warn', - 'jsx-a11y/no-static-element-interactions': 'off', - 'jsx-a11y/tabindex-no-positive': 'off', - - 'rulesdir/import-match-filename': 'off', - '@typescript-eslint/no-unused-vars': 'error', // preferable to built in 'sort-imports' because it handles default imports better and has better auto-fix @@ -96,4 +77,4 @@ module.exports = { { ignoreCase: true, memberSyntaxSortOrder: ['none', 'all', 'single', 'multiple'] }, ], }, -}; \ No newline at end of file +}; diff --git a/ip-address.ts b/ip-address.ts index a40cf4d..03a05a6 100644 --- a/ip-address.ts +++ b/ip-address.ts @@ -6,4 +6,4 @@ export { Address6 }; import * as helpers from './lib/v6/helpers'; -export const v6 = { helpers } +export const v6 = { helpers }; diff --git a/lib/common.ts b/lib/common.ts index 7171a79..e8ead51 100644 --- a/lib/common.ts +++ b/lib/common.ts @@ -1,5 +1,5 @@ -import { Address4 } from "./ipv4"; -import { Address6 } from "./ipv6"; +import { Address4 } from './ipv4'; +import { Address6 } from './ipv6'; // A wrapper function that returns false if the address is not valid; used to // avoid boilerplate checks for `if (!this.valid) { return false; }` @@ -11,9 +11,12 @@ export function falseIfInvalid any>(fn: F) { return fn.apply(this, args); }; -}; +} -export const isInSubnet = falseIfInvalid(function (this: Address4 | Address6, address: Address4 | Address6) { +export const isInSubnet = falseIfInvalid(function ( + this: Address4 | Address6, + address: Address4 | Address6 +) { if (this.subnetMask < address.subnetMask) { return false; } @@ -26,7 +29,7 @@ export const isInSubnet = falseIfInvalid(function (this: Address4 | Address6, ad }); export const isCorrect = function (defaultBits: number) { - return falseIfInvalid(function (this: Address4 | Address6, ) { + return falseIfInvalid(function (this: Address4 | Address6) { if (this.addressMinusSuffix !== this.correctForm()) { return false; } diff --git a/lib/ipv4.ts b/lib/ipv4.ts index 06e5914..6f8f9e3 100644 --- a/lib/ipv4.ts +++ b/lib/ipv4.ts @@ -1,11 +1,11 @@ -import { BigInteger } from 'jsbn'; -import { sprintf } from 'sprintf-js'; - -import padStart from 'lodash.padstart'; -import repeat from 'lodash.repeat'; +/* eslint-disable no-param-reassign */ import * as common from './common'; import * as constants from './v4/constants'; +import padStart from 'lodash.padstart'; +import repeat from 'lodash.repeat'; +import { BigInteger } from 'jsbn'; +import { sprintf } from 'sprintf-js'; /** * Represents an IPv4 address @@ -27,12 +27,12 @@ export class Address4 { constructor(address: string) { this.address = address; - var subnet = constants.RE_SUBNET_STRING.exec(address); + const subnet = constants.RE_SUBNET_STRING.exec(address); if (subnet) { this.parsedSubnet = subnet[0].replace('/', ''); this.subnetMask = parseInt(this.parsedSubnet, 10); - this.subnet = '/' + this.subnetMask; + this.subnet = `/${this.subnetMask}`; if (this.subnetMask < 0 || this.subnetMask > constants.BITS) { this.valid = false; @@ -53,7 +53,7 @@ export class Address4 { * Parses a v4 address */ parse(address: string) { - var groups = address.split('.'); + const groups = address.split('.'); if (address.match(constants.RE_ADDRESS)) { this.valid = true; @@ -62,7 +62,7 @@ export class Address4 { } return groups; - }; + } /** * Return true if the address is valid @@ -72,7 +72,7 @@ export class Address4 { */ isValid(): boolean { return this.valid; - }; + } /** * Returns the correct form of an address @@ -80,11 +80,9 @@ export class Address4 { * @instance * @returns {String} */ - correctForm() { - return this.parsedAddress.map(function (part) { - return parseInt(part, 10); - }).join('.'); - }; + correctForm(): string { + return this.parsedAddress.map((part) => parseInt(part, 10)).join('.'); + } /** * Returns true if the address is correct, false otherwise @@ -101,19 +99,19 @@ export class Address4 { * @param {string} hex - a hex string to convert * @returns {Address4} */ - static fromHex(hex: string) { - var padded = padStart(hex.replace(/:/g, ''), 8, '0'); - var groups = []; - var i; + static fromHex(hex: string): Address4 { + const padded = padStart(hex.replace(/:/g, ''), 8, '0'); + const groups = []; + let i; for (i = 0; i < 8; i += 2) { - var h = padded.slice(i, i + 2); + const h = padded.slice(i, i + 2); groups.push(parseInt(h, 16)); } return new Address4(groups.join('.')); - }; + } /** * Converts an integer into a IPv4 address object @@ -122,9 +120,9 @@ export class Address4 { * @param {integer} integer - a number to convert * @returns {Address4} */ - static fromInteger(integer: number) { + static fromInteger(integer: number): Address4 { return Address4.fromHex(integer.toString(16)); - }; + } /** * Converts an IPv4 address object to a hex string @@ -133,10 +131,8 @@ export class Address4 { * @returns {String} */ toHex(): string { - return this.parsedAddress.map(function (part) { - return sprintf('%02x', parseInt(part, 10)); - }).join(':'); - }; + return this.parsedAddress.map((part) => sprintf('%02x', parseInt(part, 10))).join(':'); + } /** * Converts an IPv4 address object to an array of bytes @@ -145,10 +141,8 @@ export class Address4 { * @returns {Array} */ toArray(): number[] { - return this.parsedAddress.map(function (part) { - return parseInt(part, 10); - }); - }; + return this.parsedAddress.map((part) => parseInt(part, 10)); + } /** * Converts an IPv4 address object to an IPv6 address group @@ -157,19 +151,21 @@ export class Address4 { * @returns {String} */ toGroup6(): string { - var output = []; - var i; + const output = []; + let i; for (i = 0; i < constants.GROUPS; i += 2) { - var hex = sprintf('%02x%02x', + const hex = sprintf( + '%02x%02x', parseInt(this.parsedAddress[i], 10), - parseInt(this.parsedAddress[i + 1], 10)); + parseInt(this.parsedAddress[i + 1], 10) + ); output.push(sprintf('%x', parseInt(hex, 16))); } return output.join(':'); - }; + } /** * Returns the address as a BigInteger @@ -182,10 +178,11 @@ export class Address4 { return null; } - return new BigInteger(this.parsedAddress.map(function (n) { - return sprintf('%02x', parseInt(n, 10)); - }).join(''), 16); - }; + return new BigInteger( + this.parsedAddress.map((n) => sprintf('%02x', parseInt(n, 10))).join(''), + 16 + ); + } /** * Helper function getting start address. @@ -194,10 +191,8 @@ export class Address4 { * @returns {BigInteger} */ _startAddress(): BigInteger { - return new BigInteger( - this.mask() + repeat('0', constants.BITS - this.subnetMask), 2 - ); - }; + return new BigInteger(this.mask() + repeat('0', constants.BITS - this.subnetMask), 2); + } /** * The first address in the range given by this address' subnet. @@ -206,9 +201,9 @@ export class Address4 { * @instance * @returns {Address4} */ - startAddress() { + startAddress(): Address4 { return Address4.fromBigInteger(this._startAddress()); - }; + } /** * The first host address in the range given by this address's subnet ie @@ -217,10 +212,10 @@ export class Address4 { * @instance * @returns {Address4} */ - startAddressExclusive() { - var adjust = new BigInteger('1'); + startAddressExclusive(): Address4 { + const adjust = new BigInteger('1'); return Address4.fromBigInteger(this._startAddress().add(adjust)); - }; + } /** * Helper function getting end address. @@ -228,11 +223,9 @@ export class Address4 { * @instance * @returns {BigInteger} */ - _endAddress() { - return new BigInteger( - this.mask() + repeat('1', constants.BITS - this.subnetMask), 2 - ); - }; + _endAddress(): BigInteger { + return new BigInteger(this.mask() + repeat('1', constants.BITS - this.subnetMask), 2); + } /** * The last address in the range given by this address' subnet @@ -241,9 +234,9 @@ export class Address4 { * @instance * @returns {Address4} */ - endAddress() { + endAddress(): Address4 { return Address4.fromBigInteger(this._endAddress()); - }; + } /** * The last host address in the range given by this address's subnet ie @@ -252,10 +245,10 @@ export class Address4 { * @instance * @returns {Address4} */ - endAddressExclusive() { - var adjust = new BigInteger('1'); + endAddressExclusive(): Address4 { + const adjust = new BigInteger('1'); return Address4.fromBigInteger(this._endAddress().subtract(adjust)); - }; + } /** * Converts a BigInteger to a v4 address object @@ -264,9 +257,9 @@ export class Address4 { * @param {BigInteger} bigInteger - a BigInteger to convert * @returns {Address4} */ - static fromBigInteger(bigInteger: BigInteger) { + static fromBigInteger(bigInteger: BigInteger): Address4 { return Address4.fromInteger(parseInt(bigInteger.toString(), 10)); - }; + } /** * Returns the first n bits of the address, defaulting to the @@ -281,7 +274,7 @@ export class Address4 { } return this.getBitsBase2(0, mask); - }; + } /** * Returns the bits in the given range as a base-2 string @@ -291,7 +284,7 @@ export class Address4 { */ getBitsBase2(start: number, end: number): string { return this.binaryZeroPad().slice(start, end); - }; + } /** * Returns true if the given address is in the subnet of the current address @@ -307,9 +300,9 @@ export class Address4 { * @instance * @returns {boolean} */ - isMulticast() { + isMulticast(): boolean { return this.isInSubnet(new Address4('224.0.0.0/4')); - }; + } /** * Returns a zero-padded base-2 string representation of the address @@ -317,7 +310,7 @@ export class Address4 { * @instance * @returns {string} */ - binaryZeroPad() { + binaryZeroPad(): string { return padStart(this.bigInteger().toString(2), constants.BITS, '0'); - }; + } } diff --git a/lib/ipv6.ts b/lib/ipv6.ts index 91da49b..bc6128b 100644 --- a/lib/ipv6.ts +++ b/lib/ipv6.ts @@ -1,22 +1,25 @@ -import { BigInteger } from 'jsbn'; -import { sprintf } from 'sprintf-js'; - -import merge from 'lodash.merge'; -import padStart from 'lodash.padstart'; -import repeat from 'lodash.repeat'; -import find from 'lodash.find'; -import max from 'lodash.max'; +/* eslint-disable prefer-destructuring */ +/* eslint-disable no-param-reassign */ +import * as common from './common'; import * as constants4 from './v4/constants'; import * as constants6 from './v6/constants'; -import * as common from './common'; import * as helpers from './v6/helpers'; - +import find from 'lodash.find'; +import max from 'lodash.max'; +import padStart from 'lodash.padstart'; +import repeat from 'lodash.repeat'; import { Address4 } from './ipv4'; -import { simpleRegularExpression, possibleElisions, ADDRESS_BOUNDARY } from './v6/regular-expressions'; +import { + ADDRESS_BOUNDARY, + possibleElisions, + simpleRegularExpression, +} from './v6/regular-expressions'; +import { BigInteger } from 'jsbn'; +import { sprintf } from 'sprintf-js'; function addCommas(number: string): string { - var r = /(\d+)(\d{3})/; + const r = /(\d+)(\d{3})/; while (r.test(number)) { number = number.replace(r, '$1,$2'); @@ -36,9 +39,9 @@ function spanLeadingZeroes4(n: string): string { * A helper function to compact an array */ function compact(address: string, slice: number[]) { - var s1 = []; - var s2 = []; - var i; + const s1 = []; + const s2 = []; + let i; for (i = 0; i < address.length; i++) { if (i < slice[0]) { @@ -56,7 +59,8 @@ function paddedHex(octet: string): string { } function unsignByte(b) { - return b & 0xFF; + // eslint-disable-next-line no-bitwise + return b & 0xff; } /** @@ -93,16 +97,14 @@ export class Address6 { this.address = address; - var subnet = constants6.RE_SUBNET_STRING.exec(address); + const subnet = constants6.RE_SUBNET_STRING.exec(address); if (subnet) { this.parsedSubnet = subnet[0].replace('/', ''); this.subnetMask = parseInt(this.parsedSubnet, 10); - this.subnet = '/' + this.subnetMask; + this.subnet = `/${this.subnetMask}`; - if (isNaN(this.subnetMask) || - this.subnetMask < 0 || - this.subnetMask > constants6.BITS) { + if (isNaN(this.subnetMask) || this.subnetMask < 0 || this.subnetMask > constants6.BITS) { this.valid = false; this.error = 'Invalid subnet mask.'; @@ -117,7 +119,7 @@ export class Address6 { return; } - var zone = constants6.RE_ZONE_STRING.exec(address); + const zone = constants6.RE_ZONE_STRING.exec(address); if (zone) { this.zone = zone[0]; @@ -142,16 +144,16 @@ export class Address6 { * address.correctForm(); // '::e8:d4a5:1000' */ static fromBigInteger(bigInteger: BigInteger): Address6 { - var hex = padStart(bigInteger.toString(16), 32, '0'); - var groups = []; - var i; + const hex = padStart(bigInteger.toString(16), 32, '0'); + const groups = []; + let i; for (i = 0; i < constants6.GROUPS; i++) { groups.push(hex.slice(i * 4, (i + 1) * 4)); } return new Address6(groups.join(':')); - }; + } /** * Convert a URL (with optional port number) to an address object @@ -164,9 +166,9 @@ export class Address6 { * addressAndPort.port; // 8080 */ static fromURL(url: string) { - var host; - var port; - var result; + let host: string; + let port: string | number; + let result: string[]; // If we have brackets parse them and find a port if (url.indexOf('[') !== -1 && url.indexOf(']:') !== -1) { @@ -176,13 +178,13 @@ export class Address6 { return { error: 'failed to parse address with port', address: null, - port: null + port: null, }; } host = result[1]; port = result[2]; - // If there's a URL extract the address + // If there's a URL extract the address } else if (url.indexOf('/') !== -1) { // Remove the protocol prefix url = url.replace(/^[a-z0-9]+:\/\//, ''); @@ -194,12 +196,12 @@ export class Address6 { return { error: 'failed to parse address from URL', address: null, - port: null + port: null, }; } host = result[1]; - // Otherwise just assign the URL to the host and let the library parse it + // Otherwise just assign the URL to the host and let the library parse it } else { host = url; } @@ -208,7 +210,7 @@ export class Address6 { if (port) { port = parseInt(port, 10); - //squelch out of range ports + // squelch out of range ports if (port < 0 || port > 65536) { port = null; } @@ -219,9 +221,9 @@ export class Address6 { return { address: new Address6(host), - port: port + port, }; - }; + } /** * Create an IPv6-mapped address given an IPv4 address @@ -239,8 +241,8 @@ export class Address6 { const mask6 = constants6.BITS - (constants4.BITS - address4.subnetMask); - return new Address6('::ffff:' + address4.correctForm() + '/' + mask6); - }; + return new Address6(`::ffff:${address4.correctForm()}/${mask6}`); + } /** * Return an address from ip6.arpa form @@ -253,29 +255,29 @@ export class Address6 { * address.correctForm(); // '2001:0:ce49:7601:e866:efff:62c3:fffe' */ static fromArpa(arpaFormAddress: string): Address6 { - //remove ending ".ip6.arpa." or just "." - var address = arpaFormAddress.replace(/(\.ip6\.arpa)?\.$/, ''); - var semicolonAmount = 7; + // remove ending ".ip6.arpa." or just "." + let address = arpaFormAddress.replace(/(\.ip6\.arpa)?\.$/, ''); + const semicolonAmount = 7; - //correct ip6.arpa form with ending removed will be 63 characters + // correct ip6.arpa form with ending removed will be 63 characters if (address.length !== 63) { return { error: "Not Valid 'ip6.arpa' form", - address: null + address: null, } as Address6; } const parts = address.split('.').reverse(); - for (var i = semicolonAmount; i > 0; i--) { - var insertIndex = i * 4; + for (let i = semicolonAmount; i > 0; i--) { + const insertIndex = i * 4; parts.splice(insertIndex, 0, ':'); } address = parts.join(''); return new Address6(address); - }; + } /** * Return the Microsoft UNC transcription of the address @@ -284,9 +286,8 @@ export class Address6 { * @returns {String} the Microsoft UNC transcription of the address */ microsoftTranscription(): string { - return sprintf('%s.ipv6-literal.net', - this.correctForm().replace(/:/g, '-')); - }; + return sprintf('%s.ipv6-literal.net', this.correctForm().replace(/:/g, '-')); + } /** * Return the first n bits of the address, defaulting to the subnet mask @@ -297,7 +298,7 @@ export class Address6 { */ mask(mask: number = this.subnetMask): string { return this.getBitsBase2(0, mask); - }; + } /** * Return the number of possible subnets of a given size in the address @@ -308,16 +309,16 @@ export class Address6 { */ // TODO: probably useful to have a numeric version of this too possibleSubnets(subnetSize: number = 128): string { - var availableBits = constants6.BITS - this.subnetMask; - var subnetBits = Math.abs(subnetSize - constants6.BITS); - var subnetPowers = availableBits - subnetBits; + const availableBits = constants6.BITS - this.subnetMask; + const subnetBits = Math.abs(subnetSize - constants6.BITS); + const subnetPowers = availableBits - subnetBits; if (subnetPowers < 0) { return '0'; } return addCommas(new BigInteger('2', 10).pow(subnetPowers).toString(10)); - }; + } /** * Helper function getting start address. @@ -326,10 +327,8 @@ export class Address6 { * @returns {BigInteger} */ _startAddress(): BigInteger { - return new BigInteger( - this.mask() + repeat('0', constants6.BITS - this.subnetMask), 2 - ); - }; + return new BigInteger(this.mask() + repeat('0', constants6.BITS - this.subnetMask), 2); + } /** * The first address in the range given by this address' subnet @@ -340,7 +339,7 @@ export class Address6 { */ startAddress(): Address6 { return Address6.fromBigInteger(this._startAddress()); - }; + } /** * The first host address in the range given by this address's subnet ie @@ -350,9 +349,9 @@ export class Address6 { * @returns {Address6} */ startAddressExclusive(): Address6 { - var adjust = new BigInteger('1'); + const adjust = new BigInteger('1'); return Address6.fromBigInteger(this._startAddress().add(adjust)); - }; + } /** * Helper function getting end address. @@ -361,10 +360,8 @@ export class Address6 { * @returns {BigInteger} */ _endAddress(): BigInteger { - return new BigInteger( - this.mask() + repeat('1', constants6.BITS - this.subnetMask), 2 - ); - }; + return new BigInteger(this.mask() + repeat('1', constants6.BITS - this.subnetMask), 2); + } /** * The last address in the range given by this address' subnet @@ -375,7 +372,7 @@ export class Address6 { */ endAddress(): Address6 { return Address6.fromBigInteger(this._endAddress()); - }; + } /** * The last host address in the range given by this address's subnet ie @@ -385,9 +382,9 @@ export class Address6 { * @returns {Address6} */ endAddressExclusive(): Address6 { - var adjust = new BigInteger('1'); + const adjust = new BigInteger('1'); return Address6.fromBigInteger(this._endAddress().subtract(adjust)); - }; + } /** * Return the scope of the address @@ -396,15 +393,14 @@ export class Address6 { * @returns {String} */ getScope(): string { - var scope = constants6.SCOPES[this.getBits(12, 16).intValue()]; + let scope = constants6.SCOPES[this.getBits(12, 16).intValue()]; - if (this.getType() === 'Global unicast' && - scope !== 'Link local') { + if (this.getType() === 'Global unicast' && scope !== 'Link local') { scope = 'Global'; } return scope; - }; + } /** * Return the type of the address @@ -413,14 +409,14 @@ export class Address6 { * @returns {String} */ getType(): string { - var self = this; + const self = this; function isType(name: string, type) { return self.isInSubnet(new Address6(type)); } return find(constants6.TYPES, isType) || 'Global unicast'; - }; + } /** * Return the bits in the given range as a BigInteger @@ -430,7 +426,7 @@ export class Address6 { */ getBits(start: number, end: number): BigInteger { return new BigInteger(this.getBitsBase2(start, end), 2); - }; + } /** * Return the bits in the given range as a base-2 string @@ -440,7 +436,7 @@ export class Address6 { */ getBitsBase2(start: number, end: number): string { return this.binaryZeroPad().slice(start, end); - }; + } /** * Return the bits in the given range as a base-16 string @@ -449,14 +445,14 @@ export class Address6 { * @returns {String} */ getBitsBase16(start: number, end: number): string { - var length = end - start; + const length = end - start; if (length % 4 !== 0) { return null; } return padStart(this.getBits(start, end).toString(16), length / 4, '0'); - }; + } /** * Return the bits that are set past the subnet mask length @@ -466,7 +462,7 @@ export class Address6 { */ getBitsPastSubnet(): string { return this.getBitsBase2(this.subnetMask, constants6.BITS); - }; + } /** * Return the reversed ip6.arpa form of the address @@ -481,9 +477,9 @@ export class Address6 { options = {}; } - var characters = Math.floor(this.subnetMask / 4); + const characters = Math.floor(this.subnetMask / 4); - var reversed = this.canonicalForm() + const reversed = this.canonicalForm() .replace(/:/g, '') .split('') .slice(0, characters) @@ -503,7 +499,7 @@ export class Address6 { } return 'ip6.arpa.'; - }; + } /** * Return the correct form of the address @@ -516,14 +512,14 @@ export class Address6 { return null; } - var i; - var groups = []; + let i; + let groups = []; - var zeroCounter = 0; - var zeroes = []; + let zeroCounter = 0; + const zeroes = []; for (i = 0; i < this.parsedAddress.length; i++) { - var value = parseInt(this.parsedAddress[i], 16); + const value = parseInt(this.parsedAddress[i], 16); if (value === 0) { zeroCounter++; @@ -540,16 +536,13 @@ export class Address6 { // Do we end with a string of zeroes? if (zeroCounter > 1) { - zeroes.push([this.parsedAddress.length - zeroCounter, - this.parsedAddress.length - 1]); + zeroes.push([this.parsedAddress.length - zeroCounter, this.parsedAddress.length - 1]); } - var zeroLengths = zeroes.map(function (n) { - return (n[1] - n[0]) + 1; - }); + const zeroLengths = zeroes.map((n) => n[1] - n[0] + 1); if (zeroes.length > 0) { - var index = zeroLengths.indexOf(max(zeroLengths)); + const index = zeroLengths.indexOf(max(zeroLengths)); groups = compact(this.parsedAddress, zeroes[index]); } else { @@ -562,14 +555,14 @@ export class Address6 { } } - var correct = groups.join(':'); + let correct = groups.join(':'); correct = correct.replace(/^compact$/, '::'); correct = correct.replace(/^compact|compact$/, ':'); correct = correct.replace(/compact/, ''); return correct; - }; + } /** * Return a zero-padded base-2 string representation of the address @@ -584,25 +577,27 @@ export class Address6 { */ binaryZeroPad(): string { return padStart(this.bigInteger().toString(2), constants6.BITS, '0'); - }; + } // TODO: Improve the semantics of this helper function parse4in6(address: string) { - var groups = address.split(':'); - var lastGroup = groups.slice(-1)[0]; + const groups = address.split(':'); + const lastGroup = groups.slice(-1)[0]; - var address4 = lastGroup.match(constants4.RE_ADDRESS); + const address4 = lastGroup.match(constants4.RE_ADDRESS); if (address4) { - var temp4 = new Address4(address4[0]); + const temp4 = new Address4(address4[0]); - for (var i = 0; i < temp4.groups; i++) { + for (let i = 0; i < temp4.groups; i++) { if (/^0[0-9]+/.test(temp4.parsedAddress[i])) { this.valid = false; this.error = 'IPv4 addresses can not have leading zeroes.'; - this.parseError = address.replace(constants4.RE_ADDRESS, - temp4.parsedAddress.map(spanLeadingZeroes4).join('.')); + this.parseError = address.replace( + constants4.RE_ADDRESS, + temp4.parsedAddress.map(spanLeadingZeroes4).join('.') + ); return null; } @@ -616,7 +611,7 @@ export class Address6 { } return address; - }; + } // TODO: Make private? parse(address: string) { @@ -626,50 +621,55 @@ export class Address6 { return null; } - var badCharacters = address.match(constants6.RE_BAD_CHARACTERS); + const badCharacters = address.match(constants6.RE_BAD_CHARACTERS); if (badCharacters) { this.valid = false; - this.error = sprintf('Bad character%s detected in address: %s', - badCharacters.length > 1 ? 's' : '', badCharacters.join('')); + this.error = sprintf( + 'Bad character%s detected in address: %s', + badCharacters.length > 1 ? 's' : '', + badCharacters.join('') + ); - this.parseError = address.replace(constants6.RE_BAD_CHARACTERS, - '$1'); + this.parseError = address.replace( + constants6.RE_BAD_CHARACTERS, + '$1' + ); return null; } - var badAddress = address.match(constants6.RE_BAD_ADDRESS); + const badAddress = address.match(constants6.RE_BAD_ADDRESS); if (badAddress) { this.valid = false; this.error = sprintf('Address failed regex: %s', badAddress.join('')); - this.parseError = address.replace(constants6.RE_BAD_ADDRESS, - '$1'); + this.parseError = address.replace( + constants6.RE_BAD_ADDRESS, + '$1' + ); return null; } - var groups = []; + let groups = []; - var halves = address.split('::'); + const halves = address.split('::'); if (halves.length === 2) { - var first = halves[0].split(':'); - var last = halves[1].split(':'); + let first = halves[0].split(':'); + let last = halves[1].split(':'); - if (first.length === 1 && - first[0] === '') { + if (first.length === 1 && first[0] === '') { first = []; } - if (last.length === 1 && - last[0] === '') { + if (last.length === 1 && last[0] === '') { last = []; } - var remaining = this.groups - (first.length + last.length); + const remaining = this.groups - (first.length + last.length); if (!remaining) { this.valid = false; @@ -683,17 +683,15 @@ export class Address6 { this.elisionBegin = first.length; this.elisionEnd = first.length + this.elidedGroups; - first.forEach(function (group) { - groups.push(group); - }); + // TODO: replace with concat? + first.forEach((group) => groups.push(group)); - for (var i = 0; i < remaining; i++) { + for (let i = 0; i < remaining; i++) { groups.push(0); } - last.forEach(function (group) { - groups.push(group); - }); + // TODO: replace with concat? + last.forEach((group) => groups.push(group)); } else if (halves.length === 1) { groups = address.split(':'); @@ -705,9 +703,7 @@ export class Address6 { return null; } - groups = groups.map(function (g) { - return sprintf('%x', parseInt(g, 16)); - }); + groups = groups.map((g) => sprintf('%x', parseInt(g, 16))); if (groups.length !== this.groups) { this.valid = false; @@ -719,7 +715,7 @@ export class Address6 { this.valid = true; return groups; - }; + } /** * Return the canonical form of the address @@ -733,7 +729,7 @@ export class Address6 { } return this.parsedAddress.map(paddedHex).join(':'); - }; + } /** * Return the decimal form of the address @@ -746,10 +742,8 @@ export class Address6 { return null; } - return this.parsedAddress.map(function (n) { - return sprintf('%05d', parseInt(n, 16)); - }).join(':'); - }; + return this.parsedAddress.map((n) => sprintf('%05d', parseInt(n, 16))).join(':'); + } /** * Return the address as a BigInteger @@ -763,7 +757,7 @@ export class Address6 { } return new BigInteger(this.parsedAddress.map(paddedHex).join(''), 16); - }; + } /** * Return the last two groups of this address as an IPv4 address string @@ -775,11 +769,10 @@ export class Address6 { * address.to4().correctForm(); // '24.37.191.17' */ to4(): Address4 { - var binary = this.binaryZeroPad().split(''); + const binary = this.binaryZeroPad().split(''); - return Address4.fromHex(new BigInteger(binary.slice(96, 128) - .join(''), 2).toString(16)); - }; + return Address4.fromHex(new BigInteger(binary.slice(96, 128).join(''), 2).toString(16)); + } /** * Return the v4-in-v6 form of the address @@ -788,19 +781,19 @@ export class Address6 { * @returns {String} */ to4in6(): string { - var address4 = this.to4(); - var address6 = new Address6(this.parsedAddress.slice(0, 6).join(':'), 6); + const address4 = this.to4(); + const address6 = new Address6(this.parsedAddress.slice(0, 6).join(':'), 6); - var correct = address6.correctForm(); + const correct = address6.correctForm(); - var infix = ''; + let infix = ''; if (!/:$/.test(correct)) { infix = ':'; } return address6.correctForm() + infix + address4.address; - }; + } /** * Return an object containing the Teredo properties of the address @@ -830,39 +823,39 @@ export class Address6 { - Bits 96 to 127 contains the obfuscated IPv4 address. This is the public IPv4 address of the NAT with all bits inverted. */ - var prefix = this.getBitsBase16(0, 32); + const prefix = this.getBitsBase16(0, 32); - var udpPort = this.getBits(80, 96).xor(new BigInteger('ffff', 16)).toString(); + const udpPort = this.getBits(80, 96).xor(new BigInteger('ffff', 16)).toString(); - var server4 = Address4.fromHex(this.getBitsBase16(32, 64)); - var client4 = Address4.fromHex(this.getBits(96, 128) - .xor(new BigInteger('ffffffff', 16)).toString(16)); + const server4 = Address4.fromHex(this.getBitsBase16(32, 64)); + const client4 = Address4.fromHex( + this.getBits(96, 128).xor(new BigInteger('ffffffff', 16)).toString(16) + ); - var flags = this.getBits(64, 80); - var flagsBase2 = this.getBitsBase2(64, 80); + const flags = this.getBits(64, 80); + const flagsBase2 = this.getBitsBase2(64, 80); - var coneNat = flags.testBit(15); - var reserved = flags.testBit(14); - var groupIndividual = flags.testBit(8); - var universalLocal = flags.testBit(9); - var nonce = new BigInteger(flagsBase2.slice(2, 6) + - flagsBase2.slice(8, 16), 2).toString(10); + const coneNat = flags.testBit(15); + const reserved = flags.testBit(14); + const groupIndividual = flags.testBit(8); + const universalLocal = flags.testBit(9); + const nonce = new BigInteger(flagsBase2.slice(2, 6) + flagsBase2.slice(8, 16), 2).toString(10); return { prefix: sprintf('%s:%s', prefix.slice(0, 4), prefix.slice(4, 8)), server4: server4.address, client4: client4.address, flags: flagsBase2, - coneNat: coneNat, + coneNat, microsoft: { - reserved: reserved, - universalLocal: universalLocal, - groupIndividual: groupIndividual, - nonce: nonce + reserved, + universalLocal, + groupIndividual, + nonce, }, - udpPort: udpPort + udpPort, }; - }; + } /** * Return an object containing the 6to4 properties of the address @@ -876,15 +869,15 @@ export class Address6 { - Bits 16 to 48 embed the IPv4 address of the 6to4 gateway that is used. */ - var prefix = this.getBitsBase16(0, 16); + const prefix = this.getBitsBase16(0, 16); - var gateway = Address4.fromHex(this.getBitsBase16(16, 48)); + const gateway = Address4.fromHex(this.getBitsBase16(16, 48)); return { prefix: sprintf('%s', prefix.slice(0, 4)), - gateway: gateway.address + gateway: gateway.address, }; - }; + } /** * Return a v6 6to4 address from a v6 v4inv6 address @@ -897,16 +890,16 @@ export class Address6 { return null; } - var addr6to4 = [ + const addr6to4 = [ '2002', this.getBitsBase16(96, 112), this.getBitsBase16(112, 128), '', - '/16' + '/16', ].join(':'); return new Address6(addr6to4); - }; + } /** * Return a byte array @@ -915,7 +908,7 @@ export class Address6 { * @returns {Array} */ toByteArray(): Array { - var byteArray = this.bigInteger().toByteArray(); + const byteArray = this.bigInteger().toByteArray(); // work around issue where `toByteArray` returns a leading 0 element if (byteArray.length === 17 && byteArray[0] === 0) { @@ -923,7 +916,7 @@ export class Address6 { } return byteArray; - }; + } /** * Return an unsigned byte array @@ -933,7 +926,7 @@ export class Address6 { */ toUnsignedByteArray(): Array { return this.toByteArray().map(unsignByte); - }; + } /** * Convert a byte array to an Address6 object @@ -943,7 +936,7 @@ export class Address6 { */ static fromByteArray(bytes): Address6 { return this.fromUnsignedByteArray(bytes.map(unsignByte)); - }; + } /** * Convert an unsigned byte array to an Address6 object @@ -952,21 +945,20 @@ export class Address6 { * @returns {Address6} */ static fromUnsignedByteArray(bytes): Address6 { - var BYTE_MAX = new BigInteger('256', 10); - var result = new BigInteger('0', 10); - var multiplier = new BigInteger('1', 10); + const BYTE_MAX = new BigInteger('256', 10); + let result = new BigInteger('0', 10); + let multiplier = new BigInteger('1', 10); - for (var i = bytes.length - 1; i >= 0; i--) { - result = result.add( - multiplier.multiply(new BigInteger(bytes[i].toString(10), 10))); + for (let i = bytes.length - 1; i >= 0; i--) { + result = result.add(multiplier.multiply(new BigInteger(bytes[i].toString(10), 10))); multiplier = multiplier.multiply(BYTE_MAX); } return Address6.fromBigInteger(result); - }; + } - //#region Attributes + // #region Attributes /** * Returns true if the address is valid, false otherwise * @memberof Address6 @@ -975,7 +967,7 @@ export class Address6 { */ isValid(this: Address6): boolean { return this.valid; - }; + } /** * Returns true if the given address is in the subnet of the current address @@ -1011,8 +1003,10 @@ export class Address6 { */ isLinkLocal = common.falseIfInvalid(function (this: Address6) { // Zeroes are required, i.e. we can't check isInSubnet with 'fe80::/10' - if (this.getBitsBase2(0, 64) === - '1111111010000000000000000000000000000000000000000000000000000000') { + if ( + this.getBitsBase2(0, 64) === + '1111111010000000000000000000000000000000000000000000000000000000' + ) { return true; } @@ -1068,9 +1062,9 @@ export class Address6 { isLoopback = common.falseIfInvalid(function () { return this.getType() === 'Loopback'; }); - //#endregion + // #endregion - //#region HTML + // #region HTML /** * @returns {String} the address in link form with a default port of 80 */ @@ -1082,12 +1076,12 @@ export class Address6 { } return sprintf('http://[%s]%s/', this.correctForm(), optionalPort); - }; + } /** * @returns {String} a link suitable for conveying the address via a URL hash */ - link(options: { className?: string; prefix?: string; v4?: boolean; }): string { + link(options: { className?: string; prefix?: string; v4?: boolean }): string { if (!options) { options = {}; } @@ -1104,39 +1098,46 @@ export class Address6 { options.v4 = false; } - var formFunction = this.correctForm; + let formFunction = this.correctForm; if (options.v4) { formFunction = this.to4in6; } if (options.className) { - return sprintf('%2$s', - options.prefix, formFunction.call(this), options.className); + return sprintf( + '%2$s', + options.prefix, + formFunction.call(this), + options.className + ); } - return sprintf('%2$s', options.prefix, - formFunction.call(this)); - }; + return sprintf('%2$s', options.prefix, formFunction.call(this)); + } /** * Groups an address * @returns {String} */ group(): string { - var address4 = this.address.match(constants4.RE_ADDRESS); - var i; + const address4 = this.address.match(constants4.RE_ADDRESS); + let i; if (address4) { // The IPv4 case - var segments = address4[0].split('.'); - - this.address = this.address.replace(constants4.RE_ADDRESS, - sprintf('%s' + - '.' + - '%s', + const segments = address4[0].split('.'); + + this.address = this.address.replace( + constants4.RE_ADDRESS, + sprintf( + '%s' + + '.' + + '%s', segments.slice(0, 2).join('.'), - segments.slice(2, 4).join('.'))); + segments.slice(2, 4).join('.') + ) + ); } if (this.elidedGroups === 0) { @@ -1145,9 +1146,9 @@ export class Address6 { } // The elided case - var output = []; + const output = []; - var halves = this.address.split('::'); + const halves = this.address.split('::'); if (halves[0].length) { output.push(helpers.simpleGroup(halves[0])); @@ -1155,10 +1156,9 @@ export class Address6 { output.push(''); } - var classes = ['hover-group']; + const classes = ['hover-group']; - for (i = this.elisionBegin; - i < this.elisionBegin + this.elidedGroups; i++) { + for (i = this.elisionBegin; i < this.elisionBegin + this.elidedGroups; i++) { classes.push(sprintf('group-%d', i)); } @@ -1171,10 +1171,10 @@ export class Address6 { } return output.join(':'); - }; - //#endregion + } + // #endregion - //#region Regular expressions + // #region Regular expressions /** * Generate a regular expression string that can be used to find or validate * all variations of this address @@ -1184,10 +1184,10 @@ export class Address6 { * @returns {string} */ regularExpressionString(this: Address6, optionalSubString: string = ''): string { - var output: string[] = []; + let output: string[] = []; // TODO: revisit why this is necessary - var address6 = new Address6(this.correctForm()); + const address6 = new Address6(this.correctForm()); if (address6.elidedGroups === 0) { // The simple case @@ -1197,15 +1197,15 @@ export class Address6 { output.push(possibleElisions(constants6.GROUPS)); } else { // A partially elided address - var halves = address6.address.split('::'); + const halves = address6.address.split('::'); if (halves[0].length) { output.push(simpleRegularExpression(halves[0].split(':'))); } - output.push(possibleElisions(address6.elidedGroups, - halves[0].length !== 0, - halves[1].length !== 0)); + output.push( + possibleElisions(address6.elidedGroups, halves[0].length !== 0, halves[1].length !== 0) + ); if (halves[1].length) { output.push(simpleRegularExpression(halves[1].split(':'))); @@ -1218,14 +1218,16 @@ export class Address6 { output = [ '(?=^|', ADDRESS_BOUNDARY, - '|[^\\w\\:])(', ...output, ')(?=[^\\w\\:]|', + '|[^\\w\\:])(', + ...output, + ')(?=[^\\w\\:]|', ADDRESS_BOUNDARY, - '|$)' - ] + '|$)', + ]; } return output.join(''); - }; + } /** * Generate a regular expression that can be used to find or validate all @@ -1237,6 +1239,6 @@ export class Address6 { */ regularExpression(this: Address6, optionalSubstring?: string): RegExp { return new RegExp(this.regularExpressionString(optionalSubstring), 'i'); - }; - //#endregion -} \ No newline at end of file + } + // #endregion +} diff --git a/lib/v6/constants.ts b/lib/v6/constants.ts index b5301e0..bfdeae7 100644 --- a/lib/v6/constants.ts +++ b/lib/v6/constants.ts @@ -14,7 +14,7 @@ export const SCOPES = { 5: 'Site local', 8: 'Organization local', 14: 'Global', - 15: 'Reserved' + 15: 'Reserved', }; /** @@ -44,7 +44,7 @@ export const TYPES = { '::/128': 'Unspecified', '::1/128': 'Loopback', 'ff00::/8': 'Multicast', - 'fe80::/10': 'Link-local unicast' + 'fe80::/10': 'Link-local unicast', }; /** @@ -52,14 +52,14 @@ export const TYPES = { * @memberof Address6 * @static */ -export const RE_BAD_CHARACTERS = /([^0-9a-f:\/%])/ig; +export const RE_BAD_CHARACTERS = /([^0-9a-f:\/%])/gi; /** * A regular expression that matches an incorrect IPv6 address * @memberof Address6 * @static */ -export const RE_BAD_ADDRESS = /([0-9a-f]{5,}|:{3,}|[^:]:$|^:[^:]|\/$)/ig; +export const RE_BAD_ADDRESS = /([0-9a-f]{5,}|:{3,}|[^:]:$|^:[^:]|\/$)/gi; /** * A regular expression that matches an IPv6 subnet diff --git a/lib/v6/helpers.ts b/lib/v6/helpers.ts index 14278ab..076a039 100644 --- a/lib/v6/helpers.ts +++ b/lib/v6/helpers.ts @@ -3,22 +3,28 @@ import { sprintf } from 'sprintf-js'; /** * @returns {String} the string with all zeroes contained in a */ -export const spanAllZeroes = function (s: string): string { +export function spanAllZeroes(s: string): string { return s.replace(/(0+)/g, '$1'); -}; +} /** * @returns {String} the string with each character contained in a */ -export const spanAll = function (s: string, offset: number = 0): string { - var letters = s.split(''); - - return letters.map(function (n, i) { - return sprintf('%s', n, - i + offset, - spanAllZeroes(n)); // XXX Use #base-2 .value-0 instead? - }).join(''); -}; +export function spanAll(s: string, offset: number = 0): string { + const letters = s.split(''); + + return letters + .map( + (n, i) => + sprintf( + '%s', + n, + i + offset, + spanAllZeroes(n) + ) // XXX Use #base-2 .value-0 instead? + ) + .join(''); +} function spanLeadingZeroesSimple(group: string): string { return group.replace(/^(0+)/, '$1'); @@ -27,28 +33,30 @@ function spanLeadingZeroesSimple(group: string): string { /** * @returns {String} the string with leading zeroes contained in a */ -export const spanLeadingZeroes = function (address: string): string { - var groups = address.split(':'); +export function spanLeadingZeroes(address: string): string { + const groups = address.split(':'); - return groups.map(function (g) { - return spanLeadingZeroesSimple(g); - }).join(':'); -}; + return groups.map((g) => spanLeadingZeroesSimple(g)).join(':'); +} /** * Groups an address * @returns {String} a grouped address */ -export const simpleGroup = function (addressString: string, offset: number = 0): string { - var groups = addressString.split(':'); - - return groups.map(function (g, i) { - if (/group-v4/.test(g)) { - return g; - } - - return sprintf('%s', - i + offset, - spanLeadingZeroesSimple(g)); - }).join(':'); -}; +export function simpleGroup(addressString: string, offset: number = 0): string { + const groups = addressString.split(':'); + + return groups + .map((g, i) => { + if (/group-v4/.test(g)) { + return g; + } + + return sprintf( + '%s', + i + offset, + spanLeadingZeroesSimple(g) + ); + }) + .join(':'); +} diff --git a/lib/v6/regular-expressions.ts b/lib/v6/regular-expressions.ts index 34c3d10..a0ad810 100644 --- a/lib/v6/regular-expressions.ts +++ b/lib/v6/regular-expressions.ts @@ -1,6 +1,5 @@ -import { Address6 } from '../ipv6'; -import { sprintf } from 'sprintf-js'; import * as v6 from './constants'; +import { sprintf } from 'sprintf-js'; export function groupPossibilities(possibilities: string[]): string { return sprintf('(%s)', possibilities.join('|')); @@ -14,13 +13,13 @@ export function padGroup(group: string): string { return group; } -export var ADDRESS_BOUNDARY = '[^A-Fa-f0-9:]'; +export const ADDRESS_BOUNDARY = '[^A-Fa-f0-9:]'; export function simpleRegularExpression(groups: string[]) { - var zeroIndexes: number[] = []; + const zeroIndexes: number[] = []; - groups.forEach(function (group, i) { - var groupInteger = parseInt(group, 16); + groups.forEach((group, i) => { + const groupInteger = parseInt(group, 16); if (groupInteger === 0) { zeroIndexes.push(i); @@ -29,17 +28,19 @@ export function simpleRegularExpression(groups: string[]) { // You can technically elide a single 0, this creates the regular expressions // to match that eventuality - var possibilities = zeroIndexes.map(function (zeroIndex) { - return groups.map(function (group, i) { - if (i === zeroIndex) { - var elision = (i === 0 || i === v6.GROUPS - 1) ? ':' : ''; + const possibilities = zeroIndexes.map((zeroIndex) => + groups + .map((group, i) => { + if (i === zeroIndex) { + const elision = i === 0 || i === v6.GROUPS - 1 ? ':' : ''; - return groupPossibilities([padGroup(group), elision]); - } + return groupPossibilities([padGroup(group), elision]); + } - return padGroup(group); - }).join(':'); - }); + return padGroup(group); + }) + .join(':') + ); // The simplest case possibilities.push(groups.map(padGroup).join(':')); @@ -47,11 +48,15 @@ export function simpleRegularExpression(groups: string[]) { return groupPossibilities(possibilities); } -export function possibleElisions(elidedGroups: number, moreLeft?: boolean, moreRight?: boolean): string { - var left = moreLeft ? '' : ':'; - var right = moreRight ? '' : ':'; +export function possibleElisions( + elidedGroups: number, + moreLeft?: boolean, + moreRight?: boolean +): string { + const left = moreLeft ? '' : ':'; + const right = moreRight ? '' : ':'; - var possibilities = []; + const possibilities = []; // 1. elision of everything (::) if (!moreLeft && !moreRight) { @@ -78,11 +83,15 @@ export function possibleElisions(elidedGroups: number, moreLeft?: boolean, moreR possibilities.push(sprintf('(0{1,4}:){%d}0{1,4}', elidedGroups - 1)); // 7. elision (including sloppy elision) from the middle - for (var groups = 1; groups < elidedGroups - 1; groups++) { - for (var position = 1; position < elidedGroups - groups; position++) { - possibilities.push(sprintf('(0{1,4}:){%d}:(0{1,4}:){%d}0{1,4}', - position, - elidedGroups - position - groups - 1)); + for (let groups = 1; groups < elidedGroups - 1; groups++) { + for (let position = 1; position < elidedGroups - groups; position++) { + possibilities.push( + sprintf( + '(0{1,4}:){%d}:(0{1,4}:){%d}0{1,4}', + position, + elidedGroups - position - groups - 1 + ) + ); } } diff --git a/package-lock.json b/package-lock.json index 9a54c80..0c5d86f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1686,6 +1686,12 @@ "integrity": "sha512-2dVz9LTEGWVj9Ov9zaDnpvqHFV+W4bXtU0EUEGAzWfdRNO3dlUuosdHpENI6/oQW+Kejn0hAjk6P/czs9h/hvg==", "dev": true }, + "@types/json-schema": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", + "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", + "dev": true + }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -1785,6 +1791,43 @@ "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==", "dev": true }, + "@typescript-eslint/eslint-plugin": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.1.1.tgz", + "integrity": "sha512-Hoxyt99EA9LMmqo/5PuWWPeWeB3mKyvibfJ1Hy5SfiUpjE8Nqp+5QNd9fOkzL66+fqvIWSIE+Ett16LGMzCGnQ==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "4.1.1", + "@typescript-eslint/scope-manager": "4.1.1", + "debug": "^4.1.1", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.0.0", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "dependencies": { + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, + "@typescript-eslint/experimental-utils": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.1.1.tgz", + "integrity": "sha512-jzYsNciHoa4Z3c1URtmeT/bamYm8Dwfw6vuN3WHIE/BXb1iC4KveAnXDErTAZtPVxTYBaYn3n2gbt6F6D2rm1A==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/scope-manager": "4.1.1", + "@typescript-eslint/types": "4.1.1", + "@typescript-eslint/typescript-estree": "4.1.1", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, "@typescript-eslint/parser": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.1.1.tgz", diff --git a/package.json b/package.json index 31c0970..7d979ac 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "@types/lodash.padstart": "^4.6.6", "@types/lodash.repeat": "^4.1.6", "@types/sprintf-js": "^1.1.2", + "@typescript-eslint/eslint-plugin": "^4.1.1", "@typescript-eslint/parser": "^4.1.1", "browserify": "^16.5.2", "chai": "^4.2.0", diff --git a/test/address-test.js b/test/address-test.js index 607eb25..499c7be 100644 --- a/test/address-test.js +++ b/test/address-test.js @@ -1,24 +1,22 @@ -var should = require('chai').should(); +/* eslint-disable no-param-reassign */ -var ip = require('../dist/ip-address'); +const should = require('chai').should(); +const { Address4, Address6 } = require('../dist/ip-address'); -var Address4 = ip.Address4; -var Address6 = ip.Address6; +const invalid4 = require('./data/invalid-ipv4-addresses.json'); +const invalid6 = require('./data/invalid-ipv6-addresses.json'); -var valid4 = require('./data/valid-ipv4-addresses.json'); -var valid6 = require('./data/valid-ipv6-addresses.json'); - -var invalid4 = require('./data/invalid-ipv4-addresses.json'); -var invalid6 = require('./data/invalid-ipv6-addresses.json'); +const valid4 = require('./data/valid-ipv4-addresses.json'); +const valid6 = require('./data/valid-ipv6-addresses.json'); function addressIs(addressString, descriptors) { - var address4 = new Address4(addressString); - var address6 = new Address6(addressString); + const address4 = new Address4(addressString); + const address6 = new Address6(addressString); - describe(addressString, function () { - descriptors.forEach(function (descriptor) { + describe(addressString, () => { + descriptors.forEach((descriptor) => { if (descriptor === 'valid-ipv4') { - it('is valid', function () { + it('is valid', () => { address4.should.be.an('object'); address4.parsedAddress.should.be.an.instanceOf(Array); @@ -37,7 +35,7 @@ function addressIs(addressString, descriptors) { } if (descriptor === 'valid-ipv6') { - it('is valid', function () { + it('is valid', () => { address6.should.be.an('object'); address6.zone.should.be.a('string'); @@ -58,55 +56,52 @@ function addressIs(addressString, descriptors) { address6.isValid().should.equal(true); }); - var re = address6.regularExpression(); - var reSubstring = address6.regularExpression(true); + const re = address6.regularExpression(); + const reSubstring = address6.regularExpression(true); - it('matches the correct form via regex', function () { + it('matches the correct form via regex', () => { re.test(address6.correctForm()).should.equal(true); - reSubstring.test('abc ' + address6.correctForm() + ' def') - .should.equal(true); + reSubstring.test(`abc ${address6.correctForm()} def`).should.equal(true); }); - it('matches the canonical form via regex', function () { + it('matches the canonical form via regex', () => { re.test(address6.canonicalForm()).should.equal(true); - reSubstring.test('abc ' + address6.canonicalForm() + ' def') - .should.equal(true); + reSubstring.test(`abc ${address6.canonicalForm()} def`).should.equal(true); }); - it('matches the given form via regex', function () { + it('matches the given form via regex', () => { // We can't match addresses like ::192.168.0.1 yet if (address6.is4()) { return; } re.test(addressString).should.equal(true); - reSubstring.test('abc ' + addressString + ' def') - .should.equal(true); + reSubstring.test(`abc ${addressString} def`).should.equal(true); }); - it('converts to a byte array and back', function () { - var byteArray = address6.toByteArray(); + it('converts to a byte array and back', () => { + const byteArray = address6.toByteArray(); byteArray.length.should.be.at.most(16); - var converted = Address6.fromByteArray(byteArray); + const converted = Address6.fromByteArray(byteArray); address6.correctForm().should.equal(converted.correctForm()); }); - it('converts to an unsigned byte array and back', function () { - var byteArray = address6.toUnsignedByteArray(); + it('converts to an unsigned byte array and back', () => { + const byteArray = address6.toUnsignedByteArray(); byteArray.length.should.be.at.most(16); - var converted = Address6.fromUnsignedByteArray(byteArray); + const converted = Address6.fromUnsignedByteArray(byteArray); address6.correctForm().should.equal(converted.correctForm()); }); } if (descriptor === 'invalid-ipv4') { - it('is invalid as parsed by v4', function () { + it('is invalid as parsed by v4', () => { address4.error.should.be.a('string'); address4.isValid().should.equal(false); @@ -114,7 +109,7 @@ function addressIs(addressString, descriptors) { } if (descriptor === 'invalid-ipv6') { - it('is invalid as parsed by v6', function () { + it('is invalid as parsed by v6', () => { address6.error.should.be.a('string'); address6.isValid().should.equal(false); @@ -123,7 +118,7 @@ function addressIs(addressString, descriptors) { } if (descriptor === 'canonical') { - it('is canonical', function () { + it('is canonical', () => { address6.isCanonical().should.equal(true); should.equal(address6.addressMinusSuffix.length, 39); @@ -131,37 +126,37 @@ function addressIs(addressString, descriptors) { } if (descriptor === 'correct') { - it('is correct', function () { + it('is correct', () => { address6.isCorrect().should.equal(true); }); } if (descriptor === 'correct-ipv4') { - it('is correct', function () { + it('is correct', () => { address4.isCorrect().should.equal(true); }); } if (descriptor === 'incorrect') { - it('is incorrect', function () { + it('is incorrect', () => { address6.isCorrect().should.equal(false); }); } if (descriptor === 'incorrect-ipv4') { - it('is incorrect', function () { + it('is incorrect', () => { address4.isCorrect().should.equal(false); }); } if (descriptor === 'has-subnet') { - it('parses the subnet', function () { + it('parses the subnet', () => { address6.subnet.should.match(/^\/\d{1,3}/); }); } if (descriptor === 'v4-in-v6') { - it('is an ipv4-in-ipv6 address', function () { + it('is an ipv4-in-ipv6 address', () => { address6.is4().should.equal(true); }); } @@ -170,9 +165,8 @@ function addressIs(addressString, descriptors) { } function loadJsonBatch(addresses, classes, noMerge) { - addresses.forEach(function (address) { - if (address.conditions === undefined || - !address.conditions.length || noMerge) { + addresses.forEach((address) => { + if (address.conditions === undefined || !address.conditions.length || noMerge) { address.conditions = classes; } else { address.conditions = address.conditions.concat(classes); @@ -182,20 +176,20 @@ function loadJsonBatch(addresses, classes, noMerge) { }); } -describe('Valid IPv4 addresses', function () { +describe('Valid IPv4 addresses', () => { loadJsonBatch(valid4, ['valid-ipv4']); loadJsonBatch(valid4, ['invalid-ipv6'], true); }); -describe('Valid IPv6 addresses', function () { +describe('Valid IPv6 addresses', () => { loadJsonBatch(valid6, ['valid-ipv6']); loadJsonBatch(valid6, ['invalid-ipv4'], true); }); -describe('Invalid IPv4 addresses', function () { +describe('Invalid IPv4 addresses', () => { loadJsonBatch(invalid4, ['invalid-ipv4']); }); -describe('Invalid IPv6 addresses', function () { +describe('Invalid IPv6 addresses', () => { loadJsonBatch(invalid6, ['invalid-ipv6']); }); diff --git a/test/functionality-v4-test.js b/test/functionality-v4-test.js index 137a886..8a634ba 100644 --- a/test/functionality-v4-test.js +++ b/test/functionality-v4-test.js @@ -1,25 +1,24 @@ -var sprintf = require('sprintf-js').sprintf; -var should = require('chai').should(); - -var { Address4 } = require('../dist/lib/ipv4'); +const should = require('chai').should(); +const { Address4 } = require('../dist/lib/ipv4'); +const { sprintf } = require('sprintf-js'); // A convenience function to convert a list of IPv4 address notations // to Address4 instances function notationsToAddresseses(notations) { - var addresses = []; + const addresses = []; - notations.forEach(function (notation) { + notations.forEach((notation) => { addresses.push(new Address4(notation)); }); return addresses; } -describe('v4', function () { - describe('An invalid address', function () { - var topic = new Address4('127.0.0'); +describe('v4', () => { + describe('An invalid address', () => { + const topic = new Address4('127.0.0'); - it('is invalid', function () { + it('is invalid', () => { topic.error.should.equal('Invalid IPv4 address.'); topic.valid.should.equal(false); @@ -28,70 +27,68 @@ describe('v4', function () { should.equal(topic.bigInteger(), null); }); - }); - describe('A correct address', function () { - var topic = new Address4('127.0.0.1'); + describe('A correct address', () => { + const topic = new Address4('127.0.0.1'); - it('validates as correct', function () { + it('validates as correct', () => { topic.isCorrect().should.equal(true); should.equal(topic.correctForm(), '127.0.0.1'); }); }); - describe('An address with a subnet', function () { - var topic = new Address4('127.0.0.1/16'); + describe('An address with a subnet', () => { + const topic = new Address4('127.0.0.1/16'); - it('is contained by an identical address with an identical subnet', - function () { - var same = new Address4('127.0.0.1/16'); + it('is contained by an identical address with an identical subnet', () => { + const same = new Address4('127.0.0.1/16'); - topic.isInSubnet(same).should.equal(true); - }); + topic.isInSubnet(same).should.equal(true); + }); }); - describe('A small subnet', function () { - var topic = new Address4('127.0.0.1/16'); + describe('A small subnet', () => { + const topic = new Address4('127.0.0.1/16'); - it('is contained by larger subnets', function () { - for (var i = 15; i > 0; i--) { - var larger = new Address4(sprintf('127.0.0.1/%d', i)); + it('is contained by larger subnets', () => { + for (let i = 15; i > 0; i--) { + const larger = new Address4(sprintf('127.0.0.1/%d', i)); topic.isInSubnet(larger).should.equal(true); } }); }); - describe('A large subnet', function () { - var topic = new Address4('127.0.0.1/8'); + describe('A large subnet', () => { + const topic = new Address4('127.0.0.1/8'); - it('is not contained by smaller subnets', function () { - for (var i = 9; i <= 32; i++) { - var smaller = new Address4(sprintf('127.0.0.1/%d', i)); + it('is not contained by smaller subnets', () => { + for (let i = 9; i <= 32; i++) { + const smaller = new Address4(sprintf('127.0.0.1/%d', i)); topic.isInSubnet(smaller).should.equal(false); } }); }); - describe('An integer v4 address', function () { - var topic = Address4.fromInteger(432432423); + describe('An integer v4 address', () => { + const topic = Address4.fromInteger(432432423); - it('validates', function () { + it('validates', () => { topic.isValid().should.equal(true); }); - it('parses correctly', function () { + it('parses correctly', () => { topic.address.should.equal('25.198.101.39'); topic.subnet.should.equal('/32'); topic.subnetMask.should.equal(32); }); - it('should match an address from its hex representation', function () { - var hex = Address4.fromHex('19c66527'); + it('should match an address from its hex representation', () => { + const hex = Address4.fromHex('19c66527'); hex.address.should.equal('25.198.101.39'); @@ -100,81 +97,81 @@ describe('v4', function () { }); }); - describe('An address with a subnet', function () { - var topic = new Address4('127.0.0.1/16'); + describe('An address with a subnet', () => { + const topic = new Address4('127.0.0.1/16'); - it('validates', function () { + it('validates', () => { topic.isValid().should.equal(true); }); - it('parses the subnet', function () { + it('parses the subnet', () => { should.equal(topic.subnet, '/16'); }); - it('has a correct start address', function () { + it('has a correct start address', () => { should.equal(topic.startAddress().correctForm(), '127.0.0.0'); }); - it('has a correct start address hosts only', function () { + it('has a correct start address hosts only', () => { should.equal(topic.startAddressExclusive().correctForm(), '127.0.0.1'); }); - it('has a correct end address', function () { + it('has a correct end address', () => { should.equal(topic.endAddress().correctForm(), '127.0.255.255'); }); - it('has a correct end address hosts only', function () { + it('has a correct end address hosts only', () => { should.equal(topic.endAddressExclusive().correctForm(), '127.0.255.254'); }); - it('is in its own subnet', function () { + it('is in its own subnet', () => { topic.isInSubnet(new Address4('127.0.0.1/16')).should.equal(true); }); - it('is not in another subnet', function () { + it('is not in another subnet', () => { topic.isInSubnet(new Address4('192.168.0.1/16')).should.equal(false); }); }); - describe('Creating an address from a BigInteger', function () { - var topic = Address4.fromBigInteger(2130706433); + describe('Creating an address from a BigInteger', () => { + const topic = Address4.fromBigInteger(2130706433); - it('should parse correctly', function () { + it('should parse correctly', () => { topic.isValid().should.equal(true); topic.correctForm().should.equal('127.0.0.1'); }); }); - describe('Converting an address to a BigInteger', function () { - var topic = new Address4('127.0.0.1'); + describe('Converting an address to a BigInteger', () => { + const topic = new Address4('127.0.0.1'); - it('should convert properly', function () { + it('should convert properly', () => { topic.bigInteger().intValue().should.equal(2130706433); }); }); - describe('Creating an address from hex', function () { - var topic = Address4.fromHex('7f:00:00:01'); + describe('Creating an address from hex', () => { + const topic = Address4.fromHex('7f:00:00:01'); - it('should parse correctly', function () { + it('should parse correctly', () => { topic.isValid().should.equal(true); topic.correctForm().should.equal('127.0.0.1'); }); }); - describe('Converting an address to hex', function () { - var topic = new Address4('127.0.0.1'); + describe('Converting an address to hex', () => { + const topic = new Address4('127.0.0.1'); - it('should convert correctly', function () { + it('should convert correctly', () => { topic.toHex().should.equal('7f:00:00:01'); }); }); - describe('Converting an address to an array', function () { - var topic = new Address4('127.0.0.1'); + describe('Converting an address to an array', () => { + const topic = new Address4('127.0.0.1'); - it('should convert correctly', function () { - var a = topic.toArray(); + it('should convert correctly', () => { + const a = topic.toArray(); a.should.be.an.instanceOf(Array).and.have.lengthOf(4); @@ -185,27 +182,27 @@ describe('v4', function () { }); }); - describe('A different notation of the same address', function () { - var addresses = notationsToAddresseses([ + describe('A different notation of the same address', () => { + const addresses = notationsToAddresseses([ '127.0.0.1/32', '127.0.0.1/032', '127.000.000.001/032', '127.000.000.001/32', '127.0.0.1', '127.000.000.001', - '127.000.0.1' + '127.000.0.1', ]); - it('is parsed to the same result', function () { - addresses.forEach(function (topic) { + it('is parsed to the same result', () => { + addresses.forEach((topic) => { should.equal(topic.correctForm(), '127.0.0.1'); should.equal(topic.subnetMask, 32); }); }); }); - describe('A multicast address', function () { - var multicastAddresses = notationsToAddresseses([ + describe('A multicast address', () => { + const multicastAddresses = notationsToAddresseses([ '224.0.1.0', '224.0.1.255', '224.0.2.0', @@ -221,18 +218,18 @@ describe('v4', function () { '234.0.0.0', '234.255.255.255', '239.0.0.0', - '239.255.255.255' + '239.255.255.255', ]); - it('is detected as multicast', function () { - multicastAddresses.forEach(function (topic) { + it('is detected as multicast', () => { + multicastAddresses.forEach((topic) => { should.equal(topic.isMulticast(), true); }); }); }); - describe('A unicast address', function () { - var unicastAddresses = notationsToAddresseses([ + describe('A unicast address', () => { + const unicastAddresses = notationsToAddresseses([ '124.0.1.0', '124.0.1.255', '124.0.2.0', @@ -248,11 +245,11 @@ describe('v4', function () { '134.0.0.0', '134.255.255.255', '139.0.0.0', - '139.255.255.255' + '139.255.255.255', ]); - it('is not detected as multicast', function () { - unicastAddresses.forEach(function (topic) { + it('is not detected as multicast', () => { + unicastAddresses.forEach((topic) => { should.equal(topic.isMulticast(), false); }); }); diff --git a/test/functionality-v6-test.js b/test/functionality-v6-test.js index 1e2e6d0..db20bcf 100644 --- a/test/functionality-v6-test.js +++ b/test/functionality-v6-test.js @@ -1,28 +1,23 @@ -var chai = require('chai'); +const chai = require('chai'); +const { Address6 } = require('../dist/lib/ipv6'); +const { BigInteger } = require('jsbn'); +const { sprintf } = require('sprintf-js'); +const { v6 } = require('../dist/ip-address'); -var expect = chai.expect; -var should = chai.should(); - -var BigInteger = require('jsbn').BigInteger; -var sprintf = require('sprintf-js').sprintf; - -var { Address6 } = require('../dist/lib/ipv6'); - -var v6 = require('../dist/ip-address').v6; +const { expect } = chai; +const should = chai.should(); // A convenience function to convert a list of IPv6 address notations // to Address6 instances function notationsToAddresseses(notations) { - return notations.map(function (notation) { - return new Address6(notation); - }); + return notations.map((notation) => new Address6(notation)); } -describe('v6', function () { - describe('An invalid address', function () { - var topic = new Address6('a:abcde::'); +describe('v6', () => { + describe('An invalid address', () => { + const topic = new Address6('a:abcde::'); - it('is invalid', function () { + it('is invalid', () => { topic.error.should.equal('Address failed regex: abcde'); topic.valid.should.equal(false); @@ -38,19 +33,19 @@ describe('v6', function () { }); }); - describe('a fully ellided /0 address', function () { - var topic = new Address6('::/0'); + describe('a fully ellided /0 address', () => { + const topic = new Address6('::/0'); - it('gets the correct reverse from', function () { - topic.reverseForm({omitSuffix: true}).should.equal(''); + it('gets the correct reverse from', () => { + topic.reverseForm({ omitSuffix: true }).should.equal(''); topic.reverseForm().should.equal('ip6.arpa.'); }); }); - describe('A link local address', function () { - var topic = new Address6('fe80::baf6:b1ff:fe15:4885'); + describe('A link local address', () => { + const topic = new Address6('fe80::baf6:b1ff:fe15:4885'); - it('gets the correct type', function () { + it('gets the correct type', () => { topic.getType().should.equal('Link-local unicast'); topic.isTeredo().should.equal(false); @@ -60,34 +55,34 @@ describe('v6', function () { }); }); - describe('A correct address', function () { - var topic = new Address6('a:b:c:d:e:f:0:1/64'); + describe('A correct address', () => { + const topic = new Address6('a:b:c:d:e:f:0:1/64'); - it('contains no uppercase letters', function () { + it('contains no uppercase letters', () => { /[A-Z]/.test(topic.address).should.equal(false); }); - it('validates as correct', function () { + it('validates as correct', () => { topic.isCorrect().should.equal(true); should.equal(topic.correctForm(), 'a:b:c:d:e:f:0:1'); }); - it('converts to and from a signed byte array', function () { - var bytes = topic.toByteArray(); - var address = Address6.fromByteArray(bytes); + it('converts to and from a signed byte array', () => { + const bytes = topic.toByteArray(); + const address = Address6.fromByteArray(bytes); address.correctForm().should.equal(topic.correctForm()); }); - it('converts to and from an unsigned byte array', function () { - var unsignedBytes = topic.toUnsignedByteArray(); - var address = Address6.fromUnsignedByteArray(unsignedBytes); + it('converts to and from an unsigned byte array', () => { + const unsignedBytes = topic.toUnsignedByteArray(); + const address = Address6.fromUnsignedByteArray(unsignedBytes); address.correctForm().should.equal(topic.correctForm()); }); - it('gets the correct type', function () { + it('gets the correct type', () => { topic.getType().should.equal('Global unicast'); topic.isTeredo().should.equal(false); @@ -96,73 +91,70 @@ describe('v6', function () { topic.isLinkLocal().should.equal(false); }); - it('gets the correct reverse from', function () { - topic.reverseForm({omitSuffix: true}) - .should.equal('d.0.0.0.c.0.0.0.b.0.0.0.a.0.0.0'); + it('gets the correct reverse from', () => { + topic.reverseForm({ omitSuffix: true }).should.equal('d.0.0.0.c.0.0.0.b.0.0.0.a.0.0.0'); - topic.reverseForm() - .should.equal('d.0.0.0.c.0.0.0.b.0.0.0.a.0.0.0.ip6.arpa.'); + topic.reverseForm().should.equal('d.0.0.0.c.0.0.0.b.0.0.0.a.0.0.0.ip6.arpa.'); }); - it('gets the correct scope', function () { + it('gets the correct scope', () => { topic.getScope().should.equal('Global'); }); - it('gets the correct is6to4 information', function () { + it('gets the correct is6to4 information', () => { topic.is6to4().should.equal(false); }); - it('gets the correct microsoft transcription', function () { - topic.microsoftTranscription() - .should.equal('a-b-c-d-e-f-0-1.ipv6-literal.net'); + it('gets the correct microsoft transcription', () => { + topic.microsoftTranscription().should.equal('a-b-c-d-e-f-0-1.ipv6-literal.net'); }); - it('has correct bit information', function () { - topic.getBitsPastSubnet().should.equal( - '0000000000001110000000000000111100000000000000000000000000000001'); + it('has correct bit information', () => { + topic + .getBitsPastSubnet() + .should.equal('0000000000001110000000000000111100000000000000000000000000000001'); topic.getBitsBase16(0, 64).should.equal('000a000b000c000d'); - topic.getBitsBase16(0, 128).should.equal( - '000a000b000c000d000e000f00000001'); + topic.getBitsBase16(0, 128).should.equal('000a000b000c000d000e000f00000001'); should.equal(topic.getBitsBase16(0, 127), null); - topic.getBitsBase2().should.equal( - '0000000000001010000000000000101100000000000011000000000000001101' + - '0000000000001110000000000000111100000000000000000000000000000001'); + topic + .getBitsBase2() + .should.equal( + '0000000000001010000000000000101100000000000011000000000000001101' + + '0000000000001110000000000000111100000000000000000000000000000001' + ); }); }); - describe('An address with a subnet', function () { - var topic = new Address6('ffff::/64'); + describe('An address with a subnet', () => { + const topic = new Address6('ffff::/64'); - it('is contained by an identical address with an identical subnet', - function () { - var same = new Address6('ffff::/64'); + it('is contained by an identical address with an identical subnet', () => { + const same = new Address6('ffff::/64'); - topic.isInSubnet(same).should.equal(true); - }); + topic.isInSubnet(same).should.equal(true); + }); - it('has a correct start address', function () { + it('has a correct start address', () => { should.equal(topic.startAddress().correctForm(), 'ffff::'); }); - it('has a correct start address hosts only', function () { + it('has a correct start address hosts only', () => { should.equal(topic.startAddressExclusive().correctForm(), 'ffff::1'); }); - it('has a correct end address', function () { - should.equal(topic.endAddress().correctForm(), - 'ffff::ffff:ffff:ffff:ffff'); + it('has a correct end address', () => { + should.equal(topic.endAddress().correctForm(), 'ffff::ffff:ffff:ffff:ffff'); }); - it('has a correct end address hosts only', function () { - should.equal(topic.endAddressExclusive().correctForm(), - 'ffff::ffff:ffff:ffff:fffe'); + it('has a correct end address hosts only', () => { + should.equal(topic.endAddressExclusive().correctForm(), 'ffff::ffff:ffff:ffff:fffe'); }); - it('calculates and formats the subnet size', function () { + it('calculates and formats the subnet size', () => { topic.possibleSubnets().should.equal('18,446,744,073,709,551,616'); topic.possibleSubnets(128).should.equal('18,446,744,073,709,551,616'); topic.possibleSubnets(96).should.equal('4,294,967,296'); @@ -173,98 +165,97 @@ describe('v6', function () { }); }); - describe('Small subnets', function () { - var topic = new Address6('ffff::/64'); + describe('Small subnets', () => { + const topic = new Address6('ffff::/64'); - it('is contained by larger subnets', function () { - for (var i = 63; i > 0; i--) { - var larger = new Address6(sprintf('ffff::/%d', i)); + it('is contained by larger subnets', () => { + for (let i = 63; i > 0; i--) { + const larger = new Address6(sprintf('ffff::/%d', i)); topic.isInSubnet(larger).should.equal(true); } }); }); - describe('Large subnets', function () { - var topic = new Address6('ffff::/8'); + describe('Large subnets', () => { + const topic = new Address6('ffff::/8'); - it('is not contained by smaller subnets', function () { - for (var i = 9; i <= 128; i++) { - var smaller = new Address6(sprintf('ffff::/%d', i)); + it('is not contained by smaller subnets', () => { + for (let i = 9; i <= 128; i++) { + const smaller = new Address6(sprintf('ffff::/%d', i)); topic.isInSubnet(smaller).should.equal(false); } }); }); - describe('A canonical address', function () { - var topic = new Address6('000a:0000:0000:0000:0000:0000:0000:000b'); + describe('A canonical address', () => { + const topic = new Address6('000a:0000:0000:0000:0000:0000:0000:000b'); - it('is 39 characters long', function () { + it('is 39 characters long', () => { should.equal(topic.address.length, 39); }); - it('validates as canonical', function () { + it('validates as canonical', () => { topic.isCanonical().should.equal(true); - should.equal(topic.canonicalForm(), - '000a:0000:0000:0000:0000:0000:0000:000b'); + should.equal(topic.canonicalForm(), '000a:0000:0000:0000:0000:0000:0000:000b'); }); }); - describe('A v4-in-v6 address', function () { - var topic = new Address6('::192.168.0.1'); + describe('A v4-in-v6 address', () => { + const topic = new Address6('::192.168.0.1'); - it('validates', function () { + it('validates', () => { topic.isValid().should.equal(true); }); - it('is v4', function () { + it('is v4', () => { topic.is4().should.equal(true); }); }); - describe('An address with a subnet', function () { - var topic = new Address6('a:b::/48'); + describe('An address with a subnet', () => { + const topic = new Address6('a:b::/48'); - it('validates', function () { + it('validates', () => { topic.isValid().should.equal(true); }); - it('parses the subnet', function () { + it('parses the subnet', () => { should.equal(topic.subnet, '/48'); }); - it('is in its own subnet', function () { + it('is in its own subnet', () => { topic.isInSubnet(new Address6('a:b::/48')).should.equal(true); }); - it('is not in another subnet', function () { + it('is not in another subnet', () => { topic.isInSubnet(new Address6('a:c::/48')).should.equal(false); }); }); - describe('An address with a zone', function () { - var topic = new Address6('a::b%abcdefg'); + describe('An address with a zone', () => { + const topic = new Address6('a::b%abcdefg'); - it('validates', function () { + it('validates', () => { topic.isValid().should.equal(true); }); - it('parses the zone', function () { + it('parses the zone', () => { should.equal(topic.zone, '%abcdefg'); }); }); - describe('A teredo address', function () { - var topic = new Address6('2001:0000:ce49:7601:e866:efff:62c3:fffe'); + describe('A teredo address', () => { + const topic = new Address6('2001:0000:ce49:7601:e866:efff:62c3:fffe'); - it('validates as Teredo', function () { + it('validates as Teredo', () => { topic.isTeredo().should.equal(true); }); - it('contains valid Teredo information', function () { - var teredo = topic.inspectTeredo(); + it('contains valid Teredo information', () => { + const teredo = topic.inspectTeredo(); should.equal(teredo.prefix, '2001:0000'); should.equal(teredo.server4, '206.73.118.1'); @@ -274,23 +265,23 @@ describe('v6', function () { }); }); - describe('A 6to4 address', function () { - var topic = new Address6('2002:ce49:7601:1:2de:adff:febe:eeef'); + describe('A 6to4 address', () => { + const topic = new Address6('2002:ce49:7601:1:2de:adff:febe:eeef'); - it('validates as 6to4', function () { + it('validates as 6to4', () => { topic.is6to4().should.equal(true); }); - it('contains valid 6to4 information', function () { - var sixToFourProperties = topic.inspect6to4(); + it('contains valid 6to4 information', () => { + const sixToFourProperties = topic.inspect6to4(); should.equal(sixToFourProperties.prefix, '2002'); should.equal(sixToFourProperties.gateway, '206.73.118.1'); }); }); - describe('A different notation of the same address', function () { - var addresses = notationsToAddresseses([ + describe('A different notation of the same address', () => { + const addresses = notationsToAddresseses([ '2001:db8:0:0:1:0:0:1/128', '2001:db8:0:0:1:0:0:1/128%eth0', '2001:db8:0:0:1:0:0:1%eth0', @@ -301,160 +292,161 @@ describe('v6', function () { '2001:0db8::1:0:0:1', '2001:db8:0:0:1::1', '2001:db8:0000:0:1::1', - '2001:DB8:0:0:1::1' + '2001:DB8:0:0:1::1', ]); - it('is parsed to the same result', function () { - addresses.forEach(function (topic) { + it('is parsed to the same result', () => { + addresses.forEach((topic) => { should.equal(topic.correctForm(), '2001:db8::1:0:0:1'); - should.equal(topic.canonicalForm(), - '2001:0db8:0000:0000:0001:0000:0000:0001'); + should.equal(topic.canonicalForm(), '2001:0db8:0000:0000:0001:0000:0000:0001'); should.equal(topic.to4in6(), '2001:db8::1:0:0.0.0.1'); - should.equal(topic.decimal(), - '08193:03512:00000:00000:00001:00000:00000:00001'); - should.equal(topic.binaryZeroPad(), + should.equal(topic.decimal(), '08193:03512:00000:00000:00001:00000:00000:00001'); + should.equal( + topic.binaryZeroPad(), '0010000000000001000011011011100000000000000000000000000000000000' + - '0000000000000001000000000000000000000000000000000000000000000001'); + '0000000000000001000000000000000000000000000000000000000000000001' + ); }); }); }); - describe('to4in6', function () { - it('should produce a valid 4in6 address', function () { - var topic1 = new Address6('1:2:3:4:5:6:7:8'); - var topic2 = new Address6('1:2:3:4::7:8'); + describe('to4in6', () => { + it('should produce a valid 4in6 address', () => { + const topic1 = new Address6('1:2:3:4:5:6:7:8'); + const topic2 = new Address6('1:2:3:4::7:8'); topic1.to4in6().should.equal('1:2:3:4:5:6:0.7.0.8'); topic2.to4in6().should.equal('1:2:3:4::0.7.0.8'); }); }); - describe('Address from an IPv4 address', function () { - var obj = Address6.fromAddress4('192.168.0.1/30'); + describe('Address from an IPv4 address', () => { + const obj = Address6.fromAddress4('192.168.0.1/30'); - it('should parse correctly', function () { + it('should parse correctly', () => { expect(obj.valid).to.equal(true); expect(obj.correctForm()).to.equal('::ffff:c0a8:1'); expect(obj.to4in6()).to.equal('::ffff:192.168.0.1'); expect(obj.subnetMask).to.equal(126); }); - it('should generate a 6to4 address', function () { + it('should generate a 6to4 address', () => { expect(obj.to6to4().correctForm()).to.equal('2002:c0a8:1::'); }); - it('should generate a v4 address', function () { + it('should generate a v4 address', () => { expect(obj.to4().correctForm()).to.equal('192.168.0.1'); }); }); - describe('Address given in ap6.arpa form', function() { - var obj = Address6.fromArpa('e.f.f.f.3.c.2.6.f.f.f.e.6.6.8.e.1.0.6.7.9.4.e.c.0.0.0.0.1.0.0.2.ip6.arpa.'); + describe('Address given in ap6.arpa form', () => { + const obj = Address6.fromArpa( + 'e.f.f.f.3.c.2.6.f.f.f.e.6.6.8.e.1.0.6.7.9.4.e.c.0.0.0.0.1.0.0.2.ip6.arpa.' + ); - it('should return an Address6 object', function() { + it('should return an Address6 object', () => { expect(obj instanceof Address6).to.equal(true); }); - it('should generate a valid v6 address', function() { + it('should generate a valid v6 address', () => { expect(obj.correctForm()).to.equal('2001:0:ce49:7601:e866:efff:62c3:fffe'); }); - it('should fail with an invalid ip6.arpa length', function() { - var obj = Address6.fromArpa('e.f.f.f.3.c.2.6.f.f.f.e.6.6.8.0.6.7.9.4.e.c.0.0.0.0.1.0.0.2.ip6.arpa.'); + it('should fail with an invalid ip6.arpa length', () => { + const fromArpa = Address6.fromArpa( + 'e.f.f.f.3.c.2.6.f.f.f.e.6.6.8.0.6.7.9.4.e.c.0.0.0.0.1.0.0.2.ip6.arpa.' + ); - expect(obj.error).to.equal("Not Valid 'ip6.arpa' form"); - expect(obj.address).to.equal(null); + expect(fromArpa.error).to.equal("Not Valid 'ip6.arpa' form"); + expect(fromArpa.address).to.equal(null); }); }); - - describe('Address inside a URL or inside a URL with a port', function () { - it('should work with a host address', function () { - var obj = Address6.fromURL('2001:db8::5'); + describe('Address inside a URL or inside a URL with a port', () => { + it('should work with a host address', () => { + const obj = Address6.fromURL('2001:db8::5'); expect(obj.address.valid).to.equal(true); expect(obj.address.address).to.equal('2001:db8::5'); expect(obj.port).to.equal(null); }); - it('should fail with an invalid URL', function () { - var obj = Address6.fromURL('http://zombo/foo'); + it('should fail with an invalid URL', () => { + const obj = Address6.fromURL('http://zombo/foo'); expect(obj.error).to.equal('failed to parse address from URL'); expect(obj.address).to.equal(null); expect(obj.port).to.equal(null); }); - it('should work with a basic URL', function () { - var obj = Address6.fromURL('http://2001:db8::5/foo'); + it('should work with a basic URL', () => { + const obj = Address6.fromURL('http://2001:db8::5/foo'); expect(obj.address.isValid()).to.equal(true); expect(obj.address.address).equal('2001:db8::5'); expect(obj.port).to.equal(null); }); - it('should work with a basic URL enclosed in brackets', function () { - var obj = Address6.fromURL('http://[2001:db8::5]/foo'); + it('should work with a basic URL enclosed in brackets', () => { + const obj = Address6.fromURL('http://[2001:db8::5]/foo'); expect(obj.address.isValid()).to.equal(true); expect(obj.address.address).equal('2001:db8::5'); expect(obj.port).to.equal(null); }); - it('should work with a URL with a port', function () { - var obj = Address6.fromURL('http://[2001:db8::5]:80/foo'); + it('should work with a URL with a port', () => { + const obj = Address6.fromURL('http://[2001:db8::5]:80/foo'); expect(obj.address.isValid()).to.equal(true); expect(obj.address.address).to.equal('2001:db8::5'); expect(obj.port).to.equal(80); }); - it('should work with a URL with a long port number', function () { - var obj = Address6.fromURL('http://[2001:db8::5]:65536/foo'); + it('should work with a URL with a long port number', () => { + const obj = Address6.fromURL('http://[2001:db8::5]:65536/foo'); expect(obj.address.isValid()).to.equal(true); expect(obj.address.address).to.equal('2001:db8::5'); expect(obj.port).to.equal(65536); }); - it('should work with a address with a port', function () { - var obj = Address6.fromURL('[2001:db8::5]:80'); + it('should work with a address with a port', () => { + const obj = Address6.fromURL('[2001:db8::5]:80'); expect(obj.address.isValid()).to.equal(true); expect(obj.address.address).to.equal('2001:db8::5'); expect(obj.port).to.equal(80); }); - it('should work with an address with a long port', function () { - var obj = Address6.fromURL('[2001:db8::5]:65536'); + it('should work with an address with a long port', () => { + const obj = Address6.fromURL('[2001:db8::5]:65536'); expect(obj.address.isValid()).to.equal(true); expect(obj.address.address).to.equal('2001:db8::5'); expect(obj.port).to.equal(65536); }); - it('should parse the address but fail with an invalid port', function () { - var obj = Address6.fromURL('[2001:db8::5]:65537'); + it('should parse the address but fail with an invalid port', () => { + const obj = Address6.fromURL('[2001:db8::5]:65537'); expect(obj.address.isValid()).to.equal(true); expect(obj.address.address).to.equal('2001:db8::5'); expect(obj.port).to.equal(null); }); - it('should fail with an invalid address and not return a port', - function () { - var obj = Address6.fromURL('[2001:db8:z:5]:65536'); + it('should fail with an invalid address and not return a port', () => { + const obj = Address6.fromURL('[2001:db8:z:5]:65536'); - expect(obj.error).to.equal('failed to parse address with port'); - expect(obj.port).to.equal(null); - }); + expect(obj.error).to.equal('failed to parse address with port'); + expect(obj.port).to.equal(null); + }); }); - describe('An address from a BigInteger', function () { - var topic = Address6 - .fromBigInteger(new BigInteger('51923840109643282840007714694758401')); + describe('An address from a BigInteger', () => { + const topic = Address6.fromBigInteger(new BigInteger('51923840109643282840007714694758401')); - it('should parse correctly', function () { + it('should parse correctly', () => { topic.valid.should.equal(true); // TODO: Define this behavior @@ -464,127 +456,147 @@ describe('v6', function () { }); }); - describe('HTML helpers', function () { - describe('href', function () { - var topic = new Address6('2001:4860:4001:803::1011'); + describe('HTML helpers', () => { + describe('href', () => { + const topic = new Address6('2001:4860:4001:803::1011'); - it('should generate a URL correctly', function () { + it('should generate a URL correctly', () => { topic.href().should.equal('http://[2001:4860:4001:803::1011]/'); topic.href(8080).should.equal('http://[2001:4860:4001:803::1011]:8080/'); }); }); - describe('link', function () { - var topic = new Address6('2001:4860:4001:803::1011'); + describe('link', () => { + const topic = new Address6('2001:4860:4001:803::1011'); - it('should generate an anchor correctly', function () { - topic.link() - .should.equal('' + - '2001:4860:4001:803::1011'); + it('should generate an anchor correctly', () => { + topic + .link() + .should.equal( + '2001:4860:4001:803::1011' + ); - topic.link({className: 'highlight', prefix: '/?address='}) - .should.equal('2001:4860:4001:803::1011'); + topic + .link({ className: 'highlight', prefix: '/?address=' }) + .should.equal( + '2001:4860:4001:803::1011' + ); }); - it('should generate a v4inv6 anchor correctly', function () { - var topic4 = new Address6('::ffff:c0a8:1'); + it('should generate a v4inv6 anchor correctly', () => { + const topic4 = new Address6('::ffff:c0a8:1'); - topic4.link({v4: true}) - .should.equal('' + - '::ffff:192.168.0.1'); + topic4 + .link({ v4: true }) + .should.equal('::ffff:192.168.0.1'); }); }); - describe('group', function () { - it('should group a fully ellided address', function () { - var topic = new Address6('::'); + describe('group', () => { + it('should group a fully ellided address', () => { + const topic = new Address6('::'); - topic.group() - .should.equal('::'); + topic + .group() + .should.equal( + '::' + ); }); - it('should group an address with no ellision', function () { - var topic = new Address6('a:b:c:d:1:2:3:4'); - - topic.group() - .should.equal('a:' + - 'b:' + - 'c:' + - 'd:' + - '1:' + - '2:' + - '3:' + - '4'); - }); + it('should group an address with no ellision', () => { + const topic = new Address6('a:b:c:d:1:2:3:4'); - it('should group an ellided address', function () { - var topic = new Address6('2001:4860:4001:803::1011'); - - topic.group() - .should.equal('2001:' + - '4860:' + - '4001:' + - '803:' + - ':' + - '1011'); + topic + .group() + .should.equal( + 'a:' + + 'b:' + + 'c:' + + 'd:' + + '1:' + + '2:' + + '3:' + + '4' + ); }); - it('should group an IPv4 address', function () { - var topic = new Address6('192.168.0.1'); + it('should group an ellided address', () => { + const topic = new Address6('2001:4860:4001:803::1011'); - topic.group().should.equal( - '192.168.' + - '0.1'); + topic + .group() + .should.equal( + '2001:' + + '4860:' + + '4001:' + + '803:' + + ':' + + '1011' + ); }); - }); - }); - describe('String helpers', function () { - describe('spanLeadingZeroes', function () { - it('should span leading zeroes', function () { - var topic = v6.helpers.spanLeadingZeroes('0000:0000:4444:0001'); + it('should group an IPv4 address', () => { + const topic = new Address6('192.168.0.1'); topic - .should.equal('0000:' + - '0000:4444:' + - '0001'); + .group() + .should.equal( + '192.168.' + + '0.1' + ); }); }); + }); - describe('spanAll', function () { - it('should span leading zeroes', function () { - var topic = v6.helpers.spanAll('001100'); + describe('String helpers', () => { + describe('spanLeadingZeroes', () => { + it('should span leading zeroes', () => { + const topic = v6.helpers.spanLeadingZeroes('0000:0000:4444:0001'); - topic - .should.equal('' + - '0' + - '' + - '0' + - '1' + - '1' + - '' + - '0' + - '' + - '0'); + topic.should.equal( + '0000:' + + '0000:4444:' + + '0001' + ); }); + }); - it('should span leading zeroes with offset', function () { - var topic = v6.helpers.spanAll('001100', 1); + describe('spanAll', () => { + it('should span leading zeroes', () => { + const topic = v6.helpers.spanAll('001100'); + + topic.should.equal( + '' + + '0' + + '' + + '0' + + '1' + + '1' + + '' + + '0' + + '' + + '0' + ); + }); - topic - .should.equal('' + - '0' + - '' + - '0' + - '1' + - '1' + - '' + - '0' + - '' + - '0'); + it('should span leading zeroes with offset', () => { + const topic = v6.helpers.spanAll('001100', 1); + + topic.should.equal( + '' + + '0' + + '' + + '0' + + '1' + + '1' + + '' + + '0' + + '' + + '0' + ); }); }); });