net-address 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +11 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@luolapeikko/result-option");var t=class t{static regex=/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;static from(n){
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@luolapeikko/result-option");var t=class t{static regex=/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;static from(n){return typeof n!=`string`||!t.regex.test(n)?(0,e.Err)(TypeError(`${JSON.stringify(n)} is invalid ipv6 value`)):t.#t(n).andThen(({leftSegs:n,rightSegs:r,embeddedIpv4:i})=>{let a=Array(8).fill(0);for(let e=0;e<n.length;e++)a[e]=n[e];let o=8-r.length-i.length;for(let e=0;e<r.length;e++)a[o+e]=r[e];for(let e=0;e<i.length;e++)a[o+r.length+e]=i[e];try{return(0,e.Ok)(new t(a))}catch(t){return(0,e.Err)(t)}})}static fromBuffer(n,r){try{let i=new DataView(n);if(r){let n=i.getBigUint64(0,!0);return(0,e.Ok)(new t(i.getBigUint64(8,!0)<<64n|n))}else{let n=i.getBigUint64(0,!1),r=i.getBigUint64(8,!1);return(0,e.Ok)(new t(n<<64n|r))}}catch(t){return(0,e.Err)(t)}}static#e(t,n){let r=parseInt(t,n);return Number.isNaN(r)?(0,e.Err)(TypeError(`${t} is not a valid number`)):(0,e.Ok)(r)}static#t(n){let r=n.split(`::`),i=r[0].split(`:`).filter(e=>e!==``),a=r.length>1?r[1].split(`:`).filter(e=>e!==``):[],o=[],s=a[a.length-1]??i[i.length-1];if(s?.includes(`.`)){let e=t.#n(s);if(e.isErr)return e;o=e.ok(),a.length>0?a.pop():i.pop()}return e.Result.tupleFlow(e.Result.asArray(i.map(e=>t.#e(e,16))),()=>e.Result.asArray(a.map(e=>t.#e(e,16))),(t,n)=>(0,e.Ok)({leftSegs:t,rightSegs:n,embeddedIpv4:o}))}static#n(n){return e.Result.asArray(n.split(`.`).map(e=>t.#e(e,10))).andThen(t=>(0,e.Ok)([t[0]<<8|t[1],t[2]<<8|t[3]]))}static BITS=128;static LOCALHOST=new t(1n);static UNSPECIFIED=new t(0n);family=`ipv6`;#r;constructor(e){if(Array.isArray(e)&&e.every(e=>typeof e==`number`))this.#r=this.#i(e);else if(typeof e==`bigint`)this.#r=e;else throw TypeError(`Invalid constructor argument. Must be a bigint or an array of 8 numbers.`)}isBenchmarking(){return this.#o(42540488320432167789079031612388147200n,48)}isDocumentation(){return this.#o(42540766411282592856903984951653826560n,32)||this.#o(85065399433376081038215121361612832768n,20)}isLoopback(){return this.#r===1n}isUnspecified(){return this.#r===0n}isMulticast(){return this.#r>>120n==255n}isMulticastInterfaceLocal(){return this.#o(338958331222012082418099330867817086976n,16)}isMulticastLinkLocal(){return this.#o(338963523518870617245727861364146307072n,16)}isMulticastRealmLocal(){return this.#o(338968715815729152073356391860475527168n,16)}isMulticastAdminLocal(){return this.#o(338973908112587686900984922356804747264n,16)}isMulticastSiteLocal(){return this.#o(338979100409446221728613452853133967360n,16)}isMulticastOrganizationLocal(){return this.#o(338994677300021826211499044342121627648n,16)}isMulticastGlobal(){return this.#o(339025831081173035177270227320096948224n,16)}isIpv4Mapped(){return this.#o(281470681743360n,96)}isUnicast(){return!this.isMulticast()}isUnicastLinkLocal(){return this.#o(338288524927261089654018896841347694592n,10)}isUnicastGlobal(){return this.isUnicast()&&!this.isLoopback()&&!this.isUnicastLinkLocal()&&!this.isUniqueLocal()&&!this.isUnspecified()&&!this.isDocumentation()}isGlobal(){return!this.isUnspecified()&&!this.isLoopback()&&!this.isIpv4Mapped()&&!this.isBenchmarking()&&!this.isDocumentation()&&!this.isUniqueLocal()&&!this.isUnicastLinkLocal()&&!this.isMulticast()}isUniqueLocal(){return this.#o(334965454937798799971759379190646833152n,7)}toIpv4(){if(this.isIpv4Mapped()||this.#o(0n,96)){let t=this.#a(this.#r);return(0,e.Some)(new n(t[6]>>8,t[6]&255,t[7]>>8,t[7]&255))}return(0,e.None)()}toIpv4Mapped(){if(this.isIpv4Mapped()){let t=this.#a(this.#r);return(0,e.Some)(new n(t[6]>>8,t[6]&255,t[7]>>8,t[7]&255))}return(0,e.None)()}toString(){let e=this.#a(this.#r),t=-1,n=0,r=-1,i=0;for(let a=0;a<e.length;a++)e[a]===0?(r===-1?(r=a,i=1):i++,i>n&&(n=i,t=r)):(r=-1,i=0);if(n<2)return e.map(e=>e.toString(16)).join(`:`);let a=e.slice(0,t).map(e=>e.toString(16)),o=e.slice(t+n).map(e=>e.toString(16));return`${a.join(`:`)}::${o.join(`:`)}`}toBuffer(e){let t=new ArrayBuffer(16),n=new DataView(t);return e?(n.setBigUint64(0,this.#r&18446744073709551615n,!0),n.setBigUint64(8,this.#r>>64n,!0)):(n.setBigUint64(0,this.#r>>64n,!1),n.setBigUint64(8,this.#r&18446744073709551615n,!1)),t}equals(e){return`family`in e&&this.family===e.family&&this.#r===e.#r}#i(e){if(e.length!==8)throw RangeError(`IPv6 address must have exactly 8 segments`);let t=0n;for(let n of e){if(n<0||n>65535)throw RangeError(`IPv6 segment must be between 0 and 65535`);t=t<<16n|BigInt(n)}return t}#a(e){return[Number(e>>112n&65535n),Number(e>>96n&65535n),Number(e>>80n&65535n),Number(e>>64n&65535n),Number(e>>48n&65535n),Number(e>>32n&65535n),Number(e>>16n&65535n),Number(e&65535n)]}#o(e,t){if(t<0||t>128)throw Error(`Invalid prefix length`);if(t===0)return!0;let n=(1n<<128n)-1n,r=n<<BigInt(128-t)&n;return(this.#r&r)===(e&r)}},n=class n{static from(t){let r=t.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/);if(!r)return(0,e.Err)(TypeError(`${t} is invalid ipv4 value`));let i=r.slice(1).map(Number);return i.some(e=>e>255)?(0,e.Err)(TypeError(`${t} is invalid ipv4 value`)):(0,e.Ok)(new n(i[0],i[1],i[2],i[3]))}static fromBuffer(t,r){try{return(0,e.Ok)(new n(new DataView(t).getUint32(0,r)))}catch(t){return(0,e.Err)(t)}}static BITS=32;static BROADCAST=new n(4294967295);static LOCALHOST=new n(2130706433);static UNSPECIFIED=new n(0);family=`ipv4`;#e;constructor(...e){if(!Array.isArray(e)||e.every(e=>typeof e!=`number`))throw TypeError(`Invalid constructor argument. Must be a number or an array of 4 numbers.`);if(e.length===1){if(e[0]<0||e[0]>4294967295)throw RangeError(`IPv4 integer value must be between 0 and 0xffffffff`);this.#e=e[0]}else this.#e=this.#t(e[0],e[1],e[2],e[3])}isBroadcast(){return this.#e===4294967295}isDocumentation(){return this.#r(3221225984,24)||this.#r(3325256704,24)||this.#r(3405803776,24)}isBenchmarking(){return this.#r(3323068416,15)}isGlobal(){return!(this.isUnspecified()||this.isPrivate()||this.isShared()||this.isLoopback()||this.isLinkLocal()||this.isDocumentation()||this.isBenchmarking()||this.isReserved()||this.isMulticast()||this.isBroadcast())}isLinkLocal(){return this.#r(2851995648,16)}isLoopback(){return this.#r(2130706432,8)}isMulticast(){return this.#r(3758096384,4)}isPrivate(){return this.#r(167772160,8)||this.#r(2886729728,12)||this.#r(3232235520,16)}isReserved(){return this.#r(4026531840,4)&&!this.isBroadcast()}isShared(){return this.#r(1681915904,10)}isUnspecified(){return this.#e===0}toIpv6(){return t.from(`::${this.toString()}`).unwrap()}toIpv6Mapped(){return t.from(`::ffff:${this.toString()}`).unwrap()}toString(){let[e,t,n,r]=this.#n(this.#e);return`${e}.${t}.${n}.${r}`}toBuffer(e){let t=new ArrayBuffer(4);return new DataView(t).setUint32(0,this.#e,e),t}equals(e){return`family`in e&&this.family===e.family&&this.#e===e.#e}#t(e,t,n,r){for(let i of[e,t,n,r])if(i<0||i>255)throw RangeError(`IPv4 octet must be between 0 and 255`);return(e<<24|t<<16|n<<8|r)>>>0}#n(e){return[e>>24&255,e>>16&255,e>>8&255,e&255]}#r(e,t){if(t<0||t>32)throw RangeError(`Invalid prefix length`);let n=t===0?0:-1<<32-t>>>0;return(this.#e&n)===(e&n)}};exports.Ipv4Addr=n,exports.Ipv6Addr=t;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["#parseComponents","#parseEmbeddedIpv4","#integerAddress","#toInteger","#match","#fromInteger","#integerAddress","#toInteger","#match","#fromInteger"],"sources":["../src/Ipv6Addr.ts","../src/Ipv4Addr.ts"],"sourcesContent":["import {Err, type IOption, type IResult, None, Ok, Some} from '@luolapeikko/result-option';\nimport {Ipv4Addr} from './Ipv4Addr';\n\n/**\n * Represents an IPv6 address.\n * @example\n * const addr1 = Ipv6Addr.from('2001:db8::1').unwrap();\n * const addr2 = new Ipv6Addr([0x2001, 0xdb8, 0, 0, 0, 0, 0, 1]);\n * const addr3 = new Ipv6Addr(0x20010db8000000000000000000000001n);\n * @since v0.0.1\n */\nexport class Ipv6Addr {\n\tprivate static regex =\n\t\t/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;\n\n\t/**\n\t * Creates an IPv6 address from text.\n\t * @returns A successful result with an IPv6 address, or an error when the input is invalid.\n\t * @example\n\t * const addr = Ipv6Addr.from('2001:db8::1').unwrap();\n\t * @since v0.0.1\n\t */\n\tpublic static from(value: string): IResult<Ipv6Addr> {\n\t\tif (!Ipv6Addr.regex.test(value)) {\n\t\t\treturn Err(new TypeError(`${value} is invalid ipv6 value`));\n\t\t}\n\t\ttry {\n\t\t\tconst {leftParts, rightParts, embeddedIpv4} = Ipv6Addr.#parseComponents(value);\n\n\t\t\tconst leftSegs = leftParts.map((p) => parseInt(p, 16));\n\t\t\tconst rightSegs = rightParts.map((p) => parseInt(p, 16));\n\n\t\t\tconst missingLen = 8 - (leftSegs.length + rightSegs.length + embeddedIpv4.length);\n\t\t\tconst segments = [...leftSegs, ...Array(missingLen).fill(0), ...rightSegs, ...embeddedIpv4];\n\n\t\t\treturn Ok(new Ipv6Addr(segments as [number, number, number, number, number, number, number, number]));\n\t\t} catch (err) {\n\t\t\treturn Err(err);\n\t\t}\n\t}\n\n\t/**\n\t * Creates an IPv6 address from a 16-byte buffer.\n\t * @returns A successful result with an IPv6 address, or an error when the buffer cannot be read.\n\t * @since v0.0.1\n\t */\n\tpublic static fromBuffer(buffer: ArrayBuffer, littleEndian?: boolean): IResult<Ipv6Addr> {\n\t\ttry {\n\t\t\tconst view = new DataView(buffer);\n\t\t\tif (littleEndian) {\n\t\t\t\tconst low = view.getBigUint64(0, true);\n\t\t\t\tconst high = view.getBigUint64(8, true);\n\t\t\t\treturn Ok(new Ipv6Addr((high << 64n) | low));\n\t\t\t} else {\n\t\t\t\tconst high = view.getBigUint64(0, false);\n\t\t\t\tconst low = view.getBigUint64(8, false);\n\t\t\t\treturn Ok(new Ipv6Addr((high << 64n) | low));\n\t\t\t}\n\t\t} catch (err) {\n\t\t\treturn Err(err as Error);\n\t\t}\n\t}\n\n\tstatic #parseComponents(value: string) {\n\t\tconst components = value.split('::');\n\t\tconst leftParts = components[0].split(':').filter((x) => x !== '');\n\t\tconst rightParts = components.length > 1 ? components[1].split(':').filter((x) => x !== '') : [];\n\t\tlet embeddedIpv4: number[] = [];\n\t\tconst lastPart = rightParts[rightParts.length - 1] ?? leftParts[leftParts.length - 1];\n\t\tif (lastPart?.includes('.')) {\n\t\t\tembeddedIpv4 = Ipv6Addr.#parseEmbeddedIpv4(lastPart);\n\t\t\tif (rightParts.length > 0) {\n\t\t\t\trightParts.pop();\n\t\t\t} else {\n\t\t\t\tleftParts.pop();\n\t\t\t}\n\t\t}\n\t\treturn {leftParts, rightParts, embeddedIpv4};\n\t}\n\n\tstatic #parseEmbeddedIpv4(value: string): number[] {\n\t\tconst ipv4Octets = value.split('.').map(Number);\n\t\treturn [(ipv4Octets[0] << 8) | ipv4Octets[1], (ipv4Octets[2] << 8) | ipv4Octets[3]];\n\t}\n\n\t/**\n\t * The number of bits in an IPv6 address.\n\t * @since v0.0.1\n\t */\n\tpublic static readonly BITS = 128;\n\n\t/**\n\t * The loopback address (`::1`).\n\t * @since v0.0.1\n\t */\n\tpublic static readonly LOCALHOST: Ipv6Addr = new Ipv6Addr(0x00000000000000000000000000000001n);\n\n\t/**\n\t * The unspecified address (`::`).\n\t * @since v0.0.1\n\t */\n\tpublic static readonly UNSPECIFIED: Ipv6Addr = new Ipv6Addr(0x00000000000000000000000000000000n);\n\n\t/**\n\t * The address family identifier for IPv6 addresses.\n\t * @since v0.0.1\n\t */\n\tpublic readonly family = 'ipv6';\n\n\t#integerAddress: bigint;\n\tpublic constructor(value: bigint);\n\tpublic constructor(segments: [number, number, number, number, number, number, number, number]);\n\tpublic constructor(valueOrSegments: [number, number, number, number, number, number, number, number] | bigint) {\n\t\tif (Array.isArray(valueOrSegments)) {\n\t\t\tthis.#integerAddress = this.#toInteger(valueOrSegments);\n\t\t} else {\n\t\t\tthis.#integerAddress = valueOrSegments;\n\t\t}\n\t}\n\n\t/**\n\t * Checks whether this address is in the benchmarking range.\n\t * @see https://tools.ietf.org/html/rfc5180 and https://www.rfc-editor.org/errata_search.php?eid=1752\n\t * @returns `true` when the address is in `2001:2::/48`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isBenchmarking(): boolean {\n\t\treturn this.#match(0x20010002000000000000000000000000n, 48);\n\t}\n\n\t/**\n\t * Checks whether this address is in a documentation-only range.\n\t * @see https://tools.ietf.org/html/rfc3849 and https://tools.ietf.org/html/rfc9637\n\t * @returns `true` for `2001:db8::/32` or `3fff::/20`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isDocumentation(): boolean {\n\t\treturn this.#match(0x20010db8000000000000000000000000n, 32) || this.#match(0x3fff0000000000000000000000000000n, 20);\n\t}\n\n\t/**\n\t * Checks whether this address is the loopback address.\n\t * @see https://tools.ietf.org/html/rfc4291#section-2.5.3\n\t * @returns `true` when the address is `::1`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isLoopback(): boolean {\n\t\treturn this.#integerAddress === 1n;\n\t}\n\n\t/**\n\t * Checks whether this address is the unspecified address.\n\t * @see https://tools.ietf.org/html/rfc4291\n\t * @returns `true` when the address is `::`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isUnspecified(): boolean {\n\t\treturn this.#integerAddress === 0n;\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast address.\n\t * @see https://tools.ietf.org/html/rfc4291\n\t * @returns `true` when the address is in `ff00::/8`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isMulticast(): boolean {\n\t\treturn this.#integerAddress >> 120n === 0xffn;\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast interface-local address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff01::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastInterfaceLocal(): boolean {\n\t\treturn this.#match(0xff010000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast link-local address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff02::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastLinkLocal(): boolean {\n\t\treturn this.#match(0xff020000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast realm-local address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff03::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastRealmLocal(): boolean {\n\t\treturn this.#match(0xff030000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast admin-local address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff04::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastAdminLocal(): boolean {\n\t\treturn this.#match(0xff040000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast site-local address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff05::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastSiteLocal(): boolean {\n\t\treturn this.#match(0xff050000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast organization-local address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff08::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastOrganizationLocal(): boolean {\n\t\treturn this.#match(0xff080000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast global address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff0e::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastGlobal(): boolean {\n\t\treturn this.#match(0xff0e0000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is an IPv4-mapped IPv6 address.\n\t * @returns `true` when the address is in `::ffff:0:0/96`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isIpv4Mapped(): boolean {\n\t\treturn this.#match(0x00000000000000000000ffff00000000n, 96);\n\t}\n\n\t/**\n\t * Checks whether this address is a unicast address.\n\t * @see https://tools.ietf.org/html/rfc4291\n\t * @returns `true` when the address is not multicast, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isUnicast(): boolean {\n\t\treturn !this.isMulticast();\n\t}\n\n\t/**\n\t * Checks whether this address is a link-local unicast address.\n\t * @see https://tools.ietf.org/html/rfc4291\n\t * @returns `true` when the address is in `fe80::/10`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isUnicastLinkLocal(): boolean {\n\t\treturn this.#match(0xfe800000000000000000000000000000n, 10);\n\t}\n\n\t/**\n\t * Checks whether this address is a global unicast address.\n\t * @see https://tools.ietf.org/html/rfc4291#section-2.5.7\n\t * @returns `true` when the address is unicast and not loopback, link-local, private, unspecified, or documentation.\n\t * @since v0.0.1\n\t */\n\tpublic isUnicastGlobal(): boolean {\n\t\treturn this.isUnicast() && !this.isLoopback() && !this.isUnicastLinkLocal() && !this.isUniqueLocal() && !this.isUnspecified() && !this.isDocumentation();\n\t}\n\n\t/**\n\t * Checks whether this address appears globally reachable.\n\t * @see https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml\n\t * @returns `true` when the address is not in known non-global special ranges.\n\t * @since v0.0.1\n\t */\n\tpublic isGlobal(): boolean {\n\t\treturn (\n\t\t\t!this.isUnspecified() &&\n\t\t\t!this.isLoopback() &&\n\t\t\t!this.isIpv4Mapped() &&\n\t\t\t!this.isBenchmarking() &&\n\t\t\t!this.isDocumentation() &&\n\t\t\t!this.isUniqueLocal() &&\n\t\t\t!this.isUnicastLinkLocal() &&\n\t\t\t!this.isMulticast()\n\t\t);\n\t}\n\n\t/**\n\t * Checks whether this address is in the unique-local range.\n\t * @see https://tools.ietf.org/html/rfc4193\n\t * @returns `true` when the address is in `fc00::/7`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isUniqueLocal(): boolean {\n\t\treturn this.#match(0xfc000000000000000000000000000000n, 7);\n\t}\n\n\t/**\n\t * Converts this address to IPv4 when compatible or mapped.\n\t * @returns An IPv4 address for `::a.b.c.d` or `::ffff:a.b.c.d`; otherwise `None`.\n\t * @since v0.0.1\n\t */\n\tpublic toIpv4(): IOption<Ipv4Addr> {\n\t\tif (this.isIpv4Mapped() || this.#match(0n, 96)) {\n\t\t\tconst segments = this.#fromInteger(this.#integerAddress);\n\t\t\treturn Some(new Ipv4Addr(segments[6] >> 8, segments[6] & 0xff, segments[7] >> 8, segments[7] & 0xff));\n\t\t}\n\t\treturn None();\n\t}\n\n\t/**\n\t * Converts this address to IPv4 only when it is IPv4-mapped.\n\t * @returns An IPv4 address for `::ffff:a.b.c.d`; otherwise `None`.\n\t * @since v0.0.1\n\t */\n\tpublic toIpv4Mapped(): IOption<Ipv4Addr> {\n\t\tif (this.isIpv4Mapped()) {\n\t\t\tconst segments = this.#fromInteger(this.#integerAddress);\n\t\t\treturn Some(new Ipv4Addr(segments[6] >> 8, segments[6] & 0xff, segments[7] >> 8, segments[7] & 0xff));\n\t\t}\n\t\treturn None();\n\t}\n\n\t/**\n\t * Formats this address as a compressed IPv6 string.\n\t * @returns The shortest standard IPv6 text form.\n\t * @since v0.0.1\n\t */\n\tpublic toString(): string {\n\t\tconst segments = this.#fromInteger(this.#integerAddress);\n\t\tlet maxZeroStart = -1;\n\t\tlet maxZeroLen = 0;\n\t\tlet currentZeroStart = -1;\n\t\tlet currentZeroLen = 0;\n\n\t\tfor (let i = 0; i < segments.length; i++) {\n\t\t\tif (segments[i] === 0) {\n\t\t\t\tif (currentZeroStart === -1) {\n\t\t\t\t\tcurrentZeroStart = i;\n\t\t\t\t\tcurrentZeroLen = 1;\n\t\t\t\t} else {\n\t\t\t\t\tcurrentZeroLen++;\n\t\t\t\t}\n\t\t\t\tif (currentZeroLen > maxZeroLen) {\n\t\t\t\t\tmaxZeroLen = currentZeroLen;\n\t\t\t\t\tmaxZeroStart = currentZeroStart;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcurrentZeroStart = -1;\n\t\t\t\tcurrentZeroLen = 0;\n\t\t\t}\n\t\t}\n\n\t\tif (maxZeroLen < 2) {\n\t\t\treturn segments.map((s) => s.toString(16)).join(':');\n\t\t}\n\n\t\tconst before = segments.slice(0, maxZeroStart).map((s) => s.toString(16));\n\t\tconst after = segments.slice(maxZeroStart + maxZeroLen).map((s) => s.toString(16));\n\n\t\treturn `${before.join(':')}::${after.join(':')}`;\n\t}\n\n\t/**\n\t * Encodes this address to a 16-byte buffer.\n\t * @param littleEndian Whether to use little-endian byte order. Defaults to `false`.\n\t * @returns An `ArrayBuffer` containing the IPv6 integer value.\n\t * @since v0.0.1\n\t */\n\tpublic toBuffer(littleEndian?: boolean): ArrayBuffer {\n\t\tconst buffer = new ArrayBuffer(16);\n\t\tconst view = new DataView(buffer);\n\t\tif (littleEndian) {\n\t\t\tview.setBigUint64(0, this.#integerAddress & 0xffffffffffffffffn, true);\n\t\t\tview.setBigUint64(8, this.#integerAddress >> 64n, true);\n\t\t} else {\n\t\t\tview.setBigUint64(0, this.#integerAddress >> 64n, false);\n\t\t\tview.setBigUint64(8, this.#integerAddress & 0xffffffffffffffffn, false);\n\t\t}\n\t\treturn buffer;\n\t}\n\n\t/**\n\t * Compares this IPv6 address with another for equality.\n\t * @param other instance of another IPv6 address to compare with.\n\t * @returns `true` if both addresses are equal, otherwise `false`.\n\t * @since v0.1.0\n\t */\n\tpublic equals(other: Ipv6Addr | Ipv4Addr | object): boolean {\n\t\treturn 'family' in other && this.family === other.family && this.#integerAddress === other.#integerAddress;\n\t}\n\n\t#toInteger(segments: [number, number, number, number, number, number, number, number]): bigint {\n\t\tlet result = 0n;\n\t\tfor (const segment of segments) {\n\t\t\tif (segment < 0 || segment > 0xffff) {\n\t\t\t\tthrow new Error('IPv6 segment must be between 0 and 65535');\n\t\t\t}\n\t\t\tresult = (result << 16n) | BigInt(segment);\n\t\t}\n\t\treturn result;\n\t}\n\n\t#fromInteger(integer: bigint): [number, number, number, number, number, number, number, number] {\n\t\treturn [\n\t\t\tNumber((integer >> 112n) & 0xffffn),\n\t\t\tNumber((integer >> 96n) & 0xffffn),\n\t\t\tNumber((integer >> 80n) & 0xffffn),\n\t\t\tNumber((integer >> 64n) & 0xffffn),\n\t\t\tNumber((integer >> 48n) & 0xffffn),\n\t\t\tNumber((integer >> 32n) & 0xffffn),\n\t\t\tNumber((integer >> 16n) & 0xffffn),\n\t\t\tNumber(integer & 0xffffn),\n\t\t];\n\t}\n\n\t#match(network: bigint, prefix: number): boolean {\n\t\tif (prefix < 0 || prefix > 128) {\n\t\t\tthrow new Error('Invalid prefix length');\n\t\t}\n\t\tif (prefix === 0) {\n\t\t\treturn true;\n\t\t}\n\t\tconst ALL_ONES = (1n << 128n) - 1n;\n\t\tconst mask = (ALL_ONES << BigInt(128 - prefix)) & ALL_ONES;\n\t\treturn (this.#integerAddress & mask) === (network & mask);\n\t}\n}\n","import {Err, type IResult, Ok} from '@luolapeikko/result-option';\nimport {Ipv6Addr} from './Ipv6Addr';\n\n/**\n * Represents an IPv4 address.\n * @example\n * const addr1 = Ipv4Addr.from('192.168.0.1').unwrap();\n * const addr2 = new Ipv4Addr(192, 168, 0, 1);\n * const addr3 = new Ipv4Addr(0xc0a80001);\n * @since v0.0.1\n */\nexport class Ipv4Addr {\n\t/**\n\t * Creates an IPv4 address from dotted-decimal text.\n\t * @returns A successful {@link IResult} with an IPv4 address, or an error when the input is invalid.\n\t * @since v0.0.1\n\t */\n\tpublic static from(value: string): IResult<Ipv4Addr, TypeError> {\n\t\tconst match = value.match(/^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/);\n\t\tif (!match) {\n\t\t\treturn Err(new TypeError(`${value} is invalid ipv4 value`));\n\t\t}\n\t\tconst octets = match.slice(1).map(Number);\n\t\tif (octets.some((o) => o > 255)) {\n\t\t\treturn Err(new TypeError(`${value} is invalid ipv4 value`));\n\t\t}\n\t\treturn Ok(new Ipv4Addr(octets[0], octets[1], octets[2], octets[3]));\n\t}\n\n\t/**\n\t * Creates an IPv4 address from a 4-byte buffer.\n\t * @returns A successful {@link IResult} with an IPv4 address, or an error when the buffer cannot be read.\n\t * @since v0.0.1\n\t */\n\tpublic static fromBuffer(buffer: ArrayBuffer, littleEndian?: boolean): IResult<Ipv4Addr> {\n\t\ttry {\n\t\t\tconst view = new DataView(buffer);\n\t\t\treturn Ok(new Ipv4Addr(view.getUint32(0, littleEndian)));\n\t\t} catch (err) {\n\t\t\treturn Err(err);\n\t\t}\n\t}\n\n\t/**\n\t * The number of bits in an IPv4 address.\n\t * @since v0.0.1\n\t */\n\tpublic static readonly BITS = 32;\n\n\t/**\n\t * The broadcast address `255.255.255.255`.\n\t * @since v0.0.1\n\t */\n\tpublic static readonly BROADCAST: Ipv4Addr = new Ipv4Addr(0xffffffff);\n\n\t/**\n\t * The localhost address `127.0.0.1`.\n\t * @since v0.0.1\n\t */\n\tpublic static readonly LOCALHOST: Ipv4Addr = new Ipv4Addr(0x7f000001);\n\n\t/**\n\t * The unspecified address `0.0.0.0`.\n\t * @since v0.0.1\n\t */\n\tpublic static readonly UNSPECIFIED: Ipv4Addr = new Ipv4Addr(0x00000000);\n\n\t/**\n\t * The address family identifier for IPv4 addresses.\n\t * @since v0.0.1\n\t */\n\tpublic readonly family = 'ipv4';\n\n\t#integerAddress: number;\n\n\t/**\n\t * Creates a new IPv4 address from four octets.\n\t * @param num1 The first octet.\n\t * @param num2 The second octet.\n\t * @param num3 The third octet.\n\t * @param num4 The fourth octet.\n\t * @example\n\t * new Ipv4Addr(192, 168, 0, 1) // creates the address `192.168.0.1`\n\t */\n\tpublic constructor(num1: number, num2: number, num3: number, num4: number);\n\t/**\n\t * Creates a new IPv4 address from an integer value.\n\t * @param integerValue The integer representation of the IPv4 address.\n\t * @example\n\t * new Ipv4Addr(0xc0a80001) // creates the address `192.168.0.1` from the integer value `0xc0a80001`\n\t */\n\tpublic constructor(integerValue: number);\n\tpublic constructor(...args: [number] | [number, number, number, number]) {\n\t\tif (args.length === 1) {\n\t\t\tthis.#integerAddress = args[0];\n\t\t} else {\n\t\t\tthis.#integerAddress = this.#toInteger(args[0], args[1], args[2], args[3]);\n\t\t}\n\t}\n\n\t/**\n\t * Checks whether this address is the broadcast address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc919#section-7\n\t * @returns `true` when the address is `255.255.255.255`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isBroadcast(): boolean {\n\t\treturn this.#integerAddress === 0xffffffff;\n\t}\n\n\t/**\n\t * Checks whether this address is in a documentation-only range.\n\t * @see https://datatracker.ietf.org/doc/html/rfc5737\n\t * @returns `true` for `192.0.2.0/24`, `198.51.100.0/24`, or `203.0.113.0/24`; otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isDocumentation(): boolean {\n\t\treturn (\n\t\t\tthis.#match(0xc0000200, 24) || // 192.0.2.0/24\n\t\t\tthis.#match(0xc6336400, 24) || // 198.51.100.0/24\n\t\t\tthis.#match(0xcb007100, 24) // 203.0.113.0/24\n\t\t);\n\t}\n\n\t/**\n\t * Checks whether this address is in the benchmarking range.\n\t * @see https://datatracker.ietf.org/doc/html/rfc2544\n\t * @returns `true` when the address is in `198.18.0.0/15`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isBenchmarking(): boolean {\n\t\treturn this.#match(0xc6120000, 15);\n\t}\n\n\t/**\n\t * Checks whether this address is globally reachable.\n\t * @see https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml\n\t * @returns `true` when the address is not in any special non-global range.\n\t * @since v0.0.1\n\t */\n\tpublic isGlobal(): boolean {\n\t\treturn !(\n\t\t\tthis.isUnspecified() ||\n\t\t\tthis.isPrivate() ||\n\t\t\tthis.isShared() ||\n\t\t\tthis.isLoopback() ||\n\t\t\tthis.isLinkLocal() ||\n\t\t\tthis.isDocumentation() ||\n\t\t\tthis.isBenchmarking() ||\n\t\t\tthis.isReserved() ||\n\t\t\tthis.isMulticast() ||\n\t\t\tthis.isBroadcast()\n\t\t);\n\t}\n\n\t/**\n\t * Checks whether this address is link-local.\n\t * @see https://datatracker.ietf.org/doc/html/rfc3927\n\t * @returns `true` when the address is in `169.254.0.0/16`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isLinkLocal(): boolean {\n\t\treturn this.#match(0xa9fe0000, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a loopback address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc1122\n\t * @returns `true` when the address is in `127.0.0.0/8`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isLoopback(): boolean {\n\t\treturn this.#match(0x7f000000, 8);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc5771\n\t * @returns `true` when the address is in `224.0.0.0/4`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isMulticast(): boolean {\n\t\treturn this.#match(0xe0000000, 4);\n\t}\n\n\t/**\n\t * Checks whether this address is in a private-use range.\n\t * @see https://datatracker.ietf.org/doc/html/rfc1918\n\t * @returns `true` for `10.0.0.0/8`, `172.16.0.0/12`, or `192.168.0.0/16`; otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isPrivate(): boolean {\n\t\treturn (\n\t\t\tthis.#match(0x0a000000, 8) || // 10.0.0.0/8\n\t\t\tthis.#match(0xac100000, 12) || // 172.16.0.0/12\n\t\t\tthis.#match(0xc0a80000, 16) // 192.168.0.0/16\n\t\t);\n\t}\n\n\t/**\n\t * Checks whether this address is in the reserved range.\n\t * @see https://datatracker.ietf.org/doc/html/rfc1112\n\t * @returns `true` when the address is in `240.0.0.0/4` except the broadcast address.\n\t * @since v0.0.1\n\t */\n\tpublic isReserved(): boolean {\n\t\treturn this.#match(0xf0000000, 4) && !this.isBroadcast();\n\t}\n\n\t/**\n\t * Checks whether this address is in the shared Carrier-Grade NAT range.\n\t * @see https://datatracker.ietf.org/doc/html/rfc6598\n\t * @returns `true` when the address is in `100.64.0.0/10`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isShared(): boolean {\n\t\treturn this.#match(0x64400000, 10);\n\t}\n\n\t/**\n\t * Checks whether this address is the unspecified address.\n\t * @returns `true` when the address is `0.0.0.0`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isUnspecified(): boolean {\n\t\treturn this.#integerAddress === 0;\n\t}\n\n\t/**\n\t * Converts this address to an IPv4-compatible IPv6 address.\n\t * @returns An IPv6 address in the form `::a.b.c.d`.\n\t * @since v0.0.1\n\t */\n\tpublic toIpv6(): Ipv6Addr {\n\t\treturn Ipv6Addr.from(`::${this.toString()}`).unwrap();\n\t}\n\n\t/**\n\t * Converts this address to an IPv4-mapped IPv6 address.\n\t * @returns An IPv6 address in the form `::ffff:a.b.c.d`.\n\t * @since v0.0.1\n\t */\n\tpublic toIpv6Mapped(): Ipv6Addr {\n\t\treturn Ipv6Addr.from(`::ffff:${this.toString()}`).unwrap();\n\t}\n\n\t/**\n\t * Formats this address as dotted-decimal text.\n\t * @returns The IPv4 string representation, such as `192.168.0.1`.\n\t * @since v0.0.1\n\t */\n\tpublic toString(): string {\n\t\tconst [num1, num2, num3, num4] = this.#fromInteger(this.#integerAddress);\n\t\treturn `${num1}.${num2}.${num3}.${num4}`;\n\t}\n\n\t/**\n\t * Encodes this address to a 4-byte buffer.\n\t * @returns An `ArrayBuffer` containing the IPv4 integer value.\n\t * @since v0.0.1\n\t */\n\tpublic toBuffer(littleEndian?: boolean): ArrayBuffer {\n\t\tconst buffer = new ArrayBuffer(4);\n\t\tconst view = new DataView(buffer);\n\t\tview.setUint32(0, this.#integerAddress, littleEndian);\n\t\treturn buffer;\n\t}\n\n\t/**\n\t * Compares this IPv4 address with another for equality.\n\t * @param other instance of another IPv4 address to compare with.\n\t * @returns `true` if both addresses are equal, otherwise `false`.\n\t * @since v0.1.0\n\t */\n\tpublic equals(other: Ipv4Addr | Ipv6Addr | object): boolean {\n\t\treturn 'family' in other && this.family === other.family && this.#integerAddress === other.#integerAddress;\n\t}\n\n\t#toInteger(num1: number, num2: number, num3: number, num4: number): number {\n\t\tfor (const octet of [num1, num2, num3, num4]) {\n\t\t\tif (octet < 0 || octet > 255) {\n\t\t\t\tthrow new Error('IPv4 octet must be between 0 and 255');\n\t\t\t}\n\t\t}\n\t\treturn ((num1 << 24) | (num2 << 16) | (num3 << 8) | num4) >>> 0;\n\t}\n\n\t#fromInteger(integer: number): [number, number, number, number] {\n\t\tconst num1 = (integer >> 24) & 0xff;\n\t\tconst num2 = (integer >> 16) & 0xff;\n\t\tconst num3 = (integer >> 8) & 0xff;\n\t\tconst num4 = integer & 0xff;\n\t\treturn [num1, num2, num3, num4];\n\t}\n\n\t#match(network: number, prefix: number): boolean {\n\t\tif (prefix < 0 || prefix > 32) {\n\t\t\tthrow new Error('Invalid prefix length');\n\t\t}\n\t\tconst mask = prefix === 0 ? 0 : (~0 << (32 - prefix)) >>> 0;\n\t\treturn (this.#integerAddress & mask) === (network & mask);\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["#parseComponents","#parseInt","#parseEmbeddedIpv4","Result","#integerAddress","#toInteger","#match","#fromInteger","#integerAddress","#toInteger","#match","#fromInteger"],"sources":["../src/Ipv6Addr.ts","../src/Ipv4Addr.ts"],"sourcesContent":["import {Err, type IOption, type IResult, None, Ok, Result, Some} from '@luolapeikko/result-option';\nimport {Ipv4Addr} from './Ipv4Addr';\n\n/**\n * Represents an IPv6 address.\n * @example\n * const addr1 = Ipv6Addr.from('2001:db8::1').unwrap();\n * const addr2 = new Ipv6Addr([0x2001, 0xdb8, 0, 0, 0, 0, 0, 1]);\n * const addr3 = new Ipv6Addr(0x20010db8000000000000000000000001n);\n * @since v0.0.1\n */\nexport class Ipv6Addr {\n\tprivate static regex =\n\t\t/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;\n\n\t/**\n\t * Creates an IPv6 address from text.\n\t * @returns A successful result with an IPv6 address, or an error when the input is invalid.\n\t * @example\n\t * const addr = Ipv6Addr.from('2001:db8::1').unwrap();\n\t * @since v0.0.1\n\t */\n\tpublic static from(value: string): IResult<Ipv6Addr, TypeError | RangeError> {\n\t\tif (typeof value !== 'string' || !Ipv6Addr.regex.test(value)) {\n\t\t\treturn Err(new TypeError(`${JSON.stringify(value)} is invalid ipv6 value`));\n\t\t}\n\t\treturn Ipv6Addr.#parseComponents(value).andThen(({leftSegs, rightSegs, embeddedIpv4}) => {\n\t\t\tconst segments: number[] = Array(8).fill(0);\n\t\t\t// Place left segments\n\t\t\tfor (let i = 0; i < leftSegs.length; i++) {\n\t\t\t\tsegments[i] = leftSegs[i];\n\t\t\t}\n\t\t\t// Place right segments\n\t\t\tconst rightStartIdx = 8 - rightSegs.length - embeddedIpv4.length;\n\t\t\tfor (let i = 0; i < rightSegs.length; i++) {\n\t\t\t\tsegments[rightStartIdx + i] = rightSegs[i];\n\t\t\t}\n\t\t\t// Place embedded IPv4\n\t\t\tfor (let i = 0; i < embeddedIpv4.length; i++) {\n\t\t\t\tsegments[rightStartIdx + rightSegs.length + i] = embeddedIpv4[i];\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn Ok(new Ipv6Addr(segments as [number, number, number, number, number, number, number, number]));\n\t\t\t} catch (err) {\n\t\t\t\treturn Err(err as RangeError);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Creates an IPv6 address from a 16-byte buffer.\n\t * @returns A successful result with an IPv6 address, or an error when the buffer cannot be read.\n\t * @since v0.0.1\n\t */\n\tpublic static fromBuffer(buffer: ArrayBuffer, littleEndian?: boolean): IResult<Ipv6Addr> {\n\t\ttry {\n\t\t\tconst view = new DataView(buffer);\n\t\t\tif (littleEndian) {\n\t\t\t\tconst low = view.getBigUint64(0, true);\n\t\t\t\tconst high = view.getBigUint64(8, true);\n\t\t\t\treturn Ok(new Ipv6Addr((high << 64n) | low));\n\t\t\t} else {\n\t\t\t\tconst high = view.getBigUint64(0, false);\n\t\t\t\tconst low = view.getBigUint64(8, false);\n\t\t\t\treturn Ok(new Ipv6Addr((high << 64n) | low));\n\t\t\t}\n\t\t} catch (err) {\n\t\t\treturn Err(err as Error);\n\t\t}\n\t}\n\n\tstatic #parseInt(value: string, radix: number): IResult<number, TypeError> {\n\t\tconst output = parseInt(value, radix);\n\t\tif (Number.isNaN(output)) {\n\t\t\treturn Err(new TypeError(`${value} is not a valid number`));\n\t\t}\n\t\treturn Ok(output);\n\t}\n\n\tstatic #parseComponents(value: string): IResult<{leftSegs: number[]; rightSegs: number[]; embeddedIpv4: number[]}, TypeError> {\n\t\tconst components = value.split('::');\n\t\tconst leftParts = components[0].split(':').filter((x) => x !== '');\n\t\tconst rightParts = components.length > 1 ? components[1].split(':').filter((x) => x !== '') : [];\n\t\tlet embeddedIpv4: number[] = [];\n\t\tconst lastPart = rightParts[rightParts.length - 1] ?? leftParts[leftParts.length - 1];\n\t\t// check if the last part is an embedded IPv4 address (e.g., ::ffff:192.168.0.1)\n\t\tif (lastPart?.includes('.')) {\n\t\t\tconst embeddedIpv4Result = Ipv6Addr.#parseEmbeddedIpv4(lastPart);\n\t\t\tif (embeddedIpv4Result.isErr) {\n\t\t\t\treturn embeddedIpv4Result;\n\t\t\t}\n\t\t\tembeddedIpv4 = embeddedIpv4Result.ok();\n\t\t\tif (rightParts.length > 0) {\n\t\t\t\trightParts.pop();\n\t\t\t} else {\n\t\t\t\tleftParts.pop();\n\t\t\t}\n\t\t}\n\t\treturn Result.tupleFlow(\n\t\t\tResult.asArray(leftParts.map((p) => Ipv6Addr.#parseInt(p, 16))),\n\t\t\t() => Result.asArray(rightParts.map((p) => Ipv6Addr.#parseInt(p, 16))),\n\t\t\t(leftSegs, rightSegs) => Ok({leftSegs, rightSegs, embeddedIpv4}),\n\t\t);\n\t}\n\n\tstatic #parseEmbeddedIpv4(value: string): IResult<number[], TypeError> {\n\t\treturn Result.asArray(value.split('.').map((octet) => Ipv6Addr.#parseInt(octet, 10))).andThen((octets) =>\n\t\t\tOk([(octets[0] << 8) | octets[1], (octets[2] << 8) | octets[3]]),\n\t\t);\n\t}\n\n\t/**\n\t * The number of bits in an IPv6 address.\n\t * @since v0.0.1\n\t */\n\tpublic static readonly BITS = 128;\n\n\t/**\n\t * The loopback address (`::1`).\n\t * @since v0.0.1\n\t */\n\tpublic static readonly LOCALHOST: Ipv6Addr = new Ipv6Addr(0x00000000000000000000000000000001n);\n\n\t/**\n\t * The unspecified address (`::`).\n\t * @since v0.0.1\n\t */\n\tpublic static readonly UNSPECIFIED: Ipv6Addr = new Ipv6Addr(0x00000000000000000000000000000000n);\n\n\t/**\n\t * The address family identifier for IPv6 addresses.\n\t * @since v0.0.1\n\t */\n\tpublic readonly family = 'ipv6';\n\n\t#integerAddress: bigint;\n\n\t/**\n\t * Creates a new IPv6 address instance.\n\t * @param value - A bigint representing the IPv6 address or an array of 8 numbers representing the segments of the address.\n\t * @throws {RangeError} If the segments array does not have exactly 8 elements or if any segment is out of range.\n\t * @throws {TypeError} If the input is neither a bigint nor an array of 8 numbers.\n\t */\n\tpublic constructor(value: bigint);\n\tpublic constructor(segments: [number, number, number, number, number, number, number, number]);\n\tpublic constructor(valueOrSegments: [number, number, number, number, number, number, number, number] | bigint) {\n\t\tif (Array.isArray(valueOrSegments) && valueOrSegments.every((seg) => typeof seg === 'number')) {\n\t\t\tthis.#integerAddress = this.#toInteger(valueOrSegments);\n\t\t} else if (typeof valueOrSegments === 'bigint') {\n\t\t\tthis.#integerAddress = valueOrSegments;\n\t\t} else {\n\t\t\tthrow new TypeError('Invalid constructor argument. Must be a bigint or an array of 8 numbers.');\n\t\t}\n\t}\n\n\t/**\n\t * Checks whether this address is in the benchmarking range.\n\t * @see https://tools.ietf.org/html/rfc5180 and https://www.rfc-editor.org/errata_search.php?eid=1752\n\t * @returns `true` when the address is in `2001:2::/48`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isBenchmarking(): boolean {\n\t\treturn this.#match(0x20010002000000000000000000000000n, 48);\n\t}\n\n\t/**\n\t * Checks whether this address is in a documentation-only range.\n\t * @see https://tools.ietf.org/html/rfc3849 and https://tools.ietf.org/html/rfc9637\n\t * @returns `true` for `2001:db8::/32` or `3fff::/20`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isDocumentation(): boolean {\n\t\treturn this.#match(0x20010db8000000000000000000000000n, 32) || this.#match(0x3fff0000000000000000000000000000n, 20);\n\t}\n\n\t/**\n\t * Checks whether this address is the loopback address.\n\t * @see https://tools.ietf.org/html/rfc4291#section-2.5.3\n\t * @returns `true` when the address is `::1`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isLoopback(): boolean {\n\t\treturn this.#integerAddress === 1n;\n\t}\n\n\t/**\n\t * Checks whether this address is the unspecified address.\n\t * @see https://tools.ietf.org/html/rfc4291\n\t * @returns `true` when the address is `::`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isUnspecified(): boolean {\n\t\treturn this.#integerAddress === 0n;\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast address.\n\t * @see https://tools.ietf.org/html/rfc4291\n\t * @returns `true` when the address is in `ff00::/8`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isMulticast(): boolean {\n\t\treturn this.#integerAddress >> 120n === 0xffn;\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast interface-local address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff01::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastInterfaceLocal(): boolean {\n\t\treturn this.#match(0xff010000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast link-local address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff02::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastLinkLocal(): boolean {\n\t\treturn this.#match(0xff020000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast realm-local address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff03::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastRealmLocal(): boolean {\n\t\treturn this.#match(0xff030000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast admin-local address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff04::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastAdminLocal(): boolean {\n\t\treturn this.#match(0xff040000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast site-local address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff05::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastSiteLocal(): boolean {\n\t\treturn this.#match(0xff050000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast organization-local address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff08::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastOrganizationLocal(): boolean {\n\t\treturn this.#match(0xff080000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast global address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff0e::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastGlobal(): boolean {\n\t\treturn this.#match(0xff0e0000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is an IPv4-mapped IPv6 address.\n\t * @returns `true` when the address is in `::ffff:0:0/96`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isIpv4Mapped(): boolean {\n\t\treturn this.#match(0x00000000000000000000ffff00000000n, 96);\n\t}\n\n\t/**\n\t * Checks whether this address is a unicast address.\n\t * @see https://tools.ietf.org/html/rfc4291\n\t * @returns `true` when the address is not multicast, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isUnicast(): boolean {\n\t\treturn !this.isMulticast();\n\t}\n\n\t/**\n\t * Checks whether this address is a link-local unicast address.\n\t * @see https://tools.ietf.org/html/rfc4291\n\t * @returns `true` when the address is in `fe80::/10`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isUnicastLinkLocal(): boolean {\n\t\treturn this.#match(0xfe800000000000000000000000000000n, 10);\n\t}\n\n\t/**\n\t * Checks whether this address is a global unicast address.\n\t * @see https://tools.ietf.org/html/rfc4291#section-2.5.7\n\t * @returns `true` when the address is unicast and not loopback, link-local, private, unspecified, or documentation.\n\t * @since v0.0.1\n\t */\n\tpublic isUnicastGlobal(): boolean {\n\t\treturn this.isUnicast() && !this.isLoopback() && !this.isUnicastLinkLocal() && !this.isUniqueLocal() && !this.isUnspecified() && !this.isDocumentation();\n\t}\n\n\t/**\n\t * Checks whether this address appears globally reachable.\n\t * @see https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml\n\t * @returns `true` when the address is not in known non-global special ranges.\n\t * @since v0.0.1\n\t */\n\tpublic isGlobal(): boolean {\n\t\treturn (\n\t\t\t!this.isUnspecified() &&\n\t\t\t!this.isLoopback() &&\n\t\t\t!this.isIpv4Mapped() &&\n\t\t\t!this.isBenchmarking() &&\n\t\t\t!this.isDocumentation() &&\n\t\t\t!this.isUniqueLocal() &&\n\t\t\t!this.isUnicastLinkLocal() &&\n\t\t\t!this.isMulticast()\n\t\t);\n\t}\n\n\t/**\n\t * Checks whether this address is in the unique-local range.\n\t * @see https://tools.ietf.org/html/rfc4193\n\t * @returns `true` when the address is in `fc00::/7`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isUniqueLocal(): boolean {\n\t\treturn this.#match(0xfc000000000000000000000000000000n, 7);\n\t}\n\n\t/**\n\t * Converts this address to IPv4 when compatible or mapped.\n\t * @returns An IPv4 address for `::a.b.c.d` or `::ffff:a.b.c.d`; otherwise `None`.\n\t * @since v0.0.1\n\t */\n\tpublic toIpv4(): IOption<Ipv4Addr> {\n\t\tif (this.isIpv4Mapped() || this.#match(0n, 96)) {\n\t\t\tconst segments = this.#fromInteger(this.#integerAddress);\n\t\t\treturn Some(new Ipv4Addr(segments[6] >> 8, segments[6] & 0xff, segments[7] >> 8, segments[7] & 0xff));\n\t\t}\n\t\treturn None();\n\t}\n\n\t/**\n\t * Converts this address to IPv4 only when it is IPv4-mapped.\n\t * @returns An IPv4 address for `::ffff:a.b.c.d`; otherwise `None`.\n\t * @since v0.0.1\n\t */\n\tpublic toIpv4Mapped(): IOption<Ipv4Addr> {\n\t\tif (this.isIpv4Mapped()) {\n\t\t\tconst segments = this.#fromInteger(this.#integerAddress);\n\t\t\treturn Some(new Ipv4Addr(segments[6] >> 8, segments[6] & 0xff, segments[7] >> 8, segments[7] & 0xff));\n\t\t}\n\t\treturn None();\n\t}\n\n\t/**\n\t * Formats this address as a compressed IPv6 string.\n\t * @returns The shortest standard IPv6 text form.\n\t * @since v0.0.1\n\t */\n\tpublic toString(): string {\n\t\tconst segments = this.#fromInteger(this.#integerAddress);\n\t\tlet maxZeroStart = -1;\n\t\tlet maxZeroLen = 0;\n\t\tlet currentZeroStart = -1;\n\t\tlet currentZeroLen = 0;\n\n\t\tfor (let i = 0; i < segments.length; i++) {\n\t\t\tif (segments[i] === 0) {\n\t\t\t\tif (currentZeroStart === -1) {\n\t\t\t\t\tcurrentZeroStart = i;\n\t\t\t\t\tcurrentZeroLen = 1;\n\t\t\t\t} else {\n\t\t\t\t\tcurrentZeroLen++;\n\t\t\t\t}\n\t\t\t\tif (currentZeroLen > maxZeroLen) {\n\t\t\t\t\tmaxZeroLen = currentZeroLen;\n\t\t\t\t\tmaxZeroStart = currentZeroStart;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcurrentZeroStart = -1;\n\t\t\t\tcurrentZeroLen = 0;\n\t\t\t}\n\t\t}\n\n\t\tif (maxZeroLen < 2) {\n\t\t\treturn segments.map((s) => s.toString(16)).join(':');\n\t\t}\n\n\t\tconst before = segments.slice(0, maxZeroStart).map((s) => s.toString(16));\n\t\tconst after = segments.slice(maxZeroStart + maxZeroLen).map((s) => s.toString(16));\n\n\t\treturn `${before.join(':')}::${after.join(':')}`;\n\t}\n\n\t/**\n\t * Encodes this address to a 16-byte buffer.\n\t * @param littleEndian Whether to use little-endian byte order. Defaults to `false`.\n\t * @returns An `ArrayBuffer` containing the IPv6 integer value.\n\t * @since v0.0.1\n\t */\n\tpublic toBuffer(littleEndian?: boolean): ArrayBuffer {\n\t\tconst buffer = new ArrayBuffer(16);\n\t\tconst view = new DataView(buffer);\n\t\tif (littleEndian) {\n\t\t\tview.setBigUint64(0, this.#integerAddress & 0xffffffffffffffffn, true);\n\t\t\tview.setBigUint64(8, this.#integerAddress >> 64n, true);\n\t\t} else {\n\t\t\tview.setBigUint64(0, this.#integerAddress >> 64n, false);\n\t\t\tview.setBigUint64(8, this.#integerAddress & 0xffffffffffffffffn, false);\n\t\t}\n\t\treturn buffer;\n\t}\n\n\t/**\n\t * Compares this IPv6 address with another for equality.\n\t * @param other instance of another IPv6 address to compare with.\n\t * @returns `true` if both addresses are equal, otherwise `false`.\n\t * @since v0.1.0\n\t */\n\tpublic equals(other: Ipv6Addr | Ipv4Addr | object): boolean {\n\t\treturn 'family' in other && this.family === other.family && this.#integerAddress === other.#integerAddress;\n\t}\n\n\t/**\n\t * Converts an array of IPv6 segments to a bigint representation.\n\t * @param segments An array of 8 numbers representing the IPv6 segments.\n\t * @returns A bigint representing the IPv6 address.\n\t * @throws {RangeError} If the segments array does not have exactly 8 elements or if any segment is out of range.\n\t */\n\t#toInteger(segments: [number, number, number, number, number, number, number, number]): bigint {\n\t\tif (segments.length !== 8) {\n\t\t\tthrow new RangeError('IPv6 address must have exactly 8 segments');\n\t\t}\n\t\tlet result = 0n;\n\t\tfor (const segment of segments) {\n\t\t\tif (segment < 0 || segment > 0xffff) {\n\t\t\t\tthrow new RangeError('IPv6 segment must be between 0 and 65535');\n\t\t\t}\n\t\t\tresult = (result << 16n) | BigInt(segment);\n\t\t}\n\t\treturn result;\n\t}\n\n\t#fromInteger(integer: bigint): [number, number, number, number, number, number, number, number] {\n\t\treturn [\n\t\t\tNumber((integer >> 112n) & 0xffffn),\n\t\t\tNumber((integer >> 96n) & 0xffffn),\n\t\t\tNumber((integer >> 80n) & 0xffffn),\n\t\t\tNumber((integer >> 64n) & 0xffffn),\n\t\t\tNumber((integer >> 48n) & 0xffffn),\n\t\t\tNumber((integer >> 32n) & 0xffffn),\n\t\t\tNumber((integer >> 16n) & 0xffffn),\n\t\t\tNumber(integer & 0xffffn),\n\t\t];\n\t}\n\n\t#match(network: bigint, prefix: number): boolean {\n\t\tif (prefix < 0 || prefix > 128) {\n\t\t\tthrow new Error('Invalid prefix length');\n\t\t}\n\t\tif (prefix === 0) {\n\t\t\treturn true;\n\t\t}\n\t\tconst ALL_ONES = (1n << 128n) - 1n;\n\t\tconst mask = (ALL_ONES << BigInt(128 - prefix)) & ALL_ONES;\n\t\treturn (this.#integerAddress & mask) === (network & mask);\n\t}\n}\n","import {Err, type IResult, Ok} from '@luolapeikko/result-option';\nimport {Ipv6Addr} from './Ipv6Addr';\n\n/**\n * Represents an IPv4 address.\n * @example\n * const addr1 = Ipv4Addr.from('192.168.0.1').unwrap();\n * const addr2 = new Ipv4Addr(192, 168, 0, 1);\n * const addr3 = new Ipv4Addr(0xc0a80001);\n * @since v0.0.1\n */\nexport class Ipv4Addr {\n\t/**\n\t * Creates an IPv4 address from dotted-decimal text.\n\t * @returns A successful {@link IResult} with an IPv4 address, or an error when the input is invalid.\n\t * @since v0.0.1\n\t */\n\tpublic static from(value: string): IResult<Ipv4Addr, TypeError> {\n\t\tconst match = value.match(/^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/);\n\t\tif (!match) {\n\t\t\treturn Err(new TypeError(`${value} is invalid ipv4 value`));\n\t\t}\n\t\tconst octets = match.slice(1).map(Number);\n\t\tif (octets.some((o) => o > 255)) {\n\t\t\treturn Err(new TypeError(`${value} is invalid ipv4 value`));\n\t\t}\n\t\treturn Ok(new Ipv4Addr(octets[0], octets[1], octets[2], octets[3]));\n\t}\n\n\t/**\n\t * Creates an IPv4 address from a 4-byte buffer.\n\t * @returns A successful {@link IResult} with an IPv4 address, or an error when the buffer cannot be read.\n\t * @since v0.0.1\n\t */\n\tpublic static fromBuffer(buffer: ArrayBuffer, littleEndian?: boolean): IResult<Ipv4Addr> {\n\t\ttry {\n\t\t\tconst view = new DataView(buffer);\n\t\t\treturn Ok(new Ipv4Addr(view.getUint32(0, littleEndian)));\n\t\t} catch (err) {\n\t\t\treturn Err(err);\n\t\t}\n\t}\n\n\t/**\n\t * The number of bits in an IPv4 address.\n\t * @since v0.0.1\n\t */\n\tpublic static readonly BITS = 32;\n\n\t/**\n\t * The broadcast address `255.255.255.255`.\n\t * @since v0.0.1\n\t */\n\tpublic static readonly BROADCAST: Ipv4Addr = new Ipv4Addr(0xffffffff);\n\n\t/**\n\t * The localhost address `127.0.0.1`.\n\t * @since v0.0.1\n\t */\n\tpublic static readonly LOCALHOST: Ipv4Addr = new Ipv4Addr(0x7f000001);\n\n\t/**\n\t * The unspecified address `0.0.0.0`.\n\t * @since v0.0.1\n\t */\n\tpublic static readonly UNSPECIFIED: Ipv4Addr = new Ipv4Addr(0x00000000);\n\n\t/**\n\t * The address family identifier for IPv4 addresses.\n\t * @since v0.0.1\n\t */\n\tpublic readonly family = 'ipv4';\n\n\t#integerAddress: number;\n\n\t/**\n\t * Creates a new IPv4 address from four octets.\n\t * @param num1 The first octet.\n\t * @param num2 The second octet.\n\t * @param num3 The third octet.\n\t * @param num4 The fourth octet.\n\t * @throws {RangeError} If the integer values are not in the range of 0 to 255 for each octet.\n\t * @throws {TypeError} If the input is not a number.\n\t * @example\n\t * new Ipv4Addr(192, 168, 0, 1) // creates the address `192.168.0.1`\n\t */\n\tpublic constructor(num1: number, num2: number, num3: number, num4: number);\n\t/**\n\t * Creates a new IPv4 address from an integer value.\n\t * @param integerValue The integer representation of the IPv4 address.\n\t * @throws {RangeError} If the integer value is not in the range of 0 to 0xffffffff.\n\t * @throws {TypeError} If the input is not a number.\n\t * @example\n\t * new Ipv4Addr(0xc0a80001) // creates the address `192.168.0.1` from the integer value `0xc0a80001`\n\t */\n\tpublic constructor(integerValue: number);\n\tpublic constructor(...args: [number] | [number, number, number, number]) {\n\t\tif (!Array.isArray(args) || args.every((arg) => typeof arg !== 'number')) {\n\t\t\tthrow new TypeError('Invalid constructor argument. Must be a number or an array of 4 numbers.');\n\t\t}\n\t\tif (args.length === 1) {\n\t\t\tif (args[0] < 0 || args[0] > 0xffffffff) {\n\t\t\t\tthrow new RangeError('IPv4 integer value must be between 0 and 0xffffffff');\n\t\t\t}\n\t\t\tthis.#integerAddress = args[0];\n\t\t} else {\n\t\t\tthis.#integerAddress = this.#toInteger(args[0], args[1], args[2], args[3]);\n\t\t}\n\t}\n\n\t/**\n\t * Checks whether this address is the broadcast address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc919#section-7\n\t * @returns `true` when the address is `255.255.255.255`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isBroadcast(): boolean {\n\t\treturn this.#integerAddress === 0xffffffff;\n\t}\n\n\t/**\n\t * Checks whether this address is in a documentation-only range.\n\t * @see https://datatracker.ietf.org/doc/html/rfc5737\n\t * @returns `true` for `192.0.2.0/24`, `198.51.100.0/24`, or `203.0.113.0/24`; otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isDocumentation(): boolean {\n\t\treturn (\n\t\t\tthis.#match(0xc0000200, 24) || // 192.0.2.0/24\n\t\t\tthis.#match(0xc6336400, 24) || // 198.51.100.0/24\n\t\t\tthis.#match(0xcb007100, 24) // 203.0.113.0/24\n\t\t);\n\t}\n\n\t/**\n\t * Checks whether this address is in the benchmarking range.\n\t * @see https://datatracker.ietf.org/doc/html/rfc2544\n\t * @returns `true` when the address is in `198.18.0.0/15`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isBenchmarking(): boolean {\n\t\treturn this.#match(0xc6120000, 15);\n\t}\n\n\t/**\n\t * Checks whether this address is globally reachable.\n\t * @see https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml\n\t * @returns `true` when the address is not in any special non-global range.\n\t * @since v0.0.1\n\t */\n\tpublic isGlobal(): boolean {\n\t\treturn !(\n\t\t\tthis.isUnspecified() ||\n\t\t\tthis.isPrivate() ||\n\t\t\tthis.isShared() ||\n\t\t\tthis.isLoopback() ||\n\t\t\tthis.isLinkLocal() ||\n\t\t\tthis.isDocumentation() ||\n\t\t\tthis.isBenchmarking() ||\n\t\t\tthis.isReserved() ||\n\t\t\tthis.isMulticast() ||\n\t\t\tthis.isBroadcast()\n\t\t);\n\t}\n\n\t/**\n\t * Checks whether this address is link-local.\n\t * @see https://datatracker.ietf.org/doc/html/rfc3927\n\t * @returns `true` when the address is in `169.254.0.0/16`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isLinkLocal(): boolean {\n\t\treturn this.#match(0xa9fe0000, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a loopback address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc1122\n\t * @returns `true` when the address is in `127.0.0.0/8`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isLoopback(): boolean {\n\t\treturn this.#match(0x7f000000, 8);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc5771\n\t * @returns `true` when the address is in `224.0.0.0/4`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isMulticast(): boolean {\n\t\treturn this.#match(0xe0000000, 4);\n\t}\n\n\t/**\n\t * Checks whether this address is in a private-use range.\n\t * @see https://datatracker.ietf.org/doc/html/rfc1918\n\t * @returns `true` for `10.0.0.0/8`, `172.16.0.0/12`, or `192.168.0.0/16`; otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isPrivate(): boolean {\n\t\treturn (\n\t\t\tthis.#match(0x0a000000, 8) || // 10.0.0.0/8\n\t\t\tthis.#match(0xac100000, 12) || // 172.16.0.0/12\n\t\t\tthis.#match(0xc0a80000, 16) // 192.168.0.0/16\n\t\t);\n\t}\n\n\t/**\n\t * Checks whether this address is in the reserved range.\n\t * @see https://datatracker.ietf.org/doc/html/rfc1112\n\t * @returns `true` when the address is in `240.0.0.0/4` except the broadcast address.\n\t * @since v0.0.1\n\t */\n\tpublic isReserved(): boolean {\n\t\treturn this.#match(0xf0000000, 4) && !this.isBroadcast();\n\t}\n\n\t/**\n\t * Checks whether this address is in the shared Carrier-Grade NAT range.\n\t * @see https://datatracker.ietf.org/doc/html/rfc6598\n\t * @returns `true` when the address is in `100.64.0.0/10`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isShared(): boolean {\n\t\treturn this.#match(0x64400000, 10);\n\t}\n\n\t/**\n\t * Checks whether this address is the unspecified address.\n\t * @returns `true` when the address is `0.0.0.0`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isUnspecified(): boolean {\n\t\treturn this.#integerAddress === 0;\n\t}\n\n\t/**\n\t * Converts this address to an IPv4-compatible IPv6 address.\n\t * @returns An IPv6 address in the form `::a.b.c.d`.\n\t * @since v0.0.1\n\t */\n\tpublic toIpv6(): Ipv6Addr {\n\t\treturn Ipv6Addr.from(`::${this.toString()}`).unwrap();\n\t}\n\n\t/**\n\t * Converts this address to an IPv4-mapped IPv6 address.\n\t * @returns An IPv6 address in the form `::ffff:a.b.c.d`.\n\t * @since v0.0.1\n\t */\n\tpublic toIpv6Mapped(): Ipv6Addr {\n\t\treturn Ipv6Addr.from(`::ffff:${this.toString()}`).unwrap();\n\t}\n\n\t/**\n\t * Formats this address as dotted-decimal text.\n\t * @returns The IPv4 string representation, such as `192.168.0.1`.\n\t * @since v0.0.1\n\t */\n\tpublic toString(): string {\n\t\tconst [num1, num2, num3, num4] = this.#fromInteger(this.#integerAddress);\n\t\treturn `${num1}.${num2}.${num3}.${num4}`;\n\t}\n\n\t/**\n\t * Encodes this address to a 4-byte buffer.\n\t * @returns An `ArrayBuffer` containing the IPv4 integer value.\n\t * @since v0.0.1\n\t */\n\tpublic toBuffer(littleEndian?: boolean): ArrayBuffer {\n\t\tconst buffer = new ArrayBuffer(4);\n\t\tconst view = new DataView(buffer);\n\t\tview.setUint32(0, this.#integerAddress, littleEndian);\n\t\treturn buffer;\n\t}\n\n\t/**\n\t * Compares this IPv4 address with another for equality.\n\t * @param other instance of another IPv4 address to compare with.\n\t * @returns `true` if both addresses are equal, otherwise `false`.\n\t * @since v0.1.0\n\t */\n\tpublic equals(other: Ipv4Addr | Ipv6Addr | object): boolean {\n\t\treturn 'family' in other && this.family === other.family && this.#integerAddress === other.#integerAddress;\n\t}\n\n\t#toInteger(num1: number, num2: number, num3: number, num4: number): number {\n\t\tfor (const octet of [num1, num2, num3, num4]) {\n\t\t\tif (octet < 0 || octet > 255) {\n\t\t\t\tthrow new RangeError('IPv4 octet must be between 0 and 255');\n\t\t\t}\n\t\t}\n\t\treturn ((num1 << 24) | (num2 << 16) | (num3 << 8) | num4) >>> 0;\n\t}\n\n\t#fromInteger(integer: number): [number, number, number, number] {\n\t\tconst num1 = (integer >> 24) & 0xff;\n\t\tconst num2 = (integer >> 16) & 0xff;\n\t\tconst num3 = (integer >> 8) & 0xff;\n\t\tconst num4 = integer & 0xff;\n\t\treturn [num1, num2, num3, num4];\n\t}\n\n\t#match(network: number, prefix: number): boolean {\n\t\tif (prefix < 0 || prefix > 32) {\n\t\t\tthrow new RangeError('Invalid prefix length');\n\t\t}\n\t\tconst mask = prefix === 0 ? 0 : (~0 << (32 - prefix)) >>> 0;\n\t\treturn (this.#integerAddress & mask) === (network & mask);\n\t}\n}\n"],"mappings":"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"}
|
package/dist/index.d.cts
CHANGED
|
@@ -19,7 +19,7 @@ declare class Ipv6Addr {
|
|
|
19
19
|
* const addr = Ipv6Addr.from('2001:db8::1').unwrap();
|
|
20
20
|
* @since v0.0.1
|
|
21
21
|
*/
|
|
22
|
-
static from(value: string): IResult<Ipv6Addr>;
|
|
22
|
+
static from(value: string): IResult<Ipv6Addr, TypeError | RangeError>;
|
|
23
23
|
/**
|
|
24
24
|
* Creates an IPv6 address from a 16-byte buffer.
|
|
25
25
|
* @returns A successful result with an IPv6 address, or an error when the buffer cannot be read.
|
|
@@ -46,6 +46,12 @@ declare class Ipv6Addr {
|
|
|
46
46
|
* @since v0.0.1
|
|
47
47
|
*/
|
|
48
48
|
readonly family = "ipv6";
|
|
49
|
+
/**
|
|
50
|
+
* Creates a new IPv6 address instance.
|
|
51
|
+
* @param value - A bigint representing the IPv6 address or an array of 8 numbers representing the segments of the address.
|
|
52
|
+
* @throws {RangeError} If the segments array does not have exactly 8 elements or if any segment is out of range.
|
|
53
|
+
* @throws {TypeError} If the input is neither a bigint nor an array of 8 numbers.
|
|
54
|
+
*/
|
|
49
55
|
constructor(value: bigint);
|
|
50
56
|
constructor(segments: [number, number, number, number, number, number, number, number]);
|
|
51
57
|
/**
|
|
@@ -261,6 +267,8 @@ declare class Ipv4Addr {
|
|
|
261
267
|
* @param num2 The second octet.
|
|
262
268
|
* @param num3 The third octet.
|
|
263
269
|
* @param num4 The fourth octet.
|
|
270
|
+
* @throws {RangeError} If the integer values are not in the range of 0 to 255 for each octet.
|
|
271
|
+
* @throws {TypeError} If the input is not a number.
|
|
264
272
|
* @example
|
|
265
273
|
* new Ipv4Addr(192, 168, 0, 1) // creates the address `192.168.0.1`
|
|
266
274
|
*/
|
|
@@ -268,6 +276,8 @@ declare class Ipv4Addr {
|
|
|
268
276
|
/**
|
|
269
277
|
* Creates a new IPv4 address from an integer value.
|
|
270
278
|
* @param integerValue The integer representation of the IPv4 address.
|
|
279
|
+
* @throws {RangeError} If the integer value is not in the range of 0 to 0xffffffff.
|
|
280
|
+
* @throws {TypeError} If the input is not a number.
|
|
271
281
|
* @example
|
|
272
282
|
* new Ipv4Addr(0xc0a80001) // creates the address `192.168.0.1` from the integer value `0xc0a80001`
|
|
273
283
|
*/
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/Ipv6Addr.ts","../src/Ipv4Addr.ts"],"mappings":";;;;AAWA;;;;;;;cAAa,QAAA;EAAA;iBACG,KAAA;;;;;;;;SAUD,IAAA,CAAK,KAAA,WAAgB,OAAA,CAAQ,QAAA
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/Ipv6Addr.ts","../src/Ipv4Addr.ts"],"mappings":";;;;AAWA;;;;;;;cAAa,QAAA;EAAA;iBACG,KAAA;;;;;;;;SAUD,IAAA,CAAK,KAAA,WAAgB,OAAA,CAAQ,QAAA,EAAU,SAAA,GAAY,UAAA;;;;;;SAgCnD,UAAA,CAAW,MAAA,EAAQ,WAAA,EAAa,YAAA,aAAyB,OAAA,CAAQ,QAAA;;;;;kBA6DxD,IAAA;;;;;kBAMA,SAAA,EAAW,QAAA;;;;;kBAMX,WAAA,EAAa,QAAA;;;;;WAMpB,MAAA;;;;;;;EAUhB,WAAA,CAAmB,KAAA;EACnB,WAAA,CAAmB,QAAA;;;;;;;EAiBnB,cAAA;;;;;;;EAUA,eAAA;;;;;;;EAUA,UAAA;;;;;;AA6PgC;EAnPhC,aAAA;;;ACpLD;;;;ED8LC,WAAA;;;;;;;EAUA,yBAAA;;;;;;;EAUA,oBAAA;;;;;;;EAUA,qBAAA;;;;;;;EAUA,qBAAA;;;;;;;EAUA,oBAAA;;;;;;;EAUA,4BAAA;;;;;;;EAUA,iBAAA;;;;;;EASA,YAAA;;;;;;;EAUA,SAAA;;;;ACNgC;;;EDgBhC,kBAAA;;;;;;;EAUA,eAAA;;;;;;;EAUA,QAAA;;;;;;;EAmBA,aAAA;;;;;;EASA,MAAA,IAAiB,OAAA,CAAQ,QAAA;;;;;;EAazB,YAAA,IAAuB,OAAA,CAAQ,QAAA;;;;;;EAa/B,QAAA;;;;;;;EAyCA,QAAA,CAAgB,YAAA,aAAyB,WAAA;;;;;;;EAmBzC,MAAA,CAAc,KAAA,EAAO,QAAA,GAAW,QAAA;AAAA;;;;AAvajC;;;;;;;cCAa,QAAA;EAAA;;;;;;SAME,IAAA,CAAK,KAAA,WAAgB,OAAA,CAAQ,QAAA,EAAU,SAAA;;;;;;SAiBvC,UAAA,CAAW,MAAA,EAAQ,WAAA,EAAa,YAAA,aAAyB,OAAA,CAAQ,QAAA;;;;;kBAaxD,IAAA;;;;;kBAMA,SAAA,EAAW,QAAA;;;;;kBAMX,SAAA,EAAW,QAAA;;;;;kBAMX,WAAA,EAAa,QAAA;;;;;WAMpB,MAAA;;;;;;;;;;;;EAehB,WAAA,CAAmB,IAAA,UAAc,IAAA,UAAc,IAAA,UAAc,IAAA;;;;;;;;;EAS7D,WAAA,CAAmB,YAAA;;;;;;;EAqBnB,WAAA;;;;;AD8TgC;;ECpThC,eAAA;;AAnHD;;;;;EAiIC,cAAA;;;;;;;EAUA,QAAA;;;;;;;EAqBA,WAAA;;;;;;;EAUA,UAAA;;;;;;;EAUA,WAAA;;;;;;;EAUA,SAAA;;;;;;;EAcA,UAAA;;;;;;;EAUA,QAAA;;;;;;EASA,aAAA;;;;;;EASA,MAAA,IAAiB,QAAA;;;;AAyCe;;EAhChC,YAAA,IAAuB,QAAA;;;;;;EASvB,QAAA;;;;;;EAUA,QAAA,CAAgB,YAAA,aAAyB,WAAA;;;;;;;EAazC,MAAA,CAAc,KAAA,EAAO,QAAA,GAAW,QAAA;AAAA"}
|
package/dist/index.d.mts
CHANGED
|
@@ -19,7 +19,7 @@ declare class Ipv6Addr {
|
|
|
19
19
|
* const addr = Ipv6Addr.from('2001:db8::1').unwrap();
|
|
20
20
|
* @since v0.0.1
|
|
21
21
|
*/
|
|
22
|
-
static from(value: string): IResult<Ipv6Addr>;
|
|
22
|
+
static from(value: string): IResult<Ipv6Addr, TypeError | RangeError>;
|
|
23
23
|
/**
|
|
24
24
|
* Creates an IPv6 address from a 16-byte buffer.
|
|
25
25
|
* @returns A successful result with an IPv6 address, or an error when the buffer cannot be read.
|
|
@@ -46,6 +46,12 @@ declare class Ipv6Addr {
|
|
|
46
46
|
* @since v0.0.1
|
|
47
47
|
*/
|
|
48
48
|
readonly family = "ipv6";
|
|
49
|
+
/**
|
|
50
|
+
* Creates a new IPv6 address instance.
|
|
51
|
+
* @param value - A bigint representing the IPv6 address or an array of 8 numbers representing the segments of the address.
|
|
52
|
+
* @throws {RangeError} If the segments array does not have exactly 8 elements or if any segment is out of range.
|
|
53
|
+
* @throws {TypeError} If the input is neither a bigint nor an array of 8 numbers.
|
|
54
|
+
*/
|
|
49
55
|
constructor(value: bigint);
|
|
50
56
|
constructor(segments: [number, number, number, number, number, number, number, number]);
|
|
51
57
|
/**
|
|
@@ -261,6 +267,8 @@ declare class Ipv4Addr {
|
|
|
261
267
|
* @param num2 The second octet.
|
|
262
268
|
* @param num3 The third octet.
|
|
263
269
|
* @param num4 The fourth octet.
|
|
270
|
+
* @throws {RangeError} If the integer values are not in the range of 0 to 255 for each octet.
|
|
271
|
+
* @throws {TypeError} If the input is not a number.
|
|
264
272
|
* @example
|
|
265
273
|
* new Ipv4Addr(192, 168, 0, 1) // creates the address `192.168.0.1`
|
|
266
274
|
*/
|
|
@@ -268,6 +276,8 @@ declare class Ipv4Addr {
|
|
|
268
276
|
/**
|
|
269
277
|
* Creates a new IPv4 address from an integer value.
|
|
270
278
|
* @param integerValue The integer representation of the IPv4 address.
|
|
279
|
+
* @throws {RangeError} If the integer value is not in the range of 0 to 0xffffffff.
|
|
280
|
+
* @throws {TypeError} If the input is not a number.
|
|
271
281
|
* @example
|
|
272
282
|
* new Ipv4Addr(0xc0a80001) // creates the address `192.168.0.1` from the integer value `0xc0a80001`
|
|
273
283
|
*/
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/Ipv6Addr.ts","../src/Ipv4Addr.ts"],"mappings":";;;;AAWA;;;;;;;cAAa,QAAA;EAAA;iBACG,KAAA;;;;;;;;SAUD,IAAA,CAAK,KAAA,WAAgB,OAAA,CAAQ,QAAA
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/Ipv6Addr.ts","../src/Ipv4Addr.ts"],"mappings":";;;;AAWA;;;;;;;cAAa,QAAA;EAAA;iBACG,KAAA;;;;;;;;SAUD,IAAA,CAAK,KAAA,WAAgB,OAAA,CAAQ,QAAA,EAAU,SAAA,GAAY,UAAA;;;;;;SAgCnD,UAAA,CAAW,MAAA,EAAQ,WAAA,EAAa,YAAA,aAAyB,OAAA,CAAQ,QAAA;;;;;kBA6DxD,IAAA;;;;;kBAMA,SAAA,EAAW,QAAA;;;;;kBAMX,WAAA,EAAa,QAAA;;;;;WAMpB,MAAA;;;;;;;EAUhB,WAAA,CAAmB,KAAA;EACnB,WAAA,CAAmB,QAAA;;;;;;;EAiBnB,cAAA;;;;;;;EAUA,eAAA;;;;;;;EAUA,UAAA;;;;;;AA6PgC;EAnPhC,aAAA;;;ACpLD;;;;ED8LC,WAAA;;;;;;;EAUA,yBAAA;;;;;;;EAUA,oBAAA;;;;;;;EAUA,qBAAA;;;;;;;EAUA,qBAAA;;;;;;;EAUA,oBAAA;;;;;;;EAUA,4BAAA;;;;;;;EAUA,iBAAA;;;;;;EASA,YAAA;;;;;;;EAUA,SAAA;;;;ACNgC;;;EDgBhC,kBAAA;;;;;;;EAUA,eAAA;;;;;;;EAUA,QAAA;;;;;;;EAmBA,aAAA;;;;;;EASA,MAAA,IAAiB,OAAA,CAAQ,QAAA;;;;;;EAazB,YAAA,IAAuB,OAAA,CAAQ,QAAA;;;;;;EAa/B,QAAA;;;;;;;EAyCA,QAAA,CAAgB,YAAA,aAAyB,WAAA;;;;;;;EAmBzC,MAAA,CAAc,KAAA,EAAO,QAAA,GAAW,QAAA;AAAA;;;;AAvajC;;;;;;;cCAa,QAAA;EAAA;;;;;;SAME,IAAA,CAAK,KAAA,WAAgB,OAAA,CAAQ,QAAA,EAAU,SAAA;;;;;;SAiBvC,UAAA,CAAW,MAAA,EAAQ,WAAA,EAAa,YAAA,aAAyB,OAAA,CAAQ,QAAA;;;;;kBAaxD,IAAA;;;;;kBAMA,SAAA,EAAW,QAAA;;;;;kBAMX,SAAA,EAAW,QAAA;;;;;kBAMX,WAAA,EAAa,QAAA;;;;;WAMpB,MAAA;;;;;;;;;;;;EAehB,WAAA,CAAmB,IAAA,UAAc,IAAA,UAAc,IAAA,UAAc,IAAA;;;;;;;;;EAS7D,WAAA,CAAmB,YAAA;;;;;;;EAqBnB,WAAA;;;;;AD8TgC;;ECpThC,eAAA;;AAnHD;;;;;EAiIC,cAAA;;;;;;;EAUA,QAAA;;;;;;;EAqBA,WAAA;;;;;;;EAUA,UAAA;;;;;;;EAUA,WAAA;;;;;;;EAUA,SAAA;;;;;;;EAcA,UAAA;;;;;;;EAUA,QAAA;;;;;;EASA,aAAA;;;;;;EASA,MAAA,IAAiB,QAAA;;;;AAyCe;;EAhChC,YAAA,IAAuB,QAAA;;;;;;EASvB,QAAA;;;;;;EAUA,QAAA,CAAgB,YAAA,aAAyB,WAAA;;;;;;;EAazC,MAAA,CAAc,KAAA,EAAO,QAAA,GAAW,QAAA;AAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Err as e,None as t,Ok as n,Some as
|
|
1
|
+
import{Err as e,None as t,Ok as n,Result as r,Some as i}from"@luolapeikko/result-option";var a=class a{static regex=/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;static from(t){return typeof t!=`string`||!a.regex.test(t)?e(TypeError(`${JSON.stringify(t)} is invalid ipv6 value`)):a.#t(t).andThen(({leftSegs:t,rightSegs:r,embeddedIpv4:i})=>{let o=Array(8).fill(0);for(let e=0;e<t.length;e++)o[e]=t[e];let s=8-r.length-i.length;for(let e=0;e<r.length;e++)o[s+e]=r[e];for(let e=0;e<i.length;e++)o[s+r.length+e]=i[e];try{return n(new a(o))}catch(t){return e(t)}})}static fromBuffer(t,r){try{let e=new DataView(t);if(r){let t=e.getBigUint64(0,!0);return n(new a(e.getBigUint64(8,!0)<<64n|t))}else{let t=e.getBigUint64(0,!1),r=e.getBigUint64(8,!1);return n(new a(t<<64n|r))}}catch(t){return e(t)}}static#e(t,r){let i=parseInt(t,r);return Number.isNaN(i)?e(TypeError(`${t} is not a valid number`)):n(i)}static#t(e){let t=e.split(`::`),i=t[0].split(`:`).filter(e=>e!==``),o=t.length>1?t[1].split(`:`).filter(e=>e!==``):[],s=[],c=o[o.length-1]??i[i.length-1];if(c?.includes(`.`)){let e=a.#n(c);if(e.isErr)return e;s=e.ok(),o.length>0?o.pop():i.pop()}return r.tupleFlow(r.asArray(i.map(e=>a.#e(e,16))),()=>r.asArray(o.map(e=>a.#e(e,16))),(e,t)=>n({leftSegs:e,rightSegs:t,embeddedIpv4:s}))}static#n(e){return r.asArray(e.split(`.`).map(e=>a.#e(e,10))).andThen(e=>n([e[0]<<8|e[1],e[2]<<8|e[3]]))}static BITS=128;static LOCALHOST=new a(1n);static UNSPECIFIED=new a(0n);family=`ipv6`;#r;constructor(e){if(Array.isArray(e)&&e.every(e=>typeof e==`number`))this.#r=this.#i(e);else if(typeof e==`bigint`)this.#r=e;else throw TypeError(`Invalid constructor argument. Must be a bigint or an array of 8 numbers.`)}isBenchmarking(){return this.#o(42540488320432167789079031612388147200n,48)}isDocumentation(){return this.#o(42540766411282592856903984951653826560n,32)||this.#o(85065399433376081038215121361612832768n,20)}isLoopback(){return this.#r===1n}isUnspecified(){return this.#r===0n}isMulticast(){return this.#r>>120n==255n}isMulticastInterfaceLocal(){return this.#o(338958331222012082418099330867817086976n,16)}isMulticastLinkLocal(){return this.#o(338963523518870617245727861364146307072n,16)}isMulticastRealmLocal(){return this.#o(338968715815729152073356391860475527168n,16)}isMulticastAdminLocal(){return this.#o(338973908112587686900984922356804747264n,16)}isMulticastSiteLocal(){return this.#o(338979100409446221728613452853133967360n,16)}isMulticastOrganizationLocal(){return this.#o(338994677300021826211499044342121627648n,16)}isMulticastGlobal(){return this.#o(339025831081173035177270227320096948224n,16)}isIpv4Mapped(){return this.#o(281470681743360n,96)}isUnicast(){return!this.isMulticast()}isUnicastLinkLocal(){return this.#o(338288524927261089654018896841347694592n,10)}isUnicastGlobal(){return this.isUnicast()&&!this.isLoopback()&&!this.isUnicastLinkLocal()&&!this.isUniqueLocal()&&!this.isUnspecified()&&!this.isDocumentation()}isGlobal(){return!this.isUnspecified()&&!this.isLoopback()&&!this.isIpv4Mapped()&&!this.isBenchmarking()&&!this.isDocumentation()&&!this.isUniqueLocal()&&!this.isUnicastLinkLocal()&&!this.isMulticast()}isUniqueLocal(){return this.#o(334965454937798799971759379190646833152n,7)}toIpv4(){if(this.isIpv4Mapped()||this.#o(0n,96)){let e=this.#a(this.#r);return i(new o(e[6]>>8,e[6]&255,e[7]>>8,e[7]&255))}return t()}toIpv4Mapped(){if(this.isIpv4Mapped()){let e=this.#a(this.#r);return i(new o(e[6]>>8,e[6]&255,e[7]>>8,e[7]&255))}return t()}toString(){let e=this.#a(this.#r),t=-1,n=0,r=-1,i=0;for(let a=0;a<e.length;a++)e[a]===0?(r===-1?(r=a,i=1):i++,i>n&&(n=i,t=r)):(r=-1,i=0);if(n<2)return e.map(e=>e.toString(16)).join(`:`);let a=e.slice(0,t).map(e=>e.toString(16)),o=e.slice(t+n).map(e=>e.toString(16));return`${a.join(`:`)}::${o.join(`:`)}`}toBuffer(e){let t=new ArrayBuffer(16),n=new DataView(t);return e?(n.setBigUint64(0,this.#r&18446744073709551615n,!0),n.setBigUint64(8,this.#r>>64n,!0)):(n.setBigUint64(0,this.#r>>64n,!1),n.setBigUint64(8,this.#r&18446744073709551615n,!1)),t}equals(e){return`family`in e&&this.family===e.family&&this.#r===e.#r}#i(e){if(e.length!==8)throw RangeError(`IPv6 address must have exactly 8 segments`);let t=0n;for(let n of e){if(n<0||n>65535)throw RangeError(`IPv6 segment must be between 0 and 65535`);t=t<<16n|BigInt(n)}return t}#a(e){return[Number(e>>112n&65535n),Number(e>>96n&65535n),Number(e>>80n&65535n),Number(e>>64n&65535n),Number(e>>48n&65535n),Number(e>>32n&65535n),Number(e>>16n&65535n),Number(e&65535n)]}#o(e,t){if(t<0||t>128)throw Error(`Invalid prefix length`);if(t===0)return!0;let n=(1n<<128n)-1n,r=n<<BigInt(128-t)&n;return(this.#r&r)===(e&r)}},o=class t{static from(r){let i=r.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/);if(!i)return e(TypeError(`${r} is invalid ipv4 value`));let a=i.slice(1).map(Number);return a.some(e=>e>255)?e(TypeError(`${r} is invalid ipv4 value`)):n(new t(a[0],a[1],a[2],a[3]))}static fromBuffer(r,i){try{return n(new t(new DataView(r).getUint32(0,i)))}catch(t){return e(t)}}static BITS=32;static BROADCAST=new t(4294967295);static LOCALHOST=new t(2130706433);static UNSPECIFIED=new t(0);family=`ipv4`;#e;constructor(...e){if(!Array.isArray(e)||e.every(e=>typeof e!=`number`))throw TypeError(`Invalid constructor argument. Must be a number or an array of 4 numbers.`);if(e.length===1){if(e[0]<0||e[0]>4294967295)throw RangeError(`IPv4 integer value must be between 0 and 0xffffffff`);this.#e=e[0]}else this.#e=this.#t(e[0],e[1],e[2],e[3])}isBroadcast(){return this.#e===4294967295}isDocumentation(){return this.#r(3221225984,24)||this.#r(3325256704,24)||this.#r(3405803776,24)}isBenchmarking(){return this.#r(3323068416,15)}isGlobal(){return!(this.isUnspecified()||this.isPrivate()||this.isShared()||this.isLoopback()||this.isLinkLocal()||this.isDocumentation()||this.isBenchmarking()||this.isReserved()||this.isMulticast()||this.isBroadcast())}isLinkLocal(){return this.#r(2851995648,16)}isLoopback(){return this.#r(2130706432,8)}isMulticast(){return this.#r(3758096384,4)}isPrivate(){return this.#r(167772160,8)||this.#r(2886729728,12)||this.#r(3232235520,16)}isReserved(){return this.#r(4026531840,4)&&!this.isBroadcast()}isShared(){return this.#r(1681915904,10)}isUnspecified(){return this.#e===0}toIpv6(){return a.from(`::${this.toString()}`).unwrap()}toIpv6Mapped(){return a.from(`::ffff:${this.toString()}`).unwrap()}toString(){let[e,t,n,r]=this.#n(this.#e);return`${e}.${t}.${n}.${r}`}toBuffer(e){let t=new ArrayBuffer(4);return new DataView(t).setUint32(0,this.#e,e),t}equals(e){return`family`in e&&this.family===e.family&&this.#e===e.#e}#t(e,t,n,r){for(let i of[e,t,n,r])if(i<0||i>255)throw RangeError(`IPv4 octet must be between 0 and 255`);return(e<<24|t<<16|n<<8|r)>>>0}#n(e){return[e>>24&255,e>>16&255,e>>8&255,e&255]}#r(e,t){if(t<0||t>32)throw RangeError(`Invalid prefix length`);let n=t===0?0:-1<<32-t>>>0;return(this.#e&n)===(e&n)}};export{o as Ipv4Addr,a as Ipv6Addr};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["#parseComponents","#parseEmbeddedIpv4","#integerAddress","#toInteger","#match","#fromInteger","#integerAddress","#toInteger","#match","#fromInteger"],"sources":["../src/Ipv6Addr.ts","../src/Ipv4Addr.ts"],"sourcesContent":["import {Err, type IOption, type IResult, None, Ok, Some} from '@luolapeikko/result-option';\nimport {Ipv4Addr} from './Ipv4Addr';\n\n/**\n * Represents an IPv6 address.\n * @example\n * const addr1 = Ipv6Addr.from('2001:db8::1').unwrap();\n * const addr2 = new Ipv6Addr([0x2001, 0xdb8, 0, 0, 0, 0, 0, 1]);\n * const addr3 = new Ipv6Addr(0x20010db8000000000000000000000001n);\n * @since v0.0.1\n */\nexport class Ipv6Addr {\n\tprivate static regex =\n\t\t/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;\n\n\t/**\n\t * Creates an IPv6 address from text.\n\t * @returns A successful result with an IPv6 address, or an error when the input is invalid.\n\t * @example\n\t * const addr = Ipv6Addr.from('2001:db8::1').unwrap();\n\t * @since v0.0.1\n\t */\n\tpublic static from(value: string): IResult<Ipv6Addr> {\n\t\tif (!Ipv6Addr.regex.test(value)) {\n\t\t\treturn Err(new TypeError(`${value} is invalid ipv6 value`));\n\t\t}\n\t\ttry {\n\t\t\tconst {leftParts, rightParts, embeddedIpv4} = Ipv6Addr.#parseComponents(value);\n\n\t\t\tconst leftSegs = leftParts.map((p) => parseInt(p, 16));\n\t\t\tconst rightSegs = rightParts.map((p) => parseInt(p, 16));\n\n\t\t\tconst missingLen = 8 - (leftSegs.length + rightSegs.length + embeddedIpv4.length);\n\t\t\tconst segments = [...leftSegs, ...Array(missingLen).fill(0), ...rightSegs, ...embeddedIpv4];\n\n\t\t\treturn Ok(new Ipv6Addr(segments as [number, number, number, number, number, number, number, number]));\n\t\t} catch (err) {\n\t\t\treturn Err(err);\n\t\t}\n\t}\n\n\t/**\n\t * Creates an IPv6 address from a 16-byte buffer.\n\t * @returns A successful result with an IPv6 address, or an error when the buffer cannot be read.\n\t * @since v0.0.1\n\t */\n\tpublic static fromBuffer(buffer: ArrayBuffer, littleEndian?: boolean): IResult<Ipv6Addr> {\n\t\ttry {\n\t\t\tconst view = new DataView(buffer);\n\t\t\tif (littleEndian) {\n\t\t\t\tconst low = view.getBigUint64(0, true);\n\t\t\t\tconst high = view.getBigUint64(8, true);\n\t\t\t\treturn Ok(new Ipv6Addr((high << 64n) | low));\n\t\t\t} else {\n\t\t\t\tconst high = view.getBigUint64(0, false);\n\t\t\t\tconst low = view.getBigUint64(8, false);\n\t\t\t\treturn Ok(new Ipv6Addr((high << 64n) | low));\n\t\t\t}\n\t\t} catch (err) {\n\t\t\treturn Err(err as Error);\n\t\t}\n\t}\n\n\tstatic #parseComponents(value: string) {\n\t\tconst components = value.split('::');\n\t\tconst leftParts = components[0].split(':').filter((x) => x !== '');\n\t\tconst rightParts = components.length > 1 ? components[1].split(':').filter((x) => x !== '') : [];\n\t\tlet embeddedIpv4: number[] = [];\n\t\tconst lastPart = rightParts[rightParts.length - 1] ?? leftParts[leftParts.length - 1];\n\t\tif (lastPart?.includes('.')) {\n\t\t\tembeddedIpv4 = Ipv6Addr.#parseEmbeddedIpv4(lastPart);\n\t\t\tif (rightParts.length > 0) {\n\t\t\t\trightParts.pop();\n\t\t\t} else {\n\t\t\t\tleftParts.pop();\n\t\t\t}\n\t\t}\n\t\treturn {leftParts, rightParts, embeddedIpv4};\n\t}\n\n\tstatic #parseEmbeddedIpv4(value: string): number[] {\n\t\tconst ipv4Octets = value.split('.').map(Number);\n\t\treturn [(ipv4Octets[0] << 8) | ipv4Octets[1], (ipv4Octets[2] << 8) | ipv4Octets[3]];\n\t}\n\n\t/**\n\t * The number of bits in an IPv6 address.\n\t * @since v0.0.1\n\t */\n\tpublic static readonly BITS = 128;\n\n\t/**\n\t * The loopback address (`::1`).\n\t * @since v0.0.1\n\t */\n\tpublic static readonly LOCALHOST: Ipv6Addr = new Ipv6Addr(0x00000000000000000000000000000001n);\n\n\t/**\n\t * The unspecified address (`::`).\n\t * @since v0.0.1\n\t */\n\tpublic static readonly UNSPECIFIED: Ipv6Addr = new Ipv6Addr(0x00000000000000000000000000000000n);\n\n\t/**\n\t * The address family identifier for IPv6 addresses.\n\t * @since v0.0.1\n\t */\n\tpublic readonly family = 'ipv6';\n\n\t#integerAddress: bigint;\n\tpublic constructor(value: bigint);\n\tpublic constructor(segments: [number, number, number, number, number, number, number, number]);\n\tpublic constructor(valueOrSegments: [number, number, number, number, number, number, number, number] | bigint) {\n\t\tif (Array.isArray(valueOrSegments)) {\n\t\t\tthis.#integerAddress = this.#toInteger(valueOrSegments);\n\t\t} else {\n\t\t\tthis.#integerAddress = valueOrSegments;\n\t\t}\n\t}\n\n\t/**\n\t * Checks whether this address is in the benchmarking range.\n\t * @see https://tools.ietf.org/html/rfc5180 and https://www.rfc-editor.org/errata_search.php?eid=1752\n\t * @returns `true` when the address is in `2001:2::/48`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isBenchmarking(): boolean {\n\t\treturn this.#match(0x20010002000000000000000000000000n, 48);\n\t}\n\n\t/**\n\t * Checks whether this address is in a documentation-only range.\n\t * @see https://tools.ietf.org/html/rfc3849 and https://tools.ietf.org/html/rfc9637\n\t * @returns `true` for `2001:db8::/32` or `3fff::/20`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isDocumentation(): boolean {\n\t\treturn this.#match(0x20010db8000000000000000000000000n, 32) || this.#match(0x3fff0000000000000000000000000000n, 20);\n\t}\n\n\t/**\n\t * Checks whether this address is the loopback address.\n\t * @see https://tools.ietf.org/html/rfc4291#section-2.5.3\n\t * @returns `true` when the address is `::1`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isLoopback(): boolean {\n\t\treturn this.#integerAddress === 1n;\n\t}\n\n\t/**\n\t * Checks whether this address is the unspecified address.\n\t * @see https://tools.ietf.org/html/rfc4291\n\t * @returns `true` when the address is `::`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isUnspecified(): boolean {\n\t\treturn this.#integerAddress === 0n;\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast address.\n\t * @see https://tools.ietf.org/html/rfc4291\n\t * @returns `true` when the address is in `ff00::/8`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isMulticast(): boolean {\n\t\treturn this.#integerAddress >> 120n === 0xffn;\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast interface-local address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff01::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastInterfaceLocal(): boolean {\n\t\treturn this.#match(0xff010000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast link-local address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff02::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastLinkLocal(): boolean {\n\t\treturn this.#match(0xff020000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast realm-local address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff03::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastRealmLocal(): boolean {\n\t\treturn this.#match(0xff030000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast admin-local address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff04::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastAdminLocal(): boolean {\n\t\treturn this.#match(0xff040000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast site-local address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff05::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastSiteLocal(): boolean {\n\t\treturn this.#match(0xff050000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast organization-local address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff08::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastOrganizationLocal(): boolean {\n\t\treturn this.#match(0xff080000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast global address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff0e::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastGlobal(): boolean {\n\t\treturn this.#match(0xff0e0000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is an IPv4-mapped IPv6 address.\n\t * @returns `true` when the address is in `::ffff:0:0/96`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isIpv4Mapped(): boolean {\n\t\treturn this.#match(0x00000000000000000000ffff00000000n, 96);\n\t}\n\n\t/**\n\t * Checks whether this address is a unicast address.\n\t * @see https://tools.ietf.org/html/rfc4291\n\t * @returns `true` when the address is not multicast, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isUnicast(): boolean {\n\t\treturn !this.isMulticast();\n\t}\n\n\t/**\n\t * Checks whether this address is a link-local unicast address.\n\t * @see https://tools.ietf.org/html/rfc4291\n\t * @returns `true` when the address is in `fe80::/10`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isUnicastLinkLocal(): boolean {\n\t\treturn this.#match(0xfe800000000000000000000000000000n, 10);\n\t}\n\n\t/**\n\t * Checks whether this address is a global unicast address.\n\t * @see https://tools.ietf.org/html/rfc4291#section-2.5.7\n\t * @returns `true` when the address is unicast and not loopback, link-local, private, unspecified, or documentation.\n\t * @since v0.0.1\n\t */\n\tpublic isUnicastGlobal(): boolean {\n\t\treturn this.isUnicast() && !this.isLoopback() && !this.isUnicastLinkLocal() && !this.isUniqueLocal() && !this.isUnspecified() && !this.isDocumentation();\n\t}\n\n\t/**\n\t * Checks whether this address appears globally reachable.\n\t * @see https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml\n\t * @returns `true` when the address is not in known non-global special ranges.\n\t * @since v0.0.1\n\t */\n\tpublic isGlobal(): boolean {\n\t\treturn (\n\t\t\t!this.isUnspecified() &&\n\t\t\t!this.isLoopback() &&\n\t\t\t!this.isIpv4Mapped() &&\n\t\t\t!this.isBenchmarking() &&\n\t\t\t!this.isDocumentation() &&\n\t\t\t!this.isUniqueLocal() &&\n\t\t\t!this.isUnicastLinkLocal() &&\n\t\t\t!this.isMulticast()\n\t\t);\n\t}\n\n\t/**\n\t * Checks whether this address is in the unique-local range.\n\t * @see https://tools.ietf.org/html/rfc4193\n\t * @returns `true` when the address is in `fc00::/7`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isUniqueLocal(): boolean {\n\t\treturn this.#match(0xfc000000000000000000000000000000n, 7);\n\t}\n\n\t/**\n\t * Converts this address to IPv4 when compatible or mapped.\n\t * @returns An IPv4 address for `::a.b.c.d` or `::ffff:a.b.c.d`; otherwise `None`.\n\t * @since v0.0.1\n\t */\n\tpublic toIpv4(): IOption<Ipv4Addr> {\n\t\tif (this.isIpv4Mapped() || this.#match(0n, 96)) {\n\t\t\tconst segments = this.#fromInteger(this.#integerAddress);\n\t\t\treturn Some(new Ipv4Addr(segments[6] >> 8, segments[6] & 0xff, segments[7] >> 8, segments[7] & 0xff));\n\t\t}\n\t\treturn None();\n\t}\n\n\t/**\n\t * Converts this address to IPv4 only when it is IPv4-mapped.\n\t * @returns An IPv4 address for `::ffff:a.b.c.d`; otherwise `None`.\n\t * @since v0.0.1\n\t */\n\tpublic toIpv4Mapped(): IOption<Ipv4Addr> {\n\t\tif (this.isIpv4Mapped()) {\n\t\t\tconst segments = this.#fromInteger(this.#integerAddress);\n\t\t\treturn Some(new Ipv4Addr(segments[6] >> 8, segments[6] & 0xff, segments[7] >> 8, segments[7] & 0xff));\n\t\t}\n\t\treturn None();\n\t}\n\n\t/**\n\t * Formats this address as a compressed IPv6 string.\n\t * @returns The shortest standard IPv6 text form.\n\t * @since v0.0.1\n\t */\n\tpublic toString(): string {\n\t\tconst segments = this.#fromInteger(this.#integerAddress);\n\t\tlet maxZeroStart = -1;\n\t\tlet maxZeroLen = 0;\n\t\tlet currentZeroStart = -1;\n\t\tlet currentZeroLen = 0;\n\n\t\tfor (let i = 0; i < segments.length; i++) {\n\t\t\tif (segments[i] === 0) {\n\t\t\t\tif (currentZeroStart === -1) {\n\t\t\t\t\tcurrentZeroStart = i;\n\t\t\t\t\tcurrentZeroLen = 1;\n\t\t\t\t} else {\n\t\t\t\t\tcurrentZeroLen++;\n\t\t\t\t}\n\t\t\t\tif (currentZeroLen > maxZeroLen) {\n\t\t\t\t\tmaxZeroLen = currentZeroLen;\n\t\t\t\t\tmaxZeroStart = currentZeroStart;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcurrentZeroStart = -1;\n\t\t\t\tcurrentZeroLen = 0;\n\t\t\t}\n\t\t}\n\n\t\tif (maxZeroLen < 2) {\n\t\t\treturn segments.map((s) => s.toString(16)).join(':');\n\t\t}\n\n\t\tconst before = segments.slice(0, maxZeroStart).map((s) => s.toString(16));\n\t\tconst after = segments.slice(maxZeroStart + maxZeroLen).map((s) => s.toString(16));\n\n\t\treturn `${before.join(':')}::${after.join(':')}`;\n\t}\n\n\t/**\n\t * Encodes this address to a 16-byte buffer.\n\t * @param littleEndian Whether to use little-endian byte order. Defaults to `false`.\n\t * @returns An `ArrayBuffer` containing the IPv6 integer value.\n\t * @since v0.0.1\n\t */\n\tpublic toBuffer(littleEndian?: boolean): ArrayBuffer {\n\t\tconst buffer = new ArrayBuffer(16);\n\t\tconst view = new DataView(buffer);\n\t\tif (littleEndian) {\n\t\t\tview.setBigUint64(0, this.#integerAddress & 0xffffffffffffffffn, true);\n\t\t\tview.setBigUint64(8, this.#integerAddress >> 64n, true);\n\t\t} else {\n\t\t\tview.setBigUint64(0, this.#integerAddress >> 64n, false);\n\t\t\tview.setBigUint64(8, this.#integerAddress & 0xffffffffffffffffn, false);\n\t\t}\n\t\treturn buffer;\n\t}\n\n\t/**\n\t * Compares this IPv6 address with another for equality.\n\t * @param other instance of another IPv6 address to compare with.\n\t * @returns `true` if both addresses are equal, otherwise `false`.\n\t * @since v0.1.0\n\t */\n\tpublic equals(other: Ipv6Addr | Ipv4Addr | object): boolean {\n\t\treturn 'family' in other && this.family === other.family && this.#integerAddress === other.#integerAddress;\n\t}\n\n\t#toInteger(segments: [number, number, number, number, number, number, number, number]): bigint {\n\t\tlet result = 0n;\n\t\tfor (const segment of segments) {\n\t\t\tif (segment < 0 || segment > 0xffff) {\n\t\t\t\tthrow new Error('IPv6 segment must be between 0 and 65535');\n\t\t\t}\n\t\t\tresult = (result << 16n) | BigInt(segment);\n\t\t}\n\t\treturn result;\n\t}\n\n\t#fromInteger(integer: bigint): [number, number, number, number, number, number, number, number] {\n\t\treturn [\n\t\t\tNumber((integer >> 112n) & 0xffffn),\n\t\t\tNumber((integer >> 96n) & 0xffffn),\n\t\t\tNumber((integer >> 80n) & 0xffffn),\n\t\t\tNumber((integer >> 64n) & 0xffffn),\n\t\t\tNumber((integer >> 48n) & 0xffffn),\n\t\t\tNumber((integer >> 32n) & 0xffffn),\n\t\t\tNumber((integer >> 16n) & 0xffffn),\n\t\t\tNumber(integer & 0xffffn),\n\t\t];\n\t}\n\n\t#match(network: bigint, prefix: number): boolean {\n\t\tif (prefix < 0 || prefix > 128) {\n\t\t\tthrow new Error('Invalid prefix length');\n\t\t}\n\t\tif (prefix === 0) {\n\t\t\treturn true;\n\t\t}\n\t\tconst ALL_ONES = (1n << 128n) - 1n;\n\t\tconst mask = (ALL_ONES << BigInt(128 - prefix)) & ALL_ONES;\n\t\treturn (this.#integerAddress & mask) === (network & mask);\n\t}\n}\n","import {Err, type IResult, Ok} from '@luolapeikko/result-option';\nimport {Ipv6Addr} from './Ipv6Addr';\n\n/**\n * Represents an IPv4 address.\n * @example\n * const addr1 = Ipv4Addr.from('192.168.0.1').unwrap();\n * const addr2 = new Ipv4Addr(192, 168, 0, 1);\n * const addr3 = new Ipv4Addr(0xc0a80001);\n * @since v0.0.1\n */\nexport class Ipv4Addr {\n\t/**\n\t * Creates an IPv4 address from dotted-decimal text.\n\t * @returns A successful {@link IResult} with an IPv4 address, or an error when the input is invalid.\n\t * @since v0.0.1\n\t */\n\tpublic static from(value: string): IResult<Ipv4Addr, TypeError> {\n\t\tconst match = value.match(/^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/);\n\t\tif (!match) {\n\t\t\treturn Err(new TypeError(`${value} is invalid ipv4 value`));\n\t\t}\n\t\tconst octets = match.slice(1).map(Number);\n\t\tif (octets.some((o) => o > 255)) {\n\t\t\treturn Err(new TypeError(`${value} is invalid ipv4 value`));\n\t\t}\n\t\treturn Ok(new Ipv4Addr(octets[0], octets[1], octets[2], octets[3]));\n\t}\n\n\t/**\n\t * Creates an IPv4 address from a 4-byte buffer.\n\t * @returns A successful {@link IResult} with an IPv4 address, or an error when the buffer cannot be read.\n\t * @since v0.0.1\n\t */\n\tpublic static fromBuffer(buffer: ArrayBuffer, littleEndian?: boolean): IResult<Ipv4Addr> {\n\t\ttry {\n\t\t\tconst view = new DataView(buffer);\n\t\t\treturn Ok(new Ipv4Addr(view.getUint32(0, littleEndian)));\n\t\t} catch (err) {\n\t\t\treturn Err(err);\n\t\t}\n\t}\n\n\t/**\n\t * The number of bits in an IPv4 address.\n\t * @since v0.0.1\n\t */\n\tpublic static readonly BITS = 32;\n\n\t/**\n\t * The broadcast address `255.255.255.255`.\n\t * @since v0.0.1\n\t */\n\tpublic static readonly BROADCAST: Ipv4Addr = new Ipv4Addr(0xffffffff);\n\n\t/**\n\t * The localhost address `127.0.0.1`.\n\t * @since v0.0.1\n\t */\n\tpublic static readonly LOCALHOST: Ipv4Addr = new Ipv4Addr(0x7f000001);\n\n\t/**\n\t * The unspecified address `0.0.0.0`.\n\t * @since v0.0.1\n\t */\n\tpublic static readonly UNSPECIFIED: Ipv4Addr = new Ipv4Addr(0x00000000);\n\n\t/**\n\t * The address family identifier for IPv4 addresses.\n\t * @since v0.0.1\n\t */\n\tpublic readonly family = 'ipv4';\n\n\t#integerAddress: number;\n\n\t/**\n\t * Creates a new IPv4 address from four octets.\n\t * @param num1 The first octet.\n\t * @param num2 The second octet.\n\t * @param num3 The third octet.\n\t * @param num4 The fourth octet.\n\t * @example\n\t * new Ipv4Addr(192, 168, 0, 1) // creates the address `192.168.0.1`\n\t */\n\tpublic constructor(num1: number, num2: number, num3: number, num4: number);\n\t/**\n\t * Creates a new IPv4 address from an integer value.\n\t * @param integerValue The integer representation of the IPv4 address.\n\t * @example\n\t * new Ipv4Addr(0xc0a80001) // creates the address `192.168.0.1` from the integer value `0xc0a80001`\n\t */\n\tpublic constructor(integerValue: number);\n\tpublic constructor(...args: [number] | [number, number, number, number]) {\n\t\tif (args.length === 1) {\n\t\t\tthis.#integerAddress = args[0];\n\t\t} else {\n\t\t\tthis.#integerAddress = this.#toInteger(args[0], args[1], args[2], args[3]);\n\t\t}\n\t}\n\n\t/**\n\t * Checks whether this address is the broadcast address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc919#section-7\n\t * @returns `true` when the address is `255.255.255.255`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isBroadcast(): boolean {\n\t\treturn this.#integerAddress === 0xffffffff;\n\t}\n\n\t/**\n\t * Checks whether this address is in a documentation-only range.\n\t * @see https://datatracker.ietf.org/doc/html/rfc5737\n\t * @returns `true` for `192.0.2.0/24`, `198.51.100.0/24`, or `203.0.113.0/24`; otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isDocumentation(): boolean {\n\t\treturn (\n\t\t\tthis.#match(0xc0000200, 24) || // 192.0.2.0/24\n\t\t\tthis.#match(0xc6336400, 24) || // 198.51.100.0/24\n\t\t\tthis.#match(0xcb007100, 24) // 203.0.113.0/24\n\t\t);\n\t}\n\n\t/**\n\t * Checks whether this address is in the benchmarking range.\n\t * @see https://datatracker.ietf.org/doc/html/rfc2544\n\t * @returns `true` when the address is in `198.18.0.0/15`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isBenchmarking(): boolean {\n\t\treturn this.#match(0xc6120000, 15);\n\t}\n\n\t/**\n\t * Checks whether this address is globally reachable.\n\t * @see https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml\n\t * @returns `true` when the address is not in any special non-global range.\n\t * @since v0.0.1\n\t */\n\tpublic isGlobal(): boolean {\n\t\treturn !(\n\t\t\tthis.isUnspecified() ||\n\t\t\tthis.isPrivate() ||\n\t\t\tthis.isShared() ||\n\t\t\tthis.isLoopback() ||\n\t\t\tthis.isLinkLocal() ||\n\t\t\tthis.isDocumentation() ||\n\t\t\tthis.isBenchmarking() ||\n\t\t\tthis.isReserved() ||\n\t\t\tthis.isMulticast() ||\n\t\t\tthis.isBroadcast()\n\t\t);\n\t}\n\n\t/**\n\t * Checks whether this address is link-local.\n\t * @see https://datatracker.ietf.org/doc/html/rfc3927\n\t * @returns `true` when the address is in `169.254.0.0/16`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isLinkLocal(): boolean {\n\t\treturn this.#match(0xa9fe0000, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a loopback address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc1122\n\t * @returns `true` when the address is in `127.0.0.0/8`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isLoopback(): boolean {\n\t\treturn this.#match(0x7f000000, 8);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc5771\n\t * @returns `true` when the address is in `224.0.0.0/4`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isMulticast(): boolean {\n\t\treturn this.#match(0xe0000000, 4);\n\t}\n\n\t/**\n\t * Checks whether this address is in a private-use range.\n\t * @see https://datatracker.ietf.org/doc/html/rfc1918\n\t * @returns `true` for `10.0.0.0/8`, `172.16.0.0/12`, or `192.168.0.0/16`; otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isPrivate(): boolean {\n\t\treturn (\n\t\t\tthis.#match(0x0a000000, 8) || // 10.0.0.0/8\n\t\t\tthis.#match(0xac100000, 12) || // 172.16.0.0/12\n\t\t\tthis.#match(0xc0a80000, 16) // 192.168.0.0/16\n\t\t);\n\t}\n\n\t/**\n\t * Checks whether this address is in the reserved range.\n\t * @see https://datatracker.ietf.org/doc/html/rfc1112\n\t * @returns `true` when the address is in `240.0.0.0/4` except the broadcast address.\n\t * @since v0.0.1\n\t */\n\tpublic isReserved(): boolean {\n\t\treturn this.#match(0xf0000000, 4) && !this.isBroadcast();\n\t}\n\n\t/**\n\t * Checks whether this address is in the shared Carrier-Grade NAT range.\n\t * @see https://datatracker.ietf.org/doc/html/rfc6598\n\t * @returns `true` when the address is in `100.64.0.0/10`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isShared(): boolean {\n\t\treturn this.#match(0x64400000, 10);\n\t}\n\n\t/**\n\t * Checks whether this address is the unspecified address.\n\t * @returns `true` when the address is `0.0.0.0`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isUnspecified(): boolean {\n\t\treturn this.#integerAddress === 0;\n\t}\n\n\t/**\n\t * Converts this address to an IPv4-compatible IPv6 address.\n\t * @returns An IPv6 address in the form `::a.b.c.d`.\n\t * @since v0.0.1\n\t */\n\tpublic toIpv6(): Ipv6Addr {\n\t\treturn Ipv6Addr.from(`::${this.toString()}`).unwrap();\n\t}\n\n\t/**\n\t * Converts this address to an IPv4-mapped IPv6 address.\n\t * @returns An IPv6 address in the form `::ffff:a.b.c.d`.\n\t * @since v0.0.1\n\t */\n\tpublic toIpv6Mapped(): Ipv6Addr {\n\t\treturn Ipv6Addr.from(`::ffff:${this.toString()}`).unwrap();\n\t}\n\n\t/**\n\t * Formats this address as dotted-decimal text.\n\t * @returns The IPv4 string representation, such as `192.168.0.1`.\n\t * @since v0.0.1\n\t */\n\tpublic toString(): string {\n\t\tconst [num1, num2, num3, num4] = this.#fromInteger(this.#integerAddress);\n\t\treturn `${num1}.${num2}.${num3}.${num4}`;\n\t}\n\n\t/**\n\t * Encodes this address to a 4-byte buffer.\n\t * @returns An `ArrayBuffer` containing the IPv4 integer value.\n\t * @since v0.0.1\n\t */\n\tpublic toBuffer(littleEndian?: boolean): ArrayBuffer {\n\t\tconst buffer = new ArrayBuffer(4);\n\t\tconst view = new DataView(buffer);\n\t\tview.setUint32(0, this.#integerAddress, littleEndian);\n\t\treturn buffer;\n\t}\n\n\t/**\n\t * Compares this IPv4 address with another for equality.\n\t * @param other instance of another IPv4 address to compare with.\n\t * @returns `true` if both addresses are equal, otherwise `false`.\n\t * @since v0.1.0\n\t */\n\tpublic equals(other: Ipv4Addr | Ipv6Addr | object): boolean {\n\t\treturn 'family' in other && this.family === other.family && this.#integerAddress === other.#integerAddress;\n\t}\n\n\t#toInteger(num1: number, num2: number, num3: number, num4: number): number {\n\t\tfor (const octet of [num1, num2, num3, num4]) {\n\t\t\tif (octet < 0 || octet > 255) {\n\t\t\t\tthrow new Error('IPv4 octet must be between 0 and 255');\n\t\t\t}\n\t\t}\n\t\treturn ((num1 << 24) | (num2 << 16) | (num3 << 8) | num4) >>> 0;\n\t}\n\n\t#fromInteger(integer: number): [number, number, number, number] {\n\t\tconst num1 = (integer >> 24) & 0xff;\n\t\tconst num2 = (integer >> 16) & 0xff;\n\t\tconst num3 = (integer >> 8) & 0xff;\n\t\tconst num4 = integer & 0xff;\n\t\treturn [num1, num2, num3, num4];\n\t}\n\n\t#match(network: number, prefix: number): boolean {\n\t\tif (prefix < 0 || prefix > 32) {\n\t\t\tthrow new Error('Invalid prefix length');\n\t\t}\n\t\tconst mask = prefix === 0 ? 0 : (~0 << (32 - prefix)) >>> 0;\n\t\treturn (this.#integerAddress & mask) === (network & mask);\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["#parseComponents","#parseInt","#parseEmbeddedIpv4","#integerAddress","#toInteger","#match","#fromInteger","#integerAddress","#toInteger","#match","#fromInteger"],"sources":["../src/Ipv6Addr.ts","../src/Ipv4Addr.ts"],"sourcesContent":["import {Err, type IOption, type IResult, None, Ok, Result, Some} from '@luolapeikko/result-option';\nimport {Ipv4Addr} from './Ipv4Addr';\n\n/**\n * Represents an IPv6 address.\n * @example\n * const addr1 = Ipv6Addr.from('2001:db8::1').unwrap();\n * const addr2 = new Ipv6Addr([0x2001, 0xdb8, 0, 0, 0, 0, 0, 1]);\n * const addr3 = new Ipv6Addr(0x20010db8000000000000000000000001n);\n * @since v0.0.1\n */\nexport class Ipv6Addr {\n\tprivate static regex =\n\t\t/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;\n\n\t/**\n\t * Creates an IPv6 address from text.\n\t * @returns A successful result with an IPv6 address, or an error when the input is invalid.\n\t * @example\n\t * const addr = Ipv6Addr.from('2001:db8::1').unwrap();\n\t * @since v0.0.1\n\t */\n\tpublic static from(value: string): IResult<Ipv6Addr, TypeError | RangeError> {\n\t\tif (typeof value !== 'string' || !Ipv6Addr.regex.test(value)) {\n\t\t\treturn Err(new TypeError(`${JSON.stringify(value)} is invalid ipv6 value`));\n\t\t}\n\t\treturn Ipv6Addr.#parseComponents(value).andThen(({leftSegs, rightSegs, embeddedIpv4}) => {\n\t\t\tconst segments: number[] = Array(8).fill(0);\n\t\t\t// Place left segments\n\t\t\tfor (let i = 0; i < leftSegs.length; i++) {\n\t\t\t\tsegments[i] = leftSegs[i];\n\t\t\t}\n\t\t\t// Place right segments\n\t\t\tconst rightStartIdx = 8 - rightSegs.length - embeddedIpv4.length;\n\t\t\tfor (let i = 0; i < rightSegs.length; i++) {\n\t\t\t\tsegments[rightStartIdx + i] = rightSegs[i];\n\t\t\t}\n\t\t\t// Place embedded IPv4\n\t\t\tfor (let i = 0; i < embeddedIpv4.length; i++) {\n\t\t\t\tsegments[rightStartIdx + rightSegs.length + i] = embeddedIpv4[i];\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn Ok(new Ipv6Addr(segments as [number, number, number, number, number, number, number, number]));\n\t\t\t} catch (err) {\n\t\t\t\treturn Err(err as RangeError);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Creates an IPv6 address from a 16-byte buffer.\n\t * @returns A successful result with an IPv6 address, or an error when the buffer cannot be read.\n\t * @since v0.0.1\n\t */\n\tpublic static fromBuffer(buffer: ArrayBuffer, littleEndian?: boolean): IResult<Ipv6Addr> {\n\t\ttry {\n\t\t\tconst view = new DataView(buffer);\n\t\t\tif (littleEndian) {\n\t\t\t\tconst low = view.getBigUint64(0, true);\n\t\t\t\tconst high = view.getBigUint64(8, true);\n\t\t\t\treturn Ok(new Ipv6Addr((high << 64n) | low));\n\t\t\t} else {\n\t\t\t\tconst high = view.getBigUint64(0, false);\n\t\t\t\tconst low = view.getBigUint64(8, false);\n\t\t\t\treturn Ok(new Ipv6Addr((high << 64n) | low));\n\t\t\t}\n\t\t} catch (err) {\n\t\t\treturn Err(err as Error);\n\t\t}\n\t}\n\n\tstatic #parseInt(value: string, radix: number): IResult<number, TypeError> {\n\t\tconst output = parseInt(value, radix);\n\t\tif (Number.isNaN(output)) {\n\t\t\treturn Err(new TypeError(`${value} is not a valid number`));\n\t\t}\n\t\treturn Ok(output);\n\t}\n\n\tstatic #parseComponents(value: string): IResult<{leftSegs: number[]; rightSegs: number[]; embeddedIpv4: number[]}, TypeError> {\n\t\tconst components = value.split('::');\n\t\tconst leftParts = components[0].split(':').filter((x) => x !== '');\n\t\tconst rightParts = components.length > 1 ? components[1].split(':').filter((x) => x !== '') : [];\n\t\tlet embeddedIpv4: number[] = [];\n\t\tconst lastPart = rightParts[rightParts.length - 1] ?? leftParts[leftParts.length - 1];\n\t\t// check if the last part is an embedded IPv4 address (e.g., ::ffff:192.168.0.1)\n\t\tif (lastPart?.includes('.')) {\n\t\t\tconst embeddedIpv4Result = Ipv6Addr.#parseEmbeddedIpv4(lastPart);\n\t\t\tif (embeddedIpv4Result.isErr) {\n\t\t\t\treturn embeddedIpv4Result;\n\t\t\t}\n\t\t\tembeddedIpv4 = embeddedIpv4Result.ok();\n\t\t\tif (rightParts.length > 0) {\n\t\t\t\trightParts.pop();\n\t\t\t} else {\n\t\t\t\tleftParts.pop();\n\t\t\t}\n\t\t}\n\t\treturn Result.tupleFlow(\n\t\t\tResult.asArray(leftParts.map((p) => Ipv6Addr.#parseInt(p, 16))),\n\t\t\t() => Result.asArray(rightParts.map((p) => Ipv6Addr.#parseInt(p, 16))),\n\t\t\t(leftSegs, rightSegs) => Ok({leftSegs, rightSegs, embeddedIpv4}),\n\t\t);\n\t}\n\n\tstatic #parseEmbeddedIpv4(value: string): IResult<number[], TypeError> {\n\t\treturn Result.asArray(value.split('.').map((octet) => Ipv6Addr.#parseInt(octet, 10))).andThen((octets) =>\n\t\t\tOk([(octets[0] << 8) | octets[1], (octets[2] << 8) | octets[3]]),\n\t\t);\n\t}\n\n\t/**\n\t * The number of bits in an IPv6 address.\n\t * @since v0.0.1\n\t */\n\tpublic static readonly BITS = 128;\n\n\t/**\n\t * The loopback address (`::1`).\n\t * @since v0.0.1\n\t */\n\tpublic static readonly LOCALHOST: Ipv6Addr = new Ipv6Addr(0x00000000000000000000000000000001n);\n\n\t/**\n\t * The unspecified address (`::`).\n\t * @since v0.0.1\n\t */\n\tpublic static readonly UNSPECIFIED: Ipv6Addr = new Ipv6Addr(0x00000000000000000000000000000000n);\n\n\t/**\n\t * The address family identifier for IPv6 addresses.\n\t * @since v0.0.1\n\t */\n\tpublic readonly family = 'ipv6';\n\n\t#integerAddress: bigint;\n\n\t/**\n\t * Creates a new IPv6 address instance.\n\t * @param value - A bigint representing the IPv6 address or an array of 8 numbers representing the segments of the address.\n\t * @throws {RangeError} If the segments array does not have exactly 8 elements or if any segment is out of range.\n\t * @throws {TypeError} If the input is neither a bigint nor an array of 8 numbers.\n\t */\n\tpublic constructor(value: bigint);\n\tpublic constructor(segments: [number, number, number, number, number, number, number, number]);\n\tpublic constructor(valueOrSegments: [number, number, number, number, number, number, number, number] | bigint) {\n\t\tif (Array.isArray(valueOrSegments) && valueOrSegments.every((seg) => typeof seg === 'number')) {\n\t\t\tthis.#integerAddress = this.#toInteger(valueOrSegments);\n\t\t} else if (typeof valueOrSegments === 'bigint') {\n\t\t\tthis.#integerAddress = valueOrSegments;\n\t\t} else {\n\t\t\tthrow new TypeError('Invalid constructor argument. Must be a bigint or an array of 8 numbers.');\n\t\t}\n\t}\n\n\t/**\n\t * Checks whether this address is in the benchmarking range.\n\t * @see https://tools.ietf.org/html/rfc5180 and https://www.rfc-editor.org/errata_search.php?eid=1752\n\t * @returns `true` when the address is in `2001:2::/48`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isBenchmarking(): boolean {\n\t\treturn this.#match(0x20010002000000000000000000000000n, 48);\n\t}\n\n\t/**\n\t * Checks whether this address is in a documentation-only range.\n\t * @see https://tools.ietf.org/html/rfc3849 and https://tools.ietf.org/html/rfc9637\n\t * @returns `true` for `2001:db8::/32` or `3fff::/20`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isDocumentation(): boolean {\n\t\treturn this.#match(0x20010db8000000000000000000000000n, 32) || this.#match(0x3fff0000000000000000000000000000n, 20);\n\t}\n\n\t/**\n\t * Checks whether this address is the loopback address.\n\t * @see https://tools.ietf.org/html/rfc4291#section-2.5.3\n\t * @returns `true` when the address is `::1`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isLoopback(): boolean {\n\t\treturn this.#integerAddress === 1n;\n\t}\n\n\t/**\n\t * Checks whether this address is the unspecified address.\n\t * @see https://tools.ietf.org/html/rfc4291\n\t * @returns `true` when the address is `::`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isUnspecified(): boolean {\n\t\treturn this.#integerAddress === 0n;\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast address.\n\t * @see https://tools.ietf.org/html/rfc4291\n\t * @returns `true` when the address is in `ff00::/8`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isMulticast(): boolean {\n\t\treturn this.#integerAddress >> 120n === 0xffn;\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast interface-local address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff01::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastInterfaceLocal(): boolean {\n\t\treturn this.#match(0xff010000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast link-local address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff02::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastLinkLocal(): boolean {\n\t\treturn this.#match(0xff020000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast realm-local address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff03::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastRealmLocal(): boolean {\n\t\treturn this.#match(0xff030000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast admin-local address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff04::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastAdminLocal(): boolean {\n\t\treturn this.#match(0xff040000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast site-local address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff05::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastSiteLocal(): boolean {\n\t\treturn this.#match(0xff050000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast organization-local address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff08::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastOrganizationLocal(): boolean {\n\t\treturn this.#match(0xff080000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast global address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc4291#section-2.7\n\t * @returns `true` when the address is in `ff0e::/16`, otherwise `false`.\n\t * @since v0.0.2\n\t */\n\tpublic isMulticastGlobal(): boolean {\n\t\treturn this.#match(0xff0e0000000000000000000000000000n, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is an IPv4-mapped IPv6 address.\n\t * @returns `true` when the address is in `::ffff:0:0/96`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isIpv4Mapped(): boolean {\n\t\treturn this.#match(0x00000000000000000000ffff00000000n, 96);\n\t}\n\n\t/**\n\t * Checks whether this address is a unicast address.\n\t * @see https://tools.ietf.org/html/rfc4291\n\t * @returns `true` when the address is not multicast, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isUnicast(): boolean {\n\t\treturn !this.isMulticast();\n\t}\n\n\t/**\n\t * Checks whether this address is a link-local unicast address.\n\t * @see https://tools.ietf.org/html/rfc4291\n\t * @returns `true` when the address is in `fe80::/10`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isUnicastLinkLocal(): boolean {\n\t\treturn this.#match(0xfe800000000000000000000000000000n, 10);\n\t}\n\n\t/**\n\t * Checks whether this address is a global unicast address.\n\t * @see https://tools.ietf.org/html/rfc4291#section-2.5.7\n\t * @returns `true` when the address is unicast and not loopback, link-local, private, unspecified, or documentation.\n\t * @since v0.0.1\n\t */\n\tpublic isUnicastGlobal(): boolean {\n\t\treturn this.isUnicast() && !this.isLoopback() && !this.isUnicastLinkLocal() && !this.isUniqueLocal() && !this.isUnspecified() && !this.isDocumentation();\n\t}\n\n\t/**\n\t * Checks whether this address appears globally reachable.\n\t * @see https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml\n\t * @returns `true` when the address is not in known non-global special ranges.\n\t * @since v0.0.1\n\t */\n\tpublic isGlobal(): boolean {\n\t\treturn (\n\t\t\t!this.isUnspecified() &&\n\t\t\t!this.isLoopback() &&\n\t\t\t!this.isIpv4Mapped() &&\n\t\t\t!this.isBenchmarking() &&\n\t\t\t!this.isDocumentation() &&\n\t\t\t!this.isUniqueLocal() &&\n\t\t\t!this.isUnicastLinkLocal() &&\n\t\t\t!this.isMulticast()\n\t\t);\n\t}\n\n\t/**\n\t * Checks whether this address is in the unique-local range.\n\t * @see https://tools.ietf.org/html/rfc4193\n\t * @returns `true` when the address is in `fc00::/7`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isUniqueLocal(): boolean {\n\t\treturn this.#match(0xfc000000000000000000000000000000n, 7);\n\t}\n\n\t/**\n\t * Converts this address to IPv4 when compatible or mapped.\n\t * @returns An IPv4 address for `::a.b.c.d` or `::ffff:a.b.c.d`; otherwise `None`.\n\t * @since v0.0.1\n\t */\n\tpublic toIpv4(): IOption<Ipv4Addr> {\n\t\tif (this.isIpv4Mapped() || this.#match(0n, 96)) {\n\t\t\tconst segments = this.#fromInteger(this.#integerAddress);\n\t\t\treturn Some(new Ipv4Addr(segments[6] >> 8, segments[6] & 0xff, segments[7] >> 8, segments[7] & 0xff));\n\t\t}\n\t\treturn None();\n\t}\n\n\t/**\n\t * Converts this address to IPv4 only when it is IPv4-mapped.\n\t * @returns An IPv4 address for `::ffff:a.b.c.d`; otherwise `None`.\n\t * @since v0.0.1\n\t */\n\tpublic toIpv4Mapped(): IOption<Ipv4Addr> {\n\t\tif (this.isIpv4Mapped()) {\n\t\t\tconst segments = this.#fromInteger(this.#integerAddress);\n\t\t\treturn Some(new Ipv4Addr(segments[6] >> 8, segments[6] & 0xff, segments[7] >> 8, segments[7] & 0xff));\n\t\t}\n\t\treturn None();\n\t}\n\n\t/**\n\t * Formats this address as a compressed IPv6 string.\n\t * @returns The shortest standard IPv6 text form.\n\t * @since v0.0.1\n\t */\n\tpublic toString(): string {\n\t\tconst segments = this.#fromInteger(this.#integerAddress);\n\t\tlet maxZeroStart = -1;\n\t\tlet maxZeroLen = 0;\n\t\tlet currentZeroStart = -1;\n\t\tlet currentZeroLen = 0;\n\n\t\tfor (let i = 0; i < segments.length; i++) {\n\t\t\tif (segments[i] === 0) {\n\t\t\t\tif (currentZeroStart === -1) {\n\t\t\t\t\tcurrentZeroStart = i;\n\t\t\t\t\tcurrentZeroLen = 1;\n\t\t\t\t} else {\n\t\t\t\t\tcurrentZeroLen++;\n\t\t\t\t}\n\t\t\t\tif (currentZeroLen > maxZeroLen) {\n\t\t\t\t\tmaxZeroLen = currentZeroLen;\n\t\t\t\t\tmaxZeroStart = currentZeroStart;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcurrentZeroStart = -1;\n\t\t\t\tcurrentZeroLen = 0;\n\t\t\t}\n\t\t}\n\n\t\tif (maxZeroLen < 2) {\n\t\t\treturn segments.map((s) => s.toString(16)).join(':');\n\t\t}\n\n\t\tconst before = segments.slice(0, maxZeroStart).map((s) => s.toString(16));\n\t\tconst after = segments.slice(maxZeroStart + maxZeroLen).map((s) => s.toString(16));\n\n\t\treturn `${before.join(':')}::${after.join(':')}`;\n\t}\n\n\t/**\n\t * Encodes this address to a 16-byte buffer.\n\t * @param littleEndian Whether to use little-endian byte order. Defaults to `false`.\n\t * @returns An `ArrayBuffer` containing the IPv6 integer value.\n\t * @since v0.0.1\n\t */\n\tpublic toBuffer(littleEndian?: boolean): ArrayBuffer {\n\t\tconst buffer = new ArrayBuffer(16);\n\t\tconst view = new DataView(buffer);\n\t\tif (littleEndian) {\n\t\t\tview.setBigUint64(0, this.#integerAddress & 0xffffffffffffffffn, true);\n\t\t\tview.setBigUint64(8, this.#integerAddress >> 64n, true);\n\t\t} else {\n\t\t\tview.setBigUint64(0, this.#integerAddress >> 64n, false);\n\t\t\tview.setBigUint64(8, this.#integerAddress & 0xffffffffffffffffn, false);\n\t\t}\n\t\treturn buffer;\n\t}\n\n\t/**\n\t * Compares this IPv6 address with another for equality.\n\t * @param other instance of another IPv6 address to compare with.\n\t * @returns `true` if both addresses are equal, otherwise `false`.\n\t * @since v0.1.0\n\t */\n\tpublic equals(other: Ipv6Addr | Ipv4Addr | object): boolean {\n\t\treturn 'family' in other && this.family === other.family && this.#integerAddress === other.#integerAddress;\n\t}\n\n\t/**\n\t * Converts an array of IPv6 segments to a bigint representation.\n\t * @param segments An array of 8 numbers representing the IPv6 segments.\n\t * @returns A bigint representing the IPv6 address.\n\t * @throws {RangeError} If the segments array does not have exactly 8 elements or if any segment is out of range.\n\t */\n\t#toInteger(segments: [number, number, number, number, number, number, number, number]): bigint {\n\t\tif (segments.length !== 8) {\n\t\t\tthrow new RangeError('IPv6 address must have exactly 8 segments');\n\t\t}\n\t\tlet result = 0n;\n\t\tfor (const segment of segments) {\n\t\t\tif (segment < 0 || segment > 0xffff) {\n\t\t\t\tthrow new RangeError('IPv6 segment must be between 0 and 65535');\n\t\t\t}\n\t\t\tresult = (result << 16n) | BigInt(segment);\n\t\t}\n\t\treturn result;\n\t}\n\n\t#fromInteger(integer: bigint): [number, number, number, number, number, number, number, number] {\n\t\treturn [\n\t\t\tNumber((integer >> 112n) & 0xffffn),\n\t\t\tNumber((integer >> 96n) & 0xffffn),\n\t\t\tNumber((integer >> 80n) & 0xffffn),\n\t\t\tNumber((integer >> 64n) & 0xffffn),\n\t\t\tNumber((integer >> 48n) & 0xffffn),\n\t\t\tNumber((integer >> 32n) & 0xffffn),\n\t\t\tNumber((integer >> 16n) & 0xffffn),\n\t\t\tNumber(integer & 0xffffn),\n\t\t];\n\t}\n\n\t#match(network: bigint, prefix: number): boolean {\n\t\tif (prefix < 0 || prefix > 128) {\n\t\t\tthrow new Error('Invalid prefix length');\n\t\t}\n\t\tif (prefix === 0) {\n\t\t\treturn true;\n\t\t}\n\t\tconst ALL_ONES = (1n << 128n) - 1n;\n\t\tconst mask = (ALL_ONES << BigInt(128 - prefix)) & ALL_ONES;\n\t\treturn (this.#integerAddress & mask) === (network & mask);\n\t}\n}\n","import {Err, type IResult, Ok} from '@luolapeikko/result-option';\nimport {Ipv6Addr} from './Ipv6Addr';\n\n/**\n * Represents an IPv4 address.\n * @example\n * const addr1 = Ipv4Addr.from('192.168.0.1').unwrap();\n * const addr2 = new Ipv4Addr(192, 168, 0, 1);\n * const addr3 = new Ipv4Addr(0xc0a80001);\n * @since v0.0.1\n */\nexport class Ipv4Addr {\n\t/**\n\t * Creates an IPv4 address from dotted-decimal text.\n\t * @returns A successful {@link IResult} with an IPv4 address, or an error when the input is invalid.\n\t * @since v0.0.1\n\t */\n\tpublic static from(value: string): IResult<Ipv4Addr, TypeError> {\n\t\tconst match = value.match(/^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/);\n\t\tif (!match) {\n\t\t\treturn Err(new TypeError(`${value} is invalid ipv4 value`));\n\t\t}\n\t\tconst octets = match.slice(1).map(Number);\n\t\tif (octets.some((o) => o > 255)) {\n\t\t\treturn Err(new TypeError(`${value} is invalid ipv4 value`));\n\t\t}\n\t\treturn Ok(new Ipv4Addr(octets[0], octets[1], octets[2], octets[3]));\n\t}\n\n\t/**\n\t * Creates an IPv4 address from a 4-byte buffer.\n\t * @returns A successful {@link IResult} with an IPv4 address, or an error when the buffer cannot be read.\n\t * @since v0.0.1\n\t */\n\tpublic static fromBuffer(buffer: ArrayBuffer, littleEndian?: boolean): IResult<Ipv4Addr> {\n\t\ttry {\n\t\t\tconst view = new DataView(buffer);\n\t\t\treturn Ok(new Ipv4Addr(view.getUint32(0, littleEndian)));\n\t\t} catch (err) {\n\t\t\treturn Err(err);\n\t\t}\n\t}\n\n\t/**\n\t * The number of bits in an IPv4 address.\n\t * @since v0.0.1\n\t */\n\tpublic static readonly BITS = 32;\n\n\t/**\n\t * The broadcast address `255.255.255.255`.\n\t * @since v0.0.1\n\t */\n\tpublic static readonly BROADCAST: Ipv4Addr = new Ipv4Addr(0xffffffff);\n\n\t/**\n\t * The localhost address `127.0.0.1`.\n\t * @since v0.0.1\n\t */\n\tpublic static readonly LOCALHOST: Ipv4Addr = new Ipv4Addr(0x7f000001);\n\n\t/**\n\t * The unspecified address `0.0.0.0`.\n\t * @since v0.0.1\n\t */\n\tpublic static readonly UNSPECIFIED: Ipv4Addr = new Ipv4Addr(0x00000000);\n\n\t/**\n\t * The address family identifier for IPv4 addresses.\n\t * @since v0.0.1\n\t */\n\tpublic readonly family = 'ipv4';\n\n\t#integerAddress: number;\n\n\t/**\n\t * Creates a new IPv4 address from four octets.\n\t * @param num1 The first octet.\n\t * @param num2 The second octet.\n\t * @param num3 The third octet.\n\t * @param num4 The fourth octet.\n\t * @throws {RangeError} If the integer values are not in the range of 0 to 255 for each octet.\n\t * @throws {TypeError} If the input is not a number.\n\t * @example\n\t * new Ipv4Addr(192, 168, 0, 1) // creates the address `192.168.0.1`\n\t */\n\tpublic constructor(num1: number, num2: number, num3: number, num4: number);\n\t/**\n\t * Creates a new IPv4 address from an integer value.\n\t * @param integerValue The integer representation of the IPv4 address.\n\t * @throws {RangeError} If the integer value is not in the range of 0 to 0xffffffff.\n\t * @throws {TypeError} If the input is not a number.\n\t * @example\n\t * new Ipv4Addr(0xc0a80001) // creates the address `192.168.0.1` from the integer value `0xc0a80001`\n\t */\n\tpublic constructor(integerValue: number);\n\tpublic constructor(...args: [number] | [number, number, number, number]) {\n\t\tif (!Array.isArray(args) || args.every((arg) => typeof arg !== 'number')) {\n\t\t\tthrow new TypeError('Invalid constructor argument. Must be a number or an array of 4 numbers.');\n\t\t}\n\t\tif (args.length === 1) {\n\t\t\tif (args[0] < 0 || args[0] > 0xffffffff) {\n\t\t\t\tthrow new RangeError('IPv4 integer value must be between 0 and 0xffffffff');\n\t\t\t}\n\t\t\tthis.#integerAddress = args[0];\n\t\t} else {\n\t\t\tthis.#integerAddress = this.#toInteger(args[0], args[1], args[2], args[3]);\n\t\t}\n\t}\n\n\t/**\n\t * Checks whether this address is the broadcast address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc919#section-7\n\t * @returns `true` when the address is `255.255.255.255`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isBroadcast(): boolean {\n\t\treturn this.#integerAddress === 0xffffffff;\n\t}\n\n\t/**\n\t * Checks whether this address is in a documentation-only range.\n\t * @see https://datatracker.ietf.org/doc/html/rfc5737\n\t * @returns `true` for `192.0.2.0/24`, `198.51.100.0/24`, or `203.0.113.0/24`; otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isDocumentation(): boolean {\n\t\treturn (\n\t\t\tthis.#match(0xc0000200, 24) || // 192.0.2.0/24\n\t\t\tthis.#match(0xc6336400, 24) || // 198.51.100.0/24\n\t\t\tthis.#match(0xcb007100, 24) // 203.0.113.0/24\n\t\t);\n\t}\n\n\t/**\n\t * Checks whether this address is in the benchmarking range.\n\t * @see https://datatracker.ietf.org/doc/html/rfc2544\n\t * @returns `true` when the address is in `198.18.0.0/15`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isBenchmarking(): boolean {\n\t\treturn this.#match(0xc6120000, 15);\n\t}\n\n\t/**\n\t * Checks whether this address is globally reachable.\n\t * @see https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml\n\t * @returns `true` when the address is not in any special non-global range.\n\t * @since v0.0.1\n\t */\n\tpublic isGlobal(): boolean {\n\t\treturn !(\n\t\t\tthis.isUnspecified() ||\n\t\t\tthis.isPrivate() ||\n\t\t\tthis.isShared() ||\n\t\t\tthis.isLoopback() ||\n\t\t\tthis.isLinkLocal() ||\n\t\t\tthis.isDocumentation() ||\n\t\t\tthis.isBenchmarking() ||\n\t\t\tthis.isReserved() ||\n\t\t\tthis.isMulticast() ||\n\t\t\tthis.isBroadcast()\n\t\t);\n\t}\n\n\t/**\n\t * Checks whether this address is link-local.\n\t * @see https://datatracker.ietf.org/doc/html/rfc3927\n\t * @returns `true` when the address is in `169.254.0.0/16`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isLinkLocal(): boolean {\n\t\treturn this.#match(0xa9fe0000, 16);\n\t}\n\n\t/**\n\t * Checks whether this address is a loopback address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc1122\n\t * @returns `true` when the address is in `127.0.0.0/8`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isLoopback(): boolean {\n\t\treturn this.#match(0x7f000000, 8);\n\t}\n\n\t/**\n\t * Checks whether this address is a multicast address.\n\t * @see https://datatracker.ietf.org/doc/html/rfc5771\n\t * @returns `true` when the address is in `224.0.0.0/4`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isMulticast(): boolean {\n\t\treturn this.#match(0xe0000000, 4);\n\t}\n\n\t/**\n\t * Checks whether this address is in a private-use range.\n\t * @see https://datatracker.ietf.org/doc/html/rfc1918\n\t * @returns `true` for `10.0.0.0/8`, `172.16.0.0/12`, or `192.168.0.0/16`; otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isPrivate(): boolean {\n\t\treturn (\n\t\t\tthis.#match(0x0a000000, 8) || // 10.0.0.0/8\n\t\t\tthis.#match(0xac100000, 12) || // 172.16.0.0/12\n\t\t\tthis.#match(0xc0a80000, 16) // 192.168.0.0/16\n\t\t);\n\t}\n\n\t/**\n\t * Checks whether this address is in the reserved range.\n\t * @see https://datatracker.ietf.org/doc/html/rfc1112\n\t * @returns `true` when the address is in `240.0.0.0/4` except the broadcast address.\n\t * @since v0.0.1\n\t */\n\tpublic isReserved(): boolean {\n\t\treturn this.#match(0xf0000000, 4) && !this.isBroadcast();\n\t}\n\n\t/**\n\t * Checks whether this address is in the shared Carrier-Grade NAT range.\n\t * @see https://datatracker.ietf.org/doc/html/rfc6598\n\t * @returns `true` when the address is in `100.64.0.0/10`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isShared(): boolean {\n\t\treturn this.#match(0x64400000, 10);\n\t}\n\n\t/**\n\t * Checks whether this address is the unspecified address.\n\t * @returns `true` when the address is `0.0.0.0`, otherwise `false`.\n\t * @since v0.0.1\n\t */\n\tpublic isUnspecified(): boolean {\n\t\treturn this.#integerAddress === 0;\n\t}\n\n\t/**\n\t * Converts this address to an IPv4-compatible IPv6 address.\n\t * @returns An IPv6 address in the form `::a.b.c.d`.\n\t * @since v0.0.1\n\t */\n\tpublic toIpv6(): Ipv6Addr {\n\t\treturn Ipv6Addr.from(`::${this.toString()}`).unwrap();\n\t}\n\n\t/**\n\t * Converts this address to an IPv4-mapped IPv6 address.\n\t * @returns An IPv6 address in the form `::ffff:a.b.c.d`.\n\t * @since v0.0.1\n\t */\n\tpublic toIpv6Mapped(): Ipv6Addr {\n\t\treturn Ipv6Addr.from(`::ffff:${this.toString()}`).unwrap();\n\t}\n\n\t/**\n\t * Formats this address as dotted-decimal text.\n\t * @returns The IPv4 string representation, such as `192.168.0.1`.\n\t * @since v0.0.1\n\t */\n\tpublic toString(): string {\n\t\tconst [num1, num2, num3, num4] = this.#fromInteger(this.#integerAddress);\n\t\treturn `${num1}.${num2}.${num3}.${num4}`;\n\t}\n\n\t/**\n\t * Encodes this address to a 4-byte buffer.\n\t * @returns An `ArrayBuffer` containing the IPv4 integer value.\n\t * @since v0.0.1\n\t */\n\tpublic toBuffer(littleEndian?: boolean): ArrayBuffer {\n\t\tconst buffer = new ArrayBuffer(4);\n\t\tconst view = new DataView(buffer);\n\t\tview.setUint32(0, this.#integerAddress, littleEndian);\n\t\treturn buffer;\n\t}\n\n\t/**\n\t * Compares this IPv4 address with another for equality.\n\t * @param other instance of another IPv4 address to compare with.\n\t * @returns `true` if both addresses are equal, otherwise `false`.\n\t * @since v0.1.0\n\t */\n\tpublic equals(other: Ipv4Addr | Ipv6Addr | object): boolean {\n\t\treturn 'family' in other && this.family === other.family && this.#integerAddress === other.#integerAddress;\n\t}\n\n\t#toInteger(num1: number, num2: number, num3: number, num4: number): number {\n\t\tfor (const octet of [num1, num2, num3, num4]) {\n\t\t\tif (octet < 0 || octet > 255) {\n\t\t\t\tthrow new RangeError('IPv4 octet must be between 0 and 255');\n\t\t\t}\n\t\t}\n\t\treturn ((num1 << 24) | (num2 << 16) | (num3 << 8) | num4) >>> 0;\n\t}\n\n\t#fromInteger(integer: number): [number, number, number, number] {\n\t\tconst num1 = (integer >> 24) & 0xff;\n\t\tconst num2 = (integer >> 16) & 0xff;\n\t\tconst num3 = (integer >> 8) & 0xff;\n\t\tconst num4 = integer & 0xff;\n\t\treturn [num1, num2, num3, num4];\n\t}\n\n\t#match(network: number, prefix: number): boolean {\n\t\tif (prefix < 0 || prefix > 32) {\n\t\t\tthrow new RangeError('Invalid prefix length');\n\t\t}\n\t\tconst mask = prefix === 0 ? 0 : (~0 << (32 - prefix)) >>> 0;\n\t\treturn (this.#integerAddress & mask) === (network & mask);\n\t}\n}\n"],"mappings":"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"}
|