diff --git a/.eslintrc.json b/.eslintrc.json
index d7e7150..214ac4d 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -6,7 +6,7 @@
"parser": "@typescript-eslint/parser",
"extends": ["plugin:@typescript-eslint/recommended", "prettier/@typescript-eslint", "plugin:prettier/recommended"],
"rules": {
- "@typescript-eslint/explicit-function-return-type": false,
- "@typescript-eslint/no-object-literal-type-assertion": false
+ "@typescript-eslint/explicit-function-return-type": 0,
+ "@typescript-eslint/no-object-literal-type-assertion": 0
}
}
diff --git a/README.md b/README.md
index a4035ce..ff71be0 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# netparser
-#### Parse and manipulate IPv4 and IPv6 network addresses.
+## Parse and manipulate IPv4 and IPv6 network addresses.
[![Build Status](https://travis-ci.org/demskie/netparser.svg?branch=master)](https://travis-ci.org/demskie/netparser) [![Coverage Status](https://coveralls.io/repos/github/demskie/netparser/badge.svg?branch=master)](https://coveralls.io/github/demskie/netparser?branch=master)
[![Dependency Status](https://david-dm.org/demskie/netparser/status.svg)](https://david-dm.org/demskie/netparser#info=dependencies&view=table)
@@ -54,22 +54,66 @@ netparser.sort(['255.255.255.255', '192.168.0.0/16', '192.168.2.3/31']);
netparser.summarize(['192.168.1.1', '192.168.0.0/16', '192.168.2.3/31']);
// returns ['192.168.0.0/16']
+
+let matcher = new netparser.Matcher();
+matcher.add("192.168.0.0/24");
+matcher.add("192.168.2.0/23");
+matcher.add("192.168.4.0/24");
+matcher.has("192.168.3.0"); // returns true
```
## FYI
-- For simplicity, the above functions will only ever return `String, String[], boolean, or null`.
+- For simplicity, all functions will only ever return `String, String[], boolean, or null`.
- By default the library will fail silently and `null` is returned when errors are encountered. To override this setting set the optional `throwErrors` parameter to `True`.
- By default the library will conveniently mask out provided `network` values to their base address when such an operation makes sense. To override this setting set the optional `strict` parameter to `True` where applicable.
+## Benchmarks
+
+```bash
+npm run bench
+
+'index.bench.ts' output:
+ baseAddress (netparser) x 1,543,101 ops/sec ±3.49% (80 runs sampled)
+ baseAddress (ip-address) x 1,200,247 ops/sec ±1.29% (89 runs sampled)
+ baseAddress (ipaddr.js) x 436,374 ops/sec ±2.02% (85 runs sampled)
+ baseAddress (netmask) x 352,156 ops/sec ±0.97% (90 runs sampled)
+ contains (netparser) x 822,829 ops/sec ±1.03% (89 runs sampled)
+ contains (ip-address) x 832,419 ops/sec ±1.35% (88 runs sampled)
+ contains (ipaddr.js) x 74,829 ops/sec ±1.71% (86 runs sampled)
+ contains (netmask) x 307,760 ops/sec ±1.14% (89 runs sampled)
+
+'match.bench.ts' output:
+ create (netparser) x 16.99 ops/sec ±5.11% (36 runs sampled)
+ create (cidr-matcher) x 9.18 ops/sec ±2.99% (27 runs sampled)
+ create (ipaddr.js) x 25.16 ops/sec ±6.47% (45 runs sampled)
+ query (netparser) x 239,542 ops/sec ±6.67% (86 runs sampled)
+ query (cidr-matcher) x 1,123 ops/sec ±1.36% (84 runs sampled)
+ query (ipaddr.js) x 15.81 ops/sec ±1.37% (43 runs sampled)
+
+'sort.bench.ts' output:
+ sort n=100 (native) x 16,666 ops/sec ±2.02% (88 runs sampled)
+ sort n=100 (insertion) x 42,144 ops/sec ±1.23% (85 runs sampled)
+ sort n=100 (radix msd) x 360 ops/sec ±1.15% (83 runs sampled)
+ sort n=1000 (native) x 1,273 ops/sec ±1.31% (80 runs sampled)
+ sort n=1000 (insertion) x 2,243 ops/sec ±0.83% (88 runs sampled)
+ sort n=1000 (radix msd) x 36.37 ops/sec ±1.21% (50 runs sampled)
+ sort n=10000 (native) x 91.33 ops/sec ±1.46% (67 runs sampled)
+ sort n=10000 (insertion) x 73.01 ops/sec ±1.58% (74 runs sampled)
+ sort n=10000 (radix msd) x 3.71 ops/sec ±1.48% (14 runs sampled)
+ sort n=100000 (native) x 4.49 ops/sec ±5.69% (16 runs sampled)
+ sort n=100000 (insertion) x 0.39 ops/sec ±0.39% (5 runs sampled)
+ sort n=100000 (radix msd) x 0.36 ops/sec ±4.99% (5 runs sampled)
+```
+
## API
Docs generated using [`docts`](https://github.com/charto/docts)
>
>
> ### Function [`baseAddress`](#api-baseAddress)
> BaseAddress returns the base address for a given subnet address
-> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L15-L30)
-> > **baseAddress( )** ⇒ null | string
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L15-L30)
+> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L22-L27)
+> > **baseAddress( )** ⇒ null | string
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L22-L27)
> > ▪ networkAddress string
- A network address like 192.168.0.4/24
> > ▫ throwErrors? undefined | true | false
- Stop the library from failing silently
>
@@ -77,16 +121,16 @@ Docs generated using [`docts`](https://github.com/charto/docts)
> ### Function [`broadcastAddress`](#api-broadcastAddress)
> BroadcastAddress returns the broadcast address for an IPv4 address.
> Please note that IPv6 does not have broadcast addresses.
-> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L44-L52)
-> > **broadcastAddress( )** ⇒ null | string
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L44-L52)
+> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L41-L46)
+> > **broadcastAddress( )** ⇒ null | string
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L41-L46)
> > ▪ network string
- A network like 192.168.0.0/24
> > ▫ throwErrors? undefined | true | false
- Stop the library from failing silently
>
>
> ### Function [`findUnusedSubnets`](#api-findUnusedSubnets)
> FindUnusedSubnets returns array of unused subnets given the aggregate and sibling subnets
-> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L67-L100)
-> > **findUnusedSubnets( )** ⇒ null | string[]
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L67-L100)
+> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L61-L88)
+> > **findUnusedSubnets( )** ⇒ null | string[]
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L61-L88)
> > ▪ aggregate string
- An aggregate network like 192.168.0.0/24
> > ▪ subnets string[]
- Array of subnetworks like ["192.168.0.0/24", "192.168.0.128/26"]
> > ▫ strict? undefined | true | false
- Do not automatically mask addresses to baseAddresses
@@ -95,16 +139,16 @@ Docs generated using [`docts`](https://github.com/charto/docts)
>
> ### Function [`ip`](#api-ip)
> Parse an IP address
-> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L113-L126)
-> > **ip( )** ⇒ null | string
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L113-L126)
+> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L101-L104)
+> > **ip( )** ⇒ null | string
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L101-L104)
> > ▪ address string
- Either an address like 192.168.0.0 or subnet 192.168.0.0/24
> > ▫ throwErrors? undefined | true | false
- Stop the library from failing silently
>
>
> ### Function [`network`](#api-network)
> Parse a network address
-> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L139-L154)
-> > **network( )** ⇒ null | string
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L139-L154)
+> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L117-L120)
+> > **network( )** ⇒ null | string
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L117-L120)
> > ▪ networkAddress string
- A network like 192.168.0.0/24
> > ▫ throwErrors? undefined | true | false
- Stop the library from failing silently
>
@@ -112,8 +156,8 @@ Docs generated using [`docts`](https://github.com/charto/docts)
> ### Function [`networkComesBefore`](#api-networkComesBefore)
> NetworkComesBefore returns a bool with regards to numerical network order.
> Please note that IPv4 comes before IPv6 and larger networks come before smaller ones.
-> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L170-L183)
-> > **networkComesBefore( )** ⇒ null | true | false
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L170-L183)
+> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L136-L149)
+> > **networkComesBefore( )** ⇒ null | true | false
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L136-L149)
> > ▪ network string
- A network like 192.168.0.0/24
> > ▪ otherNetwork string
- A network like 192.168.1.0/24
> > ▫ strict? undefined | true | false
- Do not automatically mask addresses to baseAddresses
@@ -122,8 +166,8 @@ Docs generated using [`docts`](https://github.com/charto/docts)
>
> ### Function [`networkContainsAddress`](#api-networkContainsAddress)
> NetworkContainsAddress validates that the address is inside the network
-> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L198-L204)
-> > **networkContainsAddress( )** ⇒ null | true | false
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L198-L204)
+> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L164-L174)
+> > **networkContainsAddress( )** ⇒ null | true | false
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L164-L174)
> > ▪ network string
- A network like 192.168.0.0/24
> > ▪ address string
- A network like 192.168.0.100
> > ▫ strict? undefined | true | false
- Do not automatically mask addresses to baseAddresses
@@ -132,8 +176,8 @@ Docs generated using [`docts`](https://github.com/charto/docts)
>
> ### Function [`networkContainsSubnet`](#api-networkContainsSubnet)
> NetworkContainsSubnet validates that the network is a valid supernet
-> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L219-L225)
-> > **networkContainsSubnet( )** ⇒ null | true | false
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L219-L225)
+> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L189-L195)
+> > **networkContainsSubnet( )** ⇒ null | true | false
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L189-L195)
> > ▪ network string
- A network like 192.168.0.0/16
> > ▪ subnet string
- A network like 192.168.0.0/24
> > ▫ strict? undefined | true | false
- Do not automatically mask addresses to baseAddresses
@@ -142,8 +186,8 @@ Docs generated using [`docts`](https://github.com/charto/docts)
>
> ### Function [`networksIntersect`](#api-networksIntersect)
> NetworksIntersect returns a bool showing if the networks overlap
-> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L240-L246)
-> > **networksIntersect( )** ⇒ null | true | false
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L240-L246)
+> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L210-L216)
+> > **networksIntersect( )** ⇒ null | true | false
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L210-L216)
> > ▪ network string
- A network like 192.168.0.0/23
> > ▪ otherNetwork string
- A network like 192.168.1.0/24
> > ▫ strict? undefined | true | false
- Do not automatically mask addresses to baseAddresses
@@ -152,16 +196,16 @@ Docs generated using [`docts`](https://github.com/charto/docts)
>
> ### Function [`nextAddress`](#api-nextAddress)
> NextAddress returns the next address
-> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L259-L266)
-> > **nextAddress( )** ⇒ null | string
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L259-L266)
+> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L229-L237)
+> > **nextAddress( )** ⇒ null | string
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L229-L237)
> > ▪ address string
- An address like 192.168.0.0
> > ▫ throwErrors? undefined | true | false
- Stop the library from failing silently
>
>
> ### Function [`nextNetwork`](#api-nextNetwork)
> NextNetwork returns the next network of the same size.
-> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L280-L287)
-> > **nextNetwork( )** ⇒ null | string
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L280-L287)
+> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L251-L259)
+> > **nextNetwork( )** ⇒ null | string
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L251-L259)
> > ▪ network string
- A network like 192.168.0.0/24
> > ▫ strict? undefined | true | false
- Do not automatically mask addresses to baseAddresses
> > ▫ throwErrors? undefined | true | false
- Stop the library from failing silently
@@ -169,8 +213,8 @@ Docs generated using [`docts`](https://github.com/charto/docts)
>
> ### Function [`rangeOfNetworks`](#api-rangeOfNetworks)
> RangeOfNetworks returns an array of networks given a range of addresses
-> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L301-L328)
-> > **rangeOfNetworks( )** ⇒ null | string[]
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L301-L328)
+> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L273-L300)
+> > **rangeOfNetworks( )** ⇒ null | string[]
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L273-L300)
> > ▪ startAddress string
- An address like 192.168.1.2
> > ▪ stopAddress string
- An address like 192.168.1.5
> > ▫ throwErrors? undefined | true | false
- Stop the library from failing silently
@@ -178,16 +222,16 @@ Docs generated using [`docts`](https://github.com/charto/docts)
>
> ### Function [`sort`](#api-sort)
> Sort returns an array of sorted networks
-> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L341-L368)
-> > **sort( )** ⇒ null | string[]
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L341-L368)
+> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L313-L341)
+> > **sort( )** ⇒ null | string[]
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L313-L341)
> > ▪ networkAddresses string[]
- An array of addresses or subnets
> > ▫ throwErrors? undefined | true | false
- Stop the library from failing silently
>
>
> ### Function [`summarize`](#api-summarize)
> Summarize returns an array of aggregates given a list of networks
-> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L382-L407)
-> > **summarize( )** ⇒ null | string[]
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L382-L407)
+> Source code: [`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L355-L375)
+> > **summarize( )** ⇒ null | string[]
[`<>`](http://github.com/demskie/netparser/blob/master/src/index.ts#L355-L375)
> > ▪ networks string[]
- An array of addresses or subnets
> > ▫ strict? undefined | true | false
- Do not automatically mask addresses to baseAddresses
> > ▫ throwErrors? undefined | true | false
- Stop the library from failing silently
diff --git a/package-lock.json b/package-lock.json
index bbb96c9..e29cd4f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,18 +14,18 @@
}
},
"@babel/core": {
- "version": "7.4.3",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.4.3.tgz",
- "integrity": "sha512-oDpASqKFlbspQfzAE7yaeTmdljSH2ADIvBlb0RwbStltTuWa0+7CCI1fYVINNv9saHPa1W7oaKeuNuKj+RQCvA==",
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.5.4.tgz",
+ "integrity": "sha512-+DaeBEpYq6b2+ZmHx3tHspC+ZRflrvLqwfv8E3hNr5LVQoyBnL8RPKSBCg+rK2W2My9PWlujBiqd0ZPsR9Q6zQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
- "@babel/generator": "^7.4.0",
- "@babel/helpers": "^7.4.3",
- "@babel/parser": "^7.4.3",
- "@babel/template": "^7.4.0",
- "@babel/traverse": "^7.4.3",
- "@babel/types": "^7.4.0",
+ "@babel/generator": "^7.5.0",
+ "@babel/helpers": "^7.5.4",
+ "@babel/parser": "^7.5.0",
+ "@babel/template": "^7.4.4",
+ "@babel/traverse": "^7.5.0",
+ "@babel/types": "^7.5.0",
"convert-source-map": "^1.1.0",
"debug": "^4.1.0",
"json5": "^2.1.0",
@@ -44,12 +44,12 @@
}
},
"@babel/generator": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.0.tgz",
- "integrity": "sha512-/v5I+a1jhGSKLgZDcmAUZ4K/VePi43eRkUs3yePW1HB1iANOD5tqJXwGSG4BZhSksP8J9ejSlwGeTiiOFZOrXQ==",
+ "version": "7.5.0",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.5.0.tgz",
+ "integrity": "sha512-1TTVrt7J9rcG5PMjvO7VEG3FrEoEJNHxumRq66GemPmzboLWtIjjcJgk8rokuAS7IiRSpgVSu5Vb9lc99iJkOA==",
"dev": true,
"requires": {
- "@babel/types": "^7.4.0",
+ "@babel/types": "^7.5.0",
"jsesc": "^2.5.1",
"lodash": "^4.17.11",
"source-map": "^0.5.0",
@@ -91,29 +91,29 @@
"dev": true
},
"@babel/helper-split-export-declaration": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.0.tgz",
- "integrity": "sha512-7Cuc6JZiYShaZnybDmfwhY4UYHzI6rlqhWjaIqbsJGsIqPimEYy5uh3akSRLMg65LSdSEnJ8a8/bWQN6u2oMGw==",
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz",
+ "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==",
"dev": true,
"requires": {
- "@babel/types": "^7.4.0"
+ "@babel/types": "^7.4.4"
}
},
"@babel/helpers": {
- "version": "7.4.3",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.3.tgz",
- "integrity": "sha512-BMh7X0oZqb36CfyhvtbSmcWc3GXocfxv3yNsAEuM0l+fAqSO22rQrUpijr3oE/10jCTrB6/0b9kzmG4VetCj8Q==",
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.5.4.tgz",
+ "integrity": "sha512-6LJ6xwUEJP51w0sIgKyfvFMJvIb9mWAfohJp0+m6eHJigkFdcH8duZ1sfhn0ltJRzwUIT/yqqhdSfRpCpL7oow==",
"dev": true,
"requires": {
- "@babel/template": "^7.4.0",
- "@babel/traverse": "^7.4.3",
- "@babel/types": "^7.4.0"
+ "@babel/template": "^7.4.4",
+ "@babel/traverse": "^7.5.0",
+ "@babel/types": "^7.5.0"
}
},
"@babel/highlight": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
- "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
+ "version": "7.5.0",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz",
+ "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==",
"dev": true,
"requires": {
"chalk": "^2.0.0",
@@ -122,9 +122,9 @@
}
},
"@babel/parser": {
- "version": "7.4.3",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.3.tgz",
- "integrity": "sha512-gxpEUhTS1sGA63EGQGuA+WESPR/6tz6ng7tSHFCmaTJK/cGK8y37cBTspX+U2xCAue2IQVvF6Z0oigmjwD8YGQ==",
+ "version": "7.5.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.5.0.tgz",
+ "integrity": "sha512-I5nW8AhGpOXGCCNYGc+p7ExQIBxRFnS2fd/d862bNOKvmoEPjYPcfIjsfdy0ujagYOIYPczKgD9l3FsgTkAzKA==",
"dev": true
},
"@babel/plugin-syntax-object-rest-spread": {
@@ -137,37 +137,37 @@
}
},
"@babel/template": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.0.tgz",
- "integrity": "sha512-SOWwxxClTTh5NdbbYZ0BmaBVzxzTh2tO/TeLTbF6MO6EzVhHTnff8CdBXx3mEtazFBoysmEM6GU/wF+SuSx4Fw==",
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz",
+ "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
- "@babel/parser": "^7.4.0",
- "@babel/types": "^7.4.0"
+ "@babel/parser": "^7.4.4",
+ "@babel/types": "^7.4.4"
}
},
"@babel/traverse": {
- "version": "7.4.3",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.3.tgz",
- "integrity": "sha512-HmA01qrtaCwwJWpSKpA948cBvU5BrmviAief/b3AVw936DtcdsTexlbyzNuDnthwhOQ37xshn7hvQaEQk7ISYQ==",
+ "version": "7.5.0",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.5.0.tgz",
+ "integrity": "sha512-SnA9aLbyOCcnnbQEGwdfBggnc142h/rbqqsXcaATj2hZcegCl903pUD/lfpsNBlBSuWow/YDfRyJuWi2EPR5cg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
- "@babel/generator": "^7.4.0",
+ "@babel/generator": "^7.5.0",
"@babel/helper-function-name": "^7.1.0",
- "@babel/helper-split-export-declaration": "^7.4.0",
- "@babel/parser": "^7.4.3",
- "@babel/types": "^7.4.0",
+ "@babel/helper-split-export-declaration": "^7.4.4",
+ "@babel/parser": "^7.5.0",
+ "@babel/types": "^7.5.0",
"debug": "^4.1.0",
"globals": "^11.1.0",
"lodash": "^4.17.11"
}
},
"@babel/types": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.0.tgz",
- "integrity": "sha512-aPvkXyU2SPOnztlgo8n9cEiXW755mgyvueUPcpStqdzoSPm0fjO0vQBjLkt3JKJW7ufikfcnMTTPsN1xaTsBPA==",
+ "version": "7.5.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.5.0.tgz",
+ "integrity": "sha512-UFpDVqRABKsW01bvw7/wSUe56uy6RXM5+VJibVVAybDGxEW25jdwiFJEf7ASvSaC7sN7rbE/l3cLp2izav+CtQ==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
@@ -205,32 +205,32 @@
}
},
"@jest/core": {
- "version": "24.7.1",
- "resolved": "https://registry.npmjs.org/@jest/core/-/core-24.7.1.tgz",
- "integrity": "sha512-ivlZ8HX/FOASfHcb5DJpSPFps8ydfUYzLZfgFFqjkLijYysnIEOieg72YRhO4ZUB32xu40hsSMmaw+IGYeKONA==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/@jest/core/-/core-24.8.0.tgz",
+ "integrity": "sha512-R9rhAJwCBQzaRnrRgAdVfnglUuATXdwTRsYqs6NMdVcAl5euG8LtWDe+fVkN27YfKVBW61IojVsXKaOmSnqd/A==",
"dev": true,
"requires": {
"@jest/console": "^24.7.1",
- "@jest/reporters": "^24.7.1",
- "@jest/test-result": "^24.7.1",
- "@jest/transform": "^24.7.1",
- "@jest/types": "^24.7.0",
+ "@jest/reporters": "^24.8.0",
+ "@jest/test-result": "^24.8.0",
+ "@jest/transform": "^24.8.0",
+ "@jest/types": "^24.8.0",
"ansi-escapes": "^3.0.0",
"chalk": "^2.0.1",
"exit": "^0.1.2",
"graceful-fs": "^4.1.15",
- "jest-changed-files": "^24.7.0",
- "jest-config": "^24.7.1",
- "jest-haste-map": "^24.7.1",
- "jest-message-util": "^24.7.1",
+ "jest-changed-files": "^24.8.0",
+ "jest-config": "^24.8.0",
+ "jest-haste-map": "^24.8.0",
+ "jest-message-util": "^24.8.0",
"jest-regex-util": "^24.3.0",
- "jest-resolve-dependencies": "^24.7.1",
- "jest-runner": "^24.7.1",
- "jest-runtime": "^24.7.1",
- "jest-snapshot": "^24.7.1",
- "jest-util": "^24.7.1",
- "jest-validate": "^24.7.0",
- "jest-watcher": "^24.7.1",
+ "jest-resolve-dependencies": "^24.8.0",
+ "jest-runner": "^24.8.0",
+ "jest-runtime": "^24.8.0",
+ "jest-snapshot": "^24.8.0",
+ "jest-util": "^24.8.0",
+ "jest-validate": "^24.8.0",
+ "jest-watcher": "^24.8.0",
"micromatch": "^3.1.10",
"p-each-series": "^1.0.0",
"pirates": "^4.0.1",
@@ -257,49 +257,50 @@
}
},
"@jest/environment": {
- "version": "24.7.1",
- "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.7.1.tgz",
- "integrity": "sha512-wmcTTYc4/KqA+U5h1zQd5FXXynfa7VGP2NfF+c6QeGJ7c+2nStgh65RQWNX62SC716dTtqheTRrZl0j+54oGHw==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.8.0.tgz",
+ "integrity": "sha512-vlGt2HLg7qM+vtBrSkjDxk9K0YtRBi7HfRFaDxoRtyi+DyVChzhF20duvpdAnKVBV6W5tym8jm0U9EfXbDk1tw==",
"dev": true,
"requires": {
- "@jest/fake-timers": "^24.7.1",
- "@jest/transform": "^24.7.1",
- "@jest/types": "^24.7.0",
- "jest-mock": "^24.7.0"
+ "@jest/fake-timers": "^24.8.0",
+ "@jest/transform": "^24.8.0",
+ "@jest/types": "^24.8.0",
+ "jest-mock": "^24.8.0"
}
},
"@jest/fake-timers": {
- "version": "24.7.1",
- "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.7.1.tgz",
- "integrity": "sha512-4vSQJDKfR2jScOe12L9282uiwuwQv9Lk7mgrCSZHA9evB9efB/qx8i0KJxsAKtp8fgJYBJdYY7ZU6u3F4/pyjA==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz",
+ "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==",
"dev": true,
"requires": {
- "@jest/types": "^24.7.0",
- "jest-message-util": "^24.7.1",
- "jest-mock": "^24.7.0"
+ "@jest/types": "^24.8.0",
+ "jest-message-util": "^24.8.0",
+ "jest-mock": "^24.8.0"
}
},
"@jest/reporters": {
- "version": "24.7.1",
- "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.7.1.tgz",
- "integrity": "sha512-bO+WYNwHLNhrjB9EbPL4kX/mCCG4ZhhfWmO3m4FSpbgr7N83MFejayz30kKjgqr7smLyeaRFCBQMbXpUgnhAJw==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.8.0.tgz",
+ "integrity": "sha512-eZ9TyUYpyIIXfYCrw0UHUWUvE35vx5I92HGMgS93Pv7du+GHIzl+/vh8Qj9MCWFK/4TqyttVBPakWMOfZRIfxw==",
"dev": true,
"requires": {
- "@jest/environment": "^24.7.1",
- "@jest/test-result": "^24.7.1",
- "@jest/transform": "^24.7.1",
- "@jest/types": "^24.7.0",
+ "@jest/environment": "^24.8.0",
+ "@jest/test-result": "^24.8.0",
+ "@jest/transform": "^24.8.0",
+ "@jest/types": "^24.8.0",
"chalk": "^2.0.1",
"exit": "^0.1.2",
"glob": "^7.1.2",
- "istanbul-api": "^2.1.1",
"istanbul-lib-coverage": "^2.0.2",
"istanbul-lib-instrument": "^3.0.1",
+ "istanbul-lib-report": "^2.0.4",
"istanbul-lib-source-maps": "^3.0.1",
- "jest-haste-map": "^24.7.1",
- "jest-resolve": "^24.7.1",
- "jest-runtime": "^24.7.1",
- "jest-util": "^24.7.1",
+ "istanbul-reports": "^2.1.1",
+ "jest-haste-map": "^24.8.0",
+ "jest-resolve": "^24.8.0",
+ "jest-runtime": "^24.8.0",
+ "jest-util": "^24.8.0",
"jest-worker": "^24.6.0",
"node-notifier": "^5.2.1",
"slash": "^2.0.0",
@@ -319,44 +320,44 @@
}
},
"@jest/test-result": {
- "version": "24.7.1",
- "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.7.1.tgz",
- "integrity": "sha512-3U7wITxstdEc2HMfBX7Yx3JZgiNBubwDqQMh+BXmZXHa3G13YWF3p6cK+5g0hGkN3iufg/vGPl3hLxQXD74Npg==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz",
+ "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==",
"dev": true,
"requires": {
"@jest/console": "^24.7.1",
- "@jest/types": "^24.7.0",
+ "@jest/types": "^24.8.0",
"@types/istanbul-lib-coverage": "^2.0.0"
}
},
"@jest/test-sequencer": {
- "version": "24.7.1",
- "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.7.1.tgz",
- "integrity": "sha512-84HQkCpVZI/G1zq53gHJvSmhUer4aMYp9tTaffW28Ih5OxfCg8hGr3nTSbL1OhVDRrFZwvF+/R9gY6JRkDUpUA==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.8.0.tgz",
+ "integrity": "sha512-OzL/2yHyPdCHXEzhoBuq37CE99nkme15eHkAzXRVqthreWZamEMA0WoetwstsQBCXABhczpK03JNbc4L01vvLg==",
"dev": true,
"requires": {
- "@jest/test-result": "^24.7.1",
- "jest-haste-map": "^24.7.1",
- "jest-runner": "^24.7.1",
- "jest-runtime": "^24.7.1"
+ "@jest/test-result": "^24.8.0",
+ "jest-haste-map": "^24.8.0",
+ "jest-runner": "^24.8.0",
+ "jest-runtime": "^24.8.0"
}
},
"@jest/transform": {
- "version": "24.7.1",
- "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.7.1.tgz",
- "integrity": "sha512-EsOUqP9ULuJ66IkZQhI5LufCHlTbi7hrcllRMUEV/tOgqBVQi93+9qEvkX0n8mYpVXQ8VjwmICeRgg58mrtIEw==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.8.0.tgz",
+ "integrity": "sha512-xBMfFUP7TortCs0O+Xtez2W7Zu1PLH9bvJgtraN1CDST6LBM/eTOZ9SfwS/lvV8yOfcDpFmwf9bq5cYbXvqsvA==",
"dev": true,
"requires": {
"@babel/core": "^7.1.0",
- "@jest/types": "^24.7.0",
+ "@jest/types": "^24.8.0",
"babel-plugin-istanbul": "^5.1.0",
"chalk": "^2.0.1",
"convert-source-map": "^1.4.0",
"fast-json-stable-stringify": "^2.0.0",
"graceful-fs": "^4.1.15",
- "jest-haste-map": "^24.7.1",
+ "jest-haste-map": "^24.8.0",
"jest-regex-util": "^24.3.0",
- "jest-util": "^24.7.1",
+ "jest-util": "^24.8.0",
"micromatch": "^3.1.10",
"realpath-native": "^1.1.0",
"slash": "^2.0.0",
@@ -365,19 +366,20 @@
}
},
"@jest/types": {
- "version": "24.7.0",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.7.0.tgz",
- "integrity": "sha512-ipJUa2rFWiKoBqMKP63Myb6h9+iT3FHRTF2M8OR6irxWzItisa8i4dcSg14IbvmXUnBlHBlUQPYUHWyX3UPpYA==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz",
+ "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^1.1.1",
"@types/yargs": "^12.0.9"
}
},
"@types/babel__core": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.0.tgz",
- "integrity": "sha512-wJTeJRt7BToFx3USrCDs2BhEi4ijBInTQjOIukj6a/5tEkwpFMVZ+1ppgmE+Q/FQyc5P/VWUbx7I9NELrKruHA==",
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.2.tgz",
+ "integrity": "sha512-cfCCrFmiGY/yq0NuKNxIQvZFy9kY/1immpSpTngOnyIbD4+eJOG5mxphhHDv3CHL9GltO4GcKr54kGBg3RNdbg==",
"dev": true,
"requires": {
"@babel/parser": "^7.1.0",
@@ -407,9 +409,9 @@
}
},
"@types/babel__traverse": {
- "version": "7.0.6",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.6.tgz",
- "integrity": "sha512-XYVgHF2sQ0YblLRMLNPB3CkFMewzFmlDsH/TneZFHUXDlABQgh88uOxuez7ZcXxayLFrqLwtDH1t+FmlFwNZxw==",
+ "version": "7.0.7",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.7.tgz",
+ "integrity": "sha512-CeBpmX1J8kWLcDEnI3Cl2Eo6RfbGvzUctA+CjZUhOKDFbLfcr7fc4usEqLNWetrlJd7RhAkyYe2czXop4fICpw==",
"dev": true,
"requires": {
"@babel/types": "^7.3.0"
@@ -421,6 +423,12 @@
"integrity": "sha512-F6fVNOkGEkSdo/19yWYOwVKGvzbTeWkR/XQYBKtGBQ9oGRjBN9f/L4aJI4sDcVPJO58Y1CJZN8va9V2BhrZapA==",
"dev": true
},
+ "@types/eslint-visitor-keys": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
+ "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==",
+ "dev": true
+ },
"@types/events": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
@@ -462,16 +470,44 @@
"integrity": "sha512-pGF/zvYOACZ/gLGWdQH8zSwteQS1epp68yRcVLJMgUck/MjEn/FBYmPub9pXT8C1e4a8YZfHo1CKyV8q1vKUnQ==",
"dev": true
},
+ "@types/ip-address": {
+ "version": "5.8.2",
+ "resolved": "https://registry.npmjs.org/@types/ip-address/-/ip-address-5.8.2.tgz",
+ "integrity": "sha512-LFlDGRjJDnahfPyNCZGXvlaevSmZTi/zDxjTdXeTs8TQ9pQkNZKbCWaJXW29a3bGPRsASqeO+jGgZlaTUi9jTw==",
+ "dev": true,
+ "requires": {
+ "@types/jsbn": "*"
+ }
+ },
"@types/istanbul-lib-coverage": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.0.tgz",
- "integrity": "sha512-eAtOAFZefEnfJiRFQBGw1eYqa5GTLCZ1y86N0XSI/D6EB+E8z6VPV/UL7Gi5UEclFqoQk+6NRqEDsfmDLXn8sg==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz",
+ "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==",
"dev": true
},
+ "@types/istanbul-lib-report": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz",
+ "integrity": "sha512-3BUTyMzbZa2DtDI2BkERNC6jJw2Mr2Y0oGI7mRxYNBPxppbtEK1F66u3bKwU2g+wxwWI7PAoRpJnOY1grJqzHg==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "*"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz",
+ "integrity": "sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "*",
+ "@types/istanbul-lib-report": "*"
+ }
+ },
"@types/jest": {
- "version": "24.0.11",
- "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.0.11.tgz",
- "integrity": "sha512-2kLuPC5FDnWIDvaJBzsGTBQaBbnDweznicvK7UGYzlIJP4RJR2a4A/ByLUXEyEgag6jz8eHdlWExGDtH3EYUXQ==",
+ "version": "24.0.15",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.0.15.tgz",
+ "integrity": "sha512-MU1HIvWUme74stAoc3mgAi+aMlgKOudgEvQDIm1v4RkrDudBh1T+NFp5sftpBAdXdx1J0PbdpJ+M2EsSOi1djA==",
"dev": true,
"requires": {
"@types/jest-diff": "*"
@@ -483,6 +519,12 @@
"integrity": "sha512-yALhelO3i0hqZwhjtcr6dYyaLoCHbAMshwtj6cGxTvHZAKXHsYGdff6E8EPw3xLKY0ELUTQ69Q1rQiJENnccMA==",
"dev": true
},
+ "@types/jsbn": {
+ "version": "1.2.29",
+ "resolved": "https://registry.npmjs.org/@types/jsbn/-/jsbn-1.2.29.tgz",
+ "integrity": "sha512-2dVz9LTEGWVj9Ov9zaDnpvqHFV+W4bXtU0EUEGAzWfdRNO3dlUuosdHpENI6/oQW+Kejn0hAjk6P/czs9h/hvg==",
+ "dev": true
+ },
"@types/lodash": {
"version": "4.14.123",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.123.tgz",
@@ -508,9 +550,9 @@
"dev": true
},
"@types/node": {
- "version": "12.0.8",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.8.tgz",
- "integrity": "sha512-b8bbUOTwzIY3V5vDTY1fIJ+ePKDUBqt2hC2woVGotdQQhG/2Sh62HOKHrT7ab+VerXAcPyAiTEipPu/FsreUtg==",
+ "version": "12.6.2",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.6.2.tgz",
+ "integrity": "sha512-gojym4tX0FWeV2gsW4Xmzo5wxGjXGm550oVUII7f7G5o4BV6c7DBdiG1RRQd+y1bvqRyYtPfMK85UM95vsapqQ==",
"dev": true
},
"@types/shelljs": {
@@ -536,32 +578,44 @@
"dev": true
},
"@typescript-eslint/eslint-plugin": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.6.0.tgz",
- "integrity": "sha512-U224c29E2lo861TQZs6GSmyC0OYeRNg6bE9UVIiFBxN2MlA0nq2dCrgIVyyRbC05UOcrgf2Wk/CF2gGOPQKUSQ==",
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.12.0.tgz",
+ "integrity": "sha512-J/ZTZF+pLNqjXBGNfq5fahsoJ4vJOkYbitWPavA05IrZ7BXUaf4XWlhUB/ic1lpOGTRpLWF+PLAePjiHp6dz8g==",
"dev": true,
"requires": {
- "@typescript-eslint/parser": "1.6.0",
- "@typescript-eslint/typescript-estree": "1.6.0",
- "requireindex": "^1.2.0",
+ "@typescript-eslint/experimental-utils": "1.12.0",
+ "eslint-utils": "^1.3.1",
+ "functional-red-black-tree": "^1.0.1",
+ "regexpp": "^2.0.1",
"tsutils": "^3.7.0"
}
},
+ "@typescript-eslint/experimental-utils": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-1.12.0.tgz",
+ "integrity": "sha512-s0soOTMJloytr9GbPteMLNiO2HvJ+qgQkRNplABXiVw6vq7uQRvidkby64Gqt/nA7pys74HksHwRULaB/QRVyw==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/typescript-estree": "1.12.0",
+ "eslint-scope": "^4.0.0"
+ }
+ },
"@typescript-eslint/parser": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.6.0.tgz",
- "integrity": "sha512-VB9xmSbfafI+/kI4gUK3PfrkGmrJQfh0N4EScT1gZXSZyUxpsBirPL99EWZg9MmPG0pzq/gMtgkk7/rAHj4aQw==",
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.12.0.tgz",
+ "integrity": "sha512-0uzbaa9ZLCA5yMWJywnJJ7YVENKGWVUhJDV5UrMoldC5HoI54W5kkdPhTfmtFKpPFp93MIwmJj0/61ztvmz5Dw==",
"dev": true,
"requires": {
- "@typescript-eslint/typescript-estree": "1.6.0",
- "eslint-scope": "^4.0.0",
+ "@types/eslint-visitor-keys": "^1.0.0",
+ "@typescript-eslint/experimental-utils": "1.12.0",
+ "@typescript-eslint/typescript-estree": "1.12.0",
"eslint-visitor-keys": "^1.0.0"
}
},
"@typescript-eslint/typescript-estree": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.6.0.tgz",
- "integrity": "sha512-A4CanUwfaG4oXobD5y7EXbsOHjCwn8tj1RDd820etpPAjH+Icjc2K9e/DQM1Hac5zH2BSy+u6bjvvF2wwREvYA==",
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.12.0.tgz",
+ "integrity": "sha512-nwN6yy//XcVhFs0ZyU+teJHB8tbCm7AIA8mu6E2r5hu6MajwYBY3Uwop7+rPZWUN/IUOHpL8C+iUPMDVYUU3og==",
"dev": true,
"requires": {
"lodash.unescape": "4.0.1",
@@ -575,15 +629,15 @@
"dev": true
},
"acorn": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz",
- "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==",
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.0.tgz",
+ "integrity": "sha512-8oe72N3WPMjA+2zVG71Ia0nXZ8DpQH+QyyHO+p06jT8eg8FGG3FbcUIi8KziHlAfheJQZeoqbvq1mQSQHXKYLw==",
"dev": true
},
"acorn-globals": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.0.tgz",
- "integrity": "sha512-hMtHj3s5RnuhvHPowpBYvJVj3rAar82JiDQHvGs1zO0l10ocX/xEdBShNHTJaboucJUsScghp74pH3s7EnHHQw==",
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.2.tgz",
+ "integrity": "sha512-BbzvZhVtZP+Bs1J1HcwrQe8ycfO0wStkSGxuul3He3GkHOIZ6eTqOkPuw9IP1X3+IkOo4wiJmwkobzXYz4wewQ==",
"dev": true,
"requires": {
"acorn": "^6.0.1",
@@ -597,15 +651,15 @@
"dev": true
},
"acorn-walk": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz",
- "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==",
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz",
+ "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==",
"dev": true
},
"ajv": {
- "version": "6.10.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz",
- "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==",
+ "version": "6.10.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.1.tgz",
+ "integrity": "sha512-w1YQaVGNC6t2UCPjEawK/vo/dG8OOrVtUmhBT1uJJYxbl5kU2Tj3v6LGqBcsysN1yhuCStJCCA3GqdvKY8sqXQ==",
"dev": true,
"requires": {
"fast-deep-equal": "^2.0.1",
@@ -645,15 +699,6 @@
"normalize-path": "^2.1.1"
}
},
- "append-transform": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz",
- "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==",
- "dev": true,
- "requires": {
- "default-require-extensions": "^2.0.0"
- }
- },
"arg": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz",
@@ -699,12 +744,6 @@
"integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
"dev": true
},
- "arrify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
- "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
- "dev": true
- },
"asn1": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
@@ -732,15 +771,6 @@
"integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
"dev": true
},
- "async": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz",
- "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==",
- "dev": true,
- "requires": {
- "lodash": "^4.17.11"
- }
- },
"async-limiter": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
@@ -772,13 +802,13 @@
"dev": true
},
"babel-jest": {
- "version": "24.7.1",
- "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.7.1.tgz",
- "integrity": "sha512-GPnLqfk8Mtt0i4OemjWkChi73A3ALs4w2/QbG64uAj8b5mmwzxc7jbJVRZt8NJkxi6FopVHog9S3xX6UJKb2qg==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.8.0.tgz",
+ "integrity": "sha512-+5/kaZt4I9efoXzPlZASyK/lN9qdRKmmUav9smVc0ruPQD7IsfucQ87gpOE8mn2jbDuS6M/YOW6n3v9ZoIfgnw==",
"dev": true,
"requires": {
- "@jest/transform": "^24.7.1",
- "@jest/types": "^24.7.0",
+ "@jest/transform": "^24.8.0",
+ "@jest/types": "^24.8.0",
"@types/babel__core": "^7.1.0",
"babel-plugin-istanbul": "^5.1.0",
"babel-preset-jest": "^24.6.0",
@@ -787,14 +817,14 @@
}
},
"babel-plugin-istanbul": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.1.tgz",
- "integrity": "sha512-RNNVv2lsHAXJQsEJ5jonQwrJVWK8AcZpG1oxhnjCUaAjL7xahYLANhPUZbzEQHjKy1NMYUwn+0NPKQc8iSY4xQ==",
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.4.tgz",
+ "integrity": "sha512-dySz4VJMH+dpndj0wjJ8JPs/7i1TdSPb1nRrn56/92pKOF9VKC1FMFJmMXjzlGGusnCAqujP6PBCiKq0sVA+YQ==",
"dev": true,
"requires": {
"find-up": "^3.0.0",
- "istanbul-lib-instrument": "^3.0.0",
- "test-exclude": "^5.0.0"
+ "istanbul-lib-instrument": "^3.3.0",
+ "test-exclude": "^5.2.3"
}
},
"babel-plugin-jest-hoist": {
@@ -980,9 +1010,9 @@
}
},
"bser": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz",
- "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.0.tgz",
+ "integrity": "sha512-8zsjWrQkkBoLK6uxASk1nJ2SKv97ltiGDo6A3wA0/yRPz+CwmEyDo0hUrhIuukG2JHpAl3bvFIixw2/3Hi0DOg==",
"dev": true,
"requires": {
"node-int64": "^0.4.0"
@@ -1157,9 +1187,9 @@
"dev": true
},
"combined-stream": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
- "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==",
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dev": true,
"requires": {
"delayed-stream": "~1.0.0"
@@ -1172,16 +1202,10 @@
"dev": true,
"optional": true
},
- "compare-versions": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.4.0.tgz",
- "integrity": "sha512-tK69D7oNXXqUW3ZNo/z7NXTEz22TCF0pTE+YF9cxvaAM9XnkLo1fV621xCLrRR6aevJlKxExkss0vWqUCUpqdg==",
- "dev": true
- },
"component-emitter": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
- "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
+ "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
"dev": true
},
"concat-map": {
@@ -1197,6 +1221,14 @@
"dev": true,
"requires": {
"safe-buffer": "~5.1.1"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ }
}
},
"copy-descriptor": {
@@ -1212,13 +1244,13 @@
"dev": true
},
"coveralls": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.3.tgz",
- "integrity": "sha512-viNfeGlda2zJr8Gj1zqXpDMRjw9uM54p7wzZdvLRyOgnAfCe974Dq4veZkjJdxQXbmdppu6flEajFYseHYaUhg==",
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.5.tgz",
+ "integrity": "sha512-/KD7PGfZv/tjKB6LoW97jzIgFqem0Tu9tZL9/iwBnBd8zkIZp7vT1ZSHNvnr0GSQMV/LTMxUstWg8WcDDUVQKg==",
"dev": true,
"requires": {
"growl": "~> 1.10.0",
- "js-yaml": "^3.11.0",
+ "js-yaml": "^3.13.1",
"lcov-parse": "^0.0.10",
"log-driver": "^1.2.7",
"minimist": "^1.2.0",
@@ -1247,18 +1279,18 @@
}
},
"cssom": {
- "version": "0.3.6",
- "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.6.tgz",
- "integrity": "sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A==",
+ "version": "0.3.8",
+ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
+ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
"dev": true
},
"cssstyle": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.2.2.tgz",
- "integrity": "sha512-43wY3kl1CVQSvL7wUY1qXkxVGkStjpkDmVjiIKX8R97uhajy8Bybay78uOtqvh7Q5GK75dNPfW0geWjE6qQQow==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.3.0.tgz",
+ "integrity": "sha512-wXsoRfsRfsLVNaVzoKdqvEmK/5PFaEXNspVT22Ots6K/cnJdpoDKuQFw+qlMiXnmaif1OgeC466X1zISgAOcGg==",
"dev": true,
"requires": {
- "cssom": "0.3.x"
+ "cssom": "~0.3.6"
}
},
"culvert": {
@@ -1327,15 +1359,6 @@
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
"dev": true
},
- "default-require-extensions": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz",
- "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=",
- "dev": true,
- "requires": {
- "strip-bom": "^3.0.0"
- }
- },
"define-properties": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
@@ -1526,13 +1549,13 @@
}
},
"eslint": {
- "version": "5.16.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz",
- "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.0.1.tgz",
+ "integrity": "sha512-DyQRaMmORQ+JsWShYsSg4OPTjY56u1nCjAmICrE8vLWqyLKxhFXOthwMj1SA8xwfrv0CofLNVnqbfyhwCkaO0w==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
- "ajv": "^6.9.1",
+ "ajv": "^6.10.0",
"chalk": "^2.1.0",
"cross-spawn": "^6.0.5",
"debug": "^4.0.1",
@@ -1540,18 +1563,19 @@
"eslint-scope": "^4.0.3",
"eslint-utils": "^1.3.1",
"eslint-visitor-keys": "^1.0.0",
- "espree": "^5.0.1",
+ "espree": "^6.0.0",
"esquery": "^1.0.1",
"esutils": "^2.0.2",
"file-entry-cache": "^5.0.1",
"functional-red-black-tree": "^1.0.1",
- "glob": "^7.1.2",
+ "glob-parent": "^3.1.0",
"globals": "^11.7.0",
"ignore": "^4.0.6",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
"inquirer": "^6.2.2",
- "js-yaml": "^3.13.0",
+ "is-glob": "^4.0.0",
+ "js-yaml": "^3.13.1",
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.3.0",
"lodash": "^4.17.11",
@@ -1559,7 +1583,6 @@
"mkdirp": "^0.5.1",
"natural-compare": "^1.4.0",
"optionator": "^0.8.2",
- "path-is-inside": "^1.0.2",
"progress": "^2.0.0",
"regexpp": "^2.0.1",
"semver": "^5.5.1",
@@ -1578,18 +1601,18 @@
}
},
"eslint-config-prettier": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-4.1.0.tgz",
- "integrity": "sha512-zILwX9/Ocz4SV2vX7ox85AsrAgXV3f2o2gpIicdMIOra48WYqgUnWNH/cR/iHtmD2Vb3dLSC3LiEJnS05Gkw7w==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.0.0.tgz",
+ "integrity": "sha512-vDrcCFE3+2ixNT5H83g28bO/uYAwibJxerXPj+E7op4qzBCsAV36QfvdAyVOoNxKAH2Os/e01T/2x++V0LPukA==",
"dev": true,
"requires": {
"get-stdin": "^6.0.0"
}
},
"eslint-plugin-prettier": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.0.1.tgz",
- "integrity": "sha512-/PMttrarPAY78PLvV3xfWibMOdMDl57hmlQ2XqFeA37wd+CJ7WSxV7txqjVPHi/AAFKd2lX0ZqfsOc/i5yFCSQ==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.0.tgz",
+ "integrity": "sha512-XWX2yVuwVNLOUhQijAkXz+rMPPoCr7WFiAl8ig6I7Xn+pPVhDhzg4DxHpmbeb0iqjO9UronEA3Tb09ChnFVHHA==",
"dev": true,
"requires": {
"prettier-linter-helpers": "^1.0.0"
@@ -1618,9 +1641,9 @@
"dev": true
},
"espree": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz",
- "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-6.0.0.tgz",
+ "integrity": "sha512-lJvCS6YbCn3ImT3yKkPe0+tJ+mH6ljhGNjHQH9mRtiO6gjhVAOhVXW1yjnwqGwTkK3bGbye+hb00nFNmu0l/1Q==",
"dev": true,
"requires": {
"acorn": "^6.0.7",
@@ -1742,16 +1765,16 @@
}
},
"expect": {
- "version": "24.7.1",
- "resolved": "https://registry.npmjs.org/expect/-/expect-24.7.1.tgz",
- "integrity": "sha512-mGfvMTPduksV3xoI0xur56pQsg2vJjNf5+a+bXOjqCkiCBbmCayrBbHS/75y9K430cfqyocPr2ZjiNiRx4SRKw==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-24.8.0.tgz",
+ "integrity": "sha512-/zYvP8iMDrzaaxHVa724eJBCKqSHmO0FA7EDkBiRHxg6OipmMn1fN+C8T9L9K8yr7UONkOifu6+LLH+z76CnaA==",
"dev": true,
"requires": {
- "@jest/types": "^24.7.0",
+ "@jest/types": "^24.8.0",
"ansi-styles": "^3.2.0",
- "jest-get-type": "^24.3.0",
- "jest-matcher-utils": "^24.7.0",
- "jest-message-util": "^24.7.1",
+ "jest-get-type": "^24.8.0",
+ "jest-matcher-utils": "^24.8.0",
+ "jest-message-util": "^24.8.0",
"jest-regex-util": "^24.3.0"
}
},
@@ -1783,9 +1806,9 @@
}
},
"external-editor": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz",
- "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
+ "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
"dev": true,
"requires": {
"chardet": "^0.7.0",
@@ -1915,16 +1938,6 @@
"flat-cache": "^2.0.1"
}
},
- "fileset": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz",
- "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=",
- "dev": true,
- "requires": {
- "glob": "^7.0.3",
- "minimatch": "^3.0.3"
- }
- },
"fill-range": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
@@ -1969,9 +1982,9 @@
}
},
"flatted": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz",
- "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz",
+ "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==",
"dev": true
},
"for-in": {
@@ -2024,14 +2037,14 @@
"dev": true
},
"fsevents": {
- "version": "1.2.7",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz",
- "integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==",
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz",
+ "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==",
"dev": true,
"optional": true,
"requires": {
- "nan": "^2.9.2",
- "node-pre-gyp": "^0.10.0"
+ "nan": "^2.12.1",
+ "node-pre-gyp": "^0.12.0"
},
"dependencies": {
"abbrev": {
@@ -2109,12 +2122,12 @@
"optional": true
},
"debug": {
- "version": "2.6.9",
+ "version": "4.1.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
- "ms": "2.0.0"
+ "ms": "^2.1.1"
}
},
"deep-extend": {
@@ -2285,24 +2298,24 @@
}
},
"ms": {
- "version": "2.0.0",
+ "version": "2.1.1",
"bundled": true,
"dev": true,
"optional": true
},
"needle": {
- "version": "2.2.4",
+ "version": "2.3.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
- "debug": "^2.1.2",
+ "debug": "^4.1.0",
"iconv-lite": "^0.4.4",
"sax": "^1.2.4"
}
},
"node-pre-gyp": {
- "version": "0.10.3",
+ "version": "0.12.0",
"bundled": true,
"dev": true,
"optional": true,
@@ -2330,13 +2343,13 @@
}
},
"npm-bundled": {
- "version": "1.0.5",
+ "version": "1.0.6",
"bundled": true,
"dev": true,
"optional": true
},
"npm-packlist": {
- "version": "1.2.0",
+ "version": "1.4.1",
"bundled": true,
"dev": true,
"optional": true,
@@ -2475,7 +2488,7 @@
"optional": true
},
"semver": {
- "version": "5.6.0",
+ "version": "5.7.0",
"bundled": true,
"dev": true,
"optional": true
@@ -2645,10 +2658,31 @@
"path-is-absolute": "^1.0.0"
}
},
+ "glob-parent": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+ "dev": true,
+ "requires": {
+ "is-glob": "^3.1.0",
+ "path-dirname": "^1.0.0"
+ },
+ "dependencies": {
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.0"
+ }
+ }
+ }
+ },
"globals": {
- "version": "11.11.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz",
- "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==",
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
"dev": true
},
"graceful-fs": {
@@ -2798,9 +2832,9 @@
"dev": true
},
"import-fresh": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz",
- "integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz",
+ "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==",
"dev": true,
"requires": {
"parent-module": "^1.0.0",
@@ -2840,9 +2874,9 @@
"dev": true
},
"inquirer": {
- "version": "6.2.2",
- "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.2.tgz",
- "integrity": "sha512-Z2rREiXA6cHRR9KBOarR3WuLlFzlIfAEIiB45ll5SSadMg7WqOh1MKEjjndfuH5ewXdixWCxqnVfGOQzPeiztA==",
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.0.tgz",
+ "integrity": "sha512-scfHejeG/lVZSpvCXpsB4j/wQNPM5JC8kiElOI0OUTwmc1RTpXr4H32/HOlQHcZiYl2z2VElwuCVDRG8vFmbnA==",
"dev": true,
"requires": {
"ansi-escapes": "^3.2.0",
@@ -2851,12 +2885,12 @@
"cli-width": "^2.0.0",
"external-editor": "^3.0.3",
"figures": "^2.0.0",
- "lodash": "^4.17.11",
+ "lodash": "^4.17.12",
"mute-stream": "0.0.7",
"run-async": "^2.2.0",
"rxjs": "^6.4.0",
"string-width": "^2.1.0",
- "strip-ansi": "^5.0.0",
+ "strip-ansi": "^5.1.0",
"through": "^2.3.6"
},
"dependencies": {
@@ -2866,6 +2900,12 @@
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
"dev": true
},
+ "lodash": {
+ "version": "4.17.14",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.14.tgz",
+ "integrity": "sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw==",
+ "dev": true
+ },
"strip-ansi": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
@@ -2898,6 +2938,31 @@
"integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
"dev": true
},
+ "ip-address": {
+ "version": "5.9.2",
+ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-5.9.2.tgz",
+ "integrity": "sha512-7aeFm/7oqo0mMhubTSjZ2Juw/F+WJ3hyfCScNVRQdz5RSRhw1Rj4ZlBFsmEajeKgQDI8asqVs31h8DpxEv7IfQ==",
+ "dev": true,
+ "requires": {
+ "jsbn": "1.1.0",
+ "lodash": "^4.17.11",
+ "sprintf-js": "1.1.2"
+ },
+ "dependencies": {
+ "jsbn": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
+ "integrity": "sha1-sBMHyym2GKHtJux56RH4A8TaAEA=",
+ "dev": true
+ },
+ "sprintf-js": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
+ "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==",
+ "dev": true
+ }
+ }
+ },
"ip6addr": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/ip6addr/-/ip6addr-0.2.2.tgz",
@@ -3011,6 +3076,12 @@
"integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
"dev": true
},
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true
+ },
"is-fullwidth-code-point": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
@@ -3023,6 +3094,15 @@
"integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
"dev": true
},
+ "is-glob": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
"is-number": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
@@ -3124,66 +3204,44 @@
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
"dev": true
},
- "istanbul-api": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-2.1.1.tgz",
- "integrity": "sha512-kVmYrehiwyeBAk/wE71tW6emzLiHGjYIiDrc8sfyty4F8M02/lrgXSm+R1kXysmF20zArvmZXjlE/mg24TVPJw==",
- "dev": true,
- "requires": {
- "async": "^2.6.1",
- "compare-versions": "^3.2.1",
- "fileset": "^2.0.3",
- "istanbul-lib-coverage": "^2.0.3",
- "istanbul-lib-hook": "^2.0.3",
- "istanbul-lib-instrument": "^3.1.0",
- "istanbul-lib-report": "^2.0.4",
- "istanbul-lib-source-maps": "^3.0.2",
- "istanbul-reports": "^2.1.1",
- "js-yaml": "^3.12.0",
- "make-dir": "^1.3.0",
- "minimatch": "^3.0.4",
- "once": "^1.4.0"
- }
- },
"istanbul-lib-coverage": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz",
- "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==",
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz",
+ "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==",
"dev": true
},
- "istanbul-lib-hook": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.3.tgz",
- "integrity": "sha512-CLmEqwEhuCYtGcpNVJjLV1DQyVnIqavMLFHV/DP+np/g3qvdxu3gsPqYoJMXm15sN84xOlckFB3VNvRbf5yEgA==",
- "dev": true,
- "requires": {
- "append-transform": "^1.0.0"
- }
- },
"istanbul-lib-instrument": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz",
- "integrity": "sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA==",
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz",
+ "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==",
"dev": true,
"requires": {
- "@babel/generator": "^7.0.0",
- "@babel/parser": "^7.0.0",
- "@babel/template": "^7.0.0",
- "@babel/traverse": "^7.0.0",
- "@babel/types": "^7.0.0",
- "istanbul-lib-coverage": "^2.0.3",
- "semver": "^5.5.0"
+ "@babel/generator": "^7.4.0",
+ "@babel/parser": "^7.4.3",
+ "@babel/template": "^7.4.0",
+ "@babel/traverse": "^7.4.3",
+ "@babel/types": "^7.4.0",
+ "istanbul-lib-coverage": "^2.0.5",
+ "semver": "^6.0.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.2.0.tgz",
+ "integrity": "sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A==",
+ "dev": true
+ }
}
},
"istanbul-lib-report": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.4.tgz",
- "integrity": "sha512-sOiLZLAWpA0+3b5w5/dq0cjm2rrNdAfHWaGhmn7XEFW6X++IV9Ohn+pnELAl9K3rfpaeBfbmH9JU5sejacdLeA==",
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz",
+ "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==",
"dev": true,
"requires": {
- "istanbul-lib-coverage": "^2.0.3",
- "make-dir": "^1.3.0",
- "supports-color": "^6.0.0"
+ "istanbul-lib-coverage": "^2.0.5",
+ "make-dir": "^2.1.0",
+ "supports-color": "^6.1.0"
},
"dependencies": {
"supports-color": {
@@ -3198,53 +3256,53 @@
}
},
"istanbul-lib-source-maps": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.2.tgz",
- "integrity": "sha512-JX4v0CiKTGp9fZPmoxpu9YEkPbEqCqBbO3403VabKjH+NRXo72HafD5UgnjTEqHL2SAjaZK1XDuDOkn6I5QVfQ==",
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz",
+ "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==",
"dev": true,
"requires": {
"debug": "^4.1.1",
- "istanbul-lib-coverage": "^2.0.3",
- "make-dir": "^1.3.0",
- "rimraf": "^2.6.2",
+ "istanbul-lib-coverage": "^2.0.5",
+ "make-dir": "^2.1.0",
+ "rimraf": "^2.6.3",
"source-map": "^0.6.1"
}
},
"istanbul-reports": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.1.1.tgz",
- "integrity": "sha512-FzNahnidyEPBCI0HcufJoSEoKykesRlFcSzQqjH9x0+LC8tnnE/p/90PBLu8iZTxr8yYZNyTtiAujUqyN+CIxw==",
+ "version": "2.2.6",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.6.tgz",
+ "integrity": "sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA==",
"dev": true,
"requires": {
- "handlebars": "^4.1.0"
+ "handlebars": "^4.1.2"
}
},
"jest": {
- "version": "24.7.1",
- "resolved": "https://registry.npmjs.org/jest/-/jest-24.7.1.tgz",
- "integrity": "sha512-AbvRar5r++izmqo5gdbAjTeA6uNRGoNRuj5vHB0OnDXo2DXWZJVuaObiGgtlvhKb+cWy2oYbQSfxv7Q7GjnAtA==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/jest/-/jest-24.8.0.tgz",
+ "integrity": "sha512-o0HM90RKFRNWmAWvlyV8i5jGZ97pFwkeVoGvPW1EtLTgJc2+jcuqcbbqcSZLE/3f2S5pt0y2ZBETuhpWNl1Reg==",
"dev": true,
"requires": {
"import-local": "^2.0.0",
- "jest-cli": "^24.7.1"
+ "jest-cli": "^24.8.0"
},
"dependencies": {
"jest-cli": {
- "version": "24.7.1",
- "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-24.7.1.tgz",
- "integrity": "sha512-32OBoSCVPzcTslGFl6yVCMzB2SqX3IrWwZCY5mZYkb0D2WsogmU3eV2o8z7+gRQa4o4sZPX/k7GU+II7CxM6WQ==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-24.8.0.tgz",
+ "integrity": "sha512-+p6J00jSMPQ116ZLlHJJvdf8wbjNbZdeSX9ptfHX06/MSNaXmKihQzx5vQcw0q2G6JsdVkUIdWbOWtSnaYs3yA==",
"dev": true,
"requires": {
- "@jest/core": "^24.7.1",
- "@jest/test-result": "^24.7.1",
- "@jest/types": "^24.7.0",
+ "@jest/core": "^24.8.0",
+ "@jest/test-result": "^24.8.0",
+ "@jest/types": "^24.8.0",
"chalk": "^2.0.1",
"exit": "^0.1.2",
"import-local": "^2.0.0",
"is-ci": "^2.0.0",
- "jest-config": "^24.7.1",
- "jest-util": "^24.7.1",
- "jest-validate": "^24.7.0",
+ "jest-config": "^24.8.0",
+ "jest-util": "^24.8.0",
+ "jest-validate": "^24.8.0",
"prompts": "^2.0.1",
"realpath-native": "^1.1.0",
"yargs": "^12.0.2"
@@ -3253,51 +3311,51 @@
}
},
"jest-changed-files": {
- "version": "24.7.0",
- "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-24.7.0.tgz",
- "integrity": "sha512-33BgewurnwSfJrW7T5/ZAXGE44o7swLslwh8aUckzq2e17/2Os1V0QU506ZNik3hjs8MgnEMKNkcud442NCDTw==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-24.8.0.tgz",
+ "integrity": "sha512-qgANC1Yrivsq+UrLXsvJefBKVoCsKB0Hv+mBb6NMjjZ90wwxCDmU3hsCXBya30cH+LnPYjwgcU65i6yJ5Nfuug==",
"dev": true,
"requires": {
- "@jest/types": "^24.7.0",
+ "@jest/types": "^24.8.0",
"execa": "^1.0.0",
"throat": "^4.0.0"
}
},
"jest-config": {
- "version": "24.7.1",
- "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.7.1.tgz",
- "integrity": "sha512-8FlJNLI+X+MU37j7j8RE4DnJkvAghXmBWdArVzypW6WxfGuxiL/CCkzBg0gHtXhD2rxla3IMOSUAHylSKYJ83g==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.8.0.tgz",
+ "integrity": "sha512-Czl3Nn2uEzVGsOeaewGWoDPD8GStxCpAe0zOYs2x2l0fZAgPbCr3uwUkgNKV3LwE13VXythM946cd5rdGkkBZw==",
"dev": true,
"requires": {
"@babel/core": "^7.1.0",
- "@jest/test-sequencer": "^24.7.1",
- "@jest/types": "^24.7.0",
- "babel-jest": "^24.7.1",
+ "@jest/test-sequencer": "^24.8.0",
+ "@jest/types": "^24.8.0",
+ "babel-jest": "^24.8.0",
"chalk": "^2.0.1",
"glob": "^7.1.1",
- "jest-environment-jsdom": "^24.7.1",
- "jest-environment-node": "^24.7.1",
- "jest-get-type": "^24.3.0",
- "jest-jasmine2": "^24.7.1",
+ "jest-environment-jsdom": "^24.8.0",
+ "jest-environment-node": "^24.8.0",
+ "jest-get-type": "^24.8.0",
+ "jest-jasmine2": "^24.8.0",
"jest-regex-util": "^24.3.0",
- "jest-resolve": "^24.7.1",
- "jest-util": "^24.7.1",
- "jest-validate": "^24.7.0",
+ "jest-resolve": "^24.8.0",
+ "jest-util": "^24.8.0",
+ "jest-validate": "^24.8.0",
"micromatch": "^3.1.10",
- "pretty-format": "^24.7.0",
+ "pretty-format": "^24.8.0",
"realpath-native": "^1.1.0"
}
},
"jest-diff": {
- "version": "24.7.0",
- "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.7.0.tgz",
- "integrity": "sha512-ULQZ5B1lWpH70O4xsANC4tf4Ko6RrpwhE3PtG6ERjMg1TiYTC2Wp4IntJVGro6a8HG9luYHhhmF4grF0Pltckg==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.8.0.tgz",
+ "integrity": "sha512-wxetCEl49zUpJ/bvUmIFjd/o52J+yWcoc5ZyPq4/W1LUKGEhRYDIbP1KcF6t+PvqNrGAFk4/JhtxDq/Nnzs66g==",
"dev": true,
"requires": {
"chalk": "^2.0.1",
"diff-sequences": "^24.3.0",
- "jest-get-type": "^24.3.0",
- "pretty-format": "^24.7.0"
+ "jest-get-type": "^24.8.0",
+ "pretty-format": "^24.8.0"
}
},
"jest-docblock": {
@@ -3310,65 +3368,65 @@
}
},
"jest-each": {
- "version": "24.7.1",
- "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.7.1.tgz",
- "integrity": "sha512-4fsS8fEfLa3lfnI1Jw6NxjhyRTgfpuOVTeUZZFyVYqeTa4hPhr2YkToUhouuLTrL2eMGOfpbdMyRx0GQ/VooKA==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.8.0.tgz",
+ "integrity": "sha512-NrwK9gaL5+XgrgoCsd9svsoWdVkK4gnvyhcpzd6m487tXHqIdYeykgq3MKI1u4I+5Zf0tofr70at9dWJDeb+BA==",
"dev": true,
"requires": {
- "@jest/types": "^24.7.0",
+ "@jest/types": "^24.8.0",
"chalk": "^2.0.1",
- "jest-get-type": "^24.3.0",
- "jest-util": "^24.7.1",
- "pretty-format": "^24.7.0"
+ "jest-get-type": "^24.8.0",
+ "jest-util": "^24.8.0",
+ "pretty-format": "^24.8.0"
}
},
"jest-environment-jsdom": {
- "version": "24.7.1",
- "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.7.1.tgz",
- "integrity": "sha512-Gnhb+RqE2JuQGb3kJsLF8vfqjt3PHKSstq4Xc8ic+ax7QKo4Z0RWGucU3YV+DwKR3T9SYc+3YCUQEJs8r7+Jxg==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.8.0.tgz",
+ "integrity": "sha512-qbvgLmR7PpwjoFjM/sbuqHJt/NCkviuq9vus9NBn/76hhSidO+Z6Bn9tU8friecegbJL8gzZQEMZBQlFWDCwAQ==",
"dev": true,
"requires": {
- "@jest/environment": "^24.7.1",
- "@jest/fake-timers": "^24.7.1",
- "@jest/types": "^24.7.0",
- "jest-mock": "^24.7.0",
- "jest-util": "^24.7.1",
+ "@jest/environment": "^24.8.0",
+ "@jest/fake-timers": "^24.8.0",
+ "@jest/types": "^24.8.0",
+ "jest-mock": "^24.8.0",
+ "jest-util": "^24.8.0",
"jsdom": "^11.5.1"
}
},
"jest-environment-node": {
- "version": "24.7.1",
- "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.7.1.tgz",
- "integrity": "sha512-GJJQt1p9/C6aj6yNZMvovZuxTUd+BEJprETdvTKSb4kHcw4mFj8777USQV0FJoJ4V3djpOwA5eWyPwfq//PFBA==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.8.0.tgz",
+ "integrity": "sha512-vIGUEScd1cdDgR6sqn2M08sJTRLQp6Dk/eIkCeO4PFHxZMOgy+uYLPMC4ix3PEfM5Au/x3uQ/5Tl0DpXXZsJ/Q==",
"dev": true,
"requires": {
- "@jest/environment": "^24.7.1",
- "@jest/fake-timers": "^24.7.1",
- "@jest/types": "^24.7.0",
- "jest-mock": "^24.7.0",
- "jest-util": "^24.7.1"
+ "@jest/environment": "^24.8.0",
+ "@jest/fake-timers": "^24.8.0",
+ "@jest/types": "^24.8.0",
+ "jest-mock": "^24.8.0",
+ "jest-util": "^24.8.0"
}
},
"jest-get-type": {
- "version": "24.3.0",
- "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.3.0.tgz",
- "integrity": "sha512-HYF6pry72YUlVcvUx3sEpMRwXEWGEPlJ0bSPVnB3b3n++j4phUEoSPcS6GC0pPJ9rpyPSe4cb5muFo6D39cXow==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.8.0.tgz",
+ "integrity": "sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ==",
"dev": true
},
"jest-haste-map": {
- "version": "24.7.1",
- "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.7.1.tgz",
- "integrity": "sha512-g0tWkzjpHD2qa03mTKhlydbmmYiA2KdcJe762SbfFo/7NIMgBWAA0XqQlApPwkWOF7Cxoi/gUqL0i6DIoLpMBw==",
+ "version": "24.8.1",
+ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.1.tgz",
+ "integrity": "sha512-SwaxMGVdAZk3ernAx2Uv2sorA7jm3Kx+lR0grp6rMmnY06Kn/urtKx1LPN2mGTea4fCT38impYT28FfcLUhX0g==",
"dev": true,
"requires": {
- "@jest/types": "^24.7.0",
+ "@jest/types": "^24.8.0",
"anymatch": "^2.0.0",
"fb-watchman": "^2.0.0",
"fsevents": "^1.2.7",
"graceful-fs": "^4.1.15",
"invariant": "^2.2.4",
"jest-serializer": "^24.4.0",
- "jest-util": "^24.7.1",
+ "jest-util": "^24.8.0",
"jest-worker": "^24.6.0",
"micromatch": "^3.1.10",
"sane": "^4.0.3",
@@ -3376,59 +3434,59 @@
}
},
"jest-jasmine2": {
- "version": "24.7.1",
- "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.7.1.tgz",
- "integrity": "sha512-Y/9AOJDV1XS44wNwCaThq4Pw3gBPiOv/s6NcbOAkVRRUEPu+36L2xoPsqQXsDrxoBerqeyslpn2TpCI8Zr6J2w==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.8.0.tgz",
+ "integrity": "sha512-cEky88npEE5LKd5jPpTdDCLvKkdyklnaRycBXL6GNmpxe41F0WN44+i7lpQKa/hcbXaQ+rc9RMaM4dsebrYong==",
"dev": true,
"requires": {
"@babel/traverse": "^7.1.0",
- "@jest/environment": "^24.7.1",
- "@jest/test-result": "^24.7.1",
- "@jest/types": "^24.7.0",
+ "@jest/environment": "^24.8.0",
+ "@jest/test-result": "^24.8.0",
+ "@jest/types": "^24.8.0",
"chalk": "^2.0.1",
"co": "^4.6.0",
- "expect": "^24.7.1",
+ "expect": "^24.8.0",
"is-generator-fn": "^2.0.0",
- "jest-each": "^24.7.1",
- "jest-matcher-utils": "^24.7.0",
- "jest-message-util": "^24.7.1",
- "jest-runtime": "^24.7.1",
- "jest-snapshot": "^24.7.1",
- "jest-util": "^24.7.1",
- "pretty-format": "^24.7.0",
+ "jest-each": "^24.8.0",
+ "jest-matcher-utils": "^24.8.0",
+ "jest-message-util": "^24.8.0",
+ "jest-runtime": "^24.8.0",
+ "jest-snapshot": "^24.8.0",
+ "jest-util": "^24.8.0",
+ "pretty-format": "^24.8.0",
"throat": "^4.0.0"
}
},
"jest-leak-detector": {
- "version": "24.7.0",
- "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.7.0.tgz",
- "integrity": "sha512-zV0qHKZGXtmPVVzT99CVEcHE9XDf+8LwiE0Ob7jjezERiGVljmqKFWpV2IkG+rkFIEUHFEkMiICu7wnoPM/RoQ==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.8.0.tgz",
+ "integrity": "sha512-cG0yRSK8A831LN8lIHxI3AblB40uhv0z+SsQdW3GoMMVcK+sJwrIIyax5tu3eHHNJ8Fu6IMDpnLda2jhn2pD/g==",
"dev": true,
"requires": {
- "pretty-format": "^24.7.0"
+ "pretty-format": "^24.8.0"
}
},
"jest-matcher-utils": {
- "version": "24.7.0",
- "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.7.0.tgz",
- "integrity": "sha512-158ieSgk3LNXeUhbVJYRXyTPSCqNgVXOp/GT7O94mYd3pk/8+odKTyR1JLtNOQSPzNi8NFYVONtvSWA/e1RDXg==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.8.0.tgz",
+ "integrity": "sha512-lex1yASY51FvUuHgm0GOVj7DCYEouWSlIYmCW7APSqB9v8mXmKSn5+sWVF0MhuASG0bnYY106/49JU1FZNl5hw==",
"dev": true,
"requires": {
"chalk": "^2.0.1",
- "jest-diff": "^24.7.0",
- "jest-get-type": "^24.3.0",
- "pretty-format": "^24.7.0"
+ "jest-diff": "^24.8.0",
+ "jest-get-type": "^24.8.0",
+ "pretty-format": "^24.8.0"
}
},
"jest-message-util": {
- "version": "24.7.1",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.7.1.tgz",
- "integrity": "sha512-dk0gqVtyqezCHbcbk60CdIf+8UHgD+lmRHifeH3JRcnAqh4nEyPytSc9/L1+cQyxC+ceaeP696N4ATe7L+omcg==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz",
+ "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
- "@jest/test-result": "^24.7.1",
- "@jest/types": "^24.7.0",
+ "@jest/test-result": "^24.8.0",
+ "@jest/types": "^24.8.0",
"@types/stack-utils": "^1.0.1",
"chalk": "^2.0.1",
"micromatch": "^3.1.10",
@@ -3437,12 +3495,12 @@
}
},
"jest-mock": {
- "version": "24.7.0",
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.7.0.tgz",
- "integrity": "sha512-6taW4B4WUcEiT2V9BbOmwyGuwuAFT2G8yghF7nyNW1/2gq5+6aTqSPcS9lS6ArvEkX55vbPAS/Jarx5LSm4Fng==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz",
+ "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==",
"dev": true,
"requires": {
- "@jest/types": "^24.7.0"
+ "@jest/types": "^24.8.0"
}
},
"jest-pnp-resolver": {
@@ -3458,12 +3516,12 @@
"dev": true
},
"jest-resolve": {
- "version": "24.7.1",
- "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.7.1.tgz",
- "integrity": "sha512-Bgrc+/UUZpGJ4323sQyj85hV9d+ANyPNu6XfRDUcyFNX1QrZpSoM0kE4Mb2vZMAYTJZsBFzYe8X1UaOkOELSbw==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.8.0.tgz",
+ "integrity": "sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw==",
"dev": true,
"requires": {
- "@jest/types": "^24.7.0",
+ "@jest/types": "^24.8.0",
"browser-resolve": "^1.11.3",
"chalk": "^2.0.1",
"jest-pnp-resolver": "^1.2.1",
@@ -3471,68 +3529,68 @@
}
},
"jest-resolve-dependencies": {
- "version": "24.7.1",
- "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-24.7.1.tgz",
- "integrity": "sha512-2Eyh5LJB2liNzfk4eo7bD1ZyBbqEJIyyrFtZG555cSWW9xVHxII2NuOkSl1yUYTAYCAmM2f2aIT5A7HzNmubyg==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-24.8.0.tgz",
+ "integrity": "sha512-hyK1qfIf/krV+fSNyhyJeq3elVMhK9Eijlwy+j5jqmZ9QsxwKBiP6qukQxaHtK8k6zql/KYWwCTQ+fDGTIJauw==",
"dev": true,
"requires": {
- "@jest/types": "^24.7.0",
+ "@jest/types": "^24.8.0",
"jest-regex-util": "^24.3.0",
- "jest-snapshot": "^24.7.1"
+ "jest-snapshot": "^24.8.0"
}
},
"jest-runner": {
- "version": "24.7.1",
- "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.7.1.tgz",
- "integrity": "sha512-aNFc9liWU/xt+G9pobdKZ4qTeG/wnJrJna3VqunziDNsWT3EBpmxXZRBMKCsNMyfy+A/XHiV+tsMLufdsNdgCw==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.8.0.tgz",
+ "integrity": "sha512-utFqC5BaA3JmznbissSs95X1ZF+d+4WuOWwpM9+Ak356YtMhHE/GXUondZdcyAAOTBEsRGAgH/0TwLzfI9h7ow==",
"dev": true,
"requires": {
"@jest/console": "^24.7.1",
- "@jest/environment": "^24.7.1",
- "@jest/test-result": "^24.7.1",
- "@jest/types": "^24.7.0",
+ "@jest/environment": "^24.8.0",
+ "@jest/test-result": "^24.8.0",
+ "@jest/types": "^24.8.0",
"chalk": "^2.4.2",
"exit": "^0.1.2",
"graceful-fs": "^4.1.15",
- "jest-config": "^24.7.1",
+ "jest-config": "^24.8.0",
"jest-docblock": "^24.3.0",
- "jest-haste-map": "^24.7.1",
- "jest-jasmine2": "^24.7.1",
- "jest-leak-detector": "^24.7.0",
- "jest-message-util": "^24.7.1",
- "jest-resolve": "^24.7.1",
- "jest-runtime": "^24.7.1",
- "jest-util": "^24.7.1",
+ "jest-haste-map": "^24.8.0",
+ "jest-jasmine2": "^24.8.0",
+ "jest-leak-detector": "^24.8.0",
+ "jest-message-util": "^24.8.0",
+ "jest-resolve": "^24.8.0",
+ "jest-runtime": "^24.8.0",
+ "jest-util": "^24.8.0",
"jest-worker": "^24.6.0",
"source-map-support": "^0.5.6",
"throat": "^4.0.0"
}
},
"jest-runtime": {
- "version": "24.7.1",
- "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.7.1.tgz",
- "integrity": "sha512-0VAbyBy7tll3R+82IPJpf6QZkokzXPIS71aDeqh+WzPRXRCNz6StQ45otFariPdJ4FmXpDiArdhZrzNAC3sj6A==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.8.0.tgz",
+ "integrity": "sha512-Mq0aIXhvO/3bX44ccT+czU1/57IgOMyy80oM0XR/nyD5zgBcesF84BPabZi39pJVA6UXw+fY2Q1N+4BiVUBWOA==",
"dev": true,
"requires": {
"@jest/console": "^24.7.1",
- "@jest/environment": "^24.7.1",
+ "@jest/environment": "^24.8.0",
"@jest/source-map": "^24.3.0",
- "@jest/transform": "^24.7.1",
- "@jest/types": "^24.7.0",
+ "@jest/transform": "^24.8.0",
+ "@jest/types": "^24.8.0",
"@types/yargs": "^12.0.2",
"chalk": "^2.0.1",
"exit": "^0.1.2",
"glob": "^7.1.3",
"graceful-fs": "^4.1.15",
- "jest-config": "^24.7.1",
- "jest-haste-map": "^24.7.1",
- "jest-message-util": "^24.7.1",
- "jest-mock": "^24.7.0",
+ "jest-config": "^24.8.0",
+ "jest-haste-map": "^24.8.0",
+ "jest-message-util": "^24.8.0",
+ "jest-mock": "^24.8.0",
"jest-regex-util": "^24.3.0",
- "jest-resolve": "^24.7.1",
- "jest-snapshot": "^24.7.1",
- "jest-util": "^24.7.1",
- "jest-validate": "^24.7.0",
+ "jest-resolve": "^24.8.0",
+ "jest-snapshot": "^24.8.0",
+ "jest-util": "^24.8.0",
+ "jest-validate": "^24.8.0",
"realpath-native": "^1.1.0",
"slash": "^2.0.0",
"strip-bom": "^3.0.0",
@@ -3546,36 +3604,36 @@
"dev": true
},
"jest-snapshot": {
- "version": "24.7.1",
- "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.7.1.tgz",
- "integrity": "sha512-8Xk5O4p+JsZZn4RCNUS3pxA+ORKpEKepE+a5ejIKrId9CwrVN0NY+vkqEkXqlstA5NMBkNahXkR/4qEBy0t5yA==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.8.0.tgz",
+ "integrity": "sha512-5ehtWoc8oU9/cAPe6fez6QofVJLBKyqkY2+TlKTOf0VllBB/mqUNdARdcjlZrs9F1Cv+/HKoCS/BknT0+tmfPg==",
"dev": true,
"requires": {
"@babel/types": "^7.0.0",
- "@jest/types": "^24.7.0",
+ "@jest/types": "^24.8.0",
"chalk": "^2.0.1",
- "expect": "^24.7.1",
- "jest-diff": "^24.7.0",
- "jest-matcher-utils": "^24.7.0",
- "jest-message-util": "^24.7.1",
- "jest-resolve": "^24.7.1",
+ "expect": "^24.8.0",
+ "jest-diff": "^24.8.0",
+ "jest-matcher-utils": "^24.8.0",
+ "jest-message-util": "^24.8.0",
+ "jest-resolve": "^24.8.0",
"mkdirp": "^0.5.1",
"natural-compare": "^1.4.0",
- "pretty-format": "^24.7.0",
+ "pretty-format": "^24.8.0",
"semver": "^5.5.0"
}
},
"jest-util": {
- "version": "24.7.1",
- "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.7.1.tgz",
- "integrity": "sha512-/KilOue2n2rZ5AnEBYoxOXkeTu6vi7cjgQ8MXEkih0oeAXT6JkS3fr7/j8+engCjciOU1Nq5loMSKe0A1oeX0A==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz",
+ "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==",
"dev": true,
"requires": {
"@jest/console": "^24.7.1",
- "@jest/fake-timers": "^24.7.1",
+ "@jest/fake-timers": "^24.8.0",
"@jest/source-map": "^24.3.0",
- "@jest/test-result": "^24.7.1",
- "@jest/types": "^24.7.0",
+ "@jest/test-result": "^24.8.0",
+ "@jest/types": "^24.8.0",
"callsites": "^3.0.0",
"chalk": "^2.0.1",
"graceful-fs": "^4.1.15",
@@ -3586,31 +3644,31 @@
}
},
"jest-validate": {
- "version": "24.7.0",
- "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.7.0.tgz",
- "integrity": "sha512-cgai/gts9B2chz1rqVdmLhzYxQbgQurh1PEQSvSgPZ8KGa1AqXsqC45W5wKEwzxKrWqypuQrQxnF4+G9VejJJA==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.8.0.tgz",
+ "integrity": "sha512-+/N7VOEMW1Vzsrk3UWBDYTExTPwf68tavEPKDnJzrC6UlHtUDU/fuEdXqFoHzv9XnQ+zW6X3qMZhJ3YexfeLDA==",
"dev": true,
"requires": {
- "@jest/types": "^24.7.0",
+ "@jest/types": "^24.8.0",
"camelcase": "^5.0.0",
"chalk": "^2.0.1",
- "jest-get-type": "^24.3.0",
+ "jest-get-type": "^24.8.0",
"leven": "^2.1.0",
- "pretty-format": "^24.7.0"
+ "pretty-format": "^24.8.0"
}
},
"jest-watcher": {
- "version": "24.7.1",
- "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.7.1.tgz",
- "integrity": "sha512-Wd6TepHLRHVKLNPacEsBwlp9raeBIO+01xrN24Dek4ggTS8HHnOzYSFnvp+6MtkkJ3KfMzy220KTi95e2rRkrw==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.8.0.tgz",
+ "integrity": "sha512-SBjwHt5NedQoVu54M5GEx7cl7IGEFFznvd/HNT8ier7cCAx/Qgu9ZMlaTQkvK22G1YOpcWBLQPFSImmxdn3DAw==",
"dev": true,
"requires": {
- "@jest/test-result": "^24.7.1",
- "@jest/types": "^24.7.0",
+ "@jest/test-result": "^24.8.0",
+ "@jest/types": "^24.8.0",
"@types/yargs": "^12.0.9",
"ansi-escapes": "^3.0.0",
"chalk": "^2.0.1",
- "jest-util": "^24.7.1",
+ "jest-util": "^24.8.0",
"string-length": "^2.0.0"
}
},
@@ -3890,12 +3948,27 @@
}
},
"make-dir": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
- "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+ "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
"dev": true,
"requires": {
- "pify": "^3.0.0"
+ "pify": "^4.0.1",
+ "semver": "^5.6.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+ "dev": true
+ },
+ "semver": {
+ "version": "5.7.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
+ "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
+ "dev": true
+ }
}
},
"make-error": {
@@ -3993,18 +4066,18 @@
}
},
"mime-db": {
- "version": "1.38.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz",
- "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==",
+ "version": "1.40.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
+ "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==",
"dev": true
},
"mime-types": {
- "version": "2.1.22",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz",
- "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==",
+ "version": "2.1.24",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
+ "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
"dev": true,
"requires": {
- "mime-db": "~1.38.0"
+ "mime-db": "1.40.0"
}
},
"mimic-fn": {
@@ -4029,9 +4102,9 @@
"dev": true
},
"mixin-deep": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
- "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
+ "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
"dev": true,
"requires": {
"for-in": "^1.0.2",
@@ -4059,9 +4132,9 @@
}
},
"ms": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
- "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"mute-stream": {
@@ -4071,9 +4144,9 @@
"dev": true
},
"nan": {
- "version": "2.13.2",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz",
- "integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==",
+ "version": "2.14.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
+ "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==",
"dev": true,
"optional": true
},
@@ -4182,9 +4255,9 @@
"dev": true
},
"nwsapi": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.3.tgz",
- "integrity": "sha512-RowAaJGEgYXEZfQ7tvvdtAQUKPyTR6T6wNu0fwlNsGQYr/h3yQc6oI8WnVZh3Y/Sylwc+dtAlvPqfFZjhTyk3A==",
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.4.tgz",
+ "integrity": "sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw==",
"dev": true
},
"oauth-sign": {
@@ -4419,6 +4492,12 @@
"integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
"dev": true
},
+ "path-dirname": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+ "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
+ "dev": true
+ },
"path-exists": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
@@ -4431,12 +4510,6 @@
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
},
- "path-is-inside": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
- "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
- "dev": true
- },
"path-key": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
@@ -4513,9 +4586,9 @@
"dev": true
},
"prettier": {
- "version": "1.16.4",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.4.tgz",
- "integrity": "sha512-ZzWuos7TI5CKUeQAtFd6Zhm2s6EpAD/ZLApIhsF9pRvRtM1RFo61dM/4MSRUA0SuLugA/zgrZD8m0BaY46Og7g==",
+ "version": "1.18.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.18.2.tgz",
+ "integrity": "sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw==",
"dev": true
},
"prettier-linter-helpers": {
@@ -4528,12 +4601,12 @@
}
},
"pretty-format": {
- "version": "24.7.0",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.7.0.tgz",
- "integrity": "sha512-apen5cjf/U4dj7tHetpC7UEFCvtAgnNZnBDkfPv3fokzIqyOJckAG9OlAPC1BlFALnqT/lGB2tl9EJjlK6eCsA==",
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.8.0.tgz",
+ "integrity": "sha512-P952T7dkrDEplsR+TuY7q3VXDae5Sr7zmQb12JU/NDQa/3CH7/QW0yvqLcGN6jL+zQFKaoJcPc+yJxMTGmosqw==",
"dev": true,
"requires": {
- "@jest/types": "^24.7.0",
+ "@jest/types": "^24.8.0",
"ansi-regex": "^4.0.0",
"ansi-styles": "^3.2.0",
"react-is": "^16.8.4"
@@ -4548,9 +4621,9 @@
}
},
"process-nextick-args": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
- "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"dev": true
},
"progress": {
@@ -4560,9 +4633,9 @@
"dev": true
},
"prompts": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.0.4.tgz",
- "integrity": "sha512-HTzM3UWp/99A0gk51gAegwo1QRYA7xjcZufMNe33rCclFszUYAuHe1fIN/3ZmiHeGPkUsNaRyQm1hHOfM0PKxA==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.1.0.tgz",
+ "integrity": "sha512-+x5TozgqYdOwWsQFZizE/Tra3fKvAoy037kOyU6cgz84n8f6zxngLOV4O32kTwt9FcLCxAqw0P/c8rOr9y+Gfg==",
"dev": true,
"requires": {
"kleur": "^3.0.2",
@@ -4570,9 +4643,9 @@
}
},
"psl": {
- "version": "1.1.31",
- "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz",
- "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz",
+ "integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA==",
"dev": true
},
"pump": {
@@ -4637,6 +4710,14 @@
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ }
}
},
"readts": {
@@ -4734,24 +4815,6 @@
"tough-cookie": "~2.4.3",
"tunnel-agent": "^0.6.0",
"uuid": "^3.3.2"
- },
- "dependencies": {
- "punycode": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
- "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
- "dev": true
- },
- "tough-cookie": {
- "version": "2.4.3",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
- "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
- "dev": true,
- "requires": {
- "psl": "^1.1.24",
- "punycode": "^1.4.1"
- }
- }
}
},
"request-promise-core": {
@@ -4781,15 +4844,9 @@
"dev": true
},
"require-main-filename": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
- "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
- "dev": true
- },
- "requireindex": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz",
- "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
"dev": true
},
"resolve": {
@@ -4856,9 +4913,9 @@
}
},
"rsvp": {
- "version": "4.8.4",
- "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.4.tgz",
- "integrity": "sha512-6FomvYPfs+Jy9TfXmBpBuMWNH94SgCsZmJKcanySzgNNP6LjWxBvyLTa9KaMfDDM5oxRfrKDB0r/qeRsLwnBfA==",
+ "version": "4.8.5",
+ "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz",
+ "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==",
"dev": true
},
"run-async": {
@@ -4871,18 +4928,18 @@
}
},
"rxjs": {
- "version": "6.4.0",
- "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz",
- "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==",
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz",
+ "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==",
"dev": true,
"requires": {
"tslib": "^1.9.0"
}
},
"safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
+ "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
"dev": true
},
"safe-regex": {
@@ -4944,9 +5001,9 @@
"dev": true
},
"set-value": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
- "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
+ "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
"dev": true,
"requires": {
"extend-shallow": "^2.0.1",
@@ -5005,9 +5062,9 @@
"dev": true
},
"sisteransi": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.0.tgz",
- "integrity": "sha512-N+z4pHB4AmUv0SjveWRd6q1Nj5w62m5jodv+GD8lvmbY/83T/rpbJGZOnK5T149OldDj4Db07BSv9xY4K6NTPQ==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.2.tgz",
+ "integrity": "sha512-ZcYcZcT69nSLAR2oLN2JwNmLkJEKGooFMCdvOkFrToUt/WfcRWqhIg4P4KwY4dmLbuyXIx4o4YmPsvMRJYJd/w==",
"dev": true
},
"slash": {
@@ -5217,9 +5274,9 @@
}
},
"spdx-license-ids": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz",
- "integrity": "sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA==",
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz",
+ "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==",
"dev": true
},
"split-string": {
@@ -5314,6 +5371,14 @@
"dev": true,
"requires": {
"safe-buffer": "~5.1.0"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ }
}
},
"strip-ansi": {
@@ -5353,15 +5418,15 @@
}
},
"symbol-tree": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz",
- "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=",
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
+ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
"dev": true
},
"table": {
- "version": "5.2.3",
- "resolved": "https://registry.npmjs.org/table/-/table-5.2.3.tgz",
- "integrity": "sha512-N2RsDAMvDLvYwFcwbPyF3VmVSSkuF+G1e+8inhBLtHpvwXGw4QRPEZhihQNeEN0i1up6/f6ObCJXNdlRG3YVyQ==",
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/table/-/table-5.4.1.tgz",
+ "integrity": "sha512-E6CK1/pZe2N75rGZQotFOdmzWQ1AILtgYbMAbAjvms0S1l5IDB47zG3nCnFGB/w+7nB3vKofbLXCH7HPBo864w==",
"dev": true,
"requires": {
"ajv": "^6.9.1",
@@ -5399,15 +5464,15 @@
}
},
"test-exclude": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.1.0.tgz",
- "integrity": "sha512-gwf0S2fFsANC55fSeSqpb8BYk6w3FDvwZxfNjeF6FRgvFa43r+7wRiA/Q0IxoRU37wB/LE8IQ4221BsNucTaCA==",
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz",
+ "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==",
"dev": true,
"requires": {
- "arrify": "^1.0.1",
+ "glob": "^7.1.3",
"minimatch": "^3.0.4",
"read-pkg-up": "^4.0.0",
- "require-main-filename": "^1.0.1"
+ "require-main-filename": "^2.0.0"
}
},
"text-table": {
@@ -5492,13 +5557,21 @@
}
},
"tough-cookie": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
- "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
+ "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
"dev": true,
"requires": {
- "psl": "^1.1.28",
- "punycode": "^2.1.1"
+ "psl": "^1.1.24",
+ "punycode": "^1.4.1"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+ "dev": true
+ }
}
},
"tr46": {
@@ -5562,9 +5635,9 @@
}
},
"ts-node": {
- "version": "8.2.0",
- "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.2.0.tgz",
- "integrity": "sha512-m8XQwUurkbYqXrKqr3WHCW310utRNvV5OnRVeISeea7LoCWVcdfeB/Ntl8JYWFh+WRoUAdBgESrzKochQt7sMw==",
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.3.0.tgz",
+ "integrity": "sha512-dyNS/RqyVTDcmNM4NIBAeDMpsAdaQ+ojdf0GOLqE6nwJOgzEkdRNzJywhDfwnuvB10oa6NLVG1rUJQCpRN7qoQ==",
"dev": true,
"requires": {
"arg": "^4.1.0",
@@ -5575,15 +5648,15 @@
}
},
"tslib": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
- "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==",
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
+ "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==",
"dev": true
},
"tsutils": {
- "version": "3.10.0",
- "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.10.0.tgz",
- "integrity": "sha512-q20XSMq7jutbGB8luhKKsQldRKWvyBO2BGqni3p4yq8Ys9bEP/xQw3KepKmMRt9gJ4lvQSScrihJrcKdKoSU7Q==",
+ "version": "3.14.0",
+ "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.14.0.tgz",
+ "integrity": "sha512-SmzGbB0l+8I0QwsPgjooFRaRvHLBLNYM8SeQ0k6rtNDru5sCGeLJcZdwilNndN+GysuFjF5EIYgN8GfFG6UeUw==",
"dev": true,
"requires": {
"tslib": "^1.8.1"
@@ -5598,15 +5671,6 @@
"safe-buffer": "^5.0.1"
}
},
- "turndown": {
- "version": "5.0.3",
- "resolved": "https://registry.npmjs.org/turndown/-/turndown-5.0.3.tgz",
- "integrity": "sha512-popfGXEiedpq6F5saRIAThKxq/bbEPVFnsDnUdjaDGIre9f3/OL9Yi/yPbPcZ7RYUDpekghr666bBfZPrwNnhQ==",
- "dev": true,
- "requires": {
- "jsdom": "^11.9.0"
- }
- },
"tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
@@ -5662,18 +5726,15 @@
"dev": true
},
"typedoc-plugin-markdown": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-1.2.0.tgz",
- "integrity": "sha512-M3M9bx8q5u9VppIQ4ATjYV233ZyhRNbxkgTsjy7WVo4UY38dj1JWg90335ZCYktqkNkobSzE2OhVkmbQFGvi2g==",
- "dev": true,
- "requires": {
- "turndown": "^5.0.3"
- }
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-2.0.8.tgz",
+ "integrity": "sha512-lpaesvB5N2teG6uI9CvaX0YF0O78EGo8HAk24LYe8lkEfR4+ymgZe178luGaJiOc54fKycW+MoS8qZPoX065fg==",
+ "dev": true
},
"typescript": {
- "version": "3.4.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.2.tgz",
- "integrity": "sha512-Og2Vn6Mk7JAuWA1hQdDQN/Ekm/SchX80VzLhjKN9ETYrIepBFAd8PkOdOTK2nKt0FCkmMZKBJvQ1dV1gIxPu/A==",
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz",
+ "integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==",
"dev": true
},
"uglify-js": {
@@ -5688,38 +5749,15 @@
}
},
"union-value": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
- "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
+ "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
"dev": true,
"requires": {
"arr-union": "^3.1.0",
"get-value": "^2.0.6",
"is-extendable": "^0.1.1",
- "set-value": "^0.4.3"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- },
- "set-value": {
- "version": "0.4.3",
- "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
- "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
- "dev": true,
- "requires": {
- "extend-shallow": "^2.0.1",
- "is-extendable": "^0.1.1",
- "is-plain-object": "^2.0.1",
- "to-object-path": "^0.3.0"
- }
- }
+ "set-value": "^2.0.1"
}
},
"universalify": {
@@ -6015,6 +6053,14 @@
"which-module": "^2.0.0",
"y18n": "^3.2.1 || ^4.0.0",
"yargs-parser": "^11.1.1"
+ },
+ "dependencies": {
+ "require-main-filename": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
+ "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
+ "dev": true
+ }
}
},
"yargs-parser": {
diff --git a/package.json b/package.json
index 6f22f2c..f9f9a10 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,10 @@
"scripts": {
"build": "tsc && docts && jest --coverage",
"test": "tsc --noEmit && jest --coverage",
- "bench": "ts-node -T **/*/index.bench.ts && ts-node -T **/*/match.bench.ts"
+ "bench": "npm run bench-index && npm run bench-match && npm run bench-sort",
+ "bench-index": "ts-node -T src/benchmarks/index.bench.ts",
+ "bench-match": "ts-node -T src/benchmarks/match.bench.ts",
+ "bench-sort": "ts-node -T src/benchmarks/sort.bench.ts"
},
"repository": {
"type": "git",
@@ -72,27 +75,29 @@
},
"devDependencies": {
"@types/benchmark": "^1.0.31",
- "@types/jest": "^24.0.11",
+ "@types/ip-address": "^5.8.2",
+ "@types/jest": "^24.0.15",
"@types/netmask": "^1.0.30",
- "@types/node": "^12.0.8",
- "@typescript-eslint/eslint-plugin": "^1.6.0",
- "@typescript-eslint/parser": "^1.6.0",
+ "@types/node": "^12.6.2",
+ "@typescript-eslint/eslint-plugin": "^1.12.0",
+ "@typescript-eslint/parser": "^1.12.0",
"benchmark": "^2.1.4",
"cidr-matcher": "^2.1.0",
- "coveralls": "^3.0.3",
+ "coveralls": "^3.0.5",
"docts": "^0.2.0",
- "eslint": "^5.16.0",
- "eslint-config-prettier": "^4.1.0",
- "eslint-plugin-prettier": "^3.0.1",
+ "eslint": "^6.0.1",
+ "eslint-config-prettier": "^6.0.0",
+ "eslint-plugin-prettier": "^3.1.0",
+ "ip-address": "^5.9.2",
"ipaddr.js": "^1.9.0",
- "jest": "^24.7.1",
+ "jest": "^24.8.0",
"netmask": "^1.0.6",
- "prettier": "^1.16.4",
+ "prettier": "^1.18.2",
"ts-jest": "^24.0.2",
- "ts-node": "^8.2.0",
+ "ts-node": "^8.3.0",
"typedoc": "^0.14.2",
- "typedoc-plugin-markdown": "^1.2.0",
- "typescript": "^3.4.2"
+ "typedoc-plugin-markdown": "^2.0.8",
+ "typescript": "^3.5.3"
},
"dependencies": {}
}
diff --git a/src/IPv4.ts b/src/IPv4.ts
index f968db5..6726aa8 100644
--- a/src/IPv4.ts
+++ b/src/IPv4.ts
@@ -1,42 +1,23 @@
import * as errors from "./errors";
-import * as shared from "./shared";
import * as weight from "./weight";
+import { Network } from "./network";
+import { Address } from "./address";
-export function addrToBytes(addr: string, throwErrors?: boolean) {
- const ip = addr.split(".");
- if (ip.length === 4) {
- const bytes = new Uint8Array(4);
- for (var i = 0; i < 4; i++) {
- const val = parseInt(ip[i], 10);
- if (val < 0 || val > 255) {
- if (throwErrors) throw errors.AddrInvalidInteger;
- return null;
- }
- bytes[i] = val;
- }
- return bytes;
- }
- if (throwErrors) throw errors.AddrNotFourElements;
- return null;
-}
-
-export function bytesToAddr(bytes: Uint8Array, throwErrors?: boolean) {
- if (bytes.length >= 4) {
- return bytes.slice(bytes.length - 4, bytes.length).join(".");
- }
+export function bytesToAddr(bytes: number[], throwErrors?: boolean) {
+ if (bytes.length === 4) return `${bytes[0]}.${bytes[1]}.${bytes[2]}.${bytes[3]}`;
if (throwErrors) throw errors.BytesNotFourElements;
return null;
}
export function randomAddress() {
- return bytesToAddr(Uint8Array.from(Array(4), () => Math.random() * 255));
+ return bytesToAddr(Array.from(Array(4), () => Math.floor(Math.random() * 256)));
}
const choices = Array.from(Array(31), (_, idx) => new weight.WeightedValue(Math.pow(2, idx), idx + 1));
export function randomNetwork() {
- const bytes = Uint8Array.from(Array(4), () => Math.random() * 255);
+ const bytes = Array.from(Array(4), () => Math.floor(Math.random() * 256));
+ const addr = new Address().setBytes(bytes);
const cidr = weight.getValue(choices) as number;
- shared.applySubnetMask(bytes, cidr);
- return `${bytesToAddr(bytes)}/${cidr}`;
+ return new Network().from(addr, cidr);
}
diff --git a/src/IPv6.ts b/src/IPv6.ts
index 3818438..50bf74a 100644
--- a/src/IPv6.ts
+++ b/src/IPv6.ts
@@ -1,83 +1,10 @@
-import * as shared from "./shared";
import * as errors from "./errors";
import * as weight from "./weight";
+import { Network } from "./network";
+import { Address } from "./address";
-function padZeros(addr: string, throwErrors?: boolean) {
- if (addr.length >= 2) {
- if (addr.slice(0, 2) === "::") {
- addr = "0" + addr;
- }
- if (addr.slice(addr.length - 2) === "::") {
- addr += "0";
- }
- }
- const splitAddr = addr.split("::");
- if (splitAddr.length === 1) {
- return addr;
- } else if (splitAddr.length === 2) {
- const hextetCount = splitAddr[0].split(":").length + splitAddr[1].split(":").length;
- splitAddr[0] += shared.repeatString(":0", 8 - hextetCount);
- return splitAddr.join(":");
- }
- if (throwErrors) throw errors.GenericPadZeros;
- return null;
-}
-
-// Network-Specific Prefix IPv4 IPv4-embedded IPv6 address
-// 2001:db8:122:344::/96 192.0.2.33 2001:db8:122:344::192.0.2.33
-// https://tools.ietf.org/html/rfc6052
-
-export function convertEmbeddedIPv4(addr: string) {
- let hextets = addr.split(":");
- const octets = hextets[hextets.length - 1].split(".");
- if (octets.length === 4) {
- const a = parseInt(octets[0], 10).toString(16);
- const b = parseInt(octets[1], 10).toString(16);
- const c = parseInt(octets[2], 10).toString(16);
- const d = parseInt(octets[3], 10).toString(16);
- hextets = hextets.slice(0, hextets.length - 1);
- hextets.push(parseInt(a + b, 16).toString(16));
- hextets.push(parseInt(c + d, 16).toString(16));
- addr = hextets.join(":");
- }
- return addr;
-}
-
-export function addrToBytes(addr: string, throwErrors?: boolean) {
- const padded = padZeros(addr);
- if (padded !== null) {
- const hextets = padded.split(":");
- if (hextets.length === 8) {
- const arr = new Uint8Array(16);
- for (var j = 0; j < 8; j++) {
- const hextet = hextets[j];
- switch (hextet.length) {
- case 1:
- case 2:
- arr[2 * j] = 0;
- arr[2 * j + 1] = parseInt(hextet, 16);
- break;
- case 3:
- case 4:
- const val = parseInt(hextet, 16);
- arr[2 * j] = Math.floor(val / 256);
- arr[2 * j + 1] = val % 256;
- break;
- default:
- if (throwErrors) throw errors.GenericAddrToBytes;
- return null;
- }
- }
- return arr;
- }
- }
- if (throwErrors) throw errors.GenericAddrToBytes;
- return null;
-}
-
-function findLongestZeroHextetChain(bytes: Uint8Array, throwErrors?: boolean) {
- if (bytes.length >= 16) {
- bytes = bytes.subarray(bytes.length - 16);
+function findLongestZeroHextetChain(bytes: number[], throwErrors?: boolean) {
+ if (bytes.length === 16) {
const canidate = { start: 0, length: 0 };
const longest = { start: 0, length: 0 };
for (var i = 0; i < bytes.length; i += 2) {
@@ -101,7 +28,7 @@ function findLongestZeroHextetChain(bytes: Uint8Array, throwErrors?: boolean) {
return null;
}
-export function bytesToAddr(bytes: Uint8Array, throwErrors?: boolean) {
+export function bytesToAddr(bytes: number[], throwErrors?: boolean) {
const longestHextetChain = findLongestZeroHextetChain(bytes, throwErrors);
if (longestHextetChain !== null) {
var result = "";
@@ -121,14 +48,14 @@ export function bytesToAddr(bytes: Uint8Array, throwErrors?: boolean) {
}
export function randomAddress() {
- return bytesToAddr(Uint8Array.from(Array(16), () => Math.random() * 255));
+ return bytesToAddr(Array.from(Array(16), () => Math.floor(Math.random() * 256)));
}
const choices = Array.from(Array(127), (_, idx) => new weight.WeightedValue(Math.pow(2, idx), idx + 1));
export function randomNetwork() {
- const bytes = Uint8Array.from(Array(16), () => Math.random() * 255);
+ const bytes = Array.from(Array(16), () => Math.floor(Math.random() * 256));
+ const addr = new Address().setBytes(bytes);
const cidr = weight.getValue(choices) as number;
- shared.applySubnetMask(bytes, cidr);
- return `${bytesToAddr(bytes)}/${cidr}`;
+ return new Network().from(addr, cidr);
}
diff --git a/src/address.ts b/src/address.ts
new file mode 100644
index 0000000..c881cfe
--- /dev/null
+++ b/src/address.ts
@@ -0,0 +1,274 @@
+import * as ipv4 from "./ipv4";
+import * as ipv6 from "./ipv6";
+import * as parse from "./parse";
+import * as errors from "./errors";
+import * as ranges from "./ranges";
+import { Network } from "./network";
+
+const BEFORE = -1;
+const EQUALS = 0;
+const AFTER = 1;
+
+export class Address {
+ private arr: number[];
+
+ public constructor(address?: string, throwErrors?: boolean) {
+ if (address) {
+ var net = parse.network(address, throwErrors);
+ if (net) {
+ this.arr = net.bytes;
+ return;
+ }
+ }
+ this.arr = [];
+ }
+
+ public bytes() {
+ return this.arr ? this.arr : [];
+ }
+
+ public setBytes(bytes: number[]) {
+ if (bytes.length === 4 || bytes.length === 16) {
+ this.arr = bytes;
+ } else {
+ this.arr = [];
+ }
+ return this;
+ }
+
+ public destroy() {
+ if (this.isValid()) {
+ this.arr = [];
+ }
+ return this;
+ }
+
+ public isValid() {
+ return this.arr.length > 0;
+ }
+
+ public is6to4() {
+ return ranges.check(this, "6to4");
+ }
+
+ public isIPv4() {
+ return this.arr.length === 4;
+ }
+
+ public isIPv6() {
+ return this.arr.length === 16;
+ }
+
+ public isLinkLocal() {
+ return ranges.check(this, "linkLocal");
+ }
+
+ public isLoopback() {
+ return ranges.check(this, "loopback");
+ }
+
+ public isMulticast() {
+ return ranges.check(this, "multicast");
+ }
+
+ public isTeredo() {
+ return ranges.check(this, "teredo");
+ }
+
+ public toString() {
+ if (!this.isValid()) return "";
+ if (this.arr.length === 4) {
+ return `${ipv4.bytesToAddr(this.arr)}`;
+ }
+ return `${ipv6.bytesToAddr(this.arr)}`;
+ }
+
+ public toNetwork() {
+ return new Network().from(new Address().setBytes(this.arr), this.arr.length * 8);
+ }
+
+ public duplicate() {
+ return new Address().setBytes(this.arr.slice());
+ }
+
+ public lessThan(address: Address) {
+ return this.compare(address) === BEFORE;
+ }
+
+ public lessThanOrEqual(address: Address) {
+ var result = this.compare(address);
+ if (result === null) return false;
+ return result <= EQUALS;
+ }
+
+ public equals(address: Address) {
+ return this.compare(address) === EQUALS;
+ }
+
+ public greaterThanOrEqual(address: Address) {
+ var result = this.compare(address);
+ if (result === null) return false;
+ return result >= EQUALS;
+ }
+
+ public greaterThan(address: Address) {
+ return this.compare(address) === AFTER;
+ }
+
+ public compare(address: Address) {
+ // check that both addresses are valid
+ if (!this.isValid() || !address.isValid()) return null;
+
+ // handle edge cases like mixing IPv4 and IPv6
+ if (this === address) return EQUALS;
+ if (this.arr.length < address.arr.length) return BEFORE;
+ if (this.arr.length > address.arr.length) return AFTER;
+
+ // compare addresses
+ for (var i = 0; i < this.arr.length; i++) {
+ if (this.arr[i] < address.arr[i]) return BEFORE;
+ if (this.arr[i] > address.arr[i]) return AFTER;
+ }
+
+ // otherwise they must be equal
+ return EQUALS;
+ }
+
+ public applySubnetMask(cidr: number) {
+ if (!this.isValid()) return this;
+ var maskBits = this.arr.length * 8 - cidr;
+ for (var i = this.arr.length - 1; i >= 0; i--) {
+ switch (Math.max(0, Math.min(maskBits, 8))) {
+ case 0:
+ return this;
+ case 1:
+ this.arr[i] &= ~1;
+ break;
+ case 2:
+ this.arr[i] &= ~3;
+ break;
+ case 3:
+ this.arr[i] &= ~7;
+ break;
+ case 4:
+ this.arr[i] &= ~15;
+ break;
+ case 5:
+ this.arr[i] &= ~31;
+ break;
+ case 6:
+ this.arr[i] &= ~63;
+ break;
+ case 7:
+ this.arr[i] &= ~127;
+ break;
+ case 8:
+ this.arr[i] = 0;
+ break;
+ }
+ maskBits -= 8;
+ }
+ return this;
+ }
+
+ public isBaseAddress(cidr: number) {
+ if (!this.isValid() || cidr < 0 || cidr > this.arr.length * 8) return false;
+ if (cidr === this.arr.length * 8) return true;
+ var maskBits = this.arr.length * 8 - cidr;
+ for (var i = this.arr.length - 1; i >= 0; i--) {
+ switch (Math.max(0, Math.min(maskBits, 8))) {
+ case 0:
+ return true;
+ case 1:
+ if (this.arr[i] !== (this.arr[i] & ~1)) return false;
+ break;
+ case 2:
+ if (this.arr[i] !== (this.arr[i] & ~3)) return false;
+ break;
+ case 3:
+ if (this.arr[i] !== (this.arr[i] & ~7)) return false;
+ break;
+ case 4:
+ if (this.arr[i] !== (this.arr[i] & ~15)) return false;
+ break;
+ case 5:
+ if (this.arr[i] !== (this.arr[i] & ~31)) return false;
+ break;
+ case 6:
+ if (this.arr[i] !== (this.arr[i] & ~63)) return false;
+ break;
+ case 7:
+ if (this.arr[i] !== (this.arr[i] & ~127)) return false;
+ break;
+ case 8:
+ if (this.arr[i] !== 0) return false;
+ break;
+ }
+ maskBits -= 8;
+ }
+ return true;
+ }
+
+ public increase(cidr: number, throwErrors?: boolean) {
+ if (this.isValid()) {
+ this.offsetAddress(cidr, true, throwErrors);
+ } else {
+ if (throwErrors) throw errors.GenericOffsetAddressWithCIDR;
+ this.destroy();
+ }
+ return this;
+ }
+
+ public decrease(cidr: number, throwErrors?: boolean) {
+ if (this.isValid()) {
+ this.offsetAddress(cidr, false, throwErrors);
+ } else {
+ if (throwErrors) throw errors.GenericOffsetAddressWithCIDR;
+ this.destroy();
+ }
+ return this;
+ }
+
+ public next(throwErrors?: boolean) {
+ if (this.isValid()) {
+ this.offsetAddress(this.arr.length * 8, true, throwErrors);
+ } else {
+ if (throwErrors) throw errors.GenericOffsetAddressWithCIDR;
+ this.destroy();
+ }
+ return this;
+ }
+
+ public previous(throwErrors?: boolean) {
+ if (this.isValid()) {
+ this.offsetAddress(this.arr.length * 8, false, throwErrors);
+ } else {
+ if (throwErrors) throw errors.GenericOffsetAddressWithCIDR;
+ this.destroy();
+ }
+ return this;
+ }
+
+ private offsetAddress(cidr: number, forwards: boolean, throwErrors?: boolean) {
+ var targetByte = Math.floor((cidr - 1) / 8);
+ if (this.isValid() && targetByte >= 0 && targetByte < this.arr.length) {
+ var increment = Math.pow(2, 8 - (cidr - targetByte * 8));
+ this.arr[targetByte] += increment * (forwards ? 1 : -1);
+ if (targetByte >= 0) {
+ if (this.arr[targetByte] < 0) {
+ this.arr[targetByte] = 256 + (this.arr[targetByte] % 256);
+ this.offsetAddress(targetByte * 8, forwards, throwErrors);
+ } else if (this.arr[targetByte] > 255) {
+ this.arr[targetByte] %= 256;
+ this.offsetAddress(targetByte * 8, forwards, throwErrors);
+ }
+ } else {
+ if (throwErrors) throw errors.OverflowedAddressSpace;
+ this.destroy();
+ }
+ } else {
+ if (throwErrors) throw errors.GenericOffsetAddressWithCIDR;
+ this.destroy();
+ }
+ }
+}
diff --git a/src/benchmarks/formatters.ts b/src/benchmarks/formatters.ts
new file mode 100644
index 0000000..fde21b7
--- /dev/null
+++ b/src/benchmarks/formatters.ts
@@ -0,0 +1,3 @@
+export function fixedWidth(s: string, n: number) {
+ return "\t" + s + " ".repeat(Math.max(0, n - s.length));
+}
diff --git a/src/benchmarks/index.bench.ts b/src/benchmarks/index.bench.ts
index 6ff1298..734e9ad 100644
--- a/src/benchmarks/index.bench.ts
+++ b/src/benchmarks/index.bench.ts
@@ -2,31 +2,41 @@ import * as Benchmark from "benchmark";
import * as netparser from "../index";
import { Netmask } from "netmask";
import * as ipaddr from "ipaddr.js";
+import * as ipaddress from "ip-address";
+import { fixedWidth } from "./formatters";
new Benchmark.Suite("index.bench.ts")
- .add("\tbaseAddress (netparser)", () => {
+ .add(fixedWidth("baseAddress (netparser)", 30), () => {
netparser.baseAddress("192.168.0.4/24");
})
- .add("\tbaseAddress (ipaddr.js)", () => {
+ .add(fixedWidth("baseAddress (ip-address)", 30), () => {
+ new ipaddress.Address4("192.168.0.4/24").startAddress;
+ })
+
+ .add(fixedWidth("baseAddress (ipaddr.js)", 30), () => {
ipaddr.IPv4.networkAddressFromCIDR("192.168.0.4/24").toString();
})
- .add("\tbaseAddress (netmask)", () => {
+ .add(fixedWidth("baseAddress (netmask)", 30), () => {
new Netmask("192.168.0.4/24").base;
})
- .add("\tnetworkContainsAddress (netparser)", () => {
+ .add(fixedWidth("contains (netparser)", 30), () => {
netparser.networkContainsAddress("192.168.0.0/24", "192.168.0.4");
})
- .add("\tnetworkContainsAddress (ipaddr.js)", () => {
+ .add(fixedWidth("contains (ip-address)", 30), () => {
+ new ipaddress.Address4("192.168.0.0/24").isInSubnet(new ipaddress.Address4("192.168.0.4"));
+ })
+
+ .add(fixedWidth("contains (ipaddr.js)", 30), () => {
const addr = ipaddr.parse("192.168.0.4") as ipaddr.IPv4;
addr.match(ipaddr.parseCIDR("192.168.0.0/24") as [ipaddr.IPv4, number]);
})
- .add("\tnetworkContainsAddress (netmask)", () => {
+ .add(fixedWidth("contains (netmask)", 30), () => {
new Netmask("192.168.0.0/24").contains("192.168.0.4");
})
diff --git a/src/benchmarks/match.bench.ts b/src/benchmarks/match.bench.ts
index 6e50f7b..ef96503 100644
--- a/src/benchmarks/match.bench.ts
+++ b/src/benchmarks/match.bench.ts
@@ -1,80 +1,46 @@
import * as Benchmark from "benchmark";
import * as match from "../match";
-import * as ipv4 from "../ipv4";
import * as ipv6 from "../ipv6";
import * as ipaddr from "ipaddr.js";
import { default as cidrMatcher } from "cidr-matcher";
+import { fixedWidth } from "./formatters";
-const ipv4Addresses = Array.from(Array(1000), () => ipv4.randomAddress());
-const ipv4Subnets = Array.from(Array(10000), () => ipv4.randomNetwork());
-
-let netparserMatcherIPv4 = new match.Matcher();
-let ipaddrRangeListIPv4 = { subnetRanges: [] };
-let cidrMatcherIPv4 = new cidrMatcher(ipv4Subnets);
-
-const ipv6Addresses = Array.from(Array(1000), () => ipv6.randomAddress());
-const ipv6Subnets = Array.from(Array(10000), () => ipv6.randomNetwork());
+const ipv6Addresses = Array.from(Array(1000), () => ipv6.randomAddress().toString());
+const ipv6Subnets = Array.from(Array(10000), () => ipv6.randomNetwork().toString());
let netparserMatcherIPv6 = new match.Matcher();
let ipaddrRangeListIPv6 = { subnetRanges: [] };
-let cidrMatcherIPv6 = new cidrMatcher(ipv4Subnets);
+let cidrMatcherIPv6 = new cidrMatcher(ipv6Subnets);
new Benchmark.Suite("match.bench.ts")
- .add("\tIPv4 matcher creation (netparser)", () => {
- netparserMatcherIPv4 = new match.Matcher(ipv4Subnets);
- })
-
- .add("\tIPv4 matcher creation (ipaddr.js)", () => {
- for (var subnet of ipv4Subnets) {
- ipaddrRangeListIPv4.subnetRanges.push(ipaddr.parseCIDR(subnet));
- }
- })
-
- .add("\tIPv4 matcher creation (cidr-matcher)", () => {
- cidrMatcherIPv4 = new cidrMatcher(ipv4Subnets);
- })
-
- .add("\tIPv4 matcher query (netparser)", () => {
- netparserMatcherIPv4.has(ipv4Addresses[0]);
- })
-
- .add("\tIPv4 matcher query (ipaddr.js)", () => {
- let parsedAddr = ipaddr.parse(ipv4Addresses[0]) as ipaddr.IPv4;
- ipaddr.subnetMatch(parsedAddr, ipaddrRangeListIPv4, "unknown");
- })
-
- .add("\tIPv4 matcher query (cidr-matcher)", () => {
- cidrMatcherIPv4.contains(ipv4Addresses[0]);
+ .add(fixedWidth("create (netparser)", 30), () => {
+ netparserMatcherIPv6 = new match.Matcher(ipv6Subnets);
})
- .add("\tIPv6 matcher creation (netparser)", () => {
- netparserMatcherIPv6 = new match.Matcher(ipv6Subnets);
+ .add(fixedWidth("create (cidr-matcher)", 30), () => {
+ cidrMatcherIPv6 = new cidrMatcher(ipv6Subnets);
})
- .add("\tIPv6 matcher creation (ipaddr.js)", () => {
+ .add(fixedWidth("create (ipaddr.js)", 30), () => {
for (var subnet of ipv6Subnets) {
ipaddrRangeListIPv6.subnetRanges.push(ipaddr.parseCIDR(subnet));
}
})
- .add("\tIPv6 matcher creation (cidr-matcher)", () => {
- cidrMatcherIPv6 = new cidrMatcher(ipv6Subnets);
+ .add(fixedWidth("query (netparser)", 30), () => {
+ netparserMatcherIPv6.has(ipv6Addresses[0]);
})
- .add("\tIPv6 matcher query (netparser)", () => {
- netparserMatcherIPv6.has(ipv6Addresses[0]);
+ .add(fixedWidth("query (cidr-matcher)", 30), () => {
+ cidrMatcherIPv6.contains(ipv6Addresses[0]);
})
- .add("\tIPv6 matcher query (ipaddr.js)", () => {
+ .add(fixedWidth("query (ipaddr.js)", 30), () => {
const parsedAddr = ipaddr.parse(ipv6Addresses[0]) as ipaddr.IPv6;
ipaddr.subnetMatch(parsedAddr, ipaddrRangeListIPv6, "unknown");
})
- .add("\tIPv6 matcher query (cidr-matcher)", () => {
- cidrMatcherIPv6.contains(ipv6Addresses[0]);
- })
-
.on("complete", function() {
console.log(`'${this.name}' output:`);
this.forEach((bench: Benchmark) => {
diff --git a/src/benchmarks/sort.bench.ts b/src/benchmarks/sort.bench.ts
new file mode 100644
index 0000000..0286319
--- /dev/null
+++ b/src/benchmarks/sort.bench.ts
@@ -0,0 +1,80 @@
+import * as Benchmark from "benchmark";
+import * as ipv4 from "../ipv6";
+import * as sort from "../sort";
+import { Network } from "../network";
+import { fixedWidth } from "./formatters";
+
+const e2Alpha = Array.from(Array(1e2), () => ipv4.randomNetwork());
+const e2Bravo = Array.from(e2Alpha, (net: Network) => net.duplicate());
+const e2Charlie = Array.from(e2Alpha, (net: Network) => net.duplicate());
+
+const e3Alpha = Array.from(Array(1e3), () => ipv4.randomNetwork());
+const e3Bravo = Array.from(e3Alpha, (net: Network) => net.duplicate());
+const e3Charlie = Array.from(e3Alpha, (net: Network) => net.duplicate());
+
+const e4Alpha = Array.from(Array(1e4), () => ipv4.randomNetwork());
+const e4Bravo = Array.from(e4Alpha, (net: Network) => net.duplicate());
+const e4Charlie = Array.from(e4Alpha, (net: Network) => net.duplicate());
+
+const e5Alpha = Array.from(Array(1e5), () => ipv4.randomNetwork());
+const e5Bravo = Array.from(e5Alpha, (net: Network) => net.duplicate());
+const e5Charlie = Array.from(e5Alpha, (net: Network) => net.duplicate());
+
+new Benchmark.Suite("sort.bench.ts")
+
+ .add(fixedWidth("sort n=100 (native)", 30), () => {
+ sort.nativeSort(e2Alpha);
+ })
+
+ .add(fixedWidth("sort n=100 (insertion)", 30), () => {
+ sort.insertionSort(e2Bravo);
+ })
+
+ .add(fixedWidth("sort n=100 (radix msd)", 30), () => {
+ sort.radixSort(e2Charlie);
+ })
+
+ .add(fixedWidth("sort n=1000 (native)", 30), () => {
+ sort.nativeSort(e3Alpha);
+ })
+
+ .add(fixedWidth("sort n=1000 (insertion)", 30), () => {
+ sort.insertionSort(e3Bravo);
+ })
+
+ .add(fixedWidth("sort n=1000 (radix msd)", 30), () => {
+ sort.radixSort(e3Charlie);
+ })
+
+ .add(fixedWidth("sort n=10000 (native)", 30), () => {
+ sort.nativeSort(e4Alpha);
+ })
+
+ .add(fixedWidth("sort n=10000 (insertion)", 30), () => {
+ sort.insertionSort(e4Bravo);
+ })
+
+ .add(fixedWidth("sort n=10000 (radix msd)", 30), () => {
+ sort.radixSort(e4Charlie);
+ })
+
+ .add(fixedWidth("sort n=100000 (native)", 30), () => {
+ sort.nativeSort(e5Alpha);
+ })
+
+ .add(fixedWidth("sort n=100000 (insertion)", 30), () => {
+ sort.insertionSort(e5Bravo);
+ })
+
+ .add(fixedWidth("sort n=100000 (radix msd)", 30), () => {
+ sort.radixSort(e5Charlie);
+ })
+
+ .on("complete", function() {
+ console.log(`'${this.name}' output:`);
+ this.forEach((bench: Benchmark) => {
+ console.log(bench.toString());
+ });
+ })
+
+ .run();
diff --git a/src/errors.ts b/src/errors.ts
index 6ef3eb9..5d40d7b 100644
--- a/src/errors.ts
+++ b/src/errors.ts
@@ -11,7 +11,11 @@ export const AddrInvalidInteger = new Error("'addr' has at least one invalid int
export const AddrNotFourElements = new Error("'addr' was not four elements long");
export const BytesNotFourElements = new Error("'bytes' was not at least four elements long");
-export const GenericAddrToBytes = new Error("unable to convert string to bytes");
+export const GenericNetworkParse = new Error("unable to parse string");
export const GenericBytesToAddr = new Error("unable to convert bytes to string");
export const GenericFindLongestZeroHextetChain = new Error("unable to findLongestZeroHextetChain");
-export const GenericPadZeros = new Error("unable to padZeros for IPv6 address");
+
+export const InvalidSubnet = new Error("invalid subnet");
+export const NotValidCIDR = new Error("'cidr' was not a valid integer");
+
+export const InvalidAddress = new Error("invalid address");
diff --git a/src/index.ts b/src/index.ts
index 4c66e4f..bd768a4 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,5 +1,12 @@
import * as shared from "./shared";
import * as errors from "./errors";
+import { Network } from "./network";
+import { Address } from "./address";
+import { Matcher } from "./match";
+
+const BEFORE = -1;
+const EQUALS = 0;
+const AFTER = 1;
/**
* BaseAddress returns the base address for a given subnet address
@@ -13,20 +20,10 @@ import * as errors from "./errors";
* @returns The first address in a subnet or null in case of error
*/
export function baseAddress(networkAddress: string, throwErrors?: boolean) {
- networkAddress = networkAddress.trim();
- if (shared.hasColon(networkAddress)) {
- networkAddress = shared.removeBrackets(networkAddress);
- }
- const ip = shared.removeCIDR(networkAddress, throwErrors);
- const cidr = shared.getCIDR(networkAddress, throwErrors);
- if (ip !== null && cidr !== null) {
- const bytes = shared.addrToBytes(ip, throwErrors);
- if (bytes !== null) {
- shared.applySubnetMask(bytes, cidr);
- return shared.bytesToAddr(bytes, throwErrors);
- }
- }
- return null;
+ const net = new Network(networkAddress, throwErrors);
+ if (!net.isValid()) return null;
+ net.addr.applySubnetMask(net.cidr());
+ return net.addr.toString();
}
/**
@@ -42,13 +39,10 @@ export function baseAddress(networkAddress: string, throwErrors?: boolean) {
* @returns An IPv4 address or null in case of error
*/
export function broadcastAddress(network: string, throwErrors?: boolean) {
- const net = shared.parseNetworkString(network, false, throwErrors);
- if (!net) return null;
- if (!shared.increaseAddressWithCIDR(net.bytes, net.cidr, throwErrors)) return null;
- if (!shared.decreaseAddressWithCIDR(net.bytes, net.bytes.length * 8, throwErrors)) return null;
- const addr = shared.bytesToAddr(net.bytes, throwErrors);
- if (!addr) return null;
- return `${addr}`;
+ const net = new Network(network, throwErrors);
+ if (!net.isValid() || net.addr.bytes().length === 16) return null;
+ net.addr.applySubnetMask(net.cidr());
+ return net.lastAddr().toString();
}
/**
@@ -65,36 +59,30 @@ export function broadcastAddress(network: string, throwErrors?: boolean) {
* @returns A boolean or null in case of error
*/
export function findUnusedSubnets(aggregate: string, subnets: string[], strict?: boolean, throwErrors?: boolean) {
- const aggnetwork = shared.parseNetworkString(aggregate, throwErrors, strict);
- if (!aggnetwork) return null;
- if (subnets.length === 0) return [aggregate];
- const subnetworks = [] as shared.Network[];
+ const agg = shared.parseBaseNetwork(aggregate, strict, throwErrors);
+ if (!agg || !agg.isValid()) return null;
+ if (subnets.length === 0) return [`${agg.toString()}`];
+ const subnetworks = [] as Network[];
for (var s of subnets) {
- const net = shared.parseNetworkString(s, throwErrors, strict);
- if (!net) return null;
- if (aggnetwork.bytes.length === net.bytes.length) {
+ const net = shared.parseBaseNetwork(s, strict, throwErrors);
+ if (!net || !net.isValid()) {
+ if (strict) return null;
+ continue;
+ }
+ if (agg.addr.bytes().length === net.addr.bytes().length) {
subnetworks.push(net);
}
}
- const aggnetworkEnd = shared.duplicateAddress(aggnetwork.bytes);
- shared.increaseAddressWithCIDR(aggnetworkEnd, aggnetwork.cidr);
- shared.decreaseAddressWithCIDR(aggnetworkEnd, aggnetwork.bytes.length * 8);
+ const lastAggAddr = agg.lastAddr();
const results = [] as string[];
- let currentSubnet: shared.Network | null = aggnetwork;
+ let currentSubnet: Network | null = agg;
while (currentSubnet) {
- currentSubnet = shared.findNetworkWithoutIntersection(currentSubnet, subnetworks);
- if (currentSubnet) {
- const addr = shared.bytesToAddr(currentSubnet.bytes, throwErrors);
- if (!addr) return null;
- results.push(`${addr}/${currentSubnet.cidr}`);
- if (
- !shared.increaseAddressWithCIDR(currentSubnet.bytes, currentSubnet.cidr) ||
- shared.compareAddresses(currentSubnet.bytes, aggnetworkEnd) > 0
- ) {
- break;
- }
- currentSubnet.cidr = aggnetwork.cidr;
- }
+ currentSubnet = shared.findNetworkWithoutIntersection(subnetworks, currentSubnet.addr, currentSubnet.cidr());
+ if (!currentSubnet) break;
+ results.push(`${currentSubnet.toString()}`);
+ if (!currentSubnet.next().isValid()) break;
+ if (currentSubnet.addr.greaterThan(lastAggAddr)) break;
+ currentSubnet.setCIDR(agg.cidr());
}
return results;
}
@@ -111,18 +99,8 @@ export function findUnusedSubnets(aggregate: string, subnets: string[], strict?:
* @returns The parsed IP address or null in case of error
*/
export function ip(address: string, throwErrors?: boolean) {
- address = address.trim();
- if (shared.hasColon(address)) {
- address = shared.removeBrackets(address);
- }
- const ip = shared.removeCIDR(address, throwErrors);
- if (ip !== null) {
- const bytes = shared.addrToBytes(ip, throwErrors);
- if (bytes !== null) {
- return shared.bytesToAddr(bytes, throwErrors);
- }
- }
- return null;
+ const addr = new Address(address, throwErrors).toString();
+ return addr.length > 0 ? addr : null;
}
/**
@@ -137,20 +115,8 @@ export function ip(address: string, throwErrors?: boolean) {
* @returns The parsed network address or null in case of error
*/
export function network(networkAddress: string, throwErrors?: boolean) {
- networkAddress = networkAddress.trim();
- if (shared.hasColon(networkAddress)) {
- networkAddress = shared.removeBrackets(networkAddress);
- }
- const ip = shared.removeCIDR(networkAddress, throwErrors);
- const cidr = shared.getCIDR(networkAddress, throwErrors);
- if (ip !== null && cidr !== null) {
- const bytes = shared.addrToBytes(ip, throwErrors);
- if (bytes !== null) {
- const addr = shared.bytesToAddr(bytes, throwErrors);
- if (addr) return `${addr}/${cidr}`;
- }
- }
- return null;
+ const net = new Network(networkAddress, throwErrors).toString();
+ return net.length > 0 ? net : null;
}
/**
@@ -168,17 +134,17 @@ export function network(networkAddress: string, throwErrors?: boolean) {
* @returns A boolean or null in case of error
*/
export function networkComesBefore(network: string, otherNetwork: string, strict?: boolean, throwErrors?: boolean) {
- const net = shared.parseNetworkString(network, strict, throwErrors);
- if (!net) return null;
- const otherNet = shared.parseNetworkString(otherNetwork, strict, throwErrors);
- if (!otherNet) return null;
- switch (shared.compareAddresses(net.bytes, otherNet.bytes)) {
- case shared.Pos.before:
+ const alphaNet = shared.parseBaseNetwork(network, strict, throwErrors);
+ if (!alphaNet || !alphaNet.isValid()) return null;
+ const bravoNet = shared.parseBaseNetwork(otherNetwork, strict, throwErrors);
+ if (!bravoNet || !bravoNet.isValid()) return null;
+ switch (alphaNet.compare(bravoNet)) {
+ case BEFORE:
return true;
- case shared.Pos.after:
+ case AFTER:
return false;
}
- if (net.cidr < otherNet.cidr) return true;
+ if (alphaNet.cidr() < bravoNet.cidr()) return true;
return false;
}
@@ -196,11 +162,15 @@ export function networkComesBefore(network: string, otherNetwork: string, strict
* @returns A boolean or null in case of error
*/
export function networkContainsAddress(network: string, address: string, strict?: boolean, throwErrors?: boolean) {
- const net = shared.parseNetworkString(network, strict, throwErrors);
- if (!net) return null;
- const addr = shared.parseAddressString(address, throwErrors);
- if (!addr) return null;
- return shared.networkContainsAddress(net, addr);
+ const net = shared.parseBaseNetwork(network, strict, throwErrors);
+ if (!net || !net.isValid()) return null;
+ const addrNet = new Network(address, throwErrors);
+ if (!addrNet.isValid()) return null;
+ if (addrNet.cidr() !== addrNet.addr.bytes().length * 8) {
+ if (throwErrors) throw errors.InvalidAddress;
+ return null;
+ }
+ return net.contains(addrNet);
}
/**
@@ -217,11 +187,11 @@ export function networkContainsAddress(network: string, address: string, strict?
* @returns A boolean or null in case of error
*/
export function networkContainsSubnet(network: string, subnet: string, strict?: boolean, throwErrors?: boolean) {
- const alphaNet = shared.parseNetworkString(network, strict, throwErrors);
+ const alphaNet = shared.parseBaseNetwork(network, strict, throwErrors);
if (!alphaNet) return null;
- const bravoNet = shared.parseNetworkString(subnet, strict, throwErrors);
+ const bravoNet = shared.parseBaseNetwork(subnet, strict, throwErrors);
if (!bravoNet) return null;
- return shared.networkContainsSubnet(alphaNet, bravoNet);
+ return alphaNet.contains(bravoNet);
}
/**
@@ -238,11 +208,11 @@ export function networkContainsSubnet(network: string, subnet: string, strict?:
* @returns A boolean or null in case of error
*/
export function networksIntersect(network: string, otherNetwork: string, strict?: boolean, throwErrors?: boolean) {
- const alphaNet = shared.parseNetworkString(network, strict, throwErrors);
+ const alphaNet = shared.parseBaseNetwork(network, strict, throwErrors);
if (!alphaNet) return null;
- const bravoNet = shared.parseNetworkString(otherNetwork, strict, throwErrors);
+ const bravoNet = shared.parseBaseNetwork(otherNetwork, strict, throwErrors);
if (!bravoNet) return null;
- return shared.networksIntersect(alphaNet, bravoNet, throwErrors);
+ return alphaNet.intersects(bravoNet);
}
/**
@@ -257,12 +227,13 @@ export function networksIntersect(network: string, otherNetwork: string, strict?
* @returns An address string or null in case of error
*/
export function nextAddress(address: string, throwErrors?: boolean) {
- const bytes = shared.parseAddressString(address, throwErrors);
- if (!bytes) return null;
- if (!shared.increaseAddressWithCIDR(bytes, bytes.length * 8, throwErrors)) return null;
- const addr = shared.bytesToAddr(bytes, throwErrors);
- if (!addr) return null;
- return `${addr}`;
+ const addr = new Address(address, throwErrors);
+ if (!addr.isValid()) return null;
+ if (!addr.next().isValid()) {
+ if (throwErrors) throw errors.OverflowedAddressSpace;
+ return null;
+ }
+ return addr.toString();
}
/**
@@ -278,12 +249,13 @@ export function nextAddress(address: string, throwErrors?: boolean) {
* @returns A network string or null in case of error
*/
export function nextNetwork(network: string, strict?: boolean, throwErrors?: boolean) {
- const net = shared.parseNetworkString(network, strict, throwErrors);
- if (!net) return null;
- if (!shared.increaseAddressWithCIDR(net.bytes, net.cidr, throwErrors)) return null;
- const addr = shared.bytesToAddr(net.bytes, throwErrors);
- if (!addr) return null;
- return `${addr}/${net.cidr}`;
+ const net = shared.parseBaseNetwork(network, strict, throwErrors);
+ if (!net || !net.isValid()) return null;
+ if (!net.next().isValid()) {
+ if (throwErrors) throw errors.OverflowedAddressSpace;
+ return null;
+ }
+ return net.toString();
}
/**
@@ -299,30 +271,30 @@ export function nextNetwork(network: string, strict?: boolean, throwErrors?: boo
* @returns An array of networks or null in case of error
*/
export function rangeOfNetworks(startAddress: string, stopAddress: string, throwErrors?: boolean) {
- let startAddr = shared.parseAddressString(startAddress, throwErrors);
+ let startAddr = new Address(startAddress, throwErrors);
if (!startAddr) return null;
- let stopAddr = shared.parseAddressString(stopAddress, throwErrors);
+
+ let stopAddr = new Address(stopAddress, throwErrors);
if (!stopAddr) return null;
- if (startAddr.length !== stopAddr.length) {
+
+ if (startAddr.bytes().length !== stopAddr.bytes().length) {
if (throwErrors) throw errors.MixingIPv4AndIPv6;
return null;
}
- switch (shared.compareAddresses(startAddr, stopAddr)) {
- case shared.Pos.equals:
- return [`${startAddress}/${startAddr.length * 8}`];
- case shared.Pos.after:
+ switch (startAddr.compare(stopAddr)) {
+ case EQUALS:
+ return [`${startAddress}/${startAddr.bytes().length * 8}`];
+ case AFTER:
[startAddr, stopAddr] = [stopAddr, startAddr];
}
var results = [] as string[];
- const net = { bytes: startAddr, cidr: 1 };
- while (shared.compareAddresses(net.bytes, stopAddr) <= 0) {
- while (!shared.isValidNetworkAddress(net) || shared.networkGoesPastAddress(net, stopAddr)) {
- net.cidr++;
+ const net = new Network().from(startAddr, 1);
+ while (net.addr.lessThanOrEqual(stopAddr)) {
+ while (!net.addr.isBaseAddress(net.cidr()) || net.lastAddr().greaterThan(stopAddr)) {
+ net.setCIDR(net.cidr() + 1);
}
- const addr = shared.bytesToAddr(net.bytes, throwErrors);
- results.push(`${addr}/${net.cidr}`);
- shared.increaseAddressWithCIDR(net.bytes, net.cidr, throwErrors);
- net.cidr = 1;
+ results.push(net.toString());
+ net.next().setCIDR(1);
}
return results;
}
@@ -339,15 +311,14 @@ export function rangeOfNetworks(startAddress: string, stopAddress: string, throw
* @returns An array of networks or null in case of error
*/
export function sort(networkAddresses: string[], throwErrors?: boolean) {
- let subnets = new Array(networkAddresses.length) as shared.Network[];
+ let subnets = new Array(networkAddresses.length) as Network[];
let foundCIDR = false;
for (let i = 0; i < networkAddresses.length; i++) {
- const netString = networkAddresses[i];
- const addr = shared.parseAddressString(netString, throwErrors);
+ const addr = new Address(networkAddresses[i], throwErrors);
if (!addr) return null;
- let cidr = shared.getCIDR(netString);
+ let cidr = shared.getCIDR(networkAddresses[i]);
if (!cidr) {
- if (addr.length == 4) {
+ if (addr.bytes().length == 4) {
cidr = 32;
} else {
cidr = 128;
@@ -355,14 +326,16 @@ export function sort(networkAddresses: string[], throwErrors?: boolean) {
} else {
foundCIDR = true;
}
- subnets[i] = { bytes: addr, cidr: cidr };
+ subnets[i] = new Network().from(addr, cidr);
}
- shared.sortNetworks(subnets);
+ subnets = shared.sortNetworks(subnets);
const results = new Array(subnets.length) as string[];
for (let i = 0; i < subnets.length; i++) {
- let s = shared.bytesToAddr(subnets[i].bytes, throwErrors);
- if (!s) return null;
- results[i] = foundCIDR ? `${s}/${subnets[i].cidr}` : `${s}`;
+ if (foundCIDR) {
+ results[i] = subnets[i].toString();
+ } else {
+ results[i] = subnets[i].addr.toString();
+ }
}
return results;
}
@@ -380,28 +353,23 @@ export function sort(networkAddresses: string[], throwErrors?: boolean) {
* @returns An array of networks or null in case of error
*/
export function summarize(networks: string[], strict?: boolean, throwErrors?: boolean) {
- let subnets = [] as shared.Network[];
+ let subnets = [] as Network[];
for (let i = 0; i < networks.length; i++) {
- const netString = networks[i];
- let net = shared.parseNetworkString(netString, strict, false);
- if (!net) {
- const addr = shared.parseAddressString(netString, throwErrors);
- if (!addr) return null;
- if (addr.length == 4) {
- net = { bytes: addr, cidr: 32 };
- } else {
- net = { bytes: addr, cidr: 128 };
+ const net = shared.parseBaseNetwork(networks[i], strict, false);
+ if (net) {
+ if (net.isValid()) {
+ subnets.push(net);
}
+ } else if (strict) {
+ if (throwErrors) throw errors.NotValidBaseNetworkAddress;
+ return null;
}
- subnets.push(net);
}
- shared.sortNetworks(subnets);
+ subnets = shared.sortNetworks(subnets);
subnets = shared.summarizeSortedNetworks(subnets);
const results = new Array(subnets.length) as string[];
for (let i = 0; i < subnets.length; i++) {
- let s = shared.bytesToAddr(subnets[i].bytes, throwErrors);
- if (!s) return null;
- results[i] = `${s}/${subnets[i].cidr}`;
+ results[i] = subnets[i].toString();
}
return results;
}
@@ -411,6 +379,7 @@ module.exports = {
broadcastAddress,
findUnusedSubnets,
ip,
+ Matcher,
network,
networkComesBefore,
networkContainsAddress,
@@ -422,8 +391,3 @@ module.exports = {
sort,
summarize
};
-
-// The following functions are pending an implementation:
-
-// IPv4ClassfulNetwork() eithers return the classful network given an IPv4 address or
-// returns nil if given a multicast address or IPv6 address
diff --git a/src/match.ts b/src/match.ts
index e4ab388..afd4fb3 100644
--- a/src/match.ts
+++ b/src/match.ts
@@ -1,16 +1,16 @@
import * as shared from "./shared";
import * as sort from "./sort";
+import { Network } from "./network";
export class Matcher {
- private readonly sorted = [] as shared.Network[];
+ private readonly sorted = [] as Network[];
public constructor(networks?: string[]) {
- const subnets = [] as shared.Network[];
+ var subnets = [] as Network[];
if (networks) {
- for (let netString of networks) {
- let network = shared.parseNetworkString(netString, false, false);
- if (!network) continue;
- subnets.push(network);
+ for (var s of networks) {
+ var net = shared.parseBaseNetwork(s, false, false);
+ if (net && net.isValid()) subnets.push(net);
}
}
shared.sortNetworks(subnets);
@@ -18,14 +18,20 @@ export class Matcher {
}
public has(network: string) {
- const net = shared.parseNetworkString(network, false, false);
- if (!net) return false;
- let s = shared.bytesToAddr(net.bytes, false);
- if (!s) return false;
- const idx = sort.binarySearchForInsertionIndex(net, this.sorted);
+ var net = shared.parseBaseNetwork(network, false, false);
+ if (!net || !net.isValid()) return false;
+ var idx = sort.binarySearchForInsertionIndex(net, this.sorted);
if (idx < 0) return false;
- if (idx < this.sorted.length && shared.networkContainsSubnet(this.sorted[idx], net)) return true;
- if (idx - 1 >= 0 && shared.networkContainsSubnet(this.sorted[idx - 1], net)) return true;
+ if (idx < this.sorted.length && this.sorted[idx].contains(net)) return true;
+ if (idx - 1 >= 0 && this.sorted[idx - 1].contains(net)) return true;
return false;
}
+
+ public add(network: string) {
+ var net = shared.parseBaseNetwork(network, false, false);
+ if (!net || !net.isValid()) return;
+ var idx = sort.binarySearchForInsertionIndex(net, this.sorted);
+ if (idx < this.sorted.length && this.sorted[idx].compare(net) === 0) return;
+ this.sorted.splice(idx, 0, net);
+ }
}
diff --git a/src/mockdata/subnets.mock.ts b/src/mockdata/subnets.mock.ts
index b735612..db32eb9 100644
--- a/src/mockdata/subnets.mock.ts
+++ b/src/mockdata/subnets.mock.ts
@@ -5,7 +5,7 @@ export const valid = [
"fd78:e9ac:f08a:8b18::/64",
"fd21:e152:9b7c:cd06::/64",
"fd40:c321:349b:8901::/64",
- "[fde4:3510:269e:ffbd:: /64]",
+ "[fde4:3510:269e:ffbd::/64]",
" fd55:2f4e:c926:a11c::/64"
];
diff --git a/src/network.ts b/src/network.ts
new file mode 100644
index 0000000..bdda096
--- /dev/null
+++ b/src/network.ts
@@ -0,0 +1,203 @@
+import * as parse from "./parse";
+import * as errors from "./errors";
+import { Address } from "./address";
+
+const BEFORE = -1;
+const EQUALS = 0;
+const AFTER = 1;
+
+export class Network {
+ public readonly addr = new Address();
+ private netbits = -1;
+
+ public constructor(network?: string, throwErrors?: boolean) {
+ if (network) {
+ var net = parse.network(network, throwErrors);
+ if (net) {
+ this.addr.setBytes(net.bytes);
+ this.netbits = net.cidr;
+ }
+ }
+ }
+
+ public from(address: Address, cidr: number) {
+ this.addr.setBytes(address.bytes().slice());
+ return this.setCIDR(cidr);
+ }
+
+ public destroy() {
+ if (!this.addr.isValid()) {
+ this.addr.destroy();
+ }
+ this.netbits = -1;
+ return this;
+ }
+
+ public cidr() {
+ if (this.isValid()) {
+ return this.netbits;
+ }
+ return Number.NaN;
+ }
+
+ public isValid() {
+ return this.addr.isValid() && this.netbits !== -1;
+ }
+
+ public duplicate() {
+ var network = new Network();
+ if (this.isValid()) {
+ network.addr.setBytes(this.addr.bytes().slice());
+ network.netbits = this.netbits;
+ }
+ return network;
+ }
+
+ public toString() {
+ if (this.isValid()) {
+ return `${this.addr.toString()}/${this.netbits}`;
+ }
+ return "";
+ }
+
+ public next() {
+ this.addr.increase(this.netbits);
+ return this;
+ }
+
+ public previous() {
+ this.addr.decrease(this.netbits);
+ return this;
+ }
+
+ public lastAddr() {
+ var addr = this.addr.duplicate().applySubnetMask(this.netbits);
+ var maxCIDR = this.addr.bytes().length * 8;
+ for (var i = this.netbits + 1; i <= maxCIDR; i++) addr.increase(i);
+ return addr;
+ }
+
+ public setCIDR(cidr: number, throwErrors?: boolean) {
+ if (!this.addr.isValid()) {
+ if (throwErrors) throw errors.InvalidSubnet;
+ this.destroy();
+ } else {
+ cidr = Math.floor(cidr);
+ if (cidr >= 0 && cidr <= this.addr.bytes().length * 8) {
+ this.netbits = cidr;
+ } else {
+ if (throwErrors) throw errors.NotValidCIDR;
+ this.destroy();
+ }
+ }
+ return this;
+ }
+
+ public compare(network: Network) {
+ // check that both networks are valid
+ if (!this.isValid() || !network.isValid()) return null;
+
+ // compare addresses
+ var cmp = this.addr.compare(network.addr);
+ if (cmp !== EQUALS) return cmp;
+
+ // compare subnet mask length
+ if (this.netbits < network.netbits) return BEFORE;
+ if (this.netbits > network.netbits) return AFTER;
+
+ // otherwise they must be equal
+ return EQUALS;
+ }
+
+ public contains(network: Network) {
+ // check that both networks are valid
+ if (!this.isValid() || !network.isValid()) return false;
+
+ // ensure that both IPs are of the same type
+ if (this.addr.bytes().length !== network.addr.bytes().length) return false;
+
+ // handle edge cases
+ if (this.netbits === 0) return true;
+ if (network.netbits === 0) return false;
+
+ // our base address should be less than or equal to the other base address
+ if (this.addr.compare(network.addr) === AFTER) return false;
+
+ // get the next network address for both
+ var next = this.duplicate().next();
+ var otherNext = network.duplicate().next();
+
+ // handle edge case where our next network address overflows
+ if (!next.isValid()) return true;
+
+ // our address should be more than or equal to the other address
+ if (next.addr.compare(otherNext.addr) === BEFORE) return false;
+
+ // must be a child subnet
+ return true;
+ }
+
+ public intersects(network: Network) {
+ // check that both networks are valid
+ if (!this.isValid() || !network.isValid()) return false;
+
+ // ensure that both IPs are of the same type
+ if (this.addr.bytes().length !== network.addr.bytes().length) return false;
+
+ // handle edge cases
+ if (this.netbits === 0 || network.netbits == 0) return true;
+ var cmp = this.addr.compare(network.addr);
+ if (cmp === EQUALS) return true;
+
+ // ensure that alpha addr contains the baseAddress that comes first
+ var alpha: Network, bravo: Network;
+ if (cmp === BEFORE) {
+ alpha = this.duplicate().next();
+ bravo = network.duplicate().next();
+ } else {
+ alpha = network.duplicate().next();
+ bravo = this.duplicate().next();
+ }
+
+ // if either addresses overflowed than an intersection has occured
+ if (!alpha.isValid() || !bravo.isValid()) return true;
+
+ // if alpha addr is now greater than or equal to bravo addr than we've intersected
+ if (alpha.addr.greaterThanOrEqual(bravo.addr)) return true;
+
+ // otherwise we haven't intersected
+ return false;
+ }
+
+ public adjacent(network: Network) {
+ // check that both networks are valid
+ if (!this.isValid() || !network.isValid()) return false;
+
+ // ensure that both IPs are of the same type
+ if (this.addr.bytes().length !== network.addr.bytes().length) return false;
+
+ // handle edge cases
+ if (this.netbits === 0 || network.netbits == 0) return true;
+ var cmp = this.addr.compare(network.addr);
+ if (cmp === EQUALS) return false;
+
+ // ensure that alpha addr contains the baseAddress that comes first
+ var alpha: Network, bravo: Network;
+ if (cmp === BEFORE) {
+ alpha = this.duplicate().next();
+ bravo = network;
+ } else {
+ alpha = network.duplicate().next();
+ bravo = this;
+ }
+
+ // if alpha overflows then an adjacency is not possible
+ if (!alpha.isValid()) return false;
+
+ // alpha addr should equal bravo for them to be perfectly adjacent
+ if (alpha.addr.compare(bravo.addr) === EQUALS) return true;
+
+ // otherwise we aren't adjacent
+ return false;
+ }
+}
diff --git a/src/parse.ts b/src/parse.ts
new file mode 100644
index 0000000..1a11fa6
--- /dev/null
+++ b/src/parse.ts
@@ -0,0 +1,243 @@
+/* eslint-disable @typescript-eslint/no-use-before-define */
+
+import * as errors from "./errors";
+
+export function network(s: string, throwErrors?: boolean) {
+ s = s.trim();
+ var parts = s.split("/");
+ if (parts.length === 0 || parts.length > 2) return null;
+ var isIPv4 = looksLikeIPv4(s);
+ if (isIPv4 === null) {
+ if (throwErrors) throw errors.GenericNetworkParse;
+ return null;
+ }
+ var cidr = isIPv4 ? 32 : 128;
+ if (parts.length === 2) {
+ var x = parseIntRange(parts[1], 0, cidr);
+ if (x === null) {
+ if (throwErrors) throw errors.GenericNetworkParse;
+ return null;
+ }
+ cidr = x;
+ }
+ var bytes = isIPv4 ? v4AddrToBytes(parts[0]) : v6AddrToBytes(parts[0]);
+ if (bytes === null) {
+ if (throwErrors) throw Error(`could not convert string to bytes`); //errors.GenericNetworkParse;
+ return null;
+ }
+ return { bytes, cidr };
+}
+
+function looksLikeIPv4(s: string) {
+ for (var c of s) {
+ if (c === ".") return true;
+ if (c === ":") return false;
+ }
+ return null;
+}
+
+function parseIntRange(old: string, min: number, max: number) {
+ var s = "";
+ for (var i = 0; i < old.length; i++) {
+ if (!isOneDigit(old[i])) break;
+ s += old[i];
+ }
+ var x = parseInt(s, 10);
+ if (x >= min && x <= max) return x;
+ return null;
+}
+
+function isOneDigit(s: string) {
+ switch (s) {
+ case "0":
+ case "1":
+ case "2":
+ case "3":
+ case "4":
+ case "5":
+ case "6":
+ case "7":
+ case "8":
+ case "9":
+ return true;
+ default:
+ return false;
+ }
+}
+
+export function v4AddrToBytes(old: string) {
+ var bytes = new Array(4) as number[];
+ var parts = old.split(".");
+ if (parts.length === 4) {
+ for (var i = 0; i < parts.length; i++) {
+ var x = parseInt(parts[i], 10);
+ if (x >= 0 && x <= 255) {
+ bytes[i] = x;
+ } else {
+ return null;
+ }
+ }
+ return bytes;
+ }
+ return null;
+}
+
+function parseHextet(s: string) {
+ if (s.trim().length < 1 || s.trim().length > 4) return Number.NaN;
+ var val = 0;
+ for (var i = 0; i < s.length; i++) {
+ if (i >= 4) return Number.NaN;
+ var p = 4 * (s.length - i - 1);
+ switch (s[i]) {
+ case "0":
+ break;
+ case "1":
+ val += 1 * Math.pow(2, p);
+ break;
+ case "2":
+ val += 2 * Math.pow(2, p);
+ break;
+ case "3":
+ val += 3 * Math.pow(2, p);
+ break;
+ case "4":
+ val += 4 * Math.pow(2, p);
+ break;
+ case "5":
+ val += 5 * Math.pow(2, p);
+ break;
+ case "6":
+ val += 6 * Math.pow(2, p);
+ break;
+ case "7":
+ val += 7 * Math.pow(2, p);
+ break;
+ case "8":
+ val += 8 * Math.pow(2, p);
+ break;
+ case "9":
+ val += 9 * Math.pow(2, p);
+ break;
+ case "a":
+ val += 10 * Math.pow(2, p);
+ break;
+ case "b":
+ val += 11 * Math.pow(2, p);
+ break;
+ case "c":
+ val += 12 * Math.pow(2, p);
+ break;
+ case "d":
+ val += 13 * Math.pow(2, p);
+ break;
+ case "e":
+ val += 14 * Math.pow(2, p);
+ break;
+ case "f":
+ val += 15 * Math.pow(2, p);
+ break;
+ default:
+ return Number.NaN;
+ }
+ }
+ return val;
+}
+
+/*
+ https://tools.ietf.org/html/rfc3986
+ ffff:fc00::1:1234/64
+ [fde4:3510:269e:ffbd::/64]
+ https://tools.ietf.org/html/rfc4291
+ https://tools.ietf.org/html/rfc5952#section-4
+ [2001:db8::1]:80
+ 2001:db8::1:80
+ 2001:db8::1.80
+ 2001:db8::1 port 80
+ 2001:db8::1p80
+ 2001:db8::1#80
+*/
+
+export function v6AddrToBytes(old: string) {
+ const bytes = new Array(16).fill(0) as number[];
+ if (old.length === 0) return null;
+ if (old[0] === "[") {
+ old = removeBrackets(old);
+ }
+ if (old === "::") return bytes;
+ var halves = old.split("::");
+ if (halves.length === 0 || halves.length > 2) return null;
+ var leftByteIndex = parseLeftHalf(bytes, halves[0]);
+ if (leftByteIndex === null) return null;
+ if (halves.length === 2) {
+ var rightByteIndex = parseRightHalf(bytes, halves[1], leftByteIndex);
+ if (rightByteIndex === null) return null;
+ }
+ return bytes;
+}
+
+function removeBrackets(s: string) {
+ for (var i = s.length - 1; i >= 0; i--) {
+ if (s[i] === "]") {
+ return s.substring(1, i);
+ }
+ }
+ return s.substring(1);
+}
+
+function parseLeftHalf(bytes: number[], leftHalf: string) {
+ var leftByteIndex = 0;
+ if (leftHalf !== "") {
+ var leftParts = leftHalf.split(":");
+ for (var i = 0; i < leftParts.length; i++) {
+ if (leftByteIndex >= 16) return null;
+ var ipv4Parts = leftParts[i].split(".");
+ if (ipv4Parts.length === 0) return null;
+ if (ipv4Parts.length !== 4) {
+ var x = parseHextet(leftParts[i]);
+ if (Number.isNaN(x) || x < 0 || x > 65535) return null;
+ bytes[leftByteIndex++] = Math.floor(x / 256);
+ bytes[leftByteIndex++] = Math.floor(x % 256);
+ } else {
+ for (var j = 0; j < ipv4Parts.length; j++) {
+ var x = Number(ipv4Parts[j]);
+ if (Number.isNaN(x) || x < 0 || x > 255) return null;
+ bytes[leftByteIndex++] = x;
+ }
+ }
+ }
+ }
+ return leftByteIndex;
+}
+
+function removePortInfo(s: string) {
+ return s.replace(/(#|p|\.).*/g, "").trim();
+}
+
+function parseRightHalf(bytes: number[], rightHalf: string, leftByteIndex: number) {
+ var rightByteIndex = 15;
+ if (rightHalf !== "") {
+ var rightParts = rightHalf.split(":");
+ for (var i = rightParts.length - 1; i >= 0; i--) {
+ if (rightParts[i].trim() === "") return null;
+ if (leftByteIndex > rightByteIndex) return null;
+ var ipv4Parts = rightParts[i].split(".");
+ if (ipv4Parts.length === 0) return null;
+ if (ipv4Parts.length !== 4) {
+ if (i === rightParts.length - 1) {
+ rightParts[i] = removePortInfo(rightParts[i]);
+ }
+ var x = parseHextet(rightParts[i]);
+ if (Number.isNaN(x) || x < 0 || x > 65535) return null;
+ bytes[rightByteIndex--] = Math.floor(x % 256);
+ bytes[rightByteIndex--] = Math.floor(x / 256);
+ } else {
+ for (var j = ipv4Parts.length - 1; j >= 0; j--) {
+ var x = Number(ipv4Parts[j]);
+ if (Number.isNaN(x) || x < 0 || x > 255) return null;
+ bytes[rightByteIndex--] = x;
+ }
+ }
+ }
+ }
+ return rightByteIndex;
+}
diff --git a/src/ranges.ts b/src/ranges.ts
new file mode 100644
index 0000000..415a42d
--- /dev/null
+++ b/src/ranges.ts
@@ -0,0 +1,103 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+
+import { Network } from "./network";
+import { Address } from "./address";
+
+var ipv4Ranges = undefined as any;
+
+function createIPv4Ranges() {
+ return {
+ unspecified: [
+ new Network("0.0.0.0/8", true) //
+ ],
+ broadcast: [
+ new Network("255.255.255.255/32") //
+ ],
+ multicast: [
+ new Network("224.0.0.0/4") // RFC3171
+ ],
+ linkLocal: [
+ new Network("169.254.0.0/16") // RFC3927
+ ],
+ loopback: [
+ new Network("127.0.0.0/8") // RFC5735
+ ],
+ carrierGradeNat: [
+ new Network("100.64.0.0/10") //RFC6598
+ ],
+ private: [
+ new Network("10.0.0.0/8"), // RFC1918
+ new Network("172.16.0.0/12"),
+ new Network("192.168.0.0/16")
+ ],
+ reserved: [
+ new Network("192.0.0.0/24"), // RFC5735, RFC5737, RFC2544, RFC1700
+ new Network("192.0.2.0/24"),
+ new Network("192.88.99.0/24"),
+ new Network("198.51.100.0/24"),
+ new Network("203.0.113.0/24"),
+ new Network("240.0.0.0/24")
+ ]
+ };
+}
+
+var ipv6Ranges = undefined as any;
+
+function createIPv6Ranges() {
+ return {
+ unspecified: [
+ new Network("::/128") // RFC4291
+ ],
+ linkLocal: [
+ new Network("fe80::/10") // RFC4291
+ ],
+ multicast: [
+ new Network("ff00::/8") // RFC4291
+ ],
+ loopback: [
+ new Network("::1/128") // RFC4291
+ ],
+ uniqueLocal: [
+ new Network("fc00::/7") // RFC4291
+ ],
+ ipv4Mapped: [
+ new Network("::ffff:0:0/96") // RFC4291
+ ],
+ rfc6145: [
+ new Network("::ffff:0:0:0/96") // RFC6145
+ ],
+ rfc6052: [
+ new Network("64:ff9b::/96") // RFC6052
+ ],
+ "6to4": [
+ new Network("2002::/16") // RFC3056
+ ],
+ teredo: [
+ new Network("2001::/32") // RFC6052, RFC6146
+ ],
+ reserved: [
+ new Network("2001:db8::/32") // RFC4291
+ ]
+ };
+}
+
+// https://dev.to/kingdaro/indexing-objects-in-typescript-1cgi
+function hasKey(obj: O, key: keyof any): key is keyof O {
+ return key in obj;
+}
+
+export function check(address: Address, key: string) {
+ if (address.isValid()) {
+ if (address.isIPv4()) {
+ var ranges = ipv4Ranges ? ipv4Ranges : createIPv4Ranges();
+ } else {
+ var ranges = ipv6Ranges ? ipv6Ranges : createIPv6Ranges();
+ }
+ if (hasKey(ranges, key)) {
+ for (var net of ranges[key]) {
+ if (net.contains(address.toNetwork())) return true;
+ }
+ }
+ }
+ return false;
+}
diff --git a/src/shared.ts b/src/shared.ts
index 4b34c87..faf6072 100644
--- a/src/shared.ts
+++ b/src/shared.ts
@@ -1,347 +1,92 @@
-import * as v4 from "./IPv4";
-import * as v6 from "./IPv6";
import * as sort from "./sort";
import * as errors from "./errors";
-
-export type Address = Uint8Array;
-
-export interface Network {
- bytes: Address;
- cidr: number;
-}
-
-export function hasColon(s: string) {
- return s.search(":") >= 0;
-}
-
-export function addrToBytes(addr: string, throwErrors?: boolean) {
- if (hasColon(addr)) {
- return v6.addrToBytes(addr, throwErrors);
- }
- return v4.addrToBytes(addr, throwErrors);
-}
-
-export function bytesToAddr(bytes: Uint8Array, throwErrors?: boolean) {
- if (bytes.length === 16) {
- return v6.bytesToAddr(bytes, throwErrors);
- }
- return v4.bytesToAddr(bytes, throwErrors);
-}
-
-export function repeatString(s: string, count: number) {
- var result = "";
- for (var i = 0; i < count; i++) {
- result += s;
- }
- return result;
-}
-
-export function removeCIDR(s: string, throwErrors?: boolean) {
- const splitAddr = s.split("/");
- switch (splitAddr.length) {
- case 0:
- case 1:
- return s;
- case 2:
- return splitAddr[0];
- }
- if (throwErrors) throw errors.GenericRemoveCIDR;
- return null;
-}
+import { Network } from "./network";
+import { Address } from "./address";
export function getCIDR(s: string, throwErrors?: boolean) {
const splitAddr = s.split("/");
if (splitAddr.length === 2) {
- const val = parseInt(splitAddr[1], 10);
+ const val = Number(splitAddr[1]);
if (Number.isInteger(val)) {
- if (hasColon(splitAddr[0]) && 0 < val && val <= 128) return val;
- if (0 < val && val <= 32) return val;
+ const maxCIDR = splitAddr[0].search(":") >= 0 ? 128 : 32;
+ if (0 < val && val <= maxCIDR) return val;
}
}
if (throwErrors) throw errors.GenericGetCIDR;
return null;
}
-export function removeBrackets(s: string) {
- return s.replace(/[[\]]/g, "");
-}
-
-export function duplicateAddress(address: Address) {
- return address.slice();
-}
-
-export function duplicateNetwork(network: Network) {
- return { bytes: network.bytes.slice(), cidr: network.cidr } as Network;
-}
-
-export function setAddress(dst: Uint8Array, src: Uint8Array) {
- for (var i = 0; i < src.length; i++) {
- if (i < dst.length) {
- dst[i] = src[i];
- } else {
- return;
- }
- }
-}
-
-export enum Pos {
- before = -1,
- equals = 0,
- after = 1
-}
-
-export function compareAddresses(a: Uint8Array, b: Uint8Array) {
- if (a !== b) {
- if (a.length < b.length) return Pos.before;
- if (a.length > b.length) return Pos.after;
- for (var i = 0; i < a.length; i++) {
- if (a[i] < b[i]) return Pos.before;
- if (a[i] > b[i]) return Pos.after;
- }
- }
- return Pos.equals;
-}
-
-export function compareNetworks(a: Network, b: Network) {
- if (a !== b) {
- if (a.bytes.length < b.bytes.length) return Pos.before;
- if (a.bytes.length > b.bytes.length) return Pos.after;
- for (var i = 0; i < a.bytes.length; i++) {
- if (a.bytes[i] < b.bytes[i]) return Pos.before;
- if (a.bytes[i] > b.bytes[i]) return Pos.after;
- }
- if (a.cidr < b.cidr) return Pos.before;
- if (a.cidr > b.cidr) return Pos.after;
- }
- return Pos.equals;
-}
-
-function offsetAddress(bytes: Uint8Array, cidr: number, isPositive: boolean, throwErrors?: boolean): Uint8Array | null {
- const targetByte = Math.floor((cidr - 1) / 8);
- if (targetByte < bytes.length) {
- const increment = Math.pow(2, 8 - (cidr - targetByte * 8));
- const unconstrained = bytes[targetByte] + increment * (isPositive ? 1 : -1);
- bytes[targetByte] = unconstrained % 256;
- if (0 <= unconstrained && unconstrained <= 255) {
- return bytes;
- }
- if (targetByte > 0) {
- const supernetCIDR = targetByte * 8;
- return offsetAddress(bytes, supernetCIDR, isPositive, throwErrors);
- }
- if (throwErrors) throw errors.OverflowedAddressSpace;
- return null;
- }
- if (throwErrors) throw errors.GenericOffsetAddressWithCIDR;
- return null;
-}
-
-export function increaseAddressWithCIDR(bytes: Uint8Array, cidr: number, throwErrors?: boolean) {
- if (cidr > 0 && (bytes.length === 4 || bytes.length === 16)) {
- return offsetAddress(bytes, cidr, true, throwErrors);
- }
- if (throwErrors) throw errors.GenericOffsetAddressWithCIDR;
- return null;
-}
-
-export function decreaseAddressWithCIDR(bytes: Uint8Array, cidr: number, throwErrors?: boolean) {
- if (cidr > 0 && (bytes.length === 4 || bytes.length === 16)) {
- return offsetAddress(bytes, cidr, false, throwErrors);
- }
- if (throwErrors) throw errors.GenericOffsetAddressWithCIDR;
- return null;
-}
-
-export function applySubnetMask(bytes: Uint8Array, cidr: number) {
- let maskBits = bytes.length * 8 - cidr;
- for (var i = bytes.length - 1; i >= 0; i--) {
- switch (Math.max(0, Math.min(8, maskBits))) {
- case 0:
- return;
- case 1:
- bytes[i] &= ~1;
- break;
- case 2:
- bytes[i] &= ~3;
- break;
- case 3:
- bytes[i] &= ~7;
- break;
- case 4:
- bytes[i] &= ~15;
- break;
- case 5:
- bytes[i] &= ~31;
- break;
- case 6:
- bytes[i] &= ~63;
- break;
- case 7:
- bytes[i] &= ~127;
- break;
- case 8:
- bytes[i] = 0;
- break;
- }
- maskBits -= 8;
- }
-}
-
-export function parseAddressString(s: string, throwErrors?: boolean) {
- s = s.trim();
- const isIPv6 = hasColon(s);
- if (isIPv6) {
- s = removeBrackets(s);
- }
- const ip = removeCIDR(s, throwErrors);
- if (ip !== null) {
- return addrToBytes(ip, throwErrors) as Address;
+export function sortNetworks(networks: Network[]) {
+ if (networks.length < 10000) {
+ return sort.insertionSort(networks);
}
- return null;
+ return sort.nativeSort(networks);
}
-export function parseNetworkString(s: string, strict?: boolean, throwErrors?: boolean) {
- s = s.trim();
- const isIPv6 = hasColon(s);
- if (isIPv6) {
- s = removeBrackets(s);
- }
- const ip = removeCIDR(s, throwErrors);
- let cidr = getCIDR(s, strict && throwErrors);
- if (ip !== null) {
- const bytes = addrToBytes(ip, throwErrors);
- if (!bytes) return null;
- if (!strict) {
- if (!cidr) {
- cidr = bytes.length * 8;
+export function summarizeSortedNetworks(sorted: Network[]) {
+ const summarized = [] as Network[];
+ for (let idx = 0; idx < sorted.length; idx++) {
+ summarized.push(sorted[idx]);
+ let skipped = 0;
+ for (let i = idx + 1; i < sorted.length; i++) {
+ if (sorted[idx].contains(sorted[i])) {
+ skipped++;
+ continue;
}
- applySubnetMask(bytes, cidr);
- } else {
- if (!cidr) return null;
- const bytesCopy = new Uint8Array(bytes.length);
- setAddress(bytesCopy, bytes);
- applySubnetMask(bytes, cidr);
- if (compareAddresses(bytes, bytesCopy) !== 0) {
- if (throwErrors) throw errors.NotValidBaseNetworkAddress;
- return null;
+ if (sorted[idx].cidr() === sorted[i].cidr()) {
+ if (sorted[idx].adjacent(sorted[i])) {
+ sorted[idx].setCIDR(sorted[idx].cidr() - 1);
+ skipped++;
+ continue;
+ }
}
+ break;
}
- return { bytes, cidr } as Network;
- }
- return null;
-}
-
-export function networkGoesPastAddress(net: Network, addr: Address) {
- const netBytesEnd = duplicateAddress(net.bytes);
- increaseAddressWithCIDR(netBytesEnd, net.cidr);
- decreaseAddressWithCIDR(netBytesEnd, net.bytes.length * 8);
- if (compareAddresses(netBytesEnd, addr) > 0) return true;
- return false;
-}
-
-export function networkContainsSubnet(net: Network, subnet: Network, throwErrors?: boolean) {
- if (net.bytes.length !== subnet.bytes.length) return false;
- if (compareAddresses(net.bytes, subnet.bytes) > 0) return false;
- const netBytesEnd = duplicateAddress(net.bytes);
- if (!increaseAddressWithCIDR(netBytesEnd, net.cidr, throwErrors)) return false;
- const subnetBytesEnd = duplicateAddress(subnet.bytes);
- if (!increaseAddressWithCIDR(subnetBytesEnd, subnet.cidr, throwErrors)) return false;
- if (compareAddresses(netBytesEnd, subnetBytesEnd) < 0) return false;
- return true;
-}
-
-export function networkContainsAddress(net: Network, addr: Address, throwErrors?: boolean) {
- if (net.bytes.length !== addr.length) return false;
- if (compareAddresses(net.bytes, addr) > 0) return false;
- const netBytesEnd = duplicateAddress(net.bytes);
- if (!increaseAddressWithCIDR(netBytesEnd, net.cidr, throwErrors)) return false;
- if (compareAddresses(netBytesEnd, addr) > 0) return true;
- return false;
-}
-
-export function networksIntersect(net: Network, otherNet: Network, throwErrors?: boolean) {
- if (net.bytes.length !== otherNet.bytes.length) return false;
- let alphaStart = net.bytes;
- let alphaEnd = duplicateAddress(net.bytes);
- if (!increaseAddressWithCIDR(alphaEnd, net.cidr, throwErrors)) return false;
- decreaseAddressWithCIDR(alphaEnd, net.bytes.length * 8);
- let bravoStart = otherNet.bytes;
- let bravoEnd = duplicateAddress(otherNet.bytes);
- if (!increaseAddressWithCIDR(bravoEnd, otherNet.cidr, throwErrors)) return false;
- decreaseAddressWithCIDR(bravoEnd, otherNet.bytes.length * 8);
- if (compareAddresses(alphaStart, bravoStart) > 0) {
- [alphaStart, alphaEnd, bravoStart, bravoEnd] = [bravoStart, bravoEnd, alphaStart, alphaEnd];
+ idx += skipped;
}
- if (compareAddresses(alphaEnd, bravoStart) < 0) return false;
- return true;
-}
-
-export function networksAreAdjacent(net: Network, otherNet: Network, throwErrors?: boolean) {
- if (net.bytes.length !== otherNet.bytes.length) return false;
- const netBytes = duplicateAddress(net.bytes);
- if (!increaseAddressWithCIDR(netBytes, net.cidr, throwErrors)) return false;
- if (compareAddresses(netBytes, otherNet.bytes) === 0) return true;
- return false;
+ return summarized;
}
export function findNetworkIntersection(network: Network, otherNetworks: Network[]) {
for (var otherNet of otherNetworks) {
- if (networksIntersect(network, otherNet)) {
+ if (network.intersects(otherNet)) {
return otherNet;
}
}
return null;
}
-export function isValidNetworkAddress(net: Network) {
- const netBaseBytes = duplicateAddress(net.bytes);
- applySubnetMask(netBaseBytes, net.cidr);
- return compareAddresses(net.bytes, netBaseBytes) === 0;
-}
-
-export function findNetworkWithoutIntersection(network: Network, otherNetworks: Network[]) {
- const currentNetwork = duplicateNetwork(network);
- while (currentNetwork.cidr <= network.bytes.length * 8) {
- if (isValidNetworkAddress(currentNetwork)) {
- if (!findNetworkIntersection(currentNetwork, otherNetworks)) {
- return currentNetwork;
+export function findNetworkWithoutIntersection(otherNetworks: Network[], position: Address, startingCIDR?: number) {
+ if (!startingCIDR) startingCIDR = 0;
+ const maxCIDR = position.bytes().length * 8;
+ const canidate = new Network().from(position, startingCIDR);
+ while (canidate.cidr() <= maxCIDR) {
+ if (canidate.addr.isBaseAddress(canidate.cidr())) {
+ if (!findNetworkIntersection(canidate, otherNetworks)) {
+ return canidate;
}
- if (currentNetwork.cidr >= network.bytes.length * 8) {
- if (!increaseAddressWithCIDR(currentNetwork.bytes, network.bytes.length * 8)) return null;
- currentNetwork.cidr = network.cidr;
+ if (canidate.cidr() >= maxCIDR) {
+ if (!canidate.addr.next().isValid()) return null;
+ canidate.setCIDR(startingCIDR);
}
}
- currentNetwork.cidr++;
+ canidate.setCIDR(canidate.cidr() + 1);
}
return null;
}
-export function sortNetworks(networks: Network[]) {
- if (networks && networks.length > 1) {
- sort.radixSortNetworks(networks, 0, networks.length, -1);
- }
-}
-
-export function summarizeSortedNetworks(sorted: Network[]) {
- const summarized = [] as Network[];
- for (let idx = 0; idx < sorted.length; idx++) {
- summarized.push(sorted[idx]);
- let skipped = 0;
- for (let i = idx + 1; i < sorted.length; i++) {
- if (networkContainsSubnet(sorted[idx], sorted[i])) {
- skipped++;
- continue;
- }
- if (sorted[idx].cidr === sorted[i].cidr) {
- if (networksAreAdjacent(sorted[idx], sorted[i])) {
- sorted[idx].cidr--;
- skipped++;
- continue;
- }
- }
- break;
+export function parseBaseNetwork(s: string, strict?: boolean, throwErrors?: boolean) {
+ const net = new Network(s, throwErrors);
+ if (!net.isValid()) return null;
+ if (!strict) {
+ net.addr.applySubnetMask(net.cidr());
+ } else {
+ const original = net.addr.duplicate();
+ net.addr.applySubnetMask(net.cidr());
+ if (!net.addr.equals(original)) {
+ if (throwErrors) throw errors.NotValidBaseNetworkAddress;
+ return null;
}
- idx += skipped;
}
- return summarized;
+ return net;
}
diff --git a/src/sort.ts b/src/sort.ts
index f8a931d..6c5e425 100644
--- a/src/sort.ts
+++ b/src/sort.ts
@@ -1,6 +1,64 @@
-import * as shared from "./shared";
+import { Network } from "./network";
+import { sortBy } from "lodash";
-export function radixSortNetworks(networks: shared.Network[], start: number, stop: number, byteIndex: number) {
+const BEFORE = -1;
+const EQUALS = 0;
+const AFTER = 1;
+
+export function nativeSort(networks: Network[]) {
+ return sortBy(networks, [
+ o => o.addr.bytes().length,
+ o => (o.addr.bytes()[0] ? o.addr.bytes()[0] : 0),
+ o => (o.addr.bytes()[1] ? o.addr.bytes()[1] : 0),
+ o => (o.addr.bytes()[2] ? o.addr.bytes()[2] : 0),
+ o => (o.addr.bytes()[3] ? o.addr.bytes()[3] : 0),
+ o => (o.addr.bytes()[4] ? o.addr.bytes()[4] : 0),
+ o => (o.addr.bytes()[5] ? o.addr.bytes()[5] : 0),
+ o => (o.addr.bytes()[6] ? o.addr.bytes()[6] : 0),
+ o => (o.addr.bytes()[7] ? o.addr.bytes()[7] : 0),
+ o => (o.addr.bytes()[8] ? o.addr.bytes()[8] : 0),
+ o => (o.addr.bytes()[9] ? o.addr.bytes()[9] : 0),
+ o => (o.addr.bytes()[10] ? o.addr.bytes()[10] : 0),
+ o => (o.addr.bytes()[11] ? o.addr.bytes()[11] : 0),
+ o => (o.addr.bytes()[12] ? o.addr.bytes()[12] : 0),
+ o => (o.addr.bytes()[13] ? o.addr.bytes()[13] : 0),
+ o => (o.addr.bytes()[14] ? o.addr.bytes()[14] : 0),
+ o => (o.addr.bytes()[15] ? o.addr.bytes()[15] : 0),
+ o => o.cidr()
+ ]);
+}
+
+export function binarySearchForInsertionIndex(network: Network, sortedNetworks: Network[]) {
+ if (!sortedNetworks || sortedNetworks.length === 0) return 0;
+ let left = 0;
+ let right = sortedNetworks.length - 1;
+ while (left < right) {
+ let middle = Math.floor((left + right) / 2);
+ switch (sortedNetworks[middle].compare(network)) {
+ case EQUALS:
+ return middle;
+ case BEFORE:
+ left = middle + 1;
+ break;
+ case AFTER:
+ right = middle - 1;
+ break;
+ }
+ }
+ if (sortedNetworks[left].compare(network) === BEFORE) return left + 1;
+ return left;
+}
+
+export function insertionSort(networks: Network[]) {
+ const sorted = [] as Network[];
+ networks.forEach((net: Network) => {
+ var idx = binarySearchForInsertionIndex(net, sorted);
+ sorted.splice(idx, 0, net);
+ });
+ return sorted;
+}
+
+function msdRadixSort(networks: Network[], start: number, stop: number, byteIndex: number) {
const runningPrefixSum = new Array(256) as number[];
const offsetPrefixSum = new Array(256) as number[];
const counts = runningPrefixSum;
@@ -10,17 +68,22 @@ export function radixSortNetworks(networks: shared.Network[], start: number, sto
// count each occurance of byte value
for (let i = start; i < stop; i++) {
- if (byteIndex === -1) {
- counts[networks[i].bytes.length]++;
- } else if (byteIndex < 16) {
- if (byteIndex < networks[i].bytes.length) {
- networks[i].bytes[byteIndex] = Math.min(Math.max(0, networks[i].bytes[byteIndex]), 255);
- }
- counts[networks[i].bytes[byteIndex]]++;
- } else {
- networks[i].cidr = Math.min(Math.max(0, networks[i].cidr), 8 * networks[i].bytes.length);
- counts[networks[i].cidr]++;
+ let byteValue: number;
+ switch (byteIndex) {
+ case -1:
+ byteValue = networks[i].addr.bytes().length;
+ break;
+ case 16:
+ byteValue = networks[i].cidr();
+ break;
+ default:
+ if (byteIndex < networks[i].addr.bytes().length) {
+ byteValue = networks[i].addr.bytes()[byteIndex];
+ } else {
+ byteValue = 0;
+ }
}
+ counts[byteValue]++;
}
let lastCount = counts[counts.length - 1];
@@ -46,16 +109,19 @@ export function radixSortNetworks(networks: shared.Network[], start: number, sto
let redIndex = start;
let redValue = 0;
while (redIndex < stop) {
- if (byteIndex === -1) {
- redValue = networks[redIndex].bytes.length;
- } else if (byteIndex < 16) {
- if (byteIndex < networks[redIndex].bytes.length) {
- redValue = networks[redIndex].bytes[byteIndex];
- } else {
- redValue = 0;
- }
- } else {
- redValue = networks[redIndex].cidr;
+ switch (byteIndex) {
+ case -1:
+ redValue = networks[redIndex].addr.bytes().length;
+ break;
+ case 16:
+ redValue = networks[redIndex].cidr();
+ break;
+ default:
+ if (byteIndex < networks[redIndex].addr.bytes().length) {
+ redValue = networks[redIndex].addr.bytes()[byteIndex];
+ } else {
+ redValue = 0;
+ }
}
let blueIndex = start + runningPrefixSum[redValue];
if (runningPrefixSum[redValue] < offsetPrefixSum[redValue]) {
@@ -77,31 +143,16 @@ export function radixSortNetworks(networks: shared.Network[], start: number, sto
let lastPrefixSum = 0;
for (var i = 0; i < runningPrefixSum.length; i++) {
if (runningPrefixSum[i] !== lastPrefixSum) {
- radixSortNetworks(networks, start + lastPrefixSum, start + runningPrefixSum[i], byteIndex + 1);
+ msdRadixSort(networks, start + lastPrefixSum, start + runningPrefixSum[i], byteIndex + 1);
}
lastPrefixSum = runningPrefixSum[i];
}
}
}
-export function binarySearchForInsertionIndex(network: shared.Network, sortedNetworks: shared.Network[]) {
- let left = 0;
- let right = sortedNetworks.length - 1;
- while (left < right) {
- let middle = Math.floor((left + right) / 2);
- let netCmp = shared.compareNetworks(sortedNetworks[middle], network);
- switch (netCmp) {
- case shared.Pos.equals:
- return middle;
- case shared.Pos.before:
- left = middle + 1;
- break;
- case shared.Pos.after:
- right = middle - 1;
- break;
- }
+export function radixSort(networks: Network[]) {
+ if (networks.length > 0) {
+ msdRadixSort(networks, 0, networks.length, -1);
}
- let netCmp = shared.compareNetworks(sortedNetworks[left], network);
- if (netCmp === shared.Pos.before) return left + 1;
- return left;
+ return networks;
}
diff --git a/src/tests/IPv4.test.ts b/src/tests/IPv4.test.ts
deleted file mode 100644
index 4c50bc4..0000000
--- a/src/tests/IPv4.test.ts
+++ /dev/null
@@ -1,154 +0,0 @@
-import * as index from "../index";
-import * as shared from "../shared";
-import * as ipv4 from "../IPv4";
-import * as errors from "../errors";
-
-test("sanity check IPv4 offset by /32", () => {
- const input = "192.168.0.0";
- const bytes = ipv4.addrToBytes(input, true);
- shared.increaseAddressWithCIDR(bytes, 32, true);
- const output = ipv4.bytesToAddr(bytes, true);
- const expected = "192.168.0.1";
- if (output !== expected) {
- throw new Error(`'${output}' !== '${expected}'`);
- }
-});
-
-test("sanity check IPv4 negative offset by /32", () => {
- const input = "192.168.0.0";
- const bytes = ipv4.addrToBytes(input, true);
- shared.decreaseAddressWithCIDR(bytes, 32, true);
- const output = ipv4.bytesToAddr(bytes, true);
- const expected = "192.167.255.255";
- if (output !== expected) {
- throw new Error(`'${output}' !== '${expected}'`);
- }
-});
-
-test("sanity check IPv4 offset by /24 with overflow", () => {
- const input = "192.168.255.0";
- const bytes = ipv4.addrToBytes(input, true);
- shared.increaseAddressWithCIDR(bytes, 24, true);
- const output = ipv4.bytesToAddr(bytes, true);
- const expected = "192.169.0.0";
- if (output !== expected) {
- throw new Error(`'${output}' !== '${expected}'`);
- }
-});
-
-test("sanity check IPv4 offset by /25 with overflow", () => {
- const input = "192.168.0.248";
- const bytes = ipv4.addrToBytes(input, true);
- shared.increaseAddressWithCIDR(bytes, 25, true);
- const output = ipv4.bytesToAddr(bytes, true);
- const expected = "192.168.1.120";
- if (output !== expected) {
- throw new Error(`'${output}' !== '${expected}'`);
- }
-});
-
-test("sanity check IPv4 recursion", () => {
- const input = "254.255.255.255";
- const bytes = ipv4.addrToBytes(input, true);
- shared.increaseAddressWithCIDR(bytes, 24, true);
- const output = ipv4.bytesToAddr(bytes, true);
- const expected = "255.0.0.255";
- if (output !== expected) {
- throw new Error(`'${output}' !== '${expected}'`);
- }
-});
-
-test("throw IPv4 address space overflow error", () => {
- const input = "255.255.255.255";
- const bytes = ipv4.addrToBytes(input, true);
- let err: Error | undefined;
- try {
- shared.increaseAddressWithCIDR(bytes, 32, true);
- } catch (e) {
- err = e;
- }
- if (err.message !== errors.OverflowedAddressSpace.message) {
- throw new Error(`unexpected: ${err}`);
- }
-});
-
-test("sanity check IPv4 applySubnetMask()", () => {
- const input = "192.168.0.248";
- const bytes = ipv4.addrToBytes(input, true);
- shared.applySubnetMask(bytes, 16);
- const output = ipv4.bytesToAddr(bytes, true);
- const expected = "192.168.0.0";
- if (output !== expected) {
- throw new Error(`'${output}' !== '${expected}'`);
- }
-});
-
-test("sanity check IPv4 networksIntersect() #1", () => {
- const alpha = shared.parseNetworkString("192.168.0.0/22");
- const bravo = shared.parseNetworkString("192.168.1.0/24");
- const output = shared.networksIntersect(alpha, bravo);
- expect(output).toEqual(true);
-});
-
-test("sanity check IPv4 networksIntersect() #2", () => {
- const alpha = shared.parseNetworkString("192.168.0.0/24");
- const bravo = shared.parseNetworkString("192.168.1.0/24");
- const output = shared.networksIntersect(alpha, bravo);
- expect(output).toEqual(false);
-});
-
-test("sanity check IPv4 networksIntersect() #3", () => {
- const alpha = shared.parseNetworkString("192.168.1.0/24");
- const bravo = shared.parseNetworkString("192.168.0.0/24");
- const output = shared.networksIntersect(alpha, bravo);
- expect(output).toEqual(false);
-});
-
-test("addrToBytes throws addrInvalidInteger", () => {
- try {
- ipv4.addrToBytes("-1.1.1.1", true);
- } catch (e) {
- expect(e.message).toEqual(errors.AddrInvalidInteger.message);
- }
-});
-
-test("addrToBytes does not throw addrInvalidInteger", () => {
- const output = ipv4.addrToBytes("-1.1.1.1", false);
- expect(output).toEqual(null);
-});
-
-test("addrToBytes throws addrNotFourElements", () => {
- try {
- ipv4.addrToBytes("1.2.3.4.5", true);
- } catch (e) {
- expect(e.message).toEqual(errors.AddrNotFourElements.message);
- }
-});
-
-test("addrToBytes does not throw addrNotFourElements", () => {
- const output = ipv4.addrToBytes("1.2.3.4.5", false);
- expect(output).toEqual(null);
-});
-
-test("bytesToAddr throws bytesNotFourElements", () => {
- try {
- ipv4.bytesToAddr(new Uint8Array(3), true);
- } catch (e) {
- expect(e.message).toEqual(errors.BytesNotFourElements.message);
- }
-});
-
-test("bytesToAddr returns null", () => {
- const output = ipv4.bytesToAddr(new Uint8Array(3), false);
- expect(output).toEqual(null);
-});
-
-test("sanity check ipv4.randomAddress", () => {
- const output = ipv4.randomAddress();
- expect(index.ip(output)).toBeTruthy();
-});
-
-test("sanity check ipv4.randomNetwork", () => {
- const output = ipv4.randomNetwork();
- expect(index.network(output)).toBeTruthy();
-});
diff --git a/src/tests/IPv6.test.ts b/src/tests/IPv6.test.ts
deleted file mode 100644
index 45056f3..0000000
--- a/src/tests/IPv6.test.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import * as index from "../index";
-import * as shared from "../shared";
-import * as ipv6 from "../IPv6";
-
-test("sanity check IPv6 offset by /128", () => {
- const input = "2001:db8:122:344::";
- const bytes = ipv6.addrToBytes(input, true);
- shared.increaseAddressWithCIDR(bytes, 128, true);
- const output = ipv6.bytesToAddr(bytes, true);
- const expected = "2001:db8:122:344::1";
- if (output !== expected) {
- throw new Error(`'${output}' !== '${expected}'`);
- }
-});
-
-test("sanity check IPv6 negative offset by /128", () => {
- const input = "2001:db8:122:344::";
- const bytes = ipv6.addrToBytes(input, true);
- shared.decreaseAddressWithCIDR(bytes, 128, true);
- const output = ipv6.bytesToAddr(bytes, true);
- const expected = "2001:db8:122:343:ffff:ffff:ffff:ffff";
- if (output !== expected) {
- throw new Error(`'${output}' !== '${expected}'`);
- }
-});
-
-test("sanity check IPv6 applySubnetMask()", () => {
- const input = "b011:a2c2:7328:cc01:4ee7:e2ec:6269:babf";
- const bytes = ipv6.addrToBytes(input, true);
- shared.applySubnetMask(bytes, 64);
- const output = ipv6.bytesToAddr(bytes, true);
- const expected = "b011:a2c2:7328:cc01::";
- if (output !== expected) {
- throw new Error(`'${output}' !== '${expected}'`);
- }
-});
-
-test("sanity check convertedEmbeddedIPv4", () => {
- const output = ipv6.convertEmbeddedIPv4("2001:db8:122:344::192.0.2.33");
- expect(output).toEqual("2001:db8:122:344::c00:221");
-});
-
-test("sanity check ipv6.bytesToAddr", () => {
- const output = ipv6.bytesToAddr(new Uint8Array(3));
- expect(output).toEqual(null);
-});
-
-test("sanity check ipv6.randomAddress", () => {
- const output = ipv6.randomAddress();
- expect(index.ip(output)).toBeTruthy();
-});
-
-test("sanity check ipv6.randomNetwork", () => {
- const output = ipv6.randomNetwork();
- expect(index.network(output)).toBeTruthy();
-});
diff --git a/src/tests/address.test.ts b/src/tests/address.test.ts
new file mode 100644
index 0000000..c282a0b
--- /dev/null
+++ b/src/tests/address.test.ts
@@ -0,0 +1,51 @@
+import { Address } from "../address";
+
+test("sanity check bytes #1", () => {
+ const output = new Address("192.168.0.0").bytes();
+ expect(output).toEqual([192, 168, 0, 0]);
+});
+
+test("sanity check bytes #2", () => {
+ const output = new Address();
+ expect(output.bytes()).toEqual([]);
+});
+
+test("sanity check setBytes #1", () => {
+ const output = new Address().setBytes([192, 168, 0, 4]);
+ expect(`${output}`).toEqual("192.168.0.4");
+});
+
+test("sanity check setBytes #2", () => {
+ const output = new Address().setBytes([0, 2]);
+ expect(`${output}`).toEqual("");
+});
+
+test("sanity check destroy #1", () => {
+ const output = new Address("192.168.0.0");
+ expect(`${output.destroy()}`).toEqual("");
+});
+
+test("sanity check toNetwork #1", () => {
+ const output = new Address("192.168.0.5");
+ expect(`${output.toNetwork()}`).toEqual("192.168.0.5/32");
+});
+
+test("sanity check increase #1", () => {
+ const output = new Address("192.168.0.5");
+ expect(`${output.increase(31)}`).toEqual("192.168.0.7");
+});
+
+test("sanity check decrease #1", () => {
+ const output = new Address("192.168.0.5");
+ expect(`${output.decrease(31)}`).toEqual("192.168.0.3");
+});
+
+test("sanity check next #1", () => {
+ const output = new Address("192.168.0.5");
+ expect(`${output.next()}`).toEqual("192.168.0.6");
+});
+
+test("sanity check previous #1", () => {
+ const output = new Address("192.168.0.5");
+ expect(`${output.previous()}`).toEqual("192.168.0.4");
+});
diff --git a/src/tests/index.test.ts b/src/tests/index.test.ts
index 3daa660..80444e8 100644
--- a/src/tests/index.test.ts
+++ b/src/tests/index.test.ts
@@ -345,12 +345,12 @@ test("sanity check sort #3", () => {
});
test("sanity check summarize #1", () => {
- const output = index.summarize(["192.168.0.0/16", "192.168.1.1", "192.168.2.3/31"], true);
+ const output = index.summarize(["192.168.0.0/16", "192.168.1.1", "192.168.2.3/31"], false, true);
expect(output).toEqual(["192.168.0.0/16"]);
});
test("sanity check summarize #2", () => {
- const output = index.summarize(["192.168.0.0/16", "::1", "192.168.1.1", "192.168.2.3/31"], true);
+ const output = index.summarize(["192.168.0.0/16", "::1", "192.168.1.1", "192.168.2.3/31"], false, true);
expect(output).toEqual(["192.168.0.0/16", "::1/128"]);
});
@@ -368,7 +368,7 @@ test("sanity check summarize #4", () => {
test("sanity check IPv6 parsing #1", () => {
const output = index.ip("[2001:db8::1]:80");
- // expect(output).toEqual("2001:db8::1");
+ expect(output).toEqual("2001:db8::1");
});
test("sanity check IPv6 parsing #2", () => {
@@ -383,7 +383,7 @@ test("sanity check IPv6 parsing #3", () => {
test("sanity check IPv6 parsing #4", () => {
const output = index.ip("2001:db8::1 port 80");
- // expect(output).toEqual("2001:db8::1");
+ expect(output).toEqual("2001:db8::1");
});
test("sanity check IPv6 parsing #5", () => {
diff --git a/src/tests/ipv4.test.ts b/src/tests/ipv4.test.ts
new file mode 100644
index 0000000..dcb0b37
--- /dev/null
+++ b/src/tests/ipv4.test.ts
@@ -0,0 +1,66 @@
+import * as index from "../index";
+import * as ipv4 from "../ipv4";
+import { Network } from "../network";
+import { Address } from "../address";
+
+test("sanity check IPv4 offset by /32", () => {
+ const addr = new Address("192.168.0.0");
+ expect(addr.next().toString()).toEqual("192.168.0.1");
+});
+
+test("sanity check IPv4 negative offset by /32", () => {
+ const addr = new Address("192.168.0.0");
+ expect(addr.previous().toString()).toEqual("192.167.255.255");
+});
+
+test("sanity check IPv4 offset by /24 with overflow", () => {
+ const addr = new Network("192.168.255.0/24");
+ expect(addr.next().toString()).toEqual("192.169.0.0/24");
+});
+
+test("sanity check IPv4 offset by /25 with overflow", () => {
+ const addr = new Address("192.168.0.248");
+ expect(addr.increase(25).toString()).toEqual("192.168.1.120");
+});
+
+test("sanity check IPv4 recursion", () => {
+ const addr = new Address("254.255.255.255", true);
+ expect(addr.increase(24, true).toString()).toEqual("255.0.0.255");
+});
+
+test("sanity check IPv4 address space overflow error", () => {
+ const addr = new Address("255.255.255.255", true);
+ expect(addr.next().toString()).toEqual("");
+});
+
+test("sanity check IPv4 applySubnetMask()", () => {
+ const addr = new Address("192.168.0.248", true);
+ expect(addr.applySubnetMask(16).toString()).toEqual("192.168.0.0");
+});
+
+test("sanity check IPv4 intersects() #1", () => {
+ const alpha = new Network("192.168.0.0/22");
+ const bravo = new Network("192.168.1.0/24");
+ expect(alpha.intersects(bravo)).toEqual(true);
+});
+
+test("sanity check IPv4 intersects() #2", () => {
+ const alpha = new Network("192.168.0.0/24");
+ const bravo = new Network("192.168.1.0/24");
+ expect(alpha.intersects(bravo)).toEqual(false);
+});
+
+test("sanity check IPv4 intersects() #3", () => {
+ const alpha = new Network("192.168.1.0/24");
+ const bravo = new Network("192.168.0.0/24");
+ expect(alpha.intersects(bravo)).toEqual(false);
+});
+
+test("sanity check ipv4.randomAddress", () => {
+ const output = ipv4.randomAddress();
+ expect(index.ip(output)).toBeTruthy();
+});
+
+test("sanity check ipv4.randomNetwork", () => {
+ expect(ipv4.randomNetwork().toString()).toBeTruthy();
+});
diff --git a/src/tests/ipv6.test.ts b/src/tests/ipv6.test.ts
new file mode 100644
index 0000000..10453ce
--- /dev/null
+++ b/src/tests/ipv6.test.ts
@@ -0,0 +1,32 @@
+import * as ipv6 from "../ipv6";
+import { Address } from "../address";
+
+test("sanity check IPv6 offset by /128", () => {
+ const addr = new Address("2001:db8:122:344::");
+ expect(addr.next().toString()).toEqual("2001:db8:122:344::1");
+});
+
+test("sanity check IPv6 negative offset by /128", () => {
+ const addr = new Address("2001:db8:122:344::");
+ expect(addr.previous().toString()).toEqual("2001:db8:122:343:ffff:ffff:ffff:ffff");
+});
+
+test("sanity check IPv6 applySubnetMask()", () => {
+ const addr = new Address("b011:a2c2:7328:cc01:4ee7:e2ec:6269:babf");
+ expect(addr.applySubnetMask(64).toString()).toEqual("b011:a2c2:7328:cc01::");
+});
+
+test("sanity check embedded IPv4", () => {
+ const addr = new Address("2001:db8:122:344::192.0.2.33", true);
+ expect(addr.toString()).toEqual("2001:db8:122:344::c000:221");
+});
+
+test("sanity check ipv6.randomAddress", () => {
+ const addr = ipv6.randomAddress();
+ expect(addr.toString()).not.toEqual("");
+});
+
+test("sanity check ipv6.randomNetwork", () => {
+ const addr = ipv6.randomNetwork();
+ expect(addr.toString()).not.toEqual("");
+});
diff --git a/src/tests/match.test.ts b/src/tests/match.test.ts
index 575f6d2..2abf85a 100644
--- a/src/tests/match.test.ts
+++ b/src/tests/match.test.ts
@@ -171,3 +171,25 @@ test("sanity check Matcher #8", () => {
const matcher = new match.Matcher(input);
expect(matcher.has("192.168.0.255")).toEqual(true);
});
+
+test("sanity check Matcher #9", () => {
+ const input = [
+ "192.168.0.24/32",
+ "192.168.0.52/32",
+ "192.168.0.171/32",
+ "192.168.0.222/32",
+ "192.168.0.124/32",
+ "192.168.0.123/32",
+ "192.168.0.234/32",
+ "192.168.0.254/31",
+ "192.168.0.0/32",
+ "192.168.0.3/32",
+ "192.168.0.170/32",
+ "192.168.0.125/32"
+ ];
+ const matcher = new match.Matcher();
+ input.forEach((s: string) => {
+ matcher.add(s);
+ });
+ expect(matcher.has("192.168.0.255")).toEqual(true);
+});
diff --git a/src/tests/shared.test.ts b/src/tests/shared.test.ts
index 136330c..a7a7688 100644
--- a/src/tests/shared.test.ts
+++ b/src/tests/shared.test.ts
@@ -1,34 +1,26 @@
import * as shared from "../shared";
-test("sanity check setAddress #1", () => {
- shared.setAddress(new Uint8Array(4), new Uint8Array(16));
-});
-
-test("sanity check setAddress #2", () => {
- shared.setAddress(new Uint8Array(16), new Uint8Array(4));
-});
-
-test("sanity check compareAddresses #1", () => {
- const output = shared.compareAddresses(new Uint8Array(4), new Uint8Array(16));
- expect(output).toEqual(shared.Pos.before);
+test("sanity check getCIDR #1", () => {
+ const output = shared.getCIDR("192.168.0.0/128");
+ expect(output).toEqual(null);
});
-test("sanity check compareAddresses #2", () => {
- const output = shared.compareAddresses(new Uint8Array(16), new Uint8Array(4));
- expect(output).toEqual(shared.Pos.after);
+test("sanity check getCIDR #2", () => {
+ const output = shared.getCIDR("192.168.0.0/24abc");
+ expect(output).toEqual(null);
});
-test("sanity check increaseAddressWithCIDR #1", () => {
- const output = shared.increaseAddressWithCIDR(new Uint8Array([255, 255, 255, 255]), 32);
- expect(output).toEqual(null);
+test("sanity check getCIDR #3", () => {
+ const output = shared.getCIDR("192.168.0.0/24");
+ expect(output).toEqual(24);
});
-test("sanity check decreaseAddressWithCIDR #1", () => {
- const output = shared.decreaseAddressWithCIDR(new Uint8Array([0, 0, 0, 0]), 32);
+test("sanity check parseBaseNetwork #1", () => {
+ const output = shared.parseBaseNetwork("192.168.0.4/24", true);
expect(output).toEqual(null);
});
-test("sanity check parseAddressString #1", () => {
- const output = shared.parseAddressString("foobar");
- expect(output).toEqual(null);
+test("sanity check parseBaseNetwork #2", () => {
+ const output = shared.parseBaseNetwork("192.168.0.4/24", false);
+ expect(output.toString()).toEqual("192.168.0.0/24");
});
diff --git a/src/tests/sort.test.ts b/src/tests/sort.test.ts
index 4cc970a..6cddcc2 100644
--- a/src/tests/sort.test.ts
+++ b/src/tests/sort.test.ts
@@ -1,62 +1,112 @@
-import * as shared from "../shared";
import * as sort from "../sort";
+import * as ipv4 from "../ipv6";
+import { Network } from "../network";
test("sanity check binarySearchForInsertionIndex #1", () => {
- const inputNetwork = shared.parseNetworkString("192.168.0.122/32");
+ const inputNetwork = new Network("192.168.0.122/32");
const inputArray = [
- shared.parseNetworkString("192.168.0.0/32"),
- shared.parseNetworkString("192.168.0.3/32"),
- shared.parseNetworkString("192.168.0.24/32"),
- shared.parseNetworkString("192.168.0.52/32"),
- shared.parseNetworkString("192.168.0.123/32"),
- shared.parseNetworkString("192.168.0.124/32"),
- shared.parseNetworkString("192.168.0.125/32"),
- shared.parseNetworkString("192.168.0.170/32"),
- shared.parseNetworkString("192.168.0.171/32"),
- shared.parseNetworkString("192.168.0.222/32"),
- shared.parseNetworkString("192.168.0.234/32"),
- shared.parseNetworkString("192.168.0.255/32")
+ new Network("192.168.0.0/32"),
+ new Network("192.168.0.3/32"),
+ new Network("192.168.0.24/32"),
+ new Network("192.168.0.52/32"),
+ new Network("192.168.0.123/32"),
+ new Network("192.168.0.124/32"),
+ new Network("192.168.0.125/32"),
+ new Network("192.168.0.170/32"),
+ new Network("192.168.0.171/32"),
+ new Network("192.168.0.222/32"),
+ new Network("192.168.0.234/32"),
+ new Network("192.168.0.255/32")
];
const output = sort.binarySearchForInsertionIndex(inputNetwork, inputArray);
expect(output).toEqual(4);
});
test("sanity check binarySearchForInsertionIndex #2", () => {
- const inputNetwork = shared.parseNetworkString("192.168.0.255/32");
+ const inputNetwork = new Network("192.168.0.255/32");
const inputArray = [
- shared.parseNetworkString("192.168.0.0/32"),
- shared.parseNetworkString("192.168.0.3/32"),
- shared.parseNetworkString("192.168.0.24/32"),
- shared.parseNetworkString("192.168.0.52/32"),
- shared.parseNetworkString("192.168.0.123/32"),
- shared.parseNetworkString("192.168.0.124/32"),
- shared.parseNetworkString("192.168.0.125/32"),
- shared.parseNetworkString("192.168.0.170/32"),
- shared.parseNetworkString("192.168.0.171/32"),
- shared.parseNetworkString("192.168.0.222/32"),
- shared.parseNetworkString("192.168.0.234/32"),
- shared.parseNetworkString("192.168.0.254/31")
+ new Network("192.168.0.0/32"),
+ new Network("192.168.0.3/32"),
+ new Network("192.168.0.24/32"),
+ new Network("192.168.0.52/32"),
+ new Network("192.168.0.123/32"),
+ new Network("192.168.0.124/32"),
+ new Network("192.168.0.125/32"),
+ new Network("192.168.0.170/32"),
+ new Network("192.168.0.171/32"),
+ new Network("192.168.0.222/32"),
+ new Network("192.168.0.234/32"),
+ new Network("192.168.0.254/31")
];
const output = sort.binarySearchForInsertionIndex(inputNetwork, inputArray);
expect(output).toEqual(12);
});
test("sanity check binarySearchForInsertionIndex #3", () => {
- const inputNetwork = shared.parseNetworkString("192.168.0.255/32");
+ const inputNetwork = new Network("192.168.0.255/32");
const inputArray = [
- shared.parseNetworkString("192.168.0.0/32"),
- shared.parseNetworkString("192.168.0.3/32"),
- shared.parseNetworkString("192.168.0.24/32"),
- shared.parseNetworkString("192.168.0.52/32"),
- shared.parseNetworkString("192.168.0.123/32"),
- shared.parseNetworkString("192.168.0.124/32"),
- shared.parseNetworkString("192.168.0.125/32"),
- shared.parseNetworkString("192.168.0.170/32"),
- shared.parseNetworkString("192.168.0.171/32"),
- shared.parseNetworkString("192.168.0.222/32"),
- shared.parseNetworkString("192.168.0.234/32"),
- shared.parseNetworkString("192.168.0.255/32")
+ new Network("192.168.0.0/32"),
+ new Network("192.168.0.3/32"),
+ new Network("192.168.0.24/32"),
+ new Network("192.168.0.52/32"),
+ new Network("192.168.0.123/32"),
+ new Network("192.168.0.124/32"),
+ new Network("192.168.0.125/32"),
+ new Network("192.168.0.170/32"),
+ new Network("192.168.0.171/32"),
+ new Network("192.168.0.222/32"),
+ new Network("192.168.0.234/32"),
+ new Network("192.168.0.255/32")
];
const output = sort.binarySearchForInsertionIndex(inputNetwork, inputArray);
expect(output).toEqual(11);
});
+
+test("sanity check binarySearchForInsertionIndex #4", () => {
+ const before = [
+ new Network("45.153.242.35/31"),
+ new Network("143.80.146.80/28"),
+ new Network("192.238.208.227/29"),
+ new Network("160.187.236.173/29"),
+ new Network("18.47.206.111/30"),
+ new Network("29.141.134.6/26"),
+ new Network("91.216.183.86/26"),
+ new Network("23.232.169.130/31"),
+ new Network("28.118.179.165/30"),
+ new Network("116.112.231.148/30")
+ ];
+ const after = [];
+ before.forEach((net: Network) => {
+ var idx = sort.binarySearchForInsertionIndex(net, after);
+ after.splice(idx, 0, net);
+ });
+ expect(after).toEqual([
+ new Network("18.47.206.111/30"),
+ new Network("23.232.169.130/31"),
+ new Network("28.118.179.165/30"),
+ new Network("29.141.134.6/26"),
+ new Network("45.153.242.35/31"),
+ new Network("91.216.183.86/26"),
+ new Network("116.112.231.148/30"),
+ new Network("143.80.146.80/28"),
+ new Network("160.187.236.173/29"),
+ new Network("192.238.208.227/29")
+ ]);
+});
+
+test("cross check all sorting methods", () => {
+ const alpha = Array.from(Array(10000), () => ipv4.randomNetwork());
+ const bravo = Array.from(alpha, (net: Network) => net.duplicate());
+ const charlie = Array.from(alpha, (net: Network) => net.duplicate());
+
+ const sortedAlpha = sort.insertionSort(alpha);
+ const sortedBravo = sort.radixSort(bravo);
+ const sortedCharlie = sort.nativeSort(charlie);
+
+ const sortedAlphaStrings = Array.from(sortedAlpha, (net: Network) => net.toString());
+ const sortedBravoStrings = Array.from(sortedBravo, (net: Network) => net.toString());
+ const sortedCharlieStrings = Array.from(sortedCharlie, (net: Network) => net.toString());
+
+ expect(sortedAlphaStrings).toEqual(sortedBravoStrings);
+ expect(sortedAlphaStrings).toEqual(sortedCharlieStrings);
+});