@nictool/dns-resource-record 1.2.4 → 1.3.1

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/rr/srv.js CHANGED
@@ -28,8 +28,7 @@ export default class SRV extends RR {
28
28
  setTarget(val) {
29
29
  if (!val) this.throwHelp(`SRV: target is required`)
30
30
 
31
- if (this.isIPv4(val) || this.isIPv6(val))
32
- this.throwHelp(`SRV: target must be a FQDN`)
31
+ if (this.isIPv4(val) || this.isIPv6(val)) this.throwHelp(`SRV: target must be a FQDN`)
33
32
 
34
33
  this.isFullyQualified('SRV', 'target', val)
35
34
  this.isValidHostname('SRV', 'target', val)
@@ -61,9 +60,7 @@ export default class SRV extends RR {
61
60
 
62
61
  if (str[0] === 'S') {
63
62
  // patched tinydns with S records
64
- ;[fqdn, addr, port, pri, weight, ttl, ts, loc] = str
65
- .substring(1)
66
- .split(':')
63
+ ;[fqdn, addr, port, pri, weight, ttl, ts, loc] = str.substring(1).split(':')
67
64
  } else {
68
65
  // tinydns generic record format
69
66
  ;[fqdn, n, rdata, ttl, ts, loc] = str.substring(1).split(':')
@@ -90,8 +87,7 @@ export default class SRV extends RR {
90
87
 
91
88
  fromBind(opts) {
92
89
  // test.example.com 3600 IN SRV Priority Weight Port Target
93
- const [owner, ttl, c, type, pri, weight, port, target] =
94
- opts.bindline.split(/\s+/)
90
+ const [owner, ttl, c, type, pri, weight, port, target] = opts.bindline.split(/\s+/)
95
91
  return new SRV({
96
92
  owner: owner,
97
93
  ttl: parseInt(ttl, 10),
package/rr/svcb.js CHANGED
@@ -1,5 +1,7 @@
1
1
  import RR from '../rr.js'
2
2
 
3
+ import * as TINYDNS from '../lib/tinydns.js'
4
+
3
5
  export default class SVCB extends RR {
4
6
  constructor(opts) {
5
7
  super(opts)
@@ -61,4 +63,14 @@ export default class SVCB extends RR {
61
63
  }
62
64
 
63
65
  /****** EXPORTERS *******/
66
+
67
+ toTinydns() {
68
+ const dataRe = new RegExp(/[\r\n\t:\\/]/, 'g')
69
+
70
+ return this.getTinydnsGeneric(
71
+ TINYDNS.UInt16toOctal(this.get('priority')) +
72
+ TINYDNS.packDomainName(this.get('target name')) +
73
+ TINYDNS.escapeOctal(dataRe, this.get('params')),
74
+ )
75
+ }
64
76
  }
package/rr/tlsa.js CHANGED
@@ -9,8 +9,7 @@ export default class TLSA extends RR {
9
9
 
10
10
  /****** Resource record specific setters *******/
11
11
  setCertificateUsage(val) {
12
- if (!this.getCertificateUsageOptions().has(val))
13
- this.throwHelp(`TLSA: certificate usage invalid`)
12
+ if (!this.getCertificateUsageOptions().has(val)) this.throwHelp(`TLSA: certificate usage invalid`)
14
13
 
15
14
  this.set('certificate usage', val)
16
15
  }
@@ -25,8 +24,7 @@ export default class TLSA extends RR {
25
24
  }
26
25
 
27
26
  setSelector(val) {
28
- if (!this.getSelectorOptions().has(val))
29
- this.throwHelp(`TLSA: selector invalid`)
27
+ if (!this.getSelectorOptions().has(val)) this.throwHelp(`TLSA: selector invalid`)
30
28
 
31
29
  this.set('selector', val)
32
30
  }
@@ -39,8 +37,7 @@ export default class TLSA extends RR {
39
37
  }
40
38
 
41
39
  setMatchingType(val) {
42
- if (!this.getMatchingTypeOptions().has(val))
43
- this.throwHelp(`TLSA: matching type`)
40
+ if (!this.getMatchingTypeOptions().has(val)) this.throwHelp(`TLSA: matching type`)
44
41
 
45
42
  this.set('matching type', val)
46
43
  }
@@ -62,12 +59,7 @@ export default class TLSA extends RR {
62
59
  }
63
60
 
64
61
  getRdataFields(arg) {
65
- return [
66
- 'certificate usage',
67
- 'selector',
68
- 'matching type',
69
- 'certificate association data',
70
- ]
62
+ return ['certificate usage', 'selector', 'matching type', 'certificate association data']
71
63
  }
72
64
 
73
65
  getRFCs() {
@@ -86,19 +78,17 @@ export default class TLSA extends RR {
86
78
 
87
79
  fromBind(opts) {
88
80
  // test.example.com 3600 IN TLSA, usage, selector, match, data
89
- const match = opts.bindline
90
- .trim()
91
- .split(
92
- /^([^\s]+)\s+([0-9]{1,10})\s+(IN)\s+(TLSA)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+(.*?)$/,
93
- )
81
+ const regex =
82
+ /^(?<owner>\S+)\s+(?<ttl>\d{1,10})\s+(?<cls>IN)\s+(?<type>TLSA)\s+(?<usage>\d+)\s+(?<selector>\d+)\s+(?<matchtype>\d+)\s+(?<cad>.+)$/i
83
+ const match = opts.bindline.trim().match(regex)
94
84
  if (!match) this.throwHelp(`unable to parse TLSA: ${opts.bindline}`)
95
- const [owner, ttl, c, type, usage, selector, matchtype, cad] =
96
- match.slice(1)
85
+ const { owner, ttl, cls, type, usage, selector, matchtype, cad } = match.groups
86
+
97
87
  return new TLSA({
98
88
  owner: this.fullyQualify(owner),
99
89
  ttl: parseInt(ttl, 10),
100
- class: c,
101
- type,
90
+ class: cls.toUpperCase(),
91
+ type: type.toUpperCase(),
102
92
  'certificate usage': parseInt(usage, 10),
103
93
  selector: parseInt(selector, 10),
104
94
  'matching type': parseInt(matchtype, 10),
package/rr/tsig.js CHANGED
@@ -13,15 +13,7 @@ export default class TSIG extends RR {
13
13
  }
14
14
 
15
15
  getRdataFields(arg) {
16
- return [
17
- 'algorithm name',
18
- 'time signed',
19
- 'fudge',
20
- 'mac',
21
- 'original id',
22
- 'error',
23
- 'other',
24
- ]
16
+ return ['algorithm name', 'time signed', 'fudge', 'mac', 'original id', 'error', 'other']
25
17
  }
26
18
 
27
19
  getRFCs() {
package/rr/txt.js CHANGED
@@ -70,17 +70,18 @@ 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
74
- .trim()
75
- .split(/^([\S]{1,255})\s+([0-9]{1,10})\s+(IN)\s+(\w{3})\s+?\s*(.*?)$/i)
73
+ const regex =
74
+ /^(?<owner>[\S]{1,255})\s+(?<ttl>\d{1,10})\s+(?<cls>IN)\s+(?<type>\w{3})\s+?\s*(?<rdata>.+?)$/i
75
+ const match = opts.bindline.trim().match(regex)
76
76
  if (!match) this.throwHelp(`unable to parse TXT: ${opts.bindline}`)
77
- const [owner, ttl, c, type, rdata] = match.slice(1)
77
+
78
+ const { owner, ttl, cls, type, rdata } = match.groups
78
79
 
79
80
  return new this.constructor({
80
81
  owner,
81
82
  ttl: parseInt(ttl, 10),
82
- class: c,
83
- type,
83
+ class: cls,
84
+ type: type.toUpperCase(),
84
85
  data: rdata
85
86
  .match(/"([^"]+?)"/g)
86
87
  .map((s) => s.replace(/^"|"$/g, ''))
package/rr/uri.js CHANGED
@@ -46,8 +46,7 @@ export default class URI extends RR {
46
46
 
47
47
  fromBind(opts) {
48
48
  // test.example.com 3600 IN URI priority, weight, target
49
- const [owner, ttl, c, type, priority, weight, target] =
50
- opts.bindline.split(/\s+/)
49
+ const [owner, ttl, c, type, priority, weight, target] = opts.bindline.split(/\s+/)
51
50
  return new URI({
52
51
  class: c,
53
52
  type: type,
package/rr/wks.js CHANGED
@@ -1,19 +1,36 @@
1
1
  import RR from '../rr.js'
2
2
 
3
+ import * as TINYDNS from '../lib/tinydns.js'
4
+
3
5
  export default class WKS extends RR {
4
6
  constructor(opts) {
5
7
  super(opts)
6
- if (opts === null) return
7
8
  }
8
9
 
9
10
  /****** Resource record specific setters *******/
11
+ setAddress(val) {
12
+ if (!val) this.throwHelp('WKS: address is required')
13
+ if (!this.isIPv4(val)) this.throwHelp('WKS address must be IPv4')
14
+ this.set('address', val)
15
+ }
16
+
17
+ setProtocol(val) {
18
+ if (!val) this.throwHelp('WKS: protocol is required')
19
+ const upper = typeof val === 'string' ? val.toUpperCase() : val
20
+ if (!['TCP', 'UDP', 6, 17].includes(upper)) this.throwHelp('WKS protocol must be TCP or UDP')
21
+ this.set('protocol', upper)
22
+ }
23
+
24
+ setBitMap(val) {
25
+ this.set('bit map', val ?? '')
26
+ }
10
27
 
11
28
  getDescription() {
12
29
  return 'Well Known Service'
13
30
  }
14
31
 
15
32
  getRdataFields(arg) {
16
- return ['bit map']
33
+ return ['address', 'protocol', 'bit map']
17
34
  }
18
35
 
19
36
  getRFCs() {
@@ -27,19 +44,31 @@ export default class WKS extends RR {
27
44
  /****** IMPORTERS *******/
28
45
 
29
46
  fromBind(opts) {
30
- // test.example.com 3600 IN WKS 192.168.1.1 TCP 25
31
- const [owner, ttl, c, type, address, protocol, bitmap] =
32
- opts.bindline.split(/\s+/)
47
+ // test.example.com 3600 IN WKS 192.168.1.1 TCP ftp smtp
48
+ const parts = opts.bindline.split(/\s+/)
49
+ const [owner, ttl, c, type, address, protocol] = parts
33
50
  return new WKS({
34
51
  owner,
35
52
  ttl: parseInt(ttl, 10),
36
53
  class: c,
37
54
  type,
38
- address, // 32-bit int
39
- protocol, // 8-bit int, 6=TCP, 17=UDP
40
- bitmap, // var len bit map, must be multiple of 8
55
+ address,
56
+ protocol,
57
+ 'bit map': parts.slice(6).join(' ').trim(),
41
58
  })
42
59
  }
43
60
 
44
61
  /****** EXPORTERS *******/
62
+
63
+ toTinydns() {
64
+ const dataRe = new RegExp(/[\r\n\t:\\/]/, 'g')
65
+ const protoMap = { TCP: 6, UDP: 17, 6: 6, 17: 17 }
66
+ const protoNum = protoMap[this.get('protocol')]
67
+
68
+ return this.getTinydnsGeneric(
69
+ TINYDNS.ipv4toOctal(this.get('address')) +
70
+ TINYDNS.UInt8toOctal(protoNum) +
71
+ TINYDNS.escapeOctal(dataRe, this.get('bit map')),
72
+ )
73
+ }
45
74
  }
package/rr.js CHANGED
@@ -20,8 +20,7 @@ export default class RR extends Map {
20
20
 
21
21
  for (const f of this.getFields('rdata')) {
22
22
  const fnName = `set${this.ucFirst(f)}`
23
- if (this[fnName] === undefined)
24
- this.throwHelp(`Missing ${fnName} in class ${this.get('type')}`)
23
+ if (this[fnName] === undefined) this.throwHelp(`Missing ${fnName} in class ${this.get('type')}`)
25
24
  this[fnName](opts[f])
26
25
  }
27
26
 
@@ -77,9 +76,7 @@ export default class RR extends Map {
77
76
  if (n === undefined) this.throwHelp(`owner is required`)
78
77
 
79
78
  if (n.length < 1 || n.length > 255)
80
- this.throwHelp(
81
- 'Domain names must have 1-255 octets (characters): RFC 2181',
82
- )
79
+ this.throwHelp('Domain names must have 1-255 octets (characters): RFC 2181')
83
80
 
84
81
  this.isFullyQualified(this.constructor.name, 'owner', n)
85
82
  this.hasValidLabels(n)
@@ -100,8 +97,7 @@ export default class RR extends Map {
100
97
  this.throwHelp('TTL is required, no default available')
101
98
  }
102
99
 
103
- if (typeof t !== 'number')
104
- this.throwHelp(`TTL must be numeric (${typeof t})`)
100
+ if (typeof t !== 'number') this.throwHelp(`TTL must be numeric (${typeof t})`)
105
101
 
106
102
  // RFC 1035, 2181
107
103
  this.is32bitInt(this.get('type'), 'TTL', t)
@@ -209,8 +205,7 @@ export default class RR extends Map {
209
205
 
210
206
  if (zone_opts.hide?.origin && zone_opts.origin) {
211
207
  if (fqdn === zone_opts.origin) return '@'
212
- if (fqdn.endsWith(zone_opts.origin))
213
- return fqdn.slice(0, fqdn.length - zone_opts.origin.length - 1)
208
+ if (fqdn.endsWith(zone_opts.origin)) return fqdn.slice(0, fqdn.length - zone_opts.origin.length - 1)
214
209
  }
215
210
 
216
211
  return fqdn
@@ -232,9 +227,7 @@ export default class RR extends Map {
232
227
  }
233
228
 
234
229
  getTinydnsPostamble() {
235
- return ['ttl', 'timestamp', 'location']
236
- .map((f) => this.getEmpty(f))
237
- .join(':')
230
+ return ['ttl', 'timestamp', 'location'].map((f) => this.getEmpty(f)).join(':')
238
231
  }
239
232
 
240
233
  hasValidLabels(hostname) {
@@ -258,9 +251,7 @@ export default class RR extends Map {
258
251
  )
259
252
  return true
260
253
 
261
- this.throwHelp(
262
- `${type} ${field} must be a 8-bit integer (in the range 0-255)`,
263
- )
254
+ this.throwHelp(`${type} ${field} must be a 8-bit integer (in the range 0-255)`)
264
255
  }
265
256
 
266
257
  is16bitInt(type, field, value) {
@@ -272,9 +263,7 @@ export default class RR extends Map {
272
263
  )
273
264
  return true
274
265
 
275
- this.throwHelp(
276
- `${type} ${field} must be a 16-bit integer (in the range 0-65535)`,
277
- )
266
+ this.throwHelp(`${type} ${field} must be a 16-bit integer (in the range 0-65535)`)
278
267
  }
279
268
 
280
269
  is32bitInt(type, field, value) {
@@ -286,9 +275,7 @@ export default class RR extends Map {
286
275
  )
287
276
  return true
288
277
 
289
- this.throwHelp(
290
- `${type} ${field} must be a 32-bit integer (in the range 0-2147483647)`,
291
- )
278
+ this.throwHelp(`${type} ${field} must be a 32-bit integer (in the range 0-2147483647)`)
292
279
  }
293
280
 
294
281
  isQuoted(val) {
@@ -306,9 +293,7 @@ export default class RR extends Map {
306
293
  if (!allowed.test(hostname)) return true
307
294
 
308
295
  const matches = allowed.exec(hostname)
309
- this.throwHelp(
310
- `${type}, ${field} has invalid hostname character (${matches[0]})`,
311
- )
296
+ this.throwHelp(`${type}, ${field} has invalid hostname character (${matches[0]})`)
312
297
  }
313
298
 
314
299
  isIPv4(string) {
@@ -330,10 +315,9 @@ export default class RR extends Map {
330
315
 
331
316
  toMaraDNS() {
332
317
  const type = this.get('type')
333
- const supportedTypes =
334
- 'A PTR MX AAAA SRV NAPTR NS SOA TXT SPF RAW FQDN4 FQDN6 CNAME HINFO WKS LOC'.split(
335
- /\s+/g,
336
- )
318
+ const supportedTypes = 'A PTR MX AAAA SRV NAPTR NS SOA TXT SPF RAW FQDN4 FQDN6 CNAME HINFO WKS LOC'.split(
319
+ /\s+/g,
320
+ )
337
321
  if (!supportedTypes.includes(type)) return this.toMaraGeneric()
338
322
  return `${this.get('owner')}\t+${this.get('ttl')}\t${type}\t${this.getRdataFields()
339
323
  .map((f) => this.getQuoted(f))