diff --git a/.gitignore b/.gitignore index f2ec1ab..41c1cbf 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ node_modules lib +temp diff --git a/.npmignore b/.npmignore index d6c290b..aa3b212 100644 --- a/.npmignore +++ b/.npmignore @@ -1,14 +1,5 @@ -logs -*.log - -pids -node_modules -.npm - -*.dat - -.vscode .DS_Store -config/default.json +node_modules +temp diff --git a/.vscode/settings.json b/.vscode/settings.json index 47c34b1..d614293 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,6 +3,7 @@ "files.exclude": { "*.lock": true, "lib/": true, - "node_modules/": true + "node_modules/": true, + "temp/": true } } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index c1abecd..e97c815 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,6 +1,18 @@ { "version": "2.0.0", "tasks": [ + { + "label": "Full development mode", + "detail": "Run all Watch scripts", + "group": "build", + "dependsOn": [ + "TypeScript - Watch", + "Test - Watch", + "API - Watch" + ], + "isBackground": true, + "problemMatcher": [] + }, { "type": "npm", "script": "watch", @@ -8,24 +20,27 @@ "$tsc-watch" ], "group": "build", - "label": "npm: watch", - "detail": "tsc -w", - "isBackground": true, - "runOptions": { - "runOn": "folderOpen" - } + "label": "TypeScript - Watch", + "detail": "Run tsc in watch mode", + "isBackground": true }, { "type": "npm", "script": "watch-test", "group": "test", "problemMatcher": [], - "label": "npm: watch-test", - "detail": "nodemon -w lib -e js lib/test.js", - "isBackground": true, - "runOptions": { - "runOn": "folderOpen" - } + "label": "Test - Watch", + "detail": "Run lib/test.js with sourcemap", + "isBackground": true + }, + { + "type": "npm", + "script": "watch-api", + "group": "build", + "problemMatcher": [], + "label": "API - Watch", + "detail": "api-extractor", + "isBackground": true } ] } \ No newline at end of file diff --git a/api-extractor.json b/api-extractor.json new file mode 100644 index 0000000..5100d4b --- /dev/null +++ b/api-extractor.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", + "mainEntryPointFilePath": "/lib/index.d.ts", + "apiReport": { + "enabled": true, + "reportFolder": "/api" + }, + "docModel": { + "enabled": true + }, + "dtsRollup": { + "enabled": true, + "omitTrimmingComments": true, + "untrimmedFilePath": "/api/untrimmed.d.ts", + "publicTrimmedFilePath": "/api/index.d.ts" + }, + "messages": { + "extractorMessageReporting": { + "ae-missing-release-tag": { + "logLevel": "none" + } + } + }, + "tsdocMetadata": { + "enabled": false + } +} \ No newline at end of file diff --git a/api/index.d.ts b/api/index.d.ts new file mode 100644 index 0000000..f513b65 --- /dev/null +++ b/api/index.d.ts @@ -0,0 +1,214 @@ +/** + * Library mostly focused on IP matching, but with some other fancy goods. + * Repository: https://github.com/SchoofsKelvin/ip-matching + * @packageDocumentation + */ + + +/** + * Tries to convert the given input string to an IP, aka an IPv4 or IPv6 object. + * For ease-of-use, if the input is already an IPv4 or IPv6, it is returned. + * @throws Errors if the given input format matches an IPv4/IPv6 address well enough, but is still invalid. + */ +export declare function getIP(input: string | IP): IP | null; + +/** + * Converts a string to an IPMatch object. This correspondends either to + * an IPv4, IPv4, IPRange or IPSubnetwork object, all extending the IPMatch class. + * For ease-of-use, if the given input is an IPMatch object, that object itself is returned. + * @param input - The input string to convert, or IPMatch object to return. + * @returns Returns an IPMatch for the given string (or returns the given IPMatch itself) + */ +export declare function getMatch(input: string | IPMatch): IPMatch; + +/** Represents either an IPv4 or an IPv6, aka single addresses */ +export declare type IP = IPv4 | IPv6; + +/** Represents an IP mask. The combination of an IP and a mask. A more complex version of IPSubnetwork. */ +export declare class IPMask extends IPMatch { + readonly ip: IP; + readonly mask: IP; + readonly type = "IPSubnetwork"; + readonly input: string; + constructor(ip: IP, mask: IP); + /** Checks whether the given IP matches this mask */ + matches(ip: string | IP): boolean; + equals(match: IPMatch): boolean; + /** + * Converts this IPMask to a string, by joining the IP and mask with a slash, e.g. "IP/mask". + * Does simplify the IP and mask in their IP form, but does not simplify e.g. `10.0.0.0/255.0.0.0` to `10.0.0.0/8`. + */ + toString(): string; + convertToMasks(): this[]; +} + +/** + * Superclass of the IPv4, IPv6, IPRange and IPSubnetwork classes. + * Only specifies a generic .matches() function and .type field. + * + * **Check the specific classes for more specialized methods/docs** + * e.g. IPRange comes with `convertToSubnets`, IPv6 with `toLongString`, ... + */ +export declare abstract class IPMatch { + /** String indicating the type of this IPMatch, as an alternative to `instanceof`. Check subclasses for the possible values */ + readonly type: string; + /** The string representation of this IPMatch. Not necessarily the exact input string that generated it */ + readonly input: string; + /** + * This used to be the generic way of converting a string to an IPRange/IPv4/... without assuming a type. + * This class is now made abstract with a protected constructor, in favor of the new `getMatch(input)` function. + * The abstract/deprecated/protected flag are to warn users about switching over to the new function. + * With the way TypeScript compiles them to JavaScript, this constructor still works (thus compatible with old code) + * @deprecated Use `getMatch(input: string)` instead. + */ + protected constructor(input: string | null); + /** + * Checks whether the given IP (or string to be first converted to an IP) matches this IPMatch object. + * The exact way this is checked is specific to each IPv4/IPRange/... class. Check their documentation. + */ + abstract matches(ip: string | IP): boolean; + /** Each subclass formats itself in a specific way. IPv6 also has a bunch of extra string methods. Check their documentation */ + abstract matches(ip: string | IP): boolean; + /** + * Checks whether this IPMatch equals the given match. The match type matters, e.g. the IPv4 `10.0.0.0` and + * the IPSubnetwork `10.0.0.0/32` will result in this method returning false, even though they both only match `10.0.0.0`. + */ + abstract equals(match: IPMatch): boolean; + /** + * Converts this IPMatch to a list of IPMasks (union) matching the same IPs. + * IPRange has a handy method convertToSubnets() to convert the range to an array + * of IPSubnetworks, which are basically CIDR notations. If you're looking at + * this method, you might also be interested in checking `convertToSubnets` out. + */ + abstract convertToMasks(): IPMask[]; +} + +/** Represents a range of IP addresses, according to their numerical value */ +export declare class IPRange extends IPMatch { + readonly left: IP; + readonly right: IP; + readonly type = "IPRange"; + readonly input: string; + /** Both values should be the same type (IPv4 or IPv6) and `left` should be lower in numeric value than `right` */ + constructor(left: IP, right: IP); + /** Checks whether the given IP lies in the range defined by the two bounds (inclusive) */ + matches(ip: string | IP): boolean; + equals(match: IPMatch): boolean; + /** Converts this IPRange to a string, by joining the two bounds with a dash, e.g. "IP1-IP2" */ + toString(): string; + /** Converts this IPRange to an optimized list of (CIDR) IPSubnetworks */ + convertToSubnets(): IPSubnetwork[]; + convertToMasks: () => IPMask[]; + /** Returns the first IP address in this range */ + getFirst(): IP; + /** Returns the last IP address in this range */ + getLast(): IP; + protected isLowerOrEqual(left: IP, right: IP): boolean; +} + +/** Represents a subnetwork. The combination of an IP and a (simple) mask. A simplified version of IPMask. */ +export declare class IPSubnetwork extends IPMatch { + readonly bits: number; + readonly type = "IPSubnetwork"; + readonly input: string; + protected range: IPRange; + /** Bits has to be in the range 1-32 for IPv4 and 1-128 for IPv6 */ + constructor(ip: IP, bits: number); + /** Checks whether the given IP lies in this subnetwork */ + matches(ip: string | IP): boolean; + equals(match: IPMatch): boolean; + /** Converts this IPSubnetwork to a string in CIDR representation, e.g. "IP/mask" */ + toString(): string; + convertToMasks: () => IPMask[]; + /** Returns the first IP address in this range */ + getFirst(): IP; + /** Returns the last IP address in this range */ + getLast(): IP; +} + +/** Represents an IPv4 address, optionall with wildcards */ +export declare class IPv4 extends IPMatch { + readonly type = "IPv4"; + readonly parts: number[]; + readonly input: string; + constructor(input: string); + /** + * Checks whether the given IP (or string to be first converted to an IP) matches this IPv4 object. + * - If the given string represents an IPv6 address, this method returns false. + * - In other cases, for an IPv4, we check if all 4 octets match. + * - Octets that are wildcards in this object are always assumed to match. + * - Octets that are wildcards in the input are **NOT** seen as a wildcard, e.g. + * `10.0.0.*` matches `10.0.0.3`, but the inverse would give false. + */ + matches(ip: string | IP): boolean; + equals(match: IPMatch): boolean; + /** Returns whether this IPv4 is exact (aka contains no wildcards) */ + exact(): boolean; + /** + * Returns this IPv4 in dot-decimal/quat-dotted notation. Wildcards are represented as stars. + * For example: `"10.*.0.*"` + */ + toString(): string; + convertToMasks: () => IPMask[]; + /** Returns the next address, or undefined for `255.255.255.255` */ + getNext(): IP | undefined; +} + +/** Represents an IPv6 address, optionall with wildcards */ +export declare class IPv6 extends IPMatch { + readonly type = "IPv6"; + readonly parts: number[]; + readonly input: string; + constructor(input: string); + /** + * Checks whether the given IP (or string to be first converted to an IP) matches this IPv6 object. + * - If the given string represents an IPv4 address, this method returns false. + * - In other cases, for an IPv6, we check if all 8 hextets/hexadectets match. + * - Octets that are wildcards in this object are always assumed to match. + * - Octets that are wildcards in the input are **NOT** seen as a wildcard, e.g. + * `2001::abcd:*` matches `2001::abcd:1`, but the inverse would give false. + */ + matches(ip: string | IP): boolean; + equals(match: IPMatch): boolean; + /** Returns whether this IPv4 is exact (aka contains no wildcards) */ + exact(): boolean; + /** Returns an array with the 8 hextets of this address, or `"*"` for wildcard hextets */ + toHextets(): string[]; + /** + * Returns the address in the full format, but with leading zeroes of hextets omitted. + * Hextets representing wildcards will be shown as `"*"` instead. + * Example result: `"2001:0:0:0:0:0:abc:1"` + */ + toLongString(): string; + /** + * Returns the address in the full format, but without omitting leading zeroes or hextets. + * Hextets representing wildcards will be shown as `"*"` instead. + * Example result: `"2001:0000:0000:0000:0000:0000:0abc:0001"` + */ + toFullString(): string; + /** Returns a mixed address (32 last bits representing an IPv4 address) in a mixed format e.g. "::ffff:c000:0280" as "::ffff:192.0.2.128" */ + toMixedString(): string; + /** + * Returns the address in the shortest possible format, according to RFC 5952: + * - All hexadecimal digits are lowercase (if applicable), as is the case with .toLongString(), toFullString(), ... + * - Leading zeroes of each hextet are suppressed, apart from the all-zero field which is rendered as a single zero + * - The (leftmost) longest sequence of multiple consecutive all-zero hextets is replaced with "::" + * - If this address is known to be IPv4 mapped, it is displayed as such, which currently are for e.g. 127.0.0.1: + * - `"::ffff:127.0.0.1"` + * - `"::ffff:0:127.0.0.1"` + */ + toString(): string; + convertToMasks: () => IPMask[]; + /** Returns the next address, or undefined for `ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff` */ + getNext(): IP | undefined; +} + +/** + * Checks whether the given IP matches the given whitelist + * @param ip - The IP to check, or a string to be converted to an exact IP + * @param target - The target to check against, or a string to convert to an IPMatch + * @throws Throws an error if either argument is a string but does not have a correct format + */ +export declare function matches(ip: string | IP, target: string | IPMatch): boolean; + +export { } diff --git a/api/ip-matching.api.md b/api/ip-matching.api.md new file mode 100644 index 0000000..0bcfc66 --- /dev/null +++ b/api/ip-matching.api.md @@ -0,0 +1,138 @@ +## API Report File for "ip-matching" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +// @public +export function getIP(input: string | IP): IP | null; + +// @public +export function getMatch(input: string | IPMatch): IPMatch; + +// @public +export type IP = IPv4 | IPv6; + +// @public +export class IPMask extends IPMatch { + constructor(ip: IP, mask: IP); + // (undocumented) + convertToMasks(): this[]; + // (undocumented) + equals(match: IPMatch): boolean; + // (undocumented) + readonly input: string; + // (undocumented) + readonly ip: IP; + // (undocumented) + readonly mask: IP; + matches(ip: string | IP): boolean; + toString(): string; + // (undocumented) + readonly type = "IPSubnetwork"; +} + +// @public +export abstract class IPMatch { + // @deprecated + protected constructor(input: string | null); + abstract convertToMasks(): IPMask[]; + abstract equals(match: IPMatch): boolean; + readonly input: string; + abstract matches(ip: string | IP): boolean; + abstract matches(ip: string | IP): boolean; + readonly type: string; +} + +// @public +export class IPRange extends IPMatch { + constructor(left: IP, right: IP); + // (undocumented) + convertToMasks: () => IPMask[]; + convertToSubnets(): IPSubnetwork[]; + // (undocumented) + equals(match: IPMatch): boolean; + getFirst(): IP; + getLast(): IP; + // (undocumented) + readonly input: string; + // (undocumented) + protected isLowerOrEqual(left: IP, right: IP): boolean; + // (undocumented) + readonly left: IP; + matches(ip: string | IP): boolean; + // (undocumented) + readonly right: IP; + toString(): string; + // (undocumented) + readonly type = "IPRange"; +} + +// @public +export class IPSubnetwork extends IPMatch { + constructor(ip: IP, bits: number); + // (undocumented) + readonly bits: number; + // (undocumented) + convertToMasks: () => IPMask[]; + // (undocumented) + equals(match: IPMatch): boolean; + getFirst(): IP; + getLast(): IP; + // (undocumented) + readonly input: string; + matches(ip: string | IP): boolean; + // (undocumented) + protected range: IPRange; + toString(): string; + // (undocumented) + readonly type = "IPSubnetwork"; +} + +// @public +export class IPv4 extends IPMatch { + constructor(input: string); + // (undocumented) + convertToMasks: () => IPMask[]; + // (undocumented) + equals(match: IPMatch): boolean; + exact(): boolean; + getNext(): IP | undefined; + // (undocumented) + readonly input: string; + matches(ip: string | IP): boolean; + // (undocumented) + readonly parts: number[]; + toString(): string; + // (undocumented) + readonly type = "IPv4"; +} + +// @public +export class IPv6 extends IPMatch { + constructor(input: string); + // (undocumented) + convertToMasks: () => IPMask[]; + // (undocumented) + equals(match: IPMatch): boolean; + exact(): boolean; + getNext(): IP | undefined; + // (undocumented) + readonly input: string; + matches(ip: string | IP): boolean; + // (undocumented) + readonly parts: number[]; + toFullString(): string; + toHextets(): string[]; + toLongString(): string; + toMixedString(): string; + toString(): string; + // (undocumented) + readonly type = "IPv6"; +} + +// @public +export function matches(ip: string | IP, target: string | IPMatch): boolean; + + +``` diff --git a/api/untrimmed.d.ts b/api/untrimmed.d.ts new file mode 100644 index 0000000..f513b65 --- /dev/null +++ b/api/untrimmed.d.ts @@ -0,0 +1,214 @@ +/** + * Library mostly focused on IP matching, but with some other fancy goods. + * Repository: https://github.com/SchoofsKelvin/ip-matching + * @packageDocumentation + */ + + +/** + * Tries to convert the given input string to an IP, aka an IPv4 or IPv6 object. + * For ease-of-use, if the input is already an IPv4 or IPv6, it is returned. + * @throws Errors if the given input format matches an IPv4/IPv6 address well enough, but is still invalid. + */ +export declare function getIP(input: string | IP): IP | null; + +/** + * Converts a string to an IPMatch object. This correspondends either to + * an IPv4, IPv4, IPRange or IPSubnetwork object, all extending the IPMatch class. + * For ease-of-use, if the given input is an IPMatch object, that object itself is returned. + * @param input - The input string to convert, or IPMatch object to return. + * @returns Returns an IPMatch for the given string (or returns the given IPMatch itself) + */ +export declare function getMatch(input: string | IPMatch): IPMatch; + +/** Represents either an IPv4 or an IPv6, aka single addresses */ +export declare type IP = IPv4 | IPv6; + +/** Represents an IP mask. The combination of an IP and a mask. A more complex version of IPSubnetwork. */ +export declare class IPMask extends IPMatch { + readonly ip: IP; + readonly mask: IP; + readonly type = "IPSubnetwork"; + readonly input: string; + constructor(ip: IP, mask: IP); + /** Checks whether the given IP matches this mask */ + matches(ip: string | IP): boolean; + equals(match: IPMatch): boolean; + /** + * Converts this IPMask to a string, by joining the IP and mask with a slash, e.g. "IP/mask". + * Does simplify the IP and mask in their IP form, but does not simplify e.g. `10.0.0.0/255.0.0.0` to `10.0.0.0/8`. + */ + toString(): string; + convertToMasks(): this[]; +} + +/** + * Superclass of the IPv4, IPv6, IPRange and IPSubnetwork classes. + * Only specifies a generic .matches() function and .type field. + * + * **Check the specific classes for more specialized methods/docs** + * e.g. IPRange comes with `convertToSubnets`, IPv6 with `toLongString`, ... + */ +export declare abstract class IPMatch { + /** String indicating the type of this IPMatch, as an alternative to `instanceof`. Check subclasses for the possible values */ + readonly type: string; + /** The string representation of this IPMatch. Not necessarily the exact input string that generated it */ + readonly input: string; + /** + * This used to be the generic way of converting a string to an IPRange/IPv4/... without assuming a type. + * This class is now made abstract with a protected constructor, in favor of the new `getMatch(input)` function. + * The abstract/deprecated/protected flag are to warn users about switching over to the new function. + * With the way TypeScript compiles them to JavaScript, this constructor still works (thus compatible with old code) + * @deprecated Use `getMatch(input: string)` instead. + */ + protected constructor(input: string | null); + /** + * Checks whether the given IP (or string to be first converted to an IP) matches this IPMatch object. + * The exact way this is checked is specific to each IPv4/IPRange/... class. Check their documentation. + */ + abstract matches(ip: string | IP): boolean; + /** Each subclass formats itself in a specific way. IPv6 also has a bunch of extra string methods. Check their documentation */ + abstract matches(ip: string | IP): boolean; + /** + * Checks whether this IPMatch equals the given match. The match type matters, e.g. the IPv4 `10.0.0.0` and + * the IPSubnetwork `10.0.0.0/32` will result in this method returning false, even though they both only match `10.0.0.0`. + */ + abstract equals(match: IPMatch): boolean; + /** + * Converts this IPMatch to a list of IPMasks (union) matching the same IPs. + * IPRange has a handy method convertToSubnets() to convert the range to an array + * of IPSubnetworks, which are basically CIDR notations. If you're looking at + * this method, you might also be interested in checking `convertToSubnets` out. + */ + abstract convertToMasks(): IPMask[]; +} + +/** Represents a range of IP addresses, according to their numerical value */ +export declare class IPRange extends IPMatch { + readonly left: IP; + readonly right: IP; + readonly type = "IPRange"; + readonly input: string; + /** Both values should be the same type (IPv4 or IPv6) and `left` should be lower in numeric value than `right` */ + constructor(left: IP, right: IP); + /** Checks whether the given IP lies in the range defined by the two bounds (inclusive) */ + matches(ip: string | IP): boolean; + equals(match: IPMatch): boolean; + /** Converts this IPRange to a string, by joining the two bounds with a dash, e.g. "IP1-IP2" */ + toString(): string; + /** Converts this IPRange to an optimized list of (CIDR) IPSubnetworks */ + convertToSubnets(): IPSubnetwork[]; + convertToMasks: () => IPMask[]; + /** Returns the first IP address in this range */ + getFirst(): IP; + /** Returns the last IP address in this range */ + getLast(): IP; + protected isLowerOrEqual(left: IP, right: IP): boolean; +} + +/** Represents a subnetwork. The combination of an IP and a (simple) mask. A simplified version of IPMask. */ +export declare class IPSubnetwork extends IPMatch { + readonly bits: number; + readonly type = "IPSubnetwork"; + readonly input: string; + protected range: IPRange; + /** Bits has to be in the range 1-32 for IPv4 and 1-128 for IPv6 */ + constructor(ip: IP, bits: number); + /** Checks whether the given IP lies in this subnetwork */ + matches(ip: string | IP): boolean; + equals(match: IPMatch): boolean; + /** Converts this IPSubnetwork to a string in CIDR representation, e.g. "IP/mask" */ + toString(): string; + convertToMasks: () => IPMask[]; + /** Returns the first IP address in this range */ + getFirst(): IP; + /** Returns the last IP address in this range */ + getLast(): IP; +} + +/** Represents an IPv4 address, optionall with wildcards */ +export declare class IPv4 extends IPMatch { + readonly type = "IPv4"; + readonly parts: number[]; + readonly input: string; + constructor(input: string); + /** + * Checks whether the given IP (or string to be first converted to an IP) matches this IPv4 object. + * - If the given string represents an IPv6 address, this method returns false. + * - In other cases, for an IPv4, we check if all 4 octets match. + * - Octets that are wildcards in this object are always assumed to match. + * - Octets that are wildcards in the input are **NOT** seen as a wildcard, e.g. + * `10.0.0.*` matches `10.0.0.3`, but the inverse would give false. + */ + matches(ip: string | IP): boolean; + equals(match: IPMatch): boolean; + /** Returns whether this IPv4 is exact (aka contains no wildcards) */ + exact(): boolean; + /** + * Returns this IPv4 in dot-decimal/quat-dotted notation. Wildcards are represented as stars. + * For example: `"10.*.0.*"` + */ + toString(): string; + convertToMasks: () => IPMask[]; + /** Returns the next address, or undefined for `255.255.255.255` */ + getNext(): IP | undefined; +} + +/** Represents an IPv6 address, optionall with wildcards */ +export declare class IPv6 extends IPMatch { + readonly type = "IPv6"; + readonly parts: number[]; + readonly input: string; + constructor(input: string); + /** + * Checks whether the given IP (or string to be first converted to an IP) matches this IPv6 object. + * - If the given string represents an IPv4 address, this method returns false. + * - In other cases, for an IPv6, we check if all 8 hextets/hexadectets match. + * - Octets that are wildcards in this object are always assumed to match. + * - Octets that are wildcards in the input are **NOT** seen as a wildcard, e.g. + * `2001::abcd:*` matches `2001::abcd:1`, but the inverse would give false. + */ + matches(ip: string | IP): boolean; + equals(match: IPMatch): boolean; + /** Returns whether this IPv4 is exact (aka contains no wildcards) */ + exact(): boolean; + /** Returns an array with the 8 hextets of this address, or `"*"` for wildcard hextets */ + toHextets(): string[]; + /** + * Returns the address in the full format, but with leading zeroes of hextets omitted. + * Hextets representing wildcards will be shown as `"*"` instead. + * Example result: `"2001:0:0:0:0:0:abc:1"` + */ + toLongString(): string; + /** + * Returns the address in the full format, but without omitting leading zeroes or hextets. + * Hextets representing wildcards will be shown as `"*"` instead. + * Example result: `"2001:0000:0000:0000:0000:0000:0abc:0001"` + */ + toFullString(): string; + /** Returns a mixed address (32 last bits representing an IPv4 address) in a mixed format e.g. "::ffff:c000:0280" as "::ffff:192.0.2.128" */ + toMixedString(): string; + /** + * Returns the address in the shortest possible format, according to RFC 5952: + * - All hexadecimal digits are lowercase (if applicable), as is the case with .toLongString(), toFullString(), ... + * - Leading zeroes of each hextet are suppressed, apart from the all-zero field which is rendered as a single zero + * - The (leftmost) longest sequence of multiple consecutive all-zero hextets is replaced with "::" + * - If this address is known to be IPv4 mapped, it is displayed as such, which currently are for e.g. 127.0.0.1: + * - `"::ffff:127.0.0.1"` + * - `"::ffff:0:127.0.0.1"` + */ + toString(): string; + convertToMasks: () => IPMask[]; + /** Returns the next address, or undefined for `ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff` */ + getNext(): IP | undefined; +} + +/** + * Checks whether the given IP matches the given whitelist + * @param ip - The IP to check, or a string to be converted to an exact IP + * @param target - The target to check against, or a string to convert to an IPMatch + * @throws Throws an error if either argument is a string but does not have a correct format + */ +export declare function matches(ip: string | IP, target: string | IPMatch): boolean; + +export { } diff --git a/package.json b/package.json index bbf1855..ffbb0a7 100644 --- a/package.json +++ b/package.json @@ -3,10 +3,11 @@ "version": "1.2.1", "type": "commonjs", "main": "lib/index.js", - "types": "lib/index.d.ts", + "types": "api/index.d.ts", "description": "See whether an IPv4 or IPv6 address matches an IP (range) or subnetwork", "dependencies": {}, "devDependencies": { + "@microsoft/api-extractor": "^7.13.0", "@types/node": "^10", "nodemon": "^2.0.6", "source-map-support": "^0.5.19", @@ -17,7 +18,10 @@ "watch": "tsc -w", "test": "node lib/test.js", "watch-test": "nodemon -w lib -e js lib/test.js", - "prepublishOnly": "tsc && node lib/test.js" + "api": "api-extractor run", + "api-local": "api-extractor run -l", + "watch-api": "nodemon -w api-extractor.json -w lib -e d.ts --exec yarn api-extractor -- run -l", + "prepublishOnly": "yarn compile && yarn test && yarn api" }, "author": { "name": "Kelvin Schoofs", @@ -26,5 +30,20 @@ }, "bugs": "https://github.com/SchoofsKelvin/ip-matching/issues", "repository": "SchoofsKelvin/ip-matching", - "license": "LGPL-3.0-only" + "license": "LGPL-3.0-only", + "keywords": [ + "match", + "IP", + "address", + "IPv4", + "IPv6", + "CIDR", + "notation", + "range", + "subnet", + "subnetwork", + "net", + "network", + "mask" + ] } \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 10c8063..c711ffe 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,12 +1,18 @@ +/** + * Library mostly focused on IP matching, but with some other fancy goods. + * Repository: https://github.com/SchoofsKelvin/ip-matching + * @packageDocumentation + */ + import { getMatch, IP, IPMatch } from './ip'; export * from './ip'; /** * Checks whether the given IP matches the given whitelist - * @param ip The IP to check, or a string to be converted to an exact IP - * @param target The target to check against, or a string to convert to an IPMatch + * @param ip - The IP to check, or a string to be converted to an exact IP + * @param target - The target to check against, or a string to convert to an IPMatch * @throws Throws an error if either argument is a string but does not have a correct format */ export function matches(ip: string | IP, target: string | IPMatch): boolean { diff --git a/src/ip.ts b/src/ip.ts index 34f37d7..57a826a 100644 --- a/src/ip.ts +++ b/src/ip.ts @@ -19,7 +19,7 @@ function wildcardToNumber(max: number, radix: number = 10) { * Converts a string to an IPMatch object. This correspondends either to * an IPv4, IPv4, IPRange or IPSubnetwork object, all extending the IPMatch class. * For ease-of-use, if the given input is an IPMatch object, that object itself is returned. - * @param input The input string to convert, or IPMatch object to return. + * @param input - The input string to convert, or IPMatch object to return. * @returns Returns an IPMatch for the given string (or returns the given IPMatch itself) */ export function getMatch(input: string | IPMatch): IPMatch { diff --git a/tsconfig.json b/tsconfig.json index de2077b..3c1835e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,50 +1,16 @@ { - "include": ["src"], + "include": [ + "src" + ], "compilerOptions": { - /* Basic Options */ - "target": "es2016", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - // "lib": [], /* Specify library files to be included in the compilation: */ - // "allowJs": true, /* Allow javascript files to be compiled. */ - // "checkJs": true, /* Report errors in .js files. */ - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ - "outDir": "lib", /* Redirect output structure to the directory. */ - "rootDir": "src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ - // "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ - // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* Enable strict null checks. */ - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - /* Module Resolution Options */ - "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - //"types": ["node", "node/*"], /* Type declaration files to be included in compilation. */ - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ - /* Source Map Options */ - // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + "target": "es2016", + "module": "commonjs", + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "outDir": "lib", + "rootDir": "src", + "strict": true, + "moduleResolution": "node" } } \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index dca3b6a..84e510e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,70 @@ # yarn lockfile v1 +"@microsoft/api-extractor-model@7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@microsoft/api-extractor-model/-/api-extractor-model-7.12.1.tgz#1f10915c434048da34e1c07845ba2623d5f23f66" + integrity sha512-Hw+kYfUb1gt6xPWGFW8APtLVWeNEWz4JE6PbLkSHw/j+G1hAaStzgxhBx3GOAWM/G0SCDGVJOpd5YheVOyu/KQ== + dependencies: + "@microsoft/tsdoc" "0.12.24" + "@rushstack/node-core-library" "3.35.2" + +"@microsoft/api-extractor@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@microsoft/api-extractor/-/api-extractor-7.13.0.tgz#13900fc7596c29daeecd3f33ed8960cfc5250107" + integrity sha512-T+14VIhB91oJIett5AZ02VWYmz/01VHFWkcAOWiErIQ8AiFhJZoGqTjGxoi8ZpEEBuAj2EGVYojORwLc/+aiDQ== + dependencies: + "@microsoft/api-extractor-model" "7.12.1" + "@microsoft/tsdoc" "0.12.24" + "@rushstack/node-core-library" "3.35.2" + "@rushstack/rig-package" "0.2.9" + "@rushstack/ts-command-line" "4.7.8" + colors "~1.2.1" + lodash "~4.17.15" + resolve "~1.17.0" + semver "~7.3.0" + source-map "~0.6.1" + typescript "~4.1.3" + +"@microsoft/tsdoc@0.12.24": + version "0.12.24" + resolved "https://registry.yarnpkg.com/@microsoft/tsdoc/-/tsdoc-0.12.24.tgz#30728e34ebc90351dd3aff4e18d038eed2c3e098" + integrity sha512-Mfmij13RUTmHEMi9vRUhMXD7rnGR2VvxeNYtaGtaJ4redwwjT4UXYJ+nzmVJF7hhd4pn/Fx5sncDKxMVFJSWPg== + +"@rushstack/node-core-library@3.35.2": + version "3.35.2" + resolved "https://registry.yarnpkg.com/@rushstack/node-core-library/-/node-core-library-3.35.2.tgz#21ca879b5051a5ebafa952fafcd648a07a142bcb" + integrity sha512-SPd0uG7mwsf3E30np9afCUhtaM1SBpibrbxOXPz82KWV6SQiPUtXeQfhXq9mSnGxOb3WLWoSDe7AFxQNex3+kQ== + dependencies: + "@types/node" "10.17.13" + colors "~1.2.1" + fs-extra "~7.0.1" + import-lazy "~4.0.0" + jju "~1.4.0" + resolve "~1.17.0" + semver "~7.3.0" + timsort "~0.3.0" + z-schema "~3.18.3" + +"@rushstack/rig-package@0.2.9": + version "0.2.9" + resolved "https://registry.yarnpkg.com/@rushstack/rig-package/-/rig-package-0.2.9.tgz#57ef94e7f7703b18e275b603d3f59a1a16580716" + integrity sha512-4tqsZ/m+BjeNAGeAJYzPF53CT96TsAYeZ3Pq3T4tb1pGGM3d3TWfkmALZdKNhpRlAeShKUrb/o/f/0sAuK/1VQ== + dependencies: + "@types/node" "10.17.13" + resolve "~1.17.0" + strip-json-comments "~3.1.1" + +"@rushstack/ts-command-line@4.7.8": + version "4.7.8" + resolved "https://registry.yarnpkg.com/@rushstack/ts-command-line/-/ts-command-line-4.7.8.tgz#3aa77cf544c571be3206fc2bcba20c7a096ed254" + integrity sha512-8ghIWhkph7NnLCMDJtthpsb7TMOsVGXVDvmxjE/CeklTqjbbUFBjGXizJfpbEkRQTELuZQ2+vGn7sGwIWKN2uA== + dependencies: + "@types/argparse" "1.0.38" + argparse "~1.0.9" + colors "~1.2.1" + string-argv "~0.3.1" + "@sindresorhus/is@^0.14.0": version "0.14.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" @@ -14,6 +78,16 @@ dependencies: defer-to-connect "^1.0.1" +"@types/argparse@1.0.38": + version "1.0.38" + resolved "https://registry.yarnpkg.com/@types/argparse/-/argparse-1.0.38.tgz#a81fd8606d481f873a3800c6ebae4f1d768a56a9" + integrity sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA== + +"@types/node@10.17.13": + version "10.17.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.13.tgz#ccebcdb990bd6139cd16e84c39dc2fb1023ca90c" + integrity sha512-pMCcqU2zT4TjqYFrWtYHKal7Sl30Ims6ulZ4UFXxI4xbtQqK/qqKwkDoBFCfooRqqmRu9vY3xaJRwxSh673aYg== + "@types/node@^10": version "10.17.39" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.39.tgz#ce1122758d0608de8303667cebf171f44192629b" @@ -56,6 +130,13 @@ anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" +argparse@~1.0.9: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -170,6 +251,16 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +colors@~1.2.1: + version "1.2.5" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.2.5.tgz#89c7ad9a374bc030df8013241f68136ed8835afc" + integrity sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg== + +commander@^2.7.1: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -264,6 +355,15 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +fs-extra@~7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + fsevents@~2.1.2: version "2.1.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" @@ -314,7 +414,7 @@ got@^9.6.0: to-readable-stream "^1.0.0" url-parse-lax "^3.0.0" -graceful-fs@^4.1.2: +graceful-fs@^4.1.2, graceful-fs@^4.1.6: version "4.2.4" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== @@ -349,6 +449,11 @@ import-lazy@^2.1.0: resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= +import-lazy@~4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-4.0.0.tgz#e8eb627483a0a43da3c03f3e35548be5cb0cc153" + integrity sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw== + imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -433,11 +538,23 @@ is-yarn-global@^0.3.0: resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw== +jju@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/jju/-/jju-1.4.0.tgz#a3abe2718af241a2b2904f84a625970f389ae32a" + integrity sha1-o6vicYryQaKykE+EpiWXDzia4yo= + json-buffer@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + keyv@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" @@ -452,6 +569,21 @@ latest-version@^5.0.0: dependencies: package-json "^6.3.0" +lodash.get@^4.0.0: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= + +lodash.isequal@^4.0.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= + +lodash@~4.17.15: + version "4.17.20" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" + integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== + lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" @@ -462,6 +594,13 @@ lowercase-keys@^2.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + make-dir@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" @@ -551,6 +690,11 @@ package-json@^6.3.0: registry-url "^5.0.0" semver "^6.2.0" +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + picomatch@^2.0.4, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" @@ -612,6 +756,13 @@ registry-url@^5.0.0: dependencies: rc "^1.2.8" +resolve@~1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" + integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== + dependencies: + path-parse "^1.0.6" + responselike@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" @@ -636,6 +787,13 @@ semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@~7.3.0: + version "7.3.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" + integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== + dependencies: + lru-cache "^6.0.0" + signal-exit@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" @@ -649,11 +807,21 @@ source-map-support@^0.5.19: buffer-from "^1.0.0" source-map "^0.6.0" -source-map@^0.6.0: +source-map@^0.6.0, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +string-argv@~0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" + integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== + string-width@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" @@ -691,6 +859,11 @@ strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= +strip-json-comments@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + supports-color@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -710,6 +883,11 @@ term-size@^2.1.0: resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.1.tgz#2a6a54840432c2fb6320fea0f415531e90189f54" integrity sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg== +timsort@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" + integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= + to-readable-stream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" @@ -746,6 +924,11 @@ typescript@3.9: resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.7.tgz#98d600a5ebdc38f40cb277522f12dc800e9e25fa" integrity sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw== +typescript@~4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.3.tgz#519d582bd94cba0cf8934c7d8e8467e473f53bb7" + integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg== + undefsafe@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.3.tgz#6b166e7094ad46313b2202da7ecc2cd7cc6e7aae" @@ -760,6 +943,11 @@ unique-string@^2.0.0: dependencies: crypto-random-string "^2.0.0" +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + update-notifier@^4.1.0: version "4.1.3" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-4.1.3.tgz#be86ee13e8ce48fb50043ff72057b5bd598e1ea3" @@ -786,6 +974,11 @@ url-parse-lax@^3.0.0: dependencies: prepend-http "^2.0.0" +validator@^8.0.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-8.2.0.tgz#3c1237290e37092355344fef78c231249dab77b9" + integrity sha512-Yw5wW34fSv5spzTXNkokD6S6/Oq92d8q/t14TqsS3fAiA1RYnxSFSIZ+CY3n6PGGRCq5HhJTSepQvFUS2QUDxA== + widest-line@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" @@ -812,3 +1005,19 @@ xdg-basedir@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +z-schema@~3.18.3: + version "3.18.4" + resolved "https://registry.yarnpkg.com/z-schema/-/z-schema-3.18.4.tgz#ea8132b279533ee60be2485a02f7e3e42541a9a2" + integrity sha512-DUOKC/IhbkdLKKiV89gw9DUauTV8U/8yJl1sjf6MtDmzevLKOF2duNJ495S3MFVjqZarr+qNGCPbkg4mu4PpLw== + dependencies: + lodash.get "^4.0.0" + lodash.isequal "^4.0.0" + validator "^8.0.0" + optionalDependencies: + commander "^2.7.1"