@nictool/dns-resource-record 1.2.1 → 1.2.3

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/CHANGELOG.md CHANGED
@@ -4,6 +4,20 @@ Notable changes to this project are documented in this file.
4
4
 
5
5
  #### Unreleased
6
6
 
7
+ ### [1.2.3] - 2025-04-14
8
+
9
+ - test(\*): fully qualify node modules
10
+ - feat(rr.isIPv?): added regexes to validate format
11
+ - dep(node:{net|util): remove, for browser compatiblity
12
+ - doc(CONTRIBUTORS.md): added
13
+ - ci: disable codeql schedule (#45)
14
+
15
+ ### [1.2.2] - 2024-11-17
16
+
17
+ - dep(eslint): update to v9 & config
18
+ - chore: tighten up fromBind regex
19
+ - packaging tweaks (#43)
20
+
7
21
  ### [1.2.1] - 2024-03-10
8
22
 
9
23
  - fix(nsec3param): fixed setHash fname typo
@@ -294,4 +308,8 @@ Notable changes to this project are documented in this file.
294
308
  [1.1.5]: https://github.com/NicTool/dns-resource-record/releases/tag/1.1.5
295
309
  [1.1.6]: https://github.com/NicTool/dns-resource-record/releases/tag/1.1.6
296
310
  [1.1.8]: https://github.com/NicTool/dns-resource-record/releases/tag/1.1.8
297
- [1.2.1]: https://github.com/NicTool/dns-resource-record/releases/tag/1.2.1
311
+ [1.1.7]: https://github.com/NicTool/dns-resource-record/releases/tag/1.1.7
312
+ [1.2.0]: https://github.com/NicTool/dns-resource-record/releases/tag/1.2.0
313
+ [1.2.1]: https://github.com/NicTool/dns-resource-record/releases/tag/v1.2.1
314
+ [1.2.2]: https://github.com/NicTool/dns-resource-record/releases/tag/1.2.2
315
+ [1.2.3]: https://github.com/NicTool/dns-resource-record/releases/tag/v1.2.3
package/README.md CHANGED
@@ -20,7 +20,7 @@ This module is used to:
20
20
  | **MaraDNS** | | :white_check_mark: |
21
21
  | **JS** | :white_check_mark: | :white_check_mark: |
22
22
 
23
- This package intends to import and export RFC compliant DNS resource records. Please [raise an issue](https://github.com/NicTool/dns-resource-record/issues) if you a valid resource record fails to pass or an invalid resource record passes.
23
+ This package intends to import and export RFC compliant DNS resource records. Please [raise an issue](https://github.com/NicTool/dns-resource-record/issues) if a valid resource record fails to pass or an invalid resource record passes.
24
24
 
25
25
  This package is for working with _individual_ Resource Records. For working with zones of RRs, use [dns-zone](https://github.com/NicTool/dns-zone).
26
26
 
@@ -239,6 +239,8 @@ PRs are welcome, especially PRs with tests.
239
239
 
240
240
  - [Dictionary of DNS terms](https://nictool.github.io/web/Dictionary)
241
241
  - [Wikipedia, List of DNS Record Types](https://en.wikipedia.org/wiki/List_of_DNS_record_types)
242
+ - @nictool/[dns-zone](https://www.npmjs.com/package/@nictool/dns-zone)
243
+ - @nictool/[dns-nameserver](https://www.npmjs.com/package/@nictool/dns-nameserver)
242
244
 
243
245
  ## TODO
244
246
 
package/package.json CHANGED
@@ -1,8 +1,14 @@
1
1
  {
2
2
  "name": "@nictool/dns-resource-record",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "description": "DNS Resource Records",
5
5
  "main": "index.js",
6
+ "files": [
7
+ "lib",
8
+ "rr",
9
+ "CHANGELOG.md",
10
+ "rr.js"
11
+ ],
6
12
  "type": "module",
7
13
  "scripts": {
8
14
  "format:check": "npm run prettier; npm run lint",
@@ -39,6 +45,14 @@
39
45
  },
40
46
  "homepage": "https://github.com/NicTool/dns-resource-record#readme",
41
47
  "devDependencies": {
42
- "mocha": "^10.3.0"
48
+ "@eslint/js": "^10.0.0",
49
+ "eslint": "^9.15.0",
50
+ "globals": "^16.0.0",
51
+ "mocha": "^11.2.2"
52
+ },
53
+ "prettier": {
54
+ "semi": false,
55
+ "singleQuote": true,
56
+ "trailingComma": "all"
43
57
  }
44
58
  }
package/rr/a.js CHANGED
@@ -1,5 +1,3 @@
1
- import net from 'node:net'
2
-
3
1
  import RR from '../rr.js'
4
2
 
5
3
  export default class A extends RR {
@@ -10,7 +8,7 @@ export default class A extends RR {
10
8
  /****** Resource record specific setters *******/
11
9
  setAddress(val) {
12
10
  if (!val) this.throwHelp('A: address is required')
13
- if (!net.isIPv4(val)) this.throwHelp('A address must be IPv4')
11
+ if (!this.isIPv4(val)) this.throwHelp('A address must be IPv4')
14
12
  this.set('address', val)
15
13
  }
16
14
 
package/rr/aaaa.js CHANGED
@@ -1,5 +1,3 @@
1
- import net from 'node:net'
2
-
3
1
  import RR from '../rr.js'
4
2
  import * as TINYDNS from '../lib/tinydns.js'
5
3
 
@@ -11,7 +9,7 @@ export default class AAAA extends RR {
11
9
  /****** Resource record specific setters *******/
12
10
  setAddress(val) {
13
11
  if (!val) this.throwHelp('AAAA: address is required')
14
- if (!net.isIPv6(val)) this.throwHelp(`AAAA: address must be IPv6 (${val})`)
12
+ if (!this.isIPv6(val)) this.throwHelp(`AAAA: address must be IPv6 (${val})`)
15
13
 
16
14
  this.set('address', this.expand(val.toLowerCase())) // lower case: RFC 5952
17
15
  }
package/rr/caa.js CHANGED
@@ -108,9 +108,11 @@ export default class CAA extends RR {
108
108
 
109
109
  fromBind(opts) {
110
110
  // test.example.com 3600 IN CAA flags, tags, value
111
- const fields = opts.bindline.match(
112
- /^([^\s]+)\s+([0-9]+)\s+(\w+)\s+(\w+)\s+([0-9]+)\s+(\w+)\s+("[^"]+"|[^\s]+?)\s*$/i,
113
- )
111
+ const fields = opts.bindline
112
+ .trim()
113
+ .match(
114
+ /^([\S]+)\s+([0-9]{1,10})\s+(IN)\s+(CAA)\s+([0-9]+)\s+(\w+)\s+("[^"]+"|[\S]+?)$/i,
115
+ )
114
116
  if (!fields) this.throwHelp(`unable to parse: ${opts.bindline}`)
115
117
 
116
118
  const [owner, ttl, c, type, flags, tag, value] = fields.slice(1)
package/rr/cname.js CHANGED
@@ -1,5 +1,3 @@
1
- import net from 'node:net'
2
-
3
1
  import RR from '../rr.js'
4
2
 
5
3
  export default class CNAME extends RR {
@@ -14,7 +12,7 @@ export default class CNAME extends RR {
14
12
 
15
13
  if (!val) this.throwHelp('CNAME: cname is required')
16
14
 
17
- if (net.isIPv4(val) || net.isIPv6(val))
15
+ if (this.isIPv4(val) || this.isIPv6(val))
18
16
  this.throwHelp(`CNAME: cname must be a FQDN: RFC 2181`)
19
17
 
20
18
  if (!this.isFullyQualified('CNAME', 'cname', val)) return
package/rr/dname.js CHANGED
@@ -1,5 +1,3 @@
1
- import net from 'node:net'
2
-
3
1
  import RR from '../rr.js'
4
2
  import * as TINYDNS from '../lib/tinydns.js'
5
3
 
@@ -12,7 +10,7 @@ export default class DNAME extends RR {
12
10
  setTarget(val) {
13
11
  if (!val) this.throwHelp('DNAME: target is required')
14
12
 
15
- if (net.isIPv4(val) || net.isIPv6(val))
13
+ if (this.isIPv4(val) || this.isIPv6(val))
16
14
  this.throwHelp(`DNAME: target must be a domain name`)
17
15
 
18
16
  this.isFullyQualified('DNAME', 'target', val)
package/rr/hinfo.js CHANGED
@@ -41,9 +41,11 @@ export default class HINFO extends RR {
41
41
  /****** IMPORTERS *******/
42
42
  fromBind(opts) {
43
43
  // test.example.com 3600 IN HINFO DEC-2060 TOPS20
44
- const match = opts.bindline.match(
45
- /([^\s]+)\s+([0-9]+)\s+(IN)\s+(HINFO)\s+("[^"]+"|[^\s]+)\s+("[^"]+"|[^\s]+)/i,
46
- )
44
+ const match = opts.bindline
45
+ .trim()
46
+ .match(
47
+ /^([\S]+)\s+([0-9]{1,10})\s+(IN)\s+(HINFO)\s+("[^"]+"|[\S]+)\s+("[^"]+"|[\S]+)/i,
48
+ )
47
49
  if (!match) this.throwHelp(`unable to parse HINFO: ${opts.bindline}`)
48
50
  const [owner, ttl, c, type, cpu, os] = match.slice(1)
49
51
 
package/rr/ipseckey.js CHANGED
@@ -1,5 +1,3 @@
1
- import net from 'node:net'
2
-
3
1
  import RR from '../rr.js'
4
2
 
5
3
  import * as TINYDNS from '../lib/tinydns.js'
@@ -39,10 +37,10 @@ export default class IPSECKEY extends RR {
39
37
  if (val !== '.') throw gwErr
40
38
  break
41
39
  case 1:
42
- if (!net.isIPv4(val)) throw gwErr
40
+ if (!this.isIPv4(val)) throw gwErr
43
41
  break
44
42
  case 2:
45
- if (!net.isIPv6(val)) throw gwErr
43
+ if (!this.isIPv6(val)) throw gwErr
46
44
  break
47
45
  }
48
46
 
package/rr/mx.js CHANGED
@@ -1,5 +1,3 @@
1
- import net from 'node:net'
2
-
3
1
  import RR from '../rr.js'
4
2
 
5
3
  export default class MX extends RR {
@@ -18,7 +16,7 @@ export default class MX extends RR {
18
16
  setExchange(val) {
19
17
  if (!val) this.throwHelp('MX: exchange is required')
20
18
 
21
- if (net.isIPv4(val) || net.isIPv6(val))
19
+ if (this.isIPv4(val) || this.isIPv6(val))
22
20
  this.throwHelp(`MX: exchange must be a FQDN`)
23
21
 
24
22
  this.isFullyQualified('MX', 'exchange', val)
package/rr/openpgpkey.js CHANGED
@@ -30,9 +30,9 @@ export default class OPENPGPKEY extends RR {
30
30
  fromBind(obj) {
31
31
  // test.example.com 3600 IN OPENPGPKEY <base64 public key>
32
32
  // eslint-disable-next-line no-unused-vars
33
- const [ignore, owner, ttl, c, type, publickey] = obj.bindline.match(
34
- /^([\S]+)\s+(\d+)\s+(\w+)\s+(\w+)\s+([\W\w]*)$/,
35
- )
33
+ const [ignore, owner, ttl, c, type, publickey] = obj.bindline
34
+ .trim()
35
+ .match(/^([\S]+)\s+(\d{1,10})\s+(IN)\s+(OPENPGPKEY)\s+([\W\w]*)$/)
36
36
 
37
37
  return new OPENPGPKEY({
38
38
  owner,
package/rr/srv.js CHANGED
@@ -1,5 +1,3 @@
1
- import net from 'node:net'
2
-
3
1
  import RR from '../rr.js'
4
2
  import * as TINYDNS from '../lib/tinydns.js'
5
3
 
@@ -30,7 +28,7 @@ export default class SRV extends RR {
30
28
  setTarget(val) {
31
29
  if (!val) this.throwHelp(`SRV: target is required`)
32
30
 
33
- if (net.isIPv4(val) || net.isIPv6(val))
31
+ if (this.isIPv4(val) || this.isIPv6(val))
34
32
  this.throwHelp(`SRV: target must be a FQDN`)
35
33
 
36
34
  this.isFullyQualified('SRV', 'target', val)
package/rr/tlsa.js CHANGED
@@ -60,9 +60,11 @@ export default class TLSA extends RR {
60
60
 
61
61
  fromBind(opts) {
62
62
  // test.example.com 3600 IN TLSA, usage, selector, match, data
63
- const match = opts.bindline.split(
64
- /^([^\s]+)\s+([0-9]+)\s+(\w+)\s+(\w+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+(.*?)\s*$/,
65
- )
63
+ const match = opts.bindline
64
+ .trim()
65
+ .split(
66
+ /^([^\s]+)\s+([0-9]{1,10})\s+(IN)\s+(TLSA)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+(.*?)$/,
67
+ )
66
68
  if (!match) this.throwHelp(`unable to parse TLSA: ${opts.bindline}`)
67
69
  const [owner, ttl, c, type, usage, selector, matchtype, cad] =
68
70
  match.slice(1)
package/rr/txt.js CHANGED
@@ -70,9 +70,9 @@ export default class TXT extends RR {
70
70
 
71
71
  fromBind(opts) {
72
72
  // test.example.com 3600 IN TXT "..."
73
- const match = opts.bindline.split(
74
- /^([^\s]+)\s+([0-9]+)\s+(\w+)\s+(\w+)\s+?\s*(.*?)\s*$/,
75
- )
73
+ const match = opts.bindline
74
+ .trim()
75
+ .split(/^([\S]{1,255})\s+([0-9]{1,10})\s+(IN)\s+(\w{3})\s+?\s*(.*?)$/i)
76
76
  if (!match) this.throwHelp(`unable to parse TXT: ${opts.bindline}`)
77
77
  const [owner, ttl, c, type, rdata] = match.slice(1)
78
78
 
package/rr.js CHANGED
@@ -1,5 +1,3 @@
1
- import util from 'node:util'
2
-
3
1
  export default class RR extends Map {
4
2
  constructor(opts) {
5
3
  super()
@@ -128,7 +126,7 @@ export default class RR extends Map {
128
126
  if (this.constructor.name === 'RR') throw new Error(e)
129
127
 
130
128
  const example = this.getCanonical
131
- ? `Example ${this.constructor.name}:\n${util.inspect(this.getCanonical(), { depth: null })}\n\n`
129
+ ? `Example ${this.constructor.name}:\n${this.getCanonical()}\n\n`
132
130
  : `${this.constructor.name} records have the fields: ${this.getFields().join(', ')}\n\n`
133
131
 
134
132
  throw new Error(`${e}\n\n${example}${this.citeRFC()}\n`)
@@ -313,6 +311,17 @@ export default class RR extends Map {
313
311
  )
314
312
  }
315
313
 
314
+ isIPv4(string) {
315
+ // https://stackoverflow.com/questions/5284147/validating-ipv4-addresses-with-regexp
316
+ return /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$/.test(string)
317
+ }
318
+
319
+ isIPv6(string) {
320
+ return /^(?:(?:[a-fA-F\d]{1,4}:){7}(?:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){6}(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){5}(?::(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,2}|:)|(?:[a-fA-F\d]{1,4}:){4}(?:(?::[a-fA-F\d]{1,4}){0,1}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,3}|:)|(?:[a-fA-F\d]{1,4}:){3}(?:(?::[a-fA-F\d]{1,4}){0,2}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,4}|:)|(?:[a-fA-F\d]{1,4}:){2}(?:(?::[a-fA-F\d]{1,4}){0,3}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,5}|:)|(?:[a-fA-F\d]{1,4}:){1}(?:(?::[a-fA-F\d]{1,4}){0,4}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,6}|:)|(?::(?:(?::[a-fA-F\d]{1,4}){0,5}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,7}|:)))(?:%[0-9a-zA-Z]{1,})?$/gm.test(
321
+ string,
322
+ )
323
+ }
324
+
316
325
  toBind(zone_opts) {
317
326
  return `${this.getPrefix(zone_opts)}\t${this.getRdataFields()
318
327
  .map((f) => this.getQuoted(f))