UNPKG

4.05 kBJavaScriptView Raw
1"use strict";
2
3var _LINE_FILTERS;
4
5function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6
7var SEPARATORS = require("./separators");
8
9var TYPE_COMPLETE = "complete";
10var TYPE_LIGHT = "light";
11var POSSIBLE_TYPES = [TYPE_COMPLETE, TYPE_LIGHT];
12var LINE_FILTERS = (_LINE_FILTERS = {}, _defineProperty(_LINE_FILTERS, TYPE_COMPLETE, function () {
13 return true;
14}), _defineProperty(_LINE_FILTERS, TYPE_LIGHT, function (line) {
15 return line.length > 1;
16}), _LINE_FILTERS);
17
18function compareLinesAt(lineA, lineB, i) {
19 var endOfLineA = i === lineA.length;
20 var endOfLineB = i === lineB.length;
21
22 if (endOfLineA || endOfLineB) {
23 return lineA.length - lineB.length;
24 }
25
26 return lineA[i].localeCompare(lineB[i]) || compareLinesAt(lineA, lineB, i + 1);
27}
28
29function findIndexOfDifference(lineA, lineB) {
30 var maxLength = Math.max(lineA.length, lineB.length);
31 var i;
32
33 for (i = 0; i < maxLength; i++) {
34 if (lineA[i] !== lineB[i]) {
35 return i;
36 }
37 }
38
39 return -1;
40}
41
42function lineToString(line, i, arr) {
43 var indexOfDifference = 0;
44 var separatorFromPrev = "";
45
46 if (i > 0) {
47 var prevLine = arr[i - 1];
48 indexOfDifference = findIndexOfDifference(line, prevLine);
49
50 if (indexOfDifference === -1) {
51 // Identical lines
52 return "";
53 }
54
55 if (indexOfDifference === 0) {
56 // line and prevLine are completely different
57 separatorFromPrev = SEPARATORS.RESET;
58 } else if (indexOfDifference === prevLine.length - 1) {
59 // only the last part of line and prevLine are different
60 separatorFromPrev = SEPARATORS.SAME;
61 } else if (indexOfDifference > prevLine.length - 1) {
62 // we don't need to go up the hierarchy first because prevLine is part of line
63 // so let's just start with an initial down separator
64 separatorFromPrev = SEPARATORS.DOWN;
65 } else {
66 // line and prevLine are different, but share a common root at indexOfDifference - 1
67 // we now need to go up the hierarchy to the common root
68 var levelsUp = prevLine.length - indexOfDifference - 1;
69 /* istanbul ignore if */
70
71 if (levelsUp < 1) {
72 // This is just a sanity check to ensure that serializeTrie() fails early if
73 // public suffix contains some unexpected rules.
74 // separatorFromPrev should never be an empty string if i > 0
75 // See https://github.com/peerigon/parse-domain/pull/65
76 throw new Error("Cannot serialize trie: The public suffix list contains unexpected rules.");
77 }
78
79 separatorFromPrev = new Array(levelsUp).fill(SEPARATORS.UP).join("");
80 }
81 }
82
83 return separatorFromPrev + line.slice(indexOfDifference).join(SEPARATORS.DOWN);
84}
85
86function serializeTrie(parsedList, type) {
87 type = type || TYPE_COMPLETE;
88 /**
89 * parsedList looks like:
90 * [
91 * "com",
92 * "co.uk",
93 * "gov.uk",
94 * "静岡.jp",
95 * "岐阜.jp",
96 * "موقع"
97 * ]
98 *
99 * The resulting tree looks like this:
100 * com uk jp موقع
101 * / \ / \
102 * co gov 静岡 岐阜
103 *
104 * And the textual representation of the trie looks like (using SEPARATORS):
105 * com|uk>co,gov|jp>静岡,岐阜|موقع
106 *
107 * With type "light", all domains with no subdomain are excluded from the serialized trie:
108 * uk>co,gov|jp>静岡,岐阜
109 */
110
111 if (POSSIBLE_TYPES.indexOf(type) === -1) {
112 throw new Error("Cannot serialize trie: Unknown trie type \"".concat(type, "\". Expected type to be one of ").concat(POSSIBLE_TYPES.join(", ")));
113 }
114
115 return parsedList.map(function (line) {
116 return line.split(".");
117 }).filter(LINE_FILTERS[type]).map(function (line) {
118 return line.reverse();
119 }).sort(function (lineA, lineB) {
120 return compareLinesAt(lineA, lineB, 0);
121 }).map(lineToString).join("");
122}
123
124serializeTrie.TYPE_COMPLETE = TYPE_COMPLETE;
125serializeTrie.TYPE_LIGHT = TYPE_LIGHT;
126module.exports = serializeTrie;
\No newline at end of file