better-hosts 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 BlackGlory <woshenmedoubuzhidao@blackglory.me>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT GEYSERED TO THE WARRANTIES OF MERGEYSERERTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # better-hosts
2
+ Dead simple DNS server using syntax similar to hosts file.
3
+
4
+ ## Motivations
5
+ hosts works well, until:
6
+ 1. you need wildcard-based rules.
7
+ 2. you need to share records in the hosts file.
8
+ 3. you don't want to have to request administrator or root privileges every time you edit it.
9
+
10
+ better-hosts solves these problems by creating a DNS server that uses the hosts file.
11
+
12
+ ## Install
13
+ ```sh
14
+ npm install --global better-hosts
15
+ # or
16
+ yarn global add better-hosts
17
+ ```
18
+
19
+ ### Install from source code
20
+ ```sh
21
+ git clone git@github.com:BlackGlory/better-hosts.git
22
+ cd better-hosts
23
+ yarn install
24
+ yarn build
25
+ yarn global add "file:$(pwd)"
26
+ ```
27
+
28
+ ## Usage
29
+ ```sh
30
+ Usage: better-hosts [options] <filename>
31
+
32
+ Options:
33
+ -V, --version output the version number
34
+ --port <port> (default: "53")
35
+ --fallback-server <server>
36
+ --log <level> (default: "info")
37
+ -h, --help display help for command
38
+ ```
39
+
40
+ Example:
41
+ ```sh
42
+ better-hosts hosts.txt \
43
+ --port 5353 \
44
+ --fallback-server=1.1.1.1:53
45
+ ```
package/lib/cli.js ADDED
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const commander_1 = require("commander");
5
+ const server_1 = require("./server");
6
+ const errors_1 = require("@blackglory/errors");
7
+ const extra_logger_1 = require("extra-logger");
8
+ const parse_server_info_1 = require("./utils/parse-server-info");
9
+ const hosts_1 = require("./hosts");
10
+ commander_1.program
11
+ .name(require('../package.json').name)
12
+ .version(require('../package.json').version)
13
+ .description(require('../package.json').description)
14
+ .option('--port <port>', '', '53')
15
+ .option('--fallback-server <server>', '')
16
+ .option('--log <level>', '', 'info')
17
+ .argument('<filename>')
18
+ .action(async (filename) => {
19
+ const options = getOptions();
20
+ const logger = new extra_logger_1.Logger({
21
+ level: options.logLevel,
22
+ transport: new extra_logger_1.TerminalTransport({})
23
+ });
24
+ const hosts = new hosts_1.Hosts({
25
+ filename,
26
+ logger
27
+ });
28
+ const fallbackServer = (0, parse_server_info_1.parseServerInfo)(options.fallbackServer);
29
+ (0, server_1.startServer)({
30
+ logger,
31
+ hosts,
32
+ fallbackServer,
33
+ port: options.port
34
+ });
35
+ })
36
+ .parse();
37
+ function getOptions() {
38
+ const opts = commander_1.program.opts();
39
+ (0, errors_1.assert)(/^\d+$/.test(opts.port), 'The parameter port must be integer');
40
+ const port = Number.parseInt(opts.port, 10);
41
+ const fallbackServer = opts.fallbackServer;
42
+ const logLevel = (0, extra_logger_1.stringToLevel)(opts.log, 3);
43
+ return {
44
+ port,
45
+ fallbackServer,
46
+ logLevel
47
+ };
48
+ }
49
+ //# sourceMappingURL=cli.js.map
package/lib/cli.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AACA,yCAAmC;AACnC,qCAAsC;AACtC,+CAA2C;AAC3C,+CAA8E;AAC9E,gEAA0D;AAC1D,mCAA+B;AAE/B,mBAAO;KACJ,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC;KACrC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC;KAC3C,WAAW,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,WAAW,CAAC;KACnD,MAAM,CAAC,eAAe,EAAE,EAAE,EAAE,IAAI,CAAC;KACjC,MAAM,CAAC,4BAA4B,EAAE,EAAE,CAAC;KACxC,MAAM,CAAC,eAAe,EAAE,EAAE,EAAE,MAAM,CAAC;KACnC,QAAQ,CAAC,YAAY,CAAC;KACtB,MAAM,CAAC,KAAK,EAAE,QAAgB,EAAE,EAAE;IACjC,MAAM,OAAO,GAAG,UAAU,EAAE,CAAA;IAC5B,MAAM,MAAM,GAAG,IAAI,qBAAM,CAAC;QACxB,KAAK,EAAE,OAAO,CAAC,QAAQ;QACvB,SAAS,EAAE,IAAI,gCAAiB,CAAC,EAAE,CAAC;KACrC,CAAC,CAAA;IACF,MAAM,KAAK,GAAG,IAAI,aAAK,CAAC;QACtB,QAAQ;QACR,MAAM;KACP,CAAC,CAAA;IAEF,MAAM,cAAc,GAAG,IAAA,mCAAe,EAAC,OAAO,CAAC,cAAc,CAAC,CAAA;IAE9D,IAAA,oBAAW,EAAC;QACV,MAAM;QACN,KAAK;QACL,cAAc;QACd,IAAI,EAAE,OAAO,CAAC,IAAI;KACnB,CAAC,CAAA;AACJ,CAAC,CAAC;KACD,KAAK,EAAE,CAAA;AAEV,SAAS,UAAU;IACjB,MAAM,IAAI,GAAG,mBAAO,CAAC,IAAI,EAAE,CAAA;IAE3B,IAAA,eAAM,EAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,oCAAoC,CAAC,CAAA;IACrE,MAAM,IAAI,GAAW,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;IAEnD,MAAM,cAAc,GAAW,IAAI,CAAC,cAAc,CAAA;IAClD,MAAM,QAAQ,GAAU,IAAA,4BAAa,EAAC,IAAI,CAAC,GAAG,IAAa,CAAA;IAE3D,OAAO;QACL,IAAI;QACJ,cAAc;QACd,QAAQ;KACT,CAAA;AACH,CAAC"}
package/lib/hosts.js ADDED
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Hosts = void 0;
7
+ const is_ipv4_address_1 = require("./utils/is-ipv4-address");
8
+ const is_ipv6_address_1 = require("./utils/is-ipv6-address");
9
+ const hostname_pattern_1 = require("./utils/hostname-pattern");
10
+ const read_hosts_1 = require("./utils/read-hosts");
11
+ const chokidar_1 = __importDefault(require("chokidar"));
12
+ class Hosts {
13
+ constructor({ filename, logger }) {
14
+ this.records = [];
15
+ this.update(filename);
16
+ chokidar_1.default.watch(filename, { ignoreInitial: true }).on('change', () => {
17
+ this.update(filename);
18
+ logger.info('The hosts file updated');
19
+ });
20
+ }
21
+ update(filename) {
22
+ this.records = (0, read_hosts_1.readHosts)(filename).map(record => ({
23
+ pattern: new hostname_pattern_1.HostnamePattern(record.hostname),
24
+ address: record.address
25
+ }));
26
+ }
27
+ resolveA(hostname) {
28
+ const record = this.records.find(record => {
29
+ return record.pattern.match(hostname)
30
+ && (0, is_ipv4_address_1.isIPv4Address)(record.address);
31
+ });
32
+ return record === null || record === void 0 ? void 0 : record.address;
33
+ }
34
+ resolveAAAA(hostname) {
35
+ const record = this.records.find(record => {
36
+ return record.pattern.match(hostname)
37
+ && (0, is_ipv6_address_1.isIPv6Address)(record.address);
38
+ });
39
+ return record === null || record === void 0 ? void 0 : record.address;
40
+ }
41
+ }
42
+ exports.Hosts = Hosts;
43
+ //# sourceMappingURL=hosts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hosts.js","sourceRoot":"","sources":["../src/hosts.ts"],"names":[],"mappings":";;;;;;AAAA,4DAAsD;AACtD,4DAAsD;AACtD,8DAAyD;AACzD,kDAA6C;AAE7C,wDAA+B;AAO/B,MAAa,KAAK;IAGhB,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAwC;QAF9D,YAAO,GAAc,EAAE,CAAA;QAG7B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAErB,kBAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;YAClE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;YACrB,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAA;QACvC,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,MAAM,CAAC,QAAgB;QACrB,IAAI,CAAC,OAAO,GAAG,IAAA,sBAAS,EAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAChD,OAAO,EAAE,IAAI,kCAAe,CAAC,MAAM,CAAC,QAAQ,CAAC;YAC7C,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB,CAAC,CAAC,CAAA;IACL,CAAC;IAED,QAAQ,CAAC,QAAgB;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;YACxC,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC;mBAC9B,IAAA,+BAAa,EAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QACtC,CAAC,CAAC,CAAA;QACF,OAAO,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,OAAO,CAAA;IACxB,CAAC;IAED,WAAW,CAAC,QAAgB;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;YACxC,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC;mBAC9B,IAAA,+BAAa,EAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QACtC,CAAC,CAAC,CAAA;QACF,OAAO,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,OAAO,CAAA;IACxB,CAAC;CACF;AAlCD,sBAkCC"}
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ResourceRecordType = void 0;
4
+ var ResourceRecordType;
5
+ (function (ResourceRecordType) {
6
+ ResourceRecordType[ResourceRecordType["A"] = 1] = "A";
7
+ ResourceRecordType[ResourceRecordType["NS"] = 2] = "NS";
8
+ ResourceRecordType[ResourceRecordType["MD"] = 3] = "MD";
9
+ ResourceRecordType[ResourceRecordType["MF"] = 4] = "MF";
10
+ ResourceRecordType[ResourceRecordType["CNAME"] = 5] = "CNAME";
11
+ ResourceRecordType[ResourceRecordType["SOA"] = 6] = "SOA";
12
+ ResourceRecordType[ResourceRecordType["MB"] = 7] = "MB";
13
+ ResourceRecordType[ResourceRecordType["MG"] = 8] = "MG";
14
+ ResourceRecordType[ResourceRecordType["MR"] = 9] = "MR";
15
+ ResourceRecordType[ResourceRecordType["NULL"] = 10] = "NULL";
16
+ ResourceRecordType[ResourceRecordType["WKS"] = 11] = "WKS";
17
+ ResourceRecordType[ResourceRecordType["PTR"] = 12] = "PTR";
18
+ ResourceRecordType[ResourceRecordType["HINFO"] = 13] = "HINFO";
19
+ ResourceRecordType[ResourceRecordType["MINFO"] = 14] = "MINFO";
20
+ ResourceRecordType[ResourceRecordType["MX"] = 15] = "MX";
21
+ ResourceRecordType[ResourceRecordType["TXT"] = 16] = "TXT";
22
+ ResourceRecordType[ResourceRecordType["RP"] = 17] = "RP";
23
+ ResourceRecordType[ResourceRecordType["AFSDB"] = 18] = "AFSDB";
24
+ ResourceRecordType[ResourceRecordType["X25"] = 19] = "X25";
25
+ ResourceRecordType[ResourceRecordType["ISDN"] = 20] = "ISDN";
26
+ ResourceRecordType[ResourceRecordType["RT"] = 21] = "RT";
27
+ ResourceRecordType[ResourceRecordType["NSAP"] = 22] = "NSAP";
28
+ ResourceRecordType[ResourceRecordType["NSAP-PTR"] = 23] = "NSAP-PTR";
29
+ ResourceRecordType[ResourceRecordType["SIG"] = 24] = "SIG";
30
+ ResourceRecordType[ResourceRecordType["KEY"] = 25] = "KEY";
31
+ ResourceRecordType[ResourceRecordType["PX"] = 26] = "PX";
32
+ ResourceRecordType[ResourceRecordType["GPOS"] = 27] = "GPOS";
33
+ ResourceRecordType[ResourceRecordType["AAAA"] = 28] = "AAAA";
34
+ ResourceRecordType[ResourceRecordType["LOC"] = 29] = "LOC";
35
+ ResourceRecordType[ResourceRecordType["NXT"] = 30] = "NXT";
36
+ ResourceRecordType[ResourceRecordType["EID"] = 31] = "EID";
37
+ ResourceRecordType[ResourceRecordType["NIMLOC"] = 32] = "NIMLOC";
38
+ ResourceRecordType[ResourceRecordType["SRV"] = 33] = "SRV";
39
+ ResourceRecordType[ResourceRecordType["ATMA"] = 34] = "ATMA";
40
+ ResourceRecordType[ResourceRecordType["NAPTR"] = 35] = "NAPTR";
41
+ ResourceRecordType[ResourceRecordType["KX"] = 36] = "KX";
42
+ ResourceRecordType[ResourceRecordType["CERT"] = 37] = "CERT";
43
+ ResourceRecordType[ResourceRecordType["A6"] = 38] = "A6";
44
+ ResourceRecordType[ResourceRecordType["DNAME"] = 39] = "DNAME";
45
+ ResourceRecordType[ResourceRecordType["SINK"] = 40] = "SINK";
46
+ ResourceRecordType[ResourceRecordType["OPT"] = 41] = "OPT";
47
+ ResourceRecordType[ResourceRecordType["APL"] = 42] = "APL";
48
+ ResourceRecordType[ResourceRecordType["DS"] = 43] = "DS";
49
+ ResourceRecordType[ResourceRecordType["SSHFP"] = 44] = "SSHFP";
50
+ ResourceRecordType[ResourceRecordType["IPSECKEY"] = 45] = "IPSECKEY";
51
+ ResourceRecordType[ResourceRecordType["RRSIG"] = 46] = "RRSIG";
52
+ ResourceRecordType[ResourceRecordType["NSEC"] = 47] = "NSEC";
53
+ ResourceRecordType[ResourceRecordType["DNSKEY"] = 48] = "DNSKEY";
54
+ ResourceRecordType[ResourceRecordType["DHCID"] = 49] = "DHCID";
55
+ ResourceRecordType[ResourceRecordType["NSEC3"] = 50] = "NSEC3";
56
+ ResourceRecordType[ResourceRecordType["NSEC3PARAM"] = 51] = "NSEC3PARAM";
57
+ ResourceRecordType[ResourceRecordType["TLSA"] = 52] = "TLSA";
58
+ ResourceRecordType[ResourceRecordType["HIP"] = 55] = "HIP";
59
+ ResourceRecordType[ResourceRecordType["NINFO"] = 56] = "NINFO";
60
+ ResourceRecordType[ResourceRecordType["RKEY"] = 57] = "RKEY";
61
+ ResourceRecordType[ResourceRecordType["TALINK"] = 58] = "TALINK";
62
+ ResourceRecordType[ResourceRecordType["CDS"] = 59] = "CDS";
63
+ ResourceRecordType[ResourceRecordType["SPF"] = 99] = "SPF";
64
+ ResourceRecordType[ResourceRecordType["UINFO"] = 100] = "UINFO";
65
+ ResourceRecordType[ResourceRecordType["UID"] = 101] = "UID";
66
+ ResourceRecordType[ResourceRecordType["GID"] = 102] = "GID";
67
+ ResourceRecordType[ResourceRecordType["UNSPEC"] = 103] = "UNSPEC";
68
+ ResourceRecordType[ResourceRecordType["TKEY"] = 249] = "TKEY";
69
+ ResourceRecordType[ResourceRecordType["TSIG"] = 250] = "TSIG";
70
+ ResourceRecordType[ResourceRecordType["IXFR"] = 251] = "IXFR";
71
+ ResourceRecordType[ResourceRecordType["AXFR"] = 252] = "AXFR";
72
+ ResourceRecordType[ResourceRecordType["MAILB"] = 253] = "MAILB";
73
+ ResourceRecordType[ResourceRecordType["MAILA"] = 254] = "MAILA";
74
+ ResourceRecordType[ResourceRecordType["ANY"] = 255] = "ANY";
75
+ ResourceRecordType[ResourceRecordType["URI"] = 256] = "URI";
76
+ ResourceRecordType[ResourceRecordType["CAA"] = 257] = "CAA";
77
+ ResourceRecordType[ResourceRecordType["TA"] = 32768] = "TA";
78
+ ResourceRecordType[ResourceRecordType["DLV"] = 32769] = "DLV";
79
+ })(ResourceRecordType = exports.ResourceRecordType || (exports.ResourceRecordType = {}));
80
+ //# sourceMappingURL=resource-record-type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-record-type.js","sourceRoot":"","sources":["../src/resource-record-type.ts"],"names":[],"mappings":";;;AACA,IAAY,kBA0EX;AA1ED,WAAY,kBAAkB;IAC5B,qDAAK,CAAA;IACL,uDAAM,CAAA;IACN,uDAAM,CAAA;IACN,uDAAM,CAAA;IACN,6DAAS,CAAA;IACT,yDAAO,CAAA;IACP,uDAAM,CAAA;IACN,uDAAM,CAAA;IACN,uDAAM,CAAA;IACN,4DAAS,CAAA;IACT,0DAAQ,CAAA;IACR,0DAAQ,CAAA;IACR,8DAAU,CAAA;IACV,8DAAU,CAAA;IACV,wDAAO,CAAA;IACP,0DAAQ,CAAA;IACR,wDAAO,CAAA;IACP,8DAAU,CAAA;IACV,0DAAQ,CAAA;IACR,4DAAS,CAAA;IACT,wDAAO,CAAA;IACP,4DAAS,CAAA;IACT,oEAAe,CAAA;IACf,0DAAQ,CAAA;IACR,0DAAQ,CAAA;IACR,wDAAO,CAAA;IACP,4DAAS,CAAA;IACT,4DAAS,CAAA;IACT,0DAAQ,CAAA;IACR,0DAAQ,CAAA;IACR,0DAAQ,CAAA;IACR,gEAAW,CAAA;IACX,0DAAQ,CAAA;IACR,4DAAS,CAAA;IACT,8DAAU,CAAA;IACV,wDAAO,CAAA;IACP,4DAAS,CAAA;IACT,wDAAO,CAAA;IACP,8DAAU,CAAA;IACV,4DAAS,CAAA;IACT,0DAAQ,CAAA;IACR,0DAAQ,CAAA;IACR,wDAAO,CAAA;IACP,8DAAU,CAAA;IACV,oEAAa,CAAA;IACb,8DAAU,CAAA;IACV,4DAAS,CAAA;IACT,gEAAW,CAAA;IACX,8DAAU,CAAA;IACV,8DAAU,CAAA;IACV,wEAAe,CAAA;IACf,4DAAS,CAAA;IACT,0DAAQ,CAAA;IACR,8DAAU,CAAA;IACV,4DAAS,CAAA;IACT,gEAAW,CAAA;IACX,0DAAQ,CAAA;IACR,0DAAQ,CAAA;IACR,+DAAW,CAAA;IACX,2DAAS,CAAA;IACT,2DAAS,CAAA;IACT,iEAAY,CAAA;IACZ,6DAAU,CAAA;IACV,6DAAU,CAAA;IACV,6DAAU,CAAA;IACV,6DAAU,CAAA;IACV,+DAAW,CAAA;IACX,+DAAW,CAAA;IACX,2DAAS,CAAA;IACT,2DAAS,CAAA;IACT,2DAAS,CAAA;IACT,2DAAU,CAAA;IACV,6DAAW,CAAA;AACb,CAAC,EA1EW,kBAAkB,GAAlB,0BAAkB,KAAlB,0BAAkB,QA0E7B"}
package/lib/server.js ADDED
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.startServer = void 0;
30
+ const dns = __importStar(require("native-node-dns"));
31
+ const extra_promise_1 = require("extra-promise");
32
+ const resource_record_type_1 = require("./resource-record-type");
33
+ const return_style_1 = require("return-style");
34
+ const chalk_1 = __importDefault(require("chalk"));
35
+ const ms_1 = __importDefault(require("ms"));
36
+ const types_1 = require("@blackglory/types");
37
+ const go_1 = require("@blackglory/go");
38
+ function startServer({ logger, port, hosts, fallbackServer }) {
39
+ const server = dns.createServer();
40
+ server.on('error', console.error);
41
+ server.on('socketError', console.error);
42
+ server.on('request', async (req, res) => {
43
+ const answers = await (0, extra_promise_1.map)(req.question, async (question) => {
44
+ logger.trace(`${formatHostname(question.name)} ${resource_record_type_1.ResourceRecordType[question.type]}`);
45
+ const address = (0, go_1.go)(() => {
46
+ switch (question.type) {
47
+ case resource_record_type_1.ResourceRecordType.A: return hosts.resolveA(question.name);
48
+ case resource_record_type_1.ResourceRecordType.AAAA: return hosts.resolveAAAA(question.name);
49
+ }
50
+ });
51
+ if ((0, types_1.isntUndefined)(address)) {
52
+ logger.info(`${formatHostname(question.name)} ${address}`);
53
+ return [
54
+ {
55
+ name: question.name,
56
+ type: question.type,
57
+ class: question.class,
58
+ address,
59
+ ttl: 0
60
+ }
61
+ ];
62
+ }
63
+ const startTime = Date.now();
64
+ const [err, answers] = await (0, return_style_1.getErrorResultAsync)(() => resolve(fallbackServer, question));
65
+ if (err) {
66
+ logger.error(`${formatHostname(question.name)} ${err}`, getElapsed(startTime));
67
+ return [];
68
+ }
69
+ logger.info(`${formatHostname(question.name)} ${resource_record_type_1.ResourceRecordType[question.type]}`, getElapsed(startTime));
70
+ return answers;
71
+ });
72
+ answers
73
+ .flat()
74
+ .forEach(answer => res.answer.push(answer));
75
+ res.send();
76
+ });
77
+ return server.serve(port);
78
+ }
79
+ exports.startServer = startServer;
80
+ function resolve(server, question) {
81
+ return new Promise((resolve, reject) => {
82
+ const answers = [];
83
+ const request = dns.Request({
84
+ question,
85
+ server: {
86
+ address: server.host,
87
+ port: server.port,
88
+ type: 'udp'
89
+ },
90
+ timeout: (0, ms_1.default)('30s'),
91
+ cache: false,
92
+ try_edns: true
93
+ });
94
+ request.on('timeout', () => reject());
95
+ request.on('cancelled', () => reject());
96
+ request.on('end', () => resolve(answers));
97
+ request.on('message', (err, msg) => {
98
+ if (err)
99
+ return reject(err);
100
+ msg.answer.forEach(answer => answers.push(answer));
101
+ });
102
+ request.send();
103
+ });
104
+ }
105
+ function formatHostname(hostname) {
106
+ return chalk_1.default.cyan(hostname);
107
+ }
108
+ function getElapsed(startTime) {
109
+ return Date.now() - startTime;
110
+ }
111
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HostnamePattern = void 0;
4
+ class HostnamePattern {
5
+ constructor(pattern) {
6
+ const re = pattern.replace(/\./g, '\\.')
7
+ .replace(/\*/g, '.*');
8
+ this.re = new RegExp(`^${re}$`, 'i');
9
+ }
10
+ match(hostname) {
11
+ return this.re.test(hostname);
12
+ }
13
+ }
14
+ exports.HostnamePattern = HostnamePattern;
15
+ //# sourceMappingURL=hostname-pattern.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hostname-pattern.js","sourceRoot":"","sources":["../../src/utils/hostname-pattern.ts"],"names":[],"mappings":";;;AAAA,MAAa,eAAe;IAG1B,YAAY,OAAe;QACzB,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;aACrB,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QACvC,IAAI,CAAC,EAAE,GAAG,IAAI,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;IACtC,CAAC;IAED,KAAK,CAAC,QAAgB;QACpB,OAAO,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IAC/B,CAAC;CACF;AAZD,0CAYC"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isIPv4Address = void 0;
4
+ function isIPv4Address(text) {
5
+ return /^[\d\.]+$/.test(text);
6
+ }
7
+ exports.isIPv4Address = isIPv4Address;
8
+ //# sourceMappingURL=is-ipv4-address.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"is-ipv4-address.js","sourceRoot":"","sources":["../../src/utils/is-ipv4-address.ts"],"names":[],"mappings":";;;AAAA,SAAgB,aAAa,CAAC,IAAY;IACxC,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAC/B,CAAC;AAFD,sCAEC"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isIPv6Address = void 0;
4
+ function isIPv6Address(text) {
5
+ return /^[\da-f:]+$/.test(text);
6
+ }
7
+ exports.isIPv6Address = isIPv6Address;
8
+ //# sourceMappingURL=is-ipv6-address.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"is-ipv6-address.js","sourceRoot":"","sources":["../../src/utils/is-ipv6-address.ts"],"names":[],"mappings":";;;AAAA,SAAgB,aAAa,CAAC,IAAY;IACxC,OAAO,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACjC,CAAC;AAFD,sCAEC"}
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseServerInfo = void 0;
4
+ function parseServerInfo(server) {
5
+ const [host, port] = server.split(':');
6
+ return {
7
+ host,
8
+ port: port ? Number.parseInt(port, 10) : undefined
9
+ };
10
+ }
11
+ exports.parseServerInfo = parseServerInfo;
12
+ //# sourceMappingURL=parse-server-info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-server-info.js","sourceRoot":"","sources":["../../src/utils/parse-server-info.ts"],"names":[],"mappings":";;;AAKA,SAAgB,eAAe,CAAC,MAAc;IAC5C,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAiC,CAAA;IACtE,OAAO;QACL,IAAI;QACJ,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS;KACnD,CAAA;AACH,CAAC;AAND,0CAMC"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.readHosts = void 0;
27
+ const hostile = __importStar(require("hostile"));
28
+ function readHosts(filename) {
29
+ const lines = hostile.getFile(filename, false);
30
+ const records = lines.map(([address, hostname]) => ({
31
+ hostname: hostname.toLowerCase(),
32
+ address
33
+ }));
34
+ return records;
35
+ }
36
+ exports.readHosts = readHosts;
37
+ //# sourceMappingURL=read-hosts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-hosts.js","sourceRoot":"","sources":["../../src/utils/read-hosts.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iDAAkC;AAOlC,SAAgB,SAAS,CAAC,QAAgB;IACxC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;IAC9C,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;QAClD,QAAQ,EAAE,QAAQ,CAAC,WAAW,EAAE;QAChC,OAAO;KACR,CAAC,CAAC,CAAA;IACH,OAAO,OAAO,CAAA;AAChB,CAAC;AAPD,8BAOC"}
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "better-hosts",
3
+ "version": "0.1.0",
4
+ "description": "",
5
+ "keywords": [
6
+ "dns"
7
+ ],
8
+ "bin": "lib/cli.js",
9
+ "files": [
10
+ "lib"
11
+ ],
12
+ "repository": "git@github.com:BlackGlory/better-hosts.git",
13
+ "author": "BlackGlory <woshenmedoubuzhidao@blackglory.me>",
14
+ "license": "MIT",
15
+ "scripts": {
16
+ "lint": "eslint --ext .js,.jsx,.ts,.tsx --quiet src",
17
+ "test": "jest --config jest.config.js",
18
+ "test:debug": "node --inspect-brk node_modules/.bin/jest --runInBand",
19
+ "test:coverage": "jest --coverage --config jest.config.js",
20
+ "clean": "rimraf lib",
21
+ "build": "run-s build:*",
22
+ "build:compile": "tsc --project tsconfig.build.json",
23
+ "build:patch": "tscpaths --project tsconfig.build.json --src ./src --out ./lib",
24
+ "release": "standard-version"
25
+ },
26
+ "husky": {
27
+ "hooks": {
28
+ "pre-commit": "run-s lint build test",
29
+ "commit-msg": "commitlint --env HUSKY_GIT_PARAMS"
30
+ }
31
+ },
32
+ "devDependencies": {
33
+ "@commitlint/cli": "^16.2.1",
34
+ "@commitlint/config-conventional": "^16.2.1",
35
+ "@types/hostile": "^1.3.0",
36
+ "@types/jest": "^27.4.1",
37
+ "@types/ms": "^0.7.31",
38
+ "@types/node": "14",
39
+ "@typescript-eslint/eslint-plugin": "^5.13.0",
40
+ "@typescript-eslint/parser": "^5.13.0",
41
+ "eslint": "^8.10.0",
42
+ "husky": "4",
43
+ "jest": "^27.5.1",
44
+ "npm-run-all": "^4.1.5",
45
+ "rimraf": "^3.0.2",
46
+ "standard-version": "^9.3.2",
47
+ "ts-jest": "^27.1.3",
48
+ "tsconfig-paths": "^3.12.0",
49
+ "tscpaths": "^0.0.9",
50
+ "typescript": "^4.6.2"
51
+ },
52
+ "dependencies": {
53
+ "@blackglory/errors": "^2.2.0",
54
+ "@blackglory/go": "^0.1.1",
55
+ "@blackglory/types": "^0.6.5",
56
+ "chalk": "^4.1.2",
57
+ "chokidar": "^3.5.3",
58
+ "commander": "^9.0.0",
59
+ "extra-logger": "^0.6.4",
60
+ "extra-promise": "^0.21.2",
61
+ "hostile": "^1.3.3",
62
+ "ms": "^2.1.3",
63
+ "native-node-dns": "^0.7.6",
64
+ "return-style": "^0.12.6"
65
+ }
66
+ }