From 69162fc8430fbffc04f1c3fcf0ce6e9c45e8a8f8 Mon Sep 17 00:00:00 2001 From: Johannes Ewald Date: Sat, 10 Aug 2019 20:08:49 +0200 Subject: [PATCH] fix: Fix bug when parsing private TLDs (#79) Fixes #67 --- lists/icann.complete.js | 4 +- lists/icann.light.js | 4 +- lists/private.complete.js | 4 +- package-lock.json | 207 ++++++++++++++---- scripts/build-tries.js | 6 +- src/parseDomain.js | 36 +-- .../separators.js => trie/characters.js} | 2 + src/trie/lookUp.js | 31 +++ src/trie/nodes.js | 37 ++++ src/trie/parse.js | 53 +++++ src/{tries => trie}/parsePubSuffixList.js | 0 src/{tries => trie}/serializeTrie.js | 12 +- src/tries/lookUp.js | 37 ---- src/tries/parseTrie.js | 56 ----- test/parseDomain.test.js | 125 ++++++++++- test/snapshots.test.js | 25 +-- test/trie/lookUp.test.js | 99 +++++++++ test/trie/nodes.test.js | 22 ++ test/trie/parse.test.js | 143 ++++++++++++ .../parsePubSuffixList.test.js | 2 +- test/{tries => trie}/serializeTrie.test.js | 2 +- test/tries/lookUp.test.js | 116 ---------- test/tries/parseTrie.test.js | 162 -------------- 23 files changed, 715 insertions(+), 470 deletions(-) rename src/{tries/separators.js => trie/characters.js} (62%) create mode 100644 src/trie/lookUp.js create mode 100644 src/trie/nodes.js create mode 100644 src/trie/parse.js rename src/{tries => trie}/parsePubSuffixList.js (100%) rename src/{tries => trie}/serializeTrie.js (92%) delete mode 100644 src/tries/lookUp.js delete mode 100644 src/tries/parseTrie.js create mode 100644 test/trie/lookUp.test.js create mode 100644 test/trie/nodes.test.js create mode 100644 test/trie/parse.test.js rename test/{tries => trie}/parsePubSuffixList.test.js (98%) rename test/{tries => trie}/serializeTrie.test.js (98%) delete mode 100644 test/tries/lookUp.test.js delete mode 100644 test/tries/parseTrie.test.js diff --git a/lists/icann.complete.js b/lists/icann.complete.js index 89e014f..414f64c 100644 --- a/lists/icann.complete.js +++ b/lists/icann.complete.js @@ -1,5 +1,5 @@ "use strict"; -const parseTrie = require("../lib/tries/parseTrie"); +const parse = require("../lib/trie/parse"); -module.exports = parseTrie(require("../build/tries/icann.complete.json").trie); +module.exports = parse(require("../build/tries/icann.complete.json").trie); diff --git a/lists/icann.light.js b/lists/icann.light.js index ff885f1..a61b6f1 100644 --- a/lists/icann.light.js +++ b/lists/icann.light.js @@ -1,5 +1,5 @@ "use strict"; -const parseTrie = require("../lib/tries/parseTrie"); +const parse = require("../lib/trie/parse"); -module.exports = parseTrie(require("../build/tries/icann.light.json").trie); +module.exports = parse(require("../build/tries/icann.light.json").trie); diff --git a/lists/private.complete.js b/lists/private.complete.js index 5c13af7..7795a4e 100644 --- a/lists/private.complete.js +++ b/lists/private.complete.js @@ -1,5 +1,5 @@ "use strict"; -const parseTrie = require("../lib/tries/parseTrie"); +const parse = require("../lib/trie/parse"); -module.exports = parseTrie(require("../build/tries/private.complete.json").trie); +module.exports = parse(require("../build/tries/private.complete.json").trie); diff --git a/package-lock.json b/package-lock.json index 036d02f..c8cb4e2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -927,19 +927,22 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true + "dev": true, + "optional": true }, "arr-flatten": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true + "dev": true, + "optional": true }, "arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true + "dev": true, + "optional": true }, "array-filter": { "version": "0.0.1", @@ -982,7 +985,8 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true + "dev": true, + "optional": true }, "arrify": { "version": "1.0.1", @@ -999,7 +1003,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true + "dev": true, + "optional": true }, "astral-regex": { "version": "1.0.0", @@ -1018,7 +1023,8 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true + "dev": true, + "optional": true }, "babel-eslint": { "version": "10.0.1", @@ -1056,6 +1062,7 @@ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, + "optional": true, "requires": { "cache-base": "^1.0.1", "class-utils": "^0.3.5", @@ -1071,6 +1078,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, + "optional": true, "requires": { "is-descriptor": "^1.0.0" } @@ -1080,6 +1088,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, + "optional": true, "requires": { "kind-of": "^6.0.0" } @@ -1089,6 +1098,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, + "optional": true, "requires": { "kind-of": "^6.0.0" } @@ -1098,6 +1108,7 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, + "optional": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -1127,6 +1138,7 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, + "optional": true, "requires": { "arr-flatten": "^1.1.0", "array-unique": "^0.3.2", @@ -1145,6 +1157,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, + "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -1188,6 +1201,7 @@ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, + "optional": true, "requires": { "collection-visit": "^1.0.0", "component-emitter": "^1.2.1", @@ -1345,6 +1359,7 @@ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, + "optional": true, "requires": { "arr-union": "^3.1.0", "define-property": "^0.2.5", @@ -1357,6 +1372,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, + "optional": true, "requires": { "is-descriptor": "^0.1.0" } @@ -1424,6 +1440,7 @@ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, + "optional": true, "requires": { "map-visit": "^1.0.0", "object-visit": "^1.0.0" @@ -1480,7 +1497,8 @@ "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 + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", @@ -1803,7 +1821,8 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true + "dev": true, + "optional": true }, "core-js-compat": { "version": "3.1.3", @@ -1981,6 +2000,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, + "optional": true, "requires": { "is-descriptor": "^1.0.2", "isobject": "^3.0.1" @@ -1991,6 +2011,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, + "optional": true, "requires": { "kind-of": "^6.0.0" } @@ -2000,6 +2021,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, + "optional": true, "requires": { "kind-of": "^6.0.0" } @@ -2009,6 +2031,7 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, + "optional": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -2513,6 +2536,7 @@ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, + "optional": true, "requires": { "debug": "^2.3.3", "define-property": "^0.2.5", @@ -2528,6 +2552,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "optional": true, "requires": { "ms": "2.0.0" } @@ -2537,6 +2562,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, + "optional": true, "requires": { "is-descriptor": "^0.1.0" } @@ -2546,6 +2572,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, + "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -2554,7 +2581,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "dev": true, + "optional": true } } }, @@ -2563,6 +2591,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, + "optional": true, "requires": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" @@ -2573,6 +2602,7 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, + "optional": true, "requires": { "is-plain-object": "^2.0.4" } @@ -2595,6 +2625,7 @@ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, + "optional": true, "requires": { "array-unique": "^0.3.2", "define-property": "^1.0.0", @@ -2611,6 +2642,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, + "optional": true, "requires": { "is-descriptor": "^1.0.0" } @@ -2620,6 +2652,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, + "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -2629,6 +2662,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, + "optional": true, "requires": { "kind-of": "^6.0.0" } @@ -2638,6 +2672,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, + "optional": true, "requires": { "kind-of": "^6.0.0" } @@ -2647,6 +2682,7 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, + "optional": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -2696,6 +2732,7 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, + "optional": true, "requires": { "extend-shallow": "^2.0.1", "is-number": "^3.0.0", @@ -2708,6 +2745,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, + "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -2818,7 +2856,8 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true + "dev": true, + "optional": true }, "foreground-child": { "version": "1.5.6", @@ -2847,6 +2886,7 @@ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "dev": true, + "optional": true, "requires": { "map-cache": "^0.2.2" } @@ -2900,7 +2940,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -2921,12 +2962,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2941,17 +2984,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -3068,7 +3114,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -3080,6 +3127,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3094,6 +3142,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -3101,12 +3150,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -3125,6 +3176,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -3205,7 +3257,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -3217,6 +3270,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -3302,7 +3356,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -3338,6 +3393,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -3357,6 +3413,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -3400,12 +3457,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -3653,7 +3712,8 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true + "dev": true, + "optional": true }, "git-raw-commits": { "version": "2.0.0", @@ -3886,6 +3946,7 @@ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, + "optional": true, "requires": { "get-value": "^2.0.6", "has-values": "^1.0.0", @@ -3897,6 +3958,7 @@ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "dev": true, + "optional": true, "requires": { "is-number": "^3.0.0", "kind-of": "^4.0.0" @@ -3907,6 +3969,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, + "optional": true, "requires": { "is-buffer": "^1.1.5" } @@ -4072,6 +4135,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, + "optional": true, "requires": { "kind-of": "^3.0.2" }, @@ -4081,6 +4145,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, + "optional": true, "requires": { "is-buffer": "^1.1.5" } @@ -4106,7 +4171,8 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true + "dev": true, + "optional": true }, "is-builtin-module": { "version": "1.0.0", @@ -4126,6 +4192,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, + "optional": true, "requires": { "kind-of": "^3.0.2" }, @@ -4135,6 +4202,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, + "optional": true, "requires": { "is-buffer": "^1.1.5" } @@ -4151,6 +4219,7 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, + "optional": true, "requires": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", @@ -4161,7 +4230,8 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true + "dev": true, + "optional": true } } }, @@ -4169,13 +4239,15 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true + "dev": true, + "optional": 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 + "dev": true, + "optional": true }, "is-finite": { "version": "1.0.2", @@ -4206,6 +4278,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, + "optional": true, "requires": { "kind-of": "^3.0.2" }, @@ -4215,6 +4288,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, + "optional": true, "requires": { "is-buffer": "^1.1.5" } @@ -4242,6 +4316,7 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, + "optional": true, "requires": { "isobject": "^3.0.1" } @@ -4297,7 +4372,8 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true + "dev": true, + "optional": true }, "isarray": { "version": "1.0.0", @@ -4313,7 +4389,8 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "dev": true, + "optional": true }, "istanbul-lib-coverage": { "version": "2.0.5", @@ -4525,7 +4602,8 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true + "dev": true, + "optional": true }, "lcid": { "version": "1.0.0", @@ -4689,7 +4767,8 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true + "dev": true, + "optional": true }, "map-obj": { "version": "2.0.0", @@ -4702,6 +4781,7 @@ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "dev": true, + "optional": true, "requires": { "object-visit": "^1.0.0" } @@ -4825,6 +4905,7 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, + "optional": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -4880,6 +4961,7 @@ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", "dev": true, + "optional": true, "requires": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" @@ -4890,6 +4972,7 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, + "optional": true, "requires": { "is-plain-object": "^2.0.4" } @@ -5203,6 +5286,7 @@ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", "dev": true, + "optional": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -5677,6 +5761,7 @@ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "dev": true, + "optional": true, "requires": { "copy-descriptor": "^0.1.0", "define-property": "^0.2.5", @@ -5688,6 +5773,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, + "optional": true, "requires": { "is-descriptor": "^0.1.0" } @@ -5697,6 +5783,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, + "optional": true, "requires": { "is-buffer": "^1.1.5" } @@ -5713,6 +5800,7 @@ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, + "optional": true, "requires": { "isobject": "^3.0.0" } @@ -5742,6 +5830,7 @@ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, + "optional": true, "requires": { "isobject": "^3.0.1" } @@ -5936,7 +6025,8 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true + "dev": true, + "optional": true }, "path-dirname": { "version": "1.0.2", @@ -6026,7 +6116,8 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true + "dev": true, + "optional": true }, "prelude-ls": { "version": "1.1.2", @@ -6191,6 +6282,7 @@ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, + "optional": true, "requires": { "extend-shallow": "^3.0.2", "safe-regex": "^1.1.0" @@ -6265,13 +6357,15 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true + "dev": true, + "optional": true }, "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true + "dev": true, + "optional": true }, "repeating": { "version": "2.0.1", @@ -6311,7 +6405,8 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true + "dev": true, + "optional": true }, "responselike": { "version": "1.0.2", @@ -6399,6 +6494,7 @@ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", "dev": true, + "optional": true, "requires": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", @@ -6411,6 +6507,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, + "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -6468,6 +6565,7 @@ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, + "optional": true, "requires": { "base": "^0.11.1", "debug": "^2.2.0", @@ -6484,6 +6582,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "optional": true, "requires": { "ms": "2.0.0" } @@ -6493,6 +6592,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, + "optional": true, "requires": { "is-descriptor": "^0.1.0" } @@ -6502,6 +6602,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, + "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -6510,7 +6611,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "dev": true, + "optional": true } } }, @@ -6519,6 +6621,7 @@ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, + "optional": true, "requires": { "define-property": "^1.0.0", "isobject": "^3.0.0", @@ -6530,6 +6633,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, + "optional": true, "requires": { "is-descriptor": "^1.0.0" } @@ -6539,6 +6643,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, + "optional": true, "requires": { "kind-of": "^6.0.0" } @@ -6548,6 +6653,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, + "optional": true, "requires": { "kind-of": "^6.0.0" } @@ -6557,6 +6663,7 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, + "optional": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -6570,6 +6677,7 @@ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, + "optional": true, "requires": { "kind-of": "^3.2.0" }, @@ -6579,6 +6687,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, + "optional": true, "requires": { "is-buffer": "^1.1.5" } @@ -6604,6 +6713,7 @@ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", "dev": true, + "optional": true, "requires": { "atob": "^2.1.1", "decode-uri-component": "^0.2.0", @@ -6616,7 +6726,8 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true + "dev": true, + "optional": true }, "spawn-wrap": { "version": "1.4.2", @@ -6674,6 +6785,7 @@ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dev": true, + "optional": true, "requires": { "extend-shallow": "^3.0.0" } @@ -6984,6 +7096,7 @@ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "dev": true, + "optional": true, "requires": { "define-property": "^0.2.5", "object-copy": "^0.1.0" @@ -6994,6 +7107,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, + "optional": true, "requires": { "is-descriptor": "^0.1.0" } @@ -7287,6 +7401,7 @@ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "dev": true, + "optional": true, "requires": { "kind-of": "^3.0.2" }, @@ -7296,6 +7411,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, + "optional": true, "requires": { "is-buffer": "^1.1.5" } @@ -7307,6 +7423,7 @@ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, + "optional": true, "requires": { "define-property": "^2.0.2", "extend-shallow": "^3.0.2", @@ -7319,6 +7436,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, + "optional": true, "requires": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" @@ -7427,6 +7545,7 @@ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", "dev": true, + "optional": true, "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", @@ -7439,6 +7558,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, + "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -7448,6 +7568,7 @@ "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", "dev": true, + "optional": true, "requires": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", @@ -7462,6 +7583,7 @@ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, + "optional": true, "requires": { "has-value": "^0.3.1", "isobject": "^3.0.0" @@ -7472,6 +7594,7 @@ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "dev": true, + "optional": true, "requires": { "get-value": "^2.0.3", "has-values": "^0.1.4", @@ -7483,6 +7606,7 @@ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", "dev": true, + "optional": true, "requires": { "isarray": "1.0.0" } @@ -7493,7 +7617,8 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true + "dev": true, + "optional": true } } }, @@ -7749,7 +7874,8 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true + "dev": true, + "optional": true }, "url-parse-lax": { "version": "3.0.0", @@ -7768,7 +7894,8 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true + "dev": true, + "optional": true }, "util-deprecate": { "version": "1.0.2", diff --git a/scripts/build-tries.js b/scripts/build-tries.js index 3cbafa4..ee19329 100644 --- a/scripts/build-tries.js +++ b/scripts/build-tries.js @@ -12,7 +12,7 @@ const got = require("got"); const mkdirp = require("mkdirp"); try { - require.resolve("../lib/tries/parsePubSuffixList"); + require.resolve("../lib/trie/parsePubSuffixList"); } catch (error) { // This conditions occurs when the CI system or a developer checks out the repo for the first time. // It happens because the postinstall hook kicks in *before* the lib is built. @@ -20,8 +20,8 @@ try { console.error("Lib does not exist yet, skipping build-tries step."); process.exit(0); // eslint-disable-line no-process-exit } -const parsePubSuffixList = require("../lib/tries/parsePubSuffixList"); -const serializeTrie = require("../lib/tries/serializeTrie"); +const parsePubSuffixList = require("../lib/trie/parsePubSuffixList"); +const serializeTrie = require("../lib/trie/serializeTrie"); const PUBLIC_SUFFIX_URL = "https://publicsuffix.org/list/public_suffix_list.dat"; const rootPath = path.resolve(__dirname, ".."); diff --git a/src/parseDomain.js b/src/parseDomain.js index 8db058a..b650fc2 100644 --- a/src/parseDomain.js +++ b/src/parseDomain.js @@ -3,32 +3,32 @@ const icannTrie = require("../lists/icann.complete"); const privateTrie = require("../lists/private.complete"); const normalize = require("./normalize.js"); -const lookUp = require("./tries/lookUp"); +const lookUp = require("./trie/lookUp"); // eslint-disable-next-line -const urlParts = /^(:?\/\/|https?:\/\/)?([^/]*@)?(.+?)(:\d{2,5})?([/?].*)?$/; // 1 = protocol, 2 = auth, 3 = domain, 4 = port, 5 = path +const urlParts = /^(:?\/\/|https?:\/\/)?([^/]*@)?(.+?)(:\d{2,5})?([/?].*)?$/; // 1 = protocol, 2 = auth, 3 = hostname, 4 = port, 5 = path const dot = /\./g; const emptyArr = []; -function matchTld(domain, options) { +function matchTld(hostname, options) { // for potentially unrecognized tlds, try matching against custom tlds if (options.customTlds) { // try matching against a built regexp of custom tlds - const tld = domain.match(options.customTlds); + const tld = hostname.match(options.customTlds); if (tld !== null) { return tld[0]; } } + const domains = hostname.split("."); + const icannTlds = lookUp(icannTrie, domains); + const privateTlds = options.privateTlds ? lookUp(privateTrie, domains) : emptyArr; - const tries = (options.privateTlds ? [privateTrie] : emptyArr).concat(icannTrie); - - for (const trie of tries) { - const tld = lookUp(trie, domain); - - if (tld !== null) { - return "." + tld; - } + if (privateTlds.length > icannTlds.length) { + return "." + privateTlds.join("."); + } + if (icannTlds.length > 0) { + return "." + icannTlds.join("."); } return null; @@ -54,7 +54,7 @@ function parseDomain(url, options) { const normalizedUrl = normalize.url(url); let tld = null; let urlSplit; - let domain; + let hostname; if (!normalizedUrl) { return null; @@ -69,28 +69,28 @@ function parseDomain(url, options) { return null; } - domain = urlSplit[3]; // domain will now be something like sub.domain.example.com - tld = matchTld(domain, normalizedOptions); + hostname = urlSplit[3]; // domain will now be something like sub.domain.example.com + tld = matchTld(hostname, normalizedOptions); if (tld === null) { return null; } // remove tld and split by dot - urlSplit = domain.slice(0, -tld.length).split(dot); + urlSplit = hostname.slice(0, -tld.length).split(dot); if (tld.charAt(0) === ".") { // removes the remaining dot, if present (added to handle localhost) tld = tld.slice(1); } - domain = urlSplit.pop(); + hostname = urlSplit.pop(); const subdomain = urlSplit.join("."); return { tld, - domain, + domain: hostname, subdomain, }; } diff --git a/src/tries/separators.js b/src/trie/characters.js similarity index 62% rename from src/tries/separators.js rename to src/trie/characters.js index 495458e..46b489b 100644 --- a/src/tries/separators.js +++ b/src/trie/characters.js @@ -5,4 +5,6 @@ module.exports = { SAME: ",", // same level DOWN: ">", // one level down RESET: "|", // reset level index and start new + WILDCARD: "*", // as defined by publicsuffix.org + EXCEPTION: "!", // as defined by publicsuffix.org }; diff --git a/src/trie/lookUp.js b/src/trie/lookUp.js new file mode 100644 index 0000000..14f6412 --- /dev/null +++ b/src/trie/lookUp.js @@ -0,0 +1,31 @@ +"use strict"; + +const characters = require("./characters.js"); + +function lookUp(trie, domains) { + const domainsToCheck = domains.slice(); + const topLevel = []; + let node = trie; + + while (domainsToCheck.length) { + const domain = domainsToCheck.pop(); + + if (node.children.has(characters.WILDCARD)) { + if (node.children.has(characters.EXCEPTION + domain)) { + break; + } + node = node.children.get(characters.WILDCARD); + } else { + if (node.children.has(domain) === false) { + break; + } + node = node.children.get(domain); + } + + topLevel.unshift(domain); + } + + return topLevel; +} + +module.exports = lookUp; diff --git a/src/trie/nodes.js b/src/trie/nodes.js new file mode 100644 index 0000000..de80d6a --- /dev/null +++ b/src/trie/nodes.js @@ -0,0 +1,37 @@ +"use strict"; + +function createNode(domain = null) { + return { + domain, + children: new Map(), + parent: null, + }; +} + +function createOrGetChild(parent, domain) { + let child = parent.children.get(domain); + + if (child === undefined) { + child = createNode(domain); + adoptChild(parent, child); + } + + return child; +} + +function adoptChild(parent, child) { + if (typeof child.domain !== "string") { + throw new Error("Cannot adopt child: child.domain must be a string"); + } + if (parent.children.has(child.domain)) { + throw new Error(`Cannot adopt child: parent has already a child with the domain '${child.domain}'`); + } + parent.children.set(child.domain, child); + child.parent = parent; +} + +module.exports = { + createNode, + createOrGetChild, + adoptChild, +}; diff --git a/src/trie/parse.js b/src/trie/parse.js new file mode 100644 index 0000000..1e5cc22 --- /dev/null +++ b/src/trie/parse.js @@ -0,0 +1,53 @@ +"use strict"; + +const characters = require("./characters"); +const {createNode, createOrGetChild} = require("./nodes"); + +// Parsing is complex... :) +// eslint-disable-next-line complexity +function parse(serialized) { + const rootNode = createNode(); + let domain = ""; + let parentNode = rootNode; + let node; + + function addDomain() { + node = createOrGetChild(parentNode, domain); + domain = ""; + } + + for (let i = 0; i < serialized.length; i++) { + const char = serialized.charAt(i); + + switch (char) { + case characters.SAME: { + addDomain(); + continue; + } + case characters.DOWN: { + addDomain(); + parentNode = node; + continue; + } + case characters.RESET: { + addDomain(); + parentNode = rootNode; + continue; + } + case characters.UP: { + addDomain(); + parentNode = parentNode.parent; + continue; + } + } + domain += char; + } + + if (domain !== "") { + addDomain(); + } + + return rootNode; +} + +module.exports = parse; diff --git a/src/tries/parsePubSuffixList.js b/src/trie/parsePubSuffixList.js similarity index 100% rename from src/tries/parsePubSuffixList.js rename to src/trie/parsePubSuffixList.js diff --git a/src/tries/serializeTrie.js b/src/trie/serializeTrie.js similarity index 92% rename from src/tries/serializeTrie.js rename to src/trie/serializeTrie.js index 89e81cc..6760fa5 100644 --- a/src/tries/serializeTrie.js +++ b/src/trie/serializeTrie.js @@ -1,6 +1,6 @@ "use strict"; -const SEPARATORS = require("./separators"); +const characters = require("./characters"); const TYPE_COMPLETE = "complete"; const TYPE_LIGHT = "light"; @@ -49,14 +49,14 @@ function lineToString(line, i, arr) { } if (indexOfDifference === 0) { // line and prevLine are completely different - separatorFromPrev = SEPARATORS.RESET; + separatorFromPrev = characters.RESET; } else if (indexOfDifference === prevLine.length - 1) { // only the last part of line and prevLine are different - separatorFromPrev = SEPARATORS.SAME; + separatorFromPrev = characters.SAME; } else if (indexOfDifference > prevLine.length - 1) { // we don't need to go up the hierarchy first because prevLine is part of line // so let's just start with an initial down separator - separatorFromPrev = SEPARATORS.DOWN; + separatorFromPrev = characters.DOWN; } else { // line and prevLine are different, but share a common root at indexOfDifference - 1 // we now need to go up the hierarchy to the common root @@ -71,12 +71,12 @@ function lineToString(line, i, arr) { throw new Error("Cannot serialize trie: The public suffix list contains unexpected rules."); } - separatorFromPrev = new Array(levelsUp).fill(SEPARATORS.UP) + separatorFromPrev = new Array(levelsUp).fill(characters.UP) .join(""); } } - return separatorFromPrev + line.slice(indexOfDifference).join(SEPARATORS.DOWN); + return separatorFromPrev + line.slice(indexOfDifference).join(characters.DOWN); } function serializeTrie(parsedList, type) { diff --git a/src/tries/lookUp.js b/src/tries/lookUp.js deleted file mode 100644 index 999307e..0000000 --- a/src/tries/lookUp.js +++ /dev/null @@ -1,37 +0,0 @@ -"use strict"; - -const WILDCARD = "*"; -const EXCEPTION = "!"; - -function lookUp(trie, hostname) { - const domains = hostname.split(".").reverse(); - const tlds = []; - let currentTrie = trie; - - for (let i = 0; i < domains.length; i++) { - const domain = domains[i]; - const isWildcardRule = currentTrie.has(WILDCARD); - - if (isWildcardRule) { - if (currentTrie.has(EXCEPTION + domain) === false) { - tlds.push(domain); - } - break; - } - if (currentTrie.has(domain) === false) { - break; - } - tlds.push(domain); - - const value = currentTrie.get(domain); - - if (value === true) { - break; - } - currentTrie = value; - } - - return tlds.length === 0 ? null : tlds.reverse().join("."); -} - -module.exports = lookUp; diff --git a/src/tries/parseTrie.js b/src/tries/parseTrie.js deleted file mode 100644 index f3c19b5..0000000 --- a/src/tries/parseTrie.js +++ /dev/null @@ -1,56 +0,0 @@ -"use strict"; - -const SEPARATORS = require("./separators"); - -function parseTrie(input) { - let map = new Map(); - const parentMaps = [map]; - let domain = ""; - - function setDomain(value) { - if (domain === "") { - return; - } - map.set(domain, value); - domain = ""; - } - - for (let i = 0; i < input.length; i++) { - const char = input.charAt(i); - - switch (char) { - case SEPARATORS.SAME: { - setDomain(true); - continue; - } - case SEPARATORS.DOWN: { - const childMap = new Map(); - - setDomain(childMap); - parentMaps.push(map); - map = childMap; - continue; - } - case SEPARATORS.RESET: { - setDomain(true); - // Remove all parent maps but the top most - parentMaps.length = 1; - map = parentMaps[0]; - continue; - } - case SEPARATORS.UP: { - setDomain(true); - map = parentMaps.pop(); - continue; - } - } - - domain += char; - } - - setDomain(true); - - return parentMaps[0]; -} - -module.exports = parseTrie; diff --git a/test/parseDomain.test.js b/test/parseDomain.test.js index abf3636..fc9c899 100644 --- a/test/parseDomain.test.js +++ b/test/parseDomain.test.js @@ -219,7 +219,7 @@ describe("parseDomain(url)", () => { }); // See https://github.com/peerigon/parse-domain/issues/67 - it.skip("should parse gouv.fr as tld", () => { + it("should parse gouv.fr as tld", () => { expect(parseDomain("dev.classea12.beta.gouv.fr", {privateTlds: true})).to.eql({ tld: "gouv.fr", domain: "beta", @@ -227,4 +227,127 @@ describe("parseDomain(url)", () => { }); }); }); + + describe("official test suite", () => { + it("passes all inputs", () => { + function checkPublicSuffix(input, expectedTld) { + console.log(input); + const result = parseDomain(input, {privateTlds: true}); + + if (expectedTld === null) { + // When the expectedTld is null it means that the domain + // should not be registerable. + // Our module will return an empty string for the domain + // in that case. The tld should match the input. + expect(result.tld).to.equal(input.toLowerCase()); + expect(result.domain).to.equal(""); + } else { + expect(result.domain + "." + result.tld).to.equal(expectedTld); + } + } + + // Any copyright is dedicated to the Public Domain. + // https://creativecommons.org/publicdomain/zero/1.0/ + + // null input. + // checkPublicSuffix(null, null); + // Mixed case. + checkPublicSuffix("COM", null); + checkPublicSuffix("example.COM", "example.com"); + checkPublicSuffix("WwW.example.COM", "example.com"); + // Leading dot. + // TODO: Make this test work + // checkPublicSuffix(".com", null); + // checkPublicSuffix(".example", null); + // checkPublicSuffix(".example.com", null); + // checkPublicSuffix(".example.example", null); + // Unlisted TLD. + // This is a strange test case. Why should 'example.example' be registerable when 'example' is unknown? + // checkPublicSuffix("example", null); + // checkPublicSuffix("example.example", "example.example"); + // checkPublicSuffix("b.example.example", "example.example"); + // checkPublicSuffix("a.b.example.example", "example.example"); + // Listed, but non-Internet, TLD. + // checkPublicSuffix('local', null); + // checkPublicSuffix('example.local', null); + // checkPublicSuffix('b.example.local', null); + // checkPublicSuffix('a.b.example.local', null); + // TLD with only 1 rule. + checkPublicSuffix("biz", null); + checkPublicSuffix("domain.biz", "domain.biz"); + checkPublicSuffix("b.domain.biz", "domain.biz"); + checkPublicSuffix("a.b.domain.biz", "domain.biz"); + // TLD with some 2-level rules. + checkPublicSuffix("com", null); + checkPublicSuffix("example.com", "example.com"); + checkPublicSuffix("b.example.com", "example.com"); + checkPublicSuffix("a.b.example.com", "example.com"); + checkPublicSuffix("uk.com", null); + checkPublicSuffix("example.uk.com", "example.uk.com"); + checkPublicSuffix("b.example.uk.com", "example.uk.com"); + checkPublicSuffix("a.b.example.uk.com", "example.uk.com"); + checkPublicSuffix("test.ac", "test.ac"); + // TLD with only 1 (wildcard) rule. + checkPublicSuffix("mm", null); + checkPublicSuffix("c.mm", null); + checkPublicSuffix("b.c.mm", "b.c.mm"); + checkPublicSuffix("a.b.c.mm", "b.c.mm"); + // More complex TLD. + checkPublicSuffix("jp", null); + checkPublicSuffix("test.jp", "test.jp"); + checkPublicSuffix("www.test.jp", "test.jp"); + checkPublicSuffix("ac.jp", null); + checkPublicSuffix("test.ac.jp", "test.ac.jp"); + checkPublicSuffix("www.test.ac.jp", "test.ac.jp"); + checkPublicSuffix("kyoto.jp", null); + checkPublicSuffix("test.kyoto.jp", "test.kyoto.jp"); + checkPublicSuffix("ide.kyoto.jp", null); + checkPublicSuffix("b.ide.kyoto.jp", "b.ide.kyoto.jp"); + checkPublicSuffix("a.b.ide.kyoto.jp", "b.ide.kyoto.jp"); + checkPublicSuffix("c.kobe.jp", null); + checkPublicSuffix("b.c.kobe.jp", "b.c.kobe.jp"); + checkPublicSuffix("a.b.c.kobe.jp", "b.c.kobe.jp"); + checkPublicSuffix("city.kobe.jp", "city.kobe.jp"); + checkPublicSuffix("www.city.kobe.jp", "city.kobe.jp"); + // TLD with a wildcard rule and exceptions. + checkPublicSuffix("ck", null); + checkPublicSuffix("test.ck", null); + checkPublicSuffix("b.test.ck", "b.test.ck"); + checkPublicSuffix("a.b.test.ck", "b.test.ck"); + checkPublicSuffix("www.ck", "www.ck"); + checkPublicSuffix("www.www.ck", "www.ck"); + // US K12. + checkPublicSuffix("us", null); + checkPublicSuffix("test.us", "test.us"); + checkPublicSuffix("www.test.us", "test.us"); + checkPublicSuffix("ak.us", null); + checkPublicSuffix("test.ak.us", "test.ak.us"); + checkPublicSuffix("www.test.ak.us", "test.ak.us"); + checkPublicSuffix("k12.ak.us", null); + checkPublicSuffix("test.k12.ak.us", "test.k12.ak.us"); + checkPublicSuffix("www.test.k12.ak.us", "test.k12.ak.us"); + // IDN labels. + checkPublicSuffix("食狮.com.cn", "食狮.com.cn"); + checkPublicSuffix("食狮.公司.cn", "食狮.公司.cn"); + checkPublicSuffix("www.食狮.公司.cn", "食狮.公司.cn"); + checkPublicSuffix("shishi.公司.cn", "shishi.公司.cn"); + checkPublicSuffix("公司.cn", null); + checkPublicSuffix("食狮.中国", "食狮.中国"); + checkPublicSuffix("www.食狮.中国", "食狮.中国"); + checkPublicSuffix("shishi.中国", "shishi.中国"); + checkPublicSuffix("中国", null); + // Same as above, but punycoded. + // Punycode is currently not supported + // TODO: Make these tests work + // checkPublicSuffix("xn--85x722f.com.cn", "xn--85x722f.com.cn"); + // checkPublicSuffix("xn--85x722f.xn--55qx5d.cn", "xn--85x722f.xn--55qx5d.cn"); + // checkPublicSuffix("www.xn--85x722f.xn--55qx5d.cn", "xn--85x722f.xn--55qx5d.cn"); + // checkPublicSuffix("shishi.xn--55qx5d.cn", "shishi.xn--55qx5d.cn"); + // checkPublicSuffix("xn--55qx5d.cn", null); + // checkPublicSuffix("xn--85x722f.xn--fiqs8s", "xn--85x722f.xn--fiqs8s"); + // checkPublicSuffix("www.xn--85x722f.xn--fiqs8s", "xn--85x722f.xn--fiqs8s"); + // checkPublicSuffix("shishi.xn--fiqs8s", "shishi.xn--fiqs8s"); + // checkPublicSuffix("xn--fiqs8s", null); + }); + }); }); diff --git a/test/snapshots.test.js b/test/snapshots.test.js index e6df617..f095804 100644 --- a/test/snapshots.test.js +++ b/test/snapshots.test.js @@ -3,10 +3,8 @@ const fs = require("fs"); const path = require("path"); const chai = require("chai"); -const parsePubSuffixList = require("../lib/tries/parsePubSuffixList"); -const serializeTrie = require("../lib/tries/serializeTrie"); -const parseTrie = require("../lib/tries/parseTrie"); -const lookUp = require("../lib/tries/lookUp"); +const parsePubSuffixList = require("../lib/trie/parsePubSuffixList"); +const serializeTrie = require("../lib/trie/serializeTrie"); const expect = chai.expect; const TEST_SNAPSHOT = true; @@ -36,23 +34,4 @@ describe("snapshots", () => { fs.writeFileSync(pathToSerializeTrieSnapshot, JSON.stringify(serializedTrie)); }); }); - describe("parseTrie() and lookUp() calling lookUp() with the result from parseTrie(snapshot) and hostname", () => { - const serializedTrie = JSON.parse(fs.readFileSync(pathToSerializeTrieSnapshot, "utf8")); - const parsedTrie = parseTrie(serializedTrie); - - [ - ["example.com", "com"], - ["example.a.com", "com"], - ["example.uk", "uk"], - ["example.co.uk", "co.uk"], - ["example.ab.uk", "uk"], - ].forEach(testArgs => { - const hostname = testArgs[0]; - const expectedResult = testArgs[1]; - - it(`'${hostname}' returns ${expectedResult}`, () => { - expect(lookUp(parsedTrie, hostname)).to.equal(expectedResult); - }); - }); - }); }); diff --git a/test/trie/lookUp.test.js b/test/trie/lookUp.test.js new file mode 100644 index 0000000..c35ebcf --- /dev/null +++ b/test/trie/lookUp.test.js @@ -0,0 +1,99 @@ +"use strict"; + +const chai = require("chai"); +const lookUp = require("../../lib/trie/lookUp"); +const characters = require("../../lib/trie/characters"); +const {createNode, adoptChild} = require("../../lib/trie/nodes"); + +const expect = chai.expect; + +function createOneLevelDeepTrie() { + const root = createNode(); + const com = createNode("com"); + + adoptChild(root, com); + + return root; +} + +function createTwoLevelDeepTrie() { + const root = createNode(); + const uk = createNode("uk"); + const co = createNode("co"); + + adoptChild(root, uk); + adoptChild(uk, co); + + return root; +} + +function createTrieWithWildcardAndException() { + const root = createNode(); + const wildcard = createNode(characters.WILDCARD); + const exception = createNode(characters.EXCEPTION + "exception"); + + adoptChild(root, wildcard); + adoptChild(root, exception); + + return root; +} + +describe("lookUp()", () => { + describe("with an empty trie", () => { + it("returns an empty array", () => { + const root = createNode(); + + expect(lookUp(root, ["com"])).to.eql([]); + expect(lookUp(root, ["example", "com"])).to.eql([]); + }); + }); + describe("with a one level deep trie", () => { + it("returns the known TLD as array", () => { + const root = createOneLevelDeepTrie(); + + expect(lookUp(root, ["com"])).to.eql(["com"]); + expect(lookUp(root, ["example", "com"])).to.eql(["com"]); + expect(lookUp(root, ["www", "example", "com"])).to.eql(["com"]); + }); + it("returns an empty array if there is no known TLD", () => { + const root = createOneLevelDeepTrie(); + + expect(lookUp(root, ["de"])).to.eql([]); + expect(lookUp(root, ["example", "de"])).to.eql([]); + expect(lookUp(root, ["www", "example", "de"])).to.eql([]); + }); + }); + describe("with a two level deep trie", () => { + it("returns the known TLD", () => { + const root = createTwoLevelDeepTrie(); + + expect(lookUp(root, ["uk"])).to.eql(["uk"]); + expect(lookUp(root, ["example", "uk"])).to.eql(["uk"]); + expect(lookUp(root, ["co", "uk"])).to.eql(["co", "uk"]); + expect(lookUp(root, ["example", "co", "uk"])).to.eql(["co", "uk"]); + expect(lookUp(root, ["www", "example", "co", "uk"])).to.eql(["co", "uk"]); + }); + + it("returns an empty array if there is no known TLD", () => { + const root = createTwoLevelDeepTrie(); + + expect(lookUp(root, ["de"])).to.eql([]); + expect(lookUp(root, ["example", "de"])).to.eql([]); + expect(lookUp(root, ["www", "example", "de"])).to.eql([]); + }); + }); + describe("with a wildcard and exceptions", () => { + it("does not accept the exception as TLD", () => { + const root = createTrieWithWildcardAndException(); + + expect(lookUp(root, ["exception"])).to.eql([]); + expect(lookUp(root, ["www", "exception"])).to.eql([]); + }); + it("accepts all domain names as TLD in place of the wildcard", () => { + const root = createTrieWithWildcardAndException(); + + expect(lookUp(root, ["anything"])).to.eql(["anything"]); + expect(lookUp(root, ["www", "anything"])).to.eql(["anything"]); + }); + }); +}); diff --git a/test/trie/nodes.test.js b/test/trie/nodes.test.js new file mode 100644 index 0000000..58e2955 --- /dev/null +++ b/test/trie/nodes.test.js @@ -0,0 +1,22 @@ +"use strict"; + +const chai = require("chai"); +const {createNode, adoptChild} = require("../../lib/trie/nodes"); + +const expect = chai.expect; + +describe("adoptChild()", () => { + it("throws an error if the child has no domain", () => { + expect(() => { + adoptChild(createNode(), createNode()); + }).to.throw("Cannot adopt child: child.domain must be a string"); + }); + it("throws an error if the parent has already a child with that domain", () => { + expect(() => { + const parent = createNode(); + + adoptChild(parent, createNode("some-domain")); + adoptChild(parent, createNode("some-domain")); + }).to.throw("Cannot adopt child: parent has already a child with the domain 'some-domain'"); + }); +}); diff --git a/test/trie/parse.test.js b/test/trie/parse.test.js new file mode 100644 index 0000000..a9060cf --- /dev/null +++ b/test/trie/parse.test.js @@ -0,0 +1,143 @@ +"use strict"; + +const chai = require("chai"); +const parse = require("../../lib/trie/parse"); + +const expect = chai.expect; + +describe("parse()", () => { + describe("when called with ''", () => { + it("returns a node with null as domain and no children", () => { + const root = parse(""); + + expect(root.domain).to.equal(null); + expect(root.children.size).to.equal(0); + }); + }); + describe("when called with 'a'", () => { + it("adds 'a' as child of root", () => { + const root = parse("a"); + + expect(root.children.has("a")).to.be.true; + }); + it("initializes 'a' with the correct domain and parent", () => { + const root = parse("a"); + const a = root.children.get("a"); + + expect(a.domain).to.equal("a"); + expect(a.parent).to.equal(root); + }); + }); + describe("when called with 'a,b'", () => { + it("adds 'a' and 'b' as child of root", () => { + const root = parse("a,b"); + + expect(root.children.has("a")).to.be.true; + expect(root.children.has("b")).to.be.true; + }); + it("initializes 'b' with the correct domain and parent", () => { + const root = parse("a,b"); + const b = root.children.get("b"); + + expect(b.domain).to.equal("b"); + expect(b.parent).to.equal(root); + }); + }); + describe("when called with 'a>b'", () => { + it("adds 'a' as child of root and 'b' as child of 'a'", () => { + const root = parse("a>b"); + + expect(root.children.has("a")).to.be.true; + expect(root.children.get("a").children.has("b")).to.be.true; + }); + it("initializes 'b' with the correct domain and parent", () => { + const root = parse("a>b"); + const a = root.children.get("a"); + const b = a.children.get("b"); + + expect(b.domain).to.equal("b"); + expect(b.parent).to.equal(a); + }); + }); + describe("when called with 'a>b,c'", () => { + it("adds 'b' and 'c' as child of 'a'", () => { + const root = parse("a>b,c"); + const a = root.children.get("a"); + + expect(a.children.has("b")).to.be.true; + expect(a.children.has("c")).to.be.true; + }); + it("initializes 'c' with the correct domain and parent", () => { + const root = parse("a>b,c"); + const a = root.children.get("a"); + const c = a.children.get("c"); + + expect(c.domain).to.equal("c"); + expect(c.parent).to.equal(a); + }); + }); + describe("when called with 'a>b { + it("adds 'b' as child of 'a' and 'c' as child of root", () => { + const root = parse("a>b { + const root = parse("a>b { + it("adds 'a' and 'b' as child of root", () => { + const root = parse("a|b"); + + expect(root.children.has("a")).to.be.true; + expect(root.children.has("b")).to.be.true; + }); + it("initializes 'b' with the correct domain and parent", () => { + const root = parse("a|b"); + const b = root.children.get("b"); + + expect(b.domain).to.equal("b"); + expect(b.parent).to.equal(root); + }); + }); + describe("when called with 'a>b|c'", () => { + it("adds 'b' as child of 'a' and 'c' as child of root", () => { + const root = parse("a>b|c"); + const a = root.children.get("a"); + + expect(a.children.has("b")).to.be.true; + expect(root.children.has("c")).to.be.true; + }); + }); + describe("when called with 'a>bd'", () => { + it("adds 'b' and 'd' as child of 'a'", () => { + const root = parse("a>bc"); + const a = root.children.get("a"); + + expect(a.children.has("b")).to.be.true; + expect(a.children.has("c")).to.be.true; + }); + }); + describe("when called with 'a>b>c'", () => { + it("adds 'c' as child of 'b'", () => { + const root = parse("a>b>c"); + const b = root.children.get("a").children.get("b"); + + expect(b.children.has("c")).to.be.true; + }); + }); + describe("when called with 'a>b>c>d|e'", () => { + it("adds 'e' as child node of root", () => { + const node = parse("a>b>c>d|e"); + + expect(node.children.has("e")).to.be.true; + }); + }); +}); diff --git a/test/tries/parsePubSuffixList.test.js b/test/trie/parsePubSuffixList.test.js similarity index 98% rename from test/tries/parsePubSuffixList.test.js rename to test/trie/parsePubSuffixList.test.js index e4e6760..67382b2 100644 --- a/test/tries/parsePubSuffixList.test.js +++ b/test/trie/parsePubSuffixList.test.js @@ -3,7 +3,7 @@ const fs = require("fs"); const path = require("path"); const chai = require("chai"); -const parsePubSuffixList = require("../../lib/tries/parsePubSuffixList"); +const parsePubSuffixList = require("../../lib/trie/parsePubSuffixList"); const expect = chai.expect; const pathToFixtures = path.resolve(__dirname, "..", "fixtures"); diff --git a/test/tries/serializeTrie.test.js b/test/trie/serializeTrie.test.js similarity index 98% rename from test/tries/serializeTrie.test.js rename to test/trie/serializeTrie.test.js index d241f31..cb461c6 100644 --- a/test/tries/serializeTrie.test.js +++ b/test/trie/serializeTrie.test.js @@ -1,7 +1,7 @@ "use strict"; const chai = require("chai"); -const serializeTrie = require("../../lib/tries/serializeTrie"); +const serializeTrie = require("../../lib/trie/serializeTrie"); const expect = chai.expect; diff --git a/test/tries/lookUp.test.js b/test/tries/lookUp.test.js deleted file mode 100644 index 4c45bce..0000000 --- a/test/tries/lookUp.test.js +++ /dev/null @@ -1,116 +0,0 @@ -"use strict"; - -const chai = require("chai"); -const lookUp = require("../../lib/tries/lookUp"); - -const expect = chai.expect; - -describe("lookUp()", () => { - it("returns null if the trie is empty", () => { - const trie = new Map(); - const hostname = "a.b.c"; - - expect(lookUp(trie, hostname)).to.eql(null); - }); - it("returns null if the trie contains no matching top-level domain", () => { - const trie = new Map(); - const hostname = "a.b.c"; - - trie.set("cc", true); - - expect(lookUp(trie, hostname)).to.eql(null); - }); - it("returns the hostname if the hostname is a top-level domain", () => { - const trie = new Map(); - const hostname = "a"; - - trie.set("a", true); - trie.set("b", true); - - expect(lookUp(trie, hostname)).to.eql("a"); - }); - it("returns the top-level domain from the hostname (2 domains)", () => { - const trie = new Map(); - const hostname = "b.a"; - - trie.set("a", true); - trie.set("b", true); - - expect(lookUp(trie, hostname)).to.eql("a"); - }); - it("returns the top-level domain from the hostname (3 domains)", () => { - const trie = new Map(); - const hostname = "c.b.a"; - - trie.set("a", true); - trie.set("b", true); - - expect(lookUp(trie, hostname)).to.eql("a"); - }); - it("returns the top-level domain (2 tlds) from the hostname (3 domains)", () => { - const trie = new Map(); - const trieA = new Map(); - const hostname = "c.b.a"; - - trieA.set("b", true); - trie.set("a", trieA); - trie.set("b", new Map()); - - expect(lookUp(trie, hostname)).to.eql("b.a"); - }); - it("returns the top-level domain (3 tlds) from the hostname (4 domains)", () => { - const trie = new Map(); - const trieA = new Map(); - const trieAB = new Map(); - const hostname = "d.c.b.a"; - - trieAB.set("c", true); - trieA.set("b", trieAB); - trieA.set("a", true); - trie.set("a", trieA); - trie.set("b", new Map()); - - expect(lookUp(trie, hostname)).to.eql("c.b.a"); - }); - it("interprets wildcards in the trie correctly (simple)", () => { - const trie = new Map(); - const hostname = "a.b.c"; - - trie.set("*", true); - - expect(lookUp(trie, hostname)).to.eql("c"); - }); - it("interprets wildcards in the trie correctly (nested)", () => { - const trie = new Map(); - const trieA = new Map(); - const hostname = "c.b.a"; - - trieA.set("*", true); - trie.set("a", trieA); - - expect(lookUp(trie, hostname)).to.eql("b.a"); - }); - it("interprets exceptions of wildcards in the trie correctly (simple)", () => { - const trie = new Map(); - const trieA = new Map(); - const hostname = "c.b.a"; - - trieA.set("*", true); - trieA.set("!b", true); - trie.set("a", trieA); - - expect(lookUp(trie, hostname)).to.eql("a"); - }); - it("still handles wildcards correctly if there are non-matching exceptions", () => { - const trie = new Map(); - const trieA = new Map(); - const hostname = "c.b.a"; - - trieA.set("*", true); - trieA.set("!a", true); - trieA.set("!c", true); - trie.set("a", trieA); - - expect(lookUp(trie, hostname)).to.eql("b.a"); - }); -}); diff --git a/test/tries/parseTrie.test.js b/test/tries/parseTrie.test.js deleted file mode 100644 index a09dacb..0000000 --- a/test/tries/parseTrie.test.js +++ /dev/null @@ -1,162 +0,0 @@ -"use strict"; - -const chai = require("chai"); -const parseTrie = require("../../lib/tries/parseTrie"); - -const expect = chai.expect; - -describe("parseTrie()", () => { - describe("basic cases", () => { - it("returns a map", () => { - expect(parseTrie("")).to.be.instanceOf(Map); - }); - - it("returns an empty map when an empty string is given", () => { - const trie = parseTrie(""); - - expect(trie.size).to.equal(0); - }); - - it("returns a map with the given domain as key and true as value", () => { - const trie = parseTrie("some-domain"); - const someDomain = trie.get("some-domain"); - - expect(someDomain).to.equal(true); - }); - }); - - describe("with SAME separator", () => { - it("returns a map with the given domains as key and true as value", () => { - const trie = parseTrie("a,b,c"); - const a = trie.get("a"); - const b = trie.get("b"); - const c = trie.get("c"); - - expect(a).to.equal(true); - expect(b).to.equal(true); - expect(c).to.equal(true); - }); - }); - - describe("and with DOWN separator", () => { - it("returns a nested map", () => { - const trie = parseTrie("a>a"); - const a = trie.get("a"); - const aa = a.get("a"); - - expect(aa).to.equal(true); - }); - - it("returns a deeply nested map", () => { - const trie = parseTrie("a>a>a"); - const a = trie.get("a"); - const aa = a.get("a"); - const aaa = aa.get("a"); - - expect(aa).to.be.instanceOf(Map); - expect(aaa).to.equal(true); - }); - - it("returns a nested map with the given domains as key and true as value", () => { - const trie = parseTrie("a>a,b,c"); - const a = trie.get("a"); - const aa = a.get("a"); - const ab = a.get("b"); - const ac = a.get("c"); - - expect(aa).to.equal(true); - expect(ab).to.equal(true); - expect(ac).to.equal(true); - }); - }); - - describe("and with UP separator", () => { - it("returns a map with maps", () => { - const trie = parseTrie("a>a,ba,b"); - const a = trie.get("a"); - const aa = a.get("a"); - const ab = a.get("a"); - const b = trie.get("b"); - const ba = b.get("a"); - const bb = b.get("b"); - - expect(aa).to.equal(true); - expect(ab).to.equal(true); - expect(ba).to.equal(true); - expect(bb).to.equal(true); - }); - - it("goes up multiple levels", () => { - const trie = parseTrie("a>a>a>a<< { - it("resets the domain level", () => { - const trie = parseTrie("a>a|b"); - const a = trie.get("a"); - const aa = a.get("a"); - const b = trie.get("b"); - - expect(aa).to.equal(true); - expect(b).to.equal(true); - }); - - it("works also on the top-level", () => { - const trie = parseTrie("a|b"); - const a = trie.get("a"); - const b = trie.get("b"); - - expect(a).to.equal(true); - expect(b).to.equal(true); - }); - - it("returns the expected trie", () => { - const trie = parseTrie("a>a>a|b>a|c"); - const a = trie.get("a"); - const aa = a.get("a"); - const aaa = aa.get("a"); - const b = trie.get("b"); - const ba = b.get("a"); - const c = trie.get("c"); - - expect(aaa).to.equal(true); - expect(ba).to.equal(true); - expect(c).to.equal(true); - }); - }); - - describe("complex cases", () => { - it("parses 'a>a>a>a<a>aa>a,b' without errors", () => { - const trie = parseTrie("a>a>a>a<a>aa>a,b"); - const a = trie.get("a"); - const aa = a.get("a"); - const aaa = aa.get("a"); - const aaaa = aaa.get("a"); - const ab = a.get("b"); - const ac = a.get("c"); - const b = trie.get("b"); - const ba = b.get("a"); - const baa = ba.get("a"); - const bb = b.get("b"); - const bba = bb.get("a"); - const bbaa = bba.get("a"); - const bbab = bba.get("b"); - - expect(aaaa).to.equal(true); - expect(ab).to.equal(true); - expect(ac).to.equal(true); - expect(baa).to.equal(true); - expect(bbaa).to.equal(true); - expect(bbab).to.equal(true); - }); - }); -});