@nictool/dns-resource-record 1.4.0 → 1.5.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/rr/nsec3param.js CHANGED
@@ -11,7 +11,7 @@ export default class NSEC3PARAM extends RR {
11
11
  setHashAlgorithm(val) {
12
12
  // Hash Algorithm is a single octet.
13
13
  // The Hash Algorithm field is represented as an unsigned decimal integer.
14
- if (!val) this.throwHelp(`NSEC3PARAM: 'hash algorithm' is required`)
14
+ if (val === undefined || val === null) this.throwHelp(`NSEC3PARAM: 'hash algorithm' is required`)
15
15
 
16
16
  this.is8bitInt('NSEC3PARAM', 'hash algorithm', val)
17
17
 
@@ -20,7 +20,7 @@ export default class NSEC3PARAM extends RR {
20
20
 
21
21
  setFlags(val) {
22
22
  // The Flags field is represented as an unsigned decimal integer.
23
- if (!val) this.throwHelp(`NSEC3PARAM: 'flags' is required`)
23
+ if (val === undefined || val === null) this.throwHelp(`NSEC3PARAM: 'flags' is required`)
24
24
 
25
25
  this.is8bitInt('NSEC3PARAM', 'flags', val)
26
26
 
@@ -29,7 +29,7 @@ export default class NSEC3PARAM extends RR {
29
29
 
30
30
  setIterations(val) {
31
31
  // The Iterations field is represented as an unsigned decimal integer. 0-65535
32
- if (!val) this.throwHelp(`NSEC3PARAM: 'iterations' is required`)
32
+ if (val === undefined || val === null) this.throwHelp(`NSEC3PARAM: 'iterations' is required`)
33
33
 
34
34
  this.is16bitInt('NSEC3PARAM', 'iterations', val)
35
35
 
@@ -41,6 +41,15 @@ export default class NSEC3PARAM extends RR {
41
41
  // hexadecimal digits. Whitespace is not allowed within the
42
42
  // sequence. The Salt field is represented as "-" (without the
43
43
  // quotes) when the Salt Length field has a value of 0
44
+ if (val === '-') {
45
+ this.set('salt', val)
46
+ return
47
+ }
48
+
49
+ if (val !== undefined && val !== null && !/^[0-9A-Fa-f]*$/.test(val)) {
50
+ this.throwHelp(`NSEC3PARAM: 'salt' must be hex or '-'`)
51
+ }
52
+
44
53
  this.set('salt', val)
45
54
  }
46
55
 
@@ -62,10 +71,10 @@ export default class NSEC3PARAM extends RR {
62
71
 
63
72
  /****** IMPORTERS *******/
64
73
 
65
- fromBind(str) {
74
+ fromBind({ bindline }) {
66
75
  // test.example.com 3600 IN NSEC3PARAM <hash> <flags> <iterations> <salt>
67
76
  // Example: test.example.com. 3600 IN NSEC3PARAM 1 1 12 aabbccdd
68
- const [owner, ttl, c, type, ha, flags, iterations, salt] = str.split(/\s+/)
77
+ const [owner, ttl, c, type, ha, flags, iterations, salt] = bindline.split(/\s+/)
69
78
  return new NSEC3PARAM({
70
79
  owner,
71
80
  ttl: parseInt(ttl, 10),
@@ -78,22 +87,27 @@ export default class NSEC3PARAM extends RR {
78
87
  })
79
88
  }
80
89
 
81
- fromTinydns(opts) {
82
- const rd = opts.rd
83
-
90
+ fromTinydns({ tinyline }) {
84
91
  // RDATA format: Hash Algorithm (3 octal chars) + Flags (3 octal chars) + Iterations (6 octal chars) + Salt (escaped hex string)
85
- if (rd.length < 12) {
92
+ const [owner, _typeId, rd, ttl, ts, loc] = tinyline.slice(1).split(':')
93
+ if (rd.length < 4) {
86
94
  this.throwHelp(`NSEC3PARAM: RDATA too short: ${rd}`)
87
95
  }
88
96
 
97
+ // rd may contain actual binary characters (from JS string '\\001' -> char 0x01),
98
+ // so convert via octalToChar and read bytes from a Buffer for robust parsing.
99
+ const bytes = Buffer.from(TINYDNS.octalToChar(rd), 'binary')
100
+
89
101
  return new NSEC3PARAM({
90
- owner: this.fullyQualify(opts.owner),
91
- ttl: parseInt(opts.ttl, 10),
102
+ owner: this.fullyQualify(owner),
103
+ ttl: parseInt(ttl, 10),
92
104
  type: 'NSEC3PARAM',
93
- 'hash algorithm': TINYDNS.octalToUInt8(rd.substring(0, 3)),
94
- flags: TINYDNS.octalToUInt8(rd.substring(3, 6)),
95
- iterations: TINYDNS.octalToUInt16(rd.substring(6, 12)),
96
- salt: TINYDNS.unescapeOctal(rd.substring(12)),
105
+ 'hash algorithm': bytes.readUInt8(0),
106
+ flags: bytes.readUInt8(1),
107
+ iterations: bytes.readUInt16BE(2),
108
+ salt: bytes.slice(4).toString('utf8'),
109
+ timestamp: ts,
110
+ location: loc?.trim() ?? '',
97
111
  })
98
112
  }
99
113
 
@@ -108,12 +122,11 @@ export default class NSEC3PARAM extends RR {
108
122
  toTinydns() {
109
123
  const dataRe = new RegExp(/[\r\n\t:\\/]/, 'g')
110
124
 
111
- let rdata = ''
112
- rdata += TINYDNS.UInt8toOctal(this.get('hash algorithm'))
113
- rdata += TINYDNS.UInt8toOctal(this.get('flags'))
114
- rdata += TINYDNS.UInt16toOctal(this.get('iterations'))
115
- rdata += TINYDNS.escapeOctal(dataRe, this.get('salt'))
116
-
117
- return this.getTinydnsGeneric(rdata)
125
+ return this.getTinydnsGeneric(
126
+ TINYDNS.UInt8toOctal(this.get('hash algorithm')) +
127
+ TINYDNS.UInt8toOctal(this.get('flags')) +
128
+ TINYDNS.UInt16toOctal(this.get('iterations')) +
129
+ TINYDNS.escapeOctal(dataRe, this.get('salt')),
130
+ )
118
131
  }
119
132
  }
package/rr/nxt.js CHANGED
@@ -43,9 +43,9 @@ export default class NXT extends RR {
43
43
 
44
44
  /****** IMPORTERS *******/
45
45
 
46
- fromTinydns(opts) {
47
- const [owner, n, rdata, ttl, ts, loc] = opts.tinyline.substring(1).split(':')
48
- if (n != 30) this.throwHelp('NXT fromTinydns, invalid n')
46
+ fromTinydns({ tinyline }) {
47
+ const [owner, n, rdata, ttl, ts, loc] = tinyline.slice(1).split(':')
48
+ if (parseInt(n, 10) !== this.getTypeId()) this.throwHelp('NXT fromTinydns, invalid n')
49
49
 
50
50
  const binaryRdata = Buffer.from(TINYDNS.octalToChar(rdata), 'binary')
51
51
  const [nextDomain, _escapedLen, binaryLen] = TINYDNS.unpackDomainName(rdata)
@@ -57,20 +57,20 @@ export default class NXT extends RR {
57
57
  'next domain': nextDomain,
58
58
  'type bit map': binaryRdata.slice(binaryLen).toString(),
59
59
  timestamp: ts,
60
- location: loc !== '' && loc !== '\n' ? loc : '',
60
+ location: loc?.trim() ?? '',
61
61
  })
62
62
  }
63
63
 
64
- fromBind(opts) {
64
+ fromBind({ bindline }) {
65
65
  // test.example.com 3600 IN NXT NextDomain TypeBitMap
66
- const [owner, ttl, c, type, next] = opts.bindline.split(/\s+/)
66
+ const [owner, ttl, c, type, next] = bindline.split(/\s+/)
67
67
  return new NXT({
68
68
  owner,
69
69
  ttl: parseInt(ttl, 10),
70
70
  class: c,
71
71
  type: type,
72
72
  'next domain': next,
73
- 'type bit map': opts.bindline.split(/\s+/).slice(5).filter(removeParens).join(' ').trim(),
73
+ 'type bit map': bindline.split(/\s+/).slice(5).filter(removeParens).join(' ').trim(),
74
74
  })
75
75
  }
76
76
 
package/rr/openpgpkey.js CHANGED
@@ -28,11 +28,14 @@ export default class OPENPGPKEY extends RR {
28
28
  }
29
29
 
30
30
  /****** IMPORTERS *******/
31
- fromBind(obj) {
31
+ fromBind({ bindline: bindline }) {
32
32
  // test.example.com 3600 IN OPENPGPKEY <base64 public key>
33
- const regex = /^([\S]+)\s+(\d{1,10})\s+(IN)\s+(OPENPGPKEY)\s+([\W\w]*)$/
34
- // eslint-disable-next-line no-unused-vars
35
- const [ignore, owner, ttl, c, type, publickey] = obj.bindline.trim().match(regex)
33
+ const regex =
34
+ /^(?<owner>\S+)\s+(?<ttl>\d{1,10})\s+(?<class>IN)\s+(?<type>OPENPGPKEY)\s+(?<publickey>\S[\s\S]*)$/i
35
+ const match = bindline.trim().match(regex)
36
+ if (!match) this.throwHelp(`unable to parse OPENPGPKEY: ${bindline}`)
37
+
38
+ const { owner, ttl, class: c, type, publickey } = match.groups
36
39
 
37
40
  return new OPENPGPKEY({
38
41
  owner,
@@ -43,12 +46,15 @@ export default class OPENPGPKEY extends RR {
43
46
  })
44
47
  }
45
48
 
46
- fromTinydns(opts) {
49
+ fromTinydns({ tinyline }) {
50
+ const [owner, _typeId, rd, ttl, ts, loc] = tinyline.slice(1).split(':')
47
51
  return new OPENPGPKEY({
48
- owner: this.fullyQualify(opts.owner),
49
- ttl: parseInt(opts.ttl, 10),
52
+ owner: this.fullyQualify(owner),
53
+ ttl: parseInt(ttl, 10),
50
54
  type: 'OPENPGPKEY',
51
- 'public key': Buffer.from(TINYDNS.unescapeOctal(opts.rd), 'base64').toString('utf-8'),
55
+ 'public key': Buffer.from(TINYDNS.unescapeOctal(rd), 'base64').toString('utf-8'),
56
+ timestamp: ts,
57
+ location: loc?.trim() ?? '',
52
58
  })
53
59
  }
54
60
 
package/rr/ptr.js CHANGED
@@ -31,9 +31,9 @@ export default class PTR extends RR {
31
31
  }
32
32
 
33
33
  /****** IMPORTERS *******/
34
- fromTinydns(opts) {
34
+ fromTinydns({ tinyline }) {
35
35
  // ^fqdn:p:ttl:timestamp:lo
36
- const [fqdn, p, ttl, ts, loc] = opts.tinyline.substring(1).split(':')
36
+ const [fqdn, p, ttl, ts, loc] = tinyline.slice(1).split(':')
37
37
 
38
38
  return new PTR({
39
39
  owner: this.fullyQualify(fqdn),
@@ -41,13 +41,13 @@ export default class PTR extends RR {
41
41
  type: 'PTR',
42
42
  dname: this.fullyQualify(p),
43
43
  timestamp: ts,
44
- location: loc !== '' && loc !== '\n' ? loc : '',
44
+ location: loc?.trim() ?? '',
45
45
  })
46
46
  }
47
47
 
48
- fromBind(opts) {
48
+ fromBind({ bindline }) {
49
49
  // test.example.com 3600 IN PTR dname
50
- const [owner, ttl, c, type, dname] = opts.bindline.split(/\s+/)
50
+ const [owner, ttl, c, type, dname] = bindline.split(/\s+/)
51
51
  return new PTR({
52
52
  owner,
53
53
  ttl: parseInt(ttl, 10),
package/rr/rp.js CHANGED
@@ -52,9 +52,9 @@ export default class RP extends RR {
52
52
  }
53
53
 
54
54
  /****** IMPORTERS *******/
55
- fromBind(opts) {
55
+ fromBind({ bindline }) {
56
56
  // test.example.com 3600 IN RP mbox txt
57
- const [owner, ttl, c, type, mbox, txt] = opts.bindline.split(/\s+/)
57
+ const [owner, ttl, c, type, mbox, txt] = bindline.split(/\s+/)
58
58
  return new RP({
59
59
  owner,
60
60
  ttl: parseInt(ttl, 10),
@@ -65,6 +65,23 @@ export default class RP extends RR {
65
65
  })
66
66
  }
67
67
 
68
+ fromTinydns({ tinyline }) {
69
+ const [owner, _typeId, rdata, ttl, ts, loc] = tinyline.slice(1).split(':')
70
+
71
+ const [mbox, consumed] = TINYDNS.unpackDomainName(rdata)
72
+ const txt = TINYDNS.unpackDomainName(rdata.slice(consumed))[0]
73
+
74
+ return new RP({
75
+ owner: this.fullyQualify(owner),
76
+ ttl: parseInt(ttl, 10),
77
+ type: 'RP',
78
+ mbox,
79
+ txt,
80
+ timestamp: ts,
81
+ location: loc?.trim() ?? '',
82
+ })
83
+ }
84
+
68
85
  /****** EXPORTERS *******/
69
86
  toBind(zone_opts) {
70
87
  return `${this.getPrefix(zone_opts)}\t${this.getFQDN('mbox', zone_opts)}\t${this.getFQDN('txt', zone_opts)}\n`
package/rr/rrsig.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import RR from '../rr.js'
2
+ import * as TINYDNS from '../lib/tinydns.js'
2
3
 
3
4
  export default class RRSIG extends RR {
4
5
  constructor(opts) {
@@ -101,16 +102,89 @@ export default class RRSIG extends RR {
101
102
 
102
103
  /****** IMPORTERS *******/
103
104
 
104
- // fromBind (str) {
105
- // // test.example.com 3600 IN RRSIG ...
106
- // const [ owner, ttl, c, type ] = str.split(/\s+/)
107
- // return new RRSIG({
108
- // owner,
109
- // ttl : parseInt(ttl, 10),
110
- // class : c,
111
- // type : type,
112
- // })
113
- // }
105
+ fromBind({ bindline }) {
106
+ // example.com. 3600 IN RRSIG typecovered algorithm labels origttl sigexp siginc keytag signersname ( signature )
107
+ const parts = bindline.trim().split(/\s+/)
108
+ return new RRSIG({
109
+ owner: parts[0],
110
+ ttl: parseInt(parts[1], 10),
111
+ class: parts[2],
112
+ type: 'RRSIG',
113
+ 'type covered': parseInt(parts[4], 10),
114
+ algorithm: parseInt(parts[5], 10),
115
+ labels: parseInt(parts[6], 10),
116
+ 'original ttl': parseInt(parts[7], 10),
117
+ 'signature expiration': parseInt(parts[8], 10),
118
+ 'signature inception': parseInt(parts[9], 10),
119
+ 'key tag': parseInt(parts[10], 10),
120
+ 'signers name': parts[11],
121
+ signature: parts
122
+ .slice(12)
123
+ .filter((a) => a !== '(' && a !== ')')
124
+ .join(' ')
125
+ .trim(),
126
+ })
127
+ }
128
+
129
+ fromTinydns({ tinyline }) {
130
+ const [fqdn, n, rdata, ttl, ts, loc] = tinyline.slice(1).split(':')
131
+ if (parseInt(n, 10) !== this.getTypeId()) this.throwHelp('RRSIG fromTinydns, invalid n')
132
+
133
+ const bytes = Buffer.from(TINYDNS.octalToChar(rdata), 'binary')
134
+ const typeCovered = bytes.readUInt16BE(0)
135
+ const algorithm = bytes.readUInt8(2)
136
+ const labels = bytes.readUInt8(3)
137
+ const originalTtl = bytes.readUInt32BE(4)
138
+ const signatureExpiration = bytes.readUInt32BE(8)
139
+ const signatureInception = bytes.readUInt32BE(12)
140
+ const keyTag = bytes.readUInt16BE(16)
141
+
142
+ let pos = 18
143
+ const labelArr = []
144
+ while (pos < bytes.length) {
145
+ const len = bytes.readUInt8(pos++)
146
+ if (len === 0) break
147
+ labelArr.push(bytes.slice(pos, pos + len).toString())
148
+ pos += len
149
+ }
150
+ const signersName = `${labelArr.join('.')}.`
151
+ const signature = bytes.slice(pos).toString()
152
+
153
+ return new RRSIG({
154
+ owner: this.fullyQualify(fqdn),
155
+ ttl: parseInt(ttl, 10),
156
+ type: 'RRSIG',
157
+ 'type covered': typeCovered,
158
+ algorithm,
159
+ labels,
160
+ 'original ttl': originalTtl,
161
+ 'signature expiration': signatureExpiration,
162
+ 'signature inception': signatureInception,
163
+ 'key tag': keyTag,
164
+ 'signers name': signersName,
165
+ signature,
166
+ timestamp: ts,
167
+ location: loc?.trim() ?? '',
168
+ })
169
+ }
114
170
 
115
171
  /****** EXPORTERS *******/
172
+ toBind(zone_opts) {
173
+ return `${this.getPrefix(zone_opts)}\t${this.get('type covered')}\t${this.get('algorithm')}\t${this.get('labels')}\t${this.get('original ttl')}\t${this.get('signature expiration')}\t${this.get('signature inception')}\t${this.get('key tag')}\t${this.getFQDN('signers name', zone_opts)}\t${this.get('signature')}\n`
174
+ }
175
+
176
+ toTinydns() {
177
+ const dataRe = new RegExp(/[\r\n\t:]/, 'g')
178
+ return this.getTinydnsGeneric(
179
+ TINYDNS.UInt16toOctal(this.get('type covered')) +
180
+ TINYDNS.UInt8toOctal(this.get('algorithm')) +
181
+ TINYDNS.UInt8toOctal(this.get('labels')) +
182
+ TINYDNS.UInt32toOctal(this.get('original ttl')) +
183
+ TINYDNS.UInt32toOctal(this.get('signature expiration')) +
184
+ TINYDNS.UInt32toOctal(this.get('signature inception')) +
185
+ TINYDNS.UInt16toOctal(this.get('key tag')) +
186
+ TINYDNS.packDomainName(this.get('signers name')) +
187
+ TINYDNS.escapeOctal(dataRe, this.get('signature')),
188
+ )
189
+ }
116
190
  }
package/rr/sig.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 SIG extends RR {
4
6
  constructor(opts) {
5
7
  super(opts)
@@ -15,8 +17,7 @@ export default class SIG extends RR {
15
17
 
16
18
  setAlgorithm(val) {
17
19
  // a 1 octet Algorithm field
18
-
19
- this.is8bitInt('SIG', 'labels', val)
20
+ this.is8bitInt('SIG', 'algorithm', val)
20
21
 
21
22
  this.set('algorithm', val)
22
23
  }
@@ -90,18 +91,93 @@ export default class SIG extends RR {
90
91
  }
91
92
 
92
93
  /****** IMPORTERS *******/
93
- // fromBind (str) {
94
- // // test.example.com 3600 IN SIG ...
95
- // const [ owner, ttl, c, type ] = str.split(/\s+/)
96
- // return new SIG({
97
- // owner,
98
- // ttl : parseInt(ttl, 10),
99
- // class : c,
100
- // type : type,
101
- // })
102
- // }
94
+
95
+ fromBind({ bindline }) {
96
+ // example.com. 3600 IN SIG TypeCovered Algorithm Labels OrigTTL SigExpiration SigInception KeyTag SignersName ( Signature )
97
+ const parts = bindline.trim().split(/\s+/)
98
+
99
+ return new SIG({
100
+ owner: parts[0],
101
+ ttl: parseInt(parts[1], 10),
102
+ class: parts[2],
103
+ type: 'SIG',
104
+ 'type covered': parseInt(parts[4], 10),
105
+ algorithm: parseInt(parts[5], 10),
106
+ labels: parseInt(parts[6], 10),
107
+ 'original ttl': parseInt(parts[7], 10),
108
+ 'signature expiration': parseInt(parts[8], 10),
109
+ 'signature inception': parseInt(parts[9], 10),
110
+ 'key tag': parseInt(parts[10], 10),
111
+ 'signers name': parts[11],
112
+ signature: parts
113
+ .slice(12)
114
+ .filter((a) => a !== '(' && a !== ')')
115
+ .join(' ')
116
+ .trim(),
117
+ })
118
+ }
103
119
 
104
120
  /****** EXPORTERS *******/
121
+ toTinydns() {
122
+ const dataRe = new RegExp(/[\r\n\t:]/, 'g')
123
+
124
+ return this.getTinydnsGeneric(
125
+ TINYDNS.UInt16toOctal(this.get('type covered')) +
126
+ TINYDNS.UInt8toOctal(this.get('algorithm')) +
127
+ TINYDNS.UInt8toOctal(this.get('labels')) +
128
+ TINYDNS.UInt32toOctal(this.get('original ttl')) +
129
+ TINYDNS.UInt32toOctal(this.get('signature expiration')) +
130
+ TINYDNS.UInt32toOctal(this.get('signature inception')) +
131
+ TINYDNS.UInt16toOctal(this.get('key tag')) +
132
+ TINYDNS.packDomainName(this.get('signers name')) +
133
+ TINYDNS.escapeOctal(dataRe, this.get('signature')),
134
+ )
135
+ }
136
+
137
+ fromTinydns({ tinyline }) {
138
+ const [fqdn, n, rdata, ttl, ts, loc] = tinyline.substring(1).split(':')
139
+ if (parseInt(n, 10) !== this.getTypeId()) this.throwHelp('SIG fromTinydns, invalid n')
140
+
141
+ const bytes = Buffer.from(TINYDNS.octalToChar(rdata), 'binary')
142
+
143
+ const typeCovered = bytes.readUInt16BE(0)
144
+ const algorithm = bytes.readUInt8(2)
145
+ const labels = bytes.readUInt8(3)
146
+ const originalTtl = bytes.readUInt32BE(4)
147
+ const signatureExpiration = bytes.readUInt32BE(8)
148
+ const signatureInception = bytes.readUInt32BE(12)
149
+ const keyTag = bytes.readUInt16BE(16)
150
+
151
+ // parse signers name from binary buffer starting at offset 18
152
+ let pos = 18
153
+ const labelsArr = []
154
+ while (pos < bytes.length) {
155
+ const len = bytes.readUInt8(pos++)
156
+ if (len === 0) break
157
+ labelsArr.push(bytes.slice(pos, pos + len).toString())
158
+ pos += len
159
+ }
160
+ const signersName = `${labelsArr.join('.')}.`
161
+
162
+ const signature = bytes.slice(pos).toString()
163
+
164
+ return new SIG({
165
+ owner: this.fullyQualify(fqdn),
166
+ ttl: parseInt(ttl, 10),
167
+ type: 'SIG',
168
+ 'type covered': typeCovered,
169
+ algorithm,
170
+ labels,
171
+ 'original ttl': originalTtl,
172
+ 'signature expiration': signatureExpiration,
173
+ 'signature inception': signatureInception,
174
+ 'key tag': keyTag,
175
+ 'signers name': signersName,
176
+ signature,
177
+ timestamp: ts,
178
+ location: loc?.trim() ?? '',
179
+ })
180
+ }
105
181
 
106
182
  toBind(zone_opts) {
107
183
  return `${this.getFQDN('owner', zone_opts)} ${this.get('ttl')} ${this.get('class')} SIG${this.getRdataFields()
package/rr/smimea.js CHANGED
@@ -76,9 +76,9 @@ export default class SMIMEA extends RR {
76
76
 
77
77
  /****** IMPORTERS *******/
78
78
 
79
- fromBind(opts) {
79
+ fromBind({ bindline }) {
80
80
  // test.example.com 3600 IN SMIMEA, usage, selector, match, data
81
- const [owner, ttl, c, type, usage, selector, match] = opts.bindline.split(/\s+/)
81
+ const [owner, ttl, c, type, usage, selector, match] = bindline.split(/\s+/)
82
82
  return new SMIMEA({
83
83
  owner,
84
84
  ttl: parseInt(ttl, 10),
@@ -87,12 +87,12 @@ export default class SMIMEA extends RR {
87
87
  'certificate usage': parseInt(usage, 10),
88
88
  selector: parseInt(selector, 10),
89
89
  'matching type': parseInt(match, 10),
90
- 'certificate association data': opts.bindline.split(/\s+/).slice(7).join(' ').trim(),
90
+ 'certificate association data': bindline.split(/\s+/).slice(7).join(' ').trim(),
91
91
  })
92
92
  }
93
93
 
94
- fromTinydns(opts) {
95
- const [owner, _typeId, rdata, ttl, ts, loc] = opts.tinyline.substring(1).split(':')
94
+ fromTinydns({ tinyline }) {
95
+ const [owner, _typeId, rdata, ttl, ts, loc] = tinyline.slice(1).split(':')
96
96
  const binaryRdata = Buffer.from(TINYDNS.octalToChar(rdata), 'binary')
97
97
 
98
98
  return new SMIMEA({
@@ -104,7 +104,7 @@ export default class SMIMEA extends RR {
104
104
  'matching type': binaryRdata.readUInt8(2),
105
105
  'certificate association data': binaryRdata.slice(3).toString(),
106
106
  timestamp: ts,
107
- location: loc !== '' && loc !== '\n' ? loc : '',
107
+ location: loc?.trim() ?? '',
108
108
  })
109
109
  }
110
110
 
package/rr/soa.js CHANGED
@@ -84,10 +84,10 @@ export default class SOA extends RR {
84
84
  }
85
85
 
86
86
  /****** IMPORTERS *******/
87
- fromBind(opts) {
87
+ fromBind({ bindline }) {
88
88
  // example.com TTL IN SOA mname rname serial refresh retry expire minimum
89
89
  const [owner, ttl, c, type, mname, rname, serial, refresh, retry, expire, minimum] =
90
- opts.bindline.split(/[\s+]/)
90
+ bindline.split(/[\s+]/)
91
91
 
92
92
  return new SOA({
93
93
  owner,
@@ -104,9 +104,9 @@ export default class SOA extends RR {
104
104
  })
105
105
  }
106
106
 
107
- fromTinydns(opts) {
107
+ fromTinydns({ tinyline }) {
108
108
  // Zfqdn:mname:rname:ser:ref:ret:exp:min:ttl:time:lo
109
- const [fqdn, mname, rname, ser, ref, ret, exp, min, ttl, ts, loc] = opts.tinyline.substring(1).split(':')
109
+ const [fqdn, mname, rname, ser, ref, ret, exp, min, ttl, ts, loc] = tinyline.slice(1).split(':')
110
110
 
111
111
  return new SOA({
112
112
  owner: this.fullyQualify(fqdn),
@@ -114,13 +114,13 @@ export default class SOA extends RR {
114
114
  type: 'SOA',
115
115
  mname: this.fullyQualify(mname),
116
116
  rname: this.fullyQualify(rname),
117
- serial: parseInt(ser || opts.default?.serial, 10),
117
+ serial: parseInt(ser ?? this.default?.serial, 10),
118
118
  refresh: parseInt(ref, 10) || 16384,
119
119
  retry: parseInt(ret, 10) || 2048,
120
120
  expire: parseInt(exp, 10) || 1048576,
121
121
  minimum: parseInt(min, 10) || 2560,
122
122
  timestamp: parseInt(ts) || '',
123
- location: loc !== '' && loc !== '\n' ? loc : '',
123
+ location: loc?.trim() ?? '',
124
124
  })
125
125
  }
126
126
 
package/rr/spf.js CHANGED
@@ -31,9 +31,9 @@ export default class SPF extends TXT {
31
31
  }
32
32
 
33
33
  /****** IMPORTERS *******/
34
- fromTinydns(opts) {
34
+ fromTinydns({ tinyline }) {
35
35
  // SPF via generic, :fqdn:n:rdata:ttl:timestamp:lo
36
- const [fqdn, n, rdata, ttl, ts, loc] = opts.tinyline.substring(1).split(':')
36
+ const [fqdn, n, rdata, ttl, ts, loc] = tinyline.slice(1).split(':')
37
37
  if (n != 99) this.throwHelp('SPF fromTinydns, invalid n')
38
38
 
39
39
  return new SPF({
@@ -42,7 +42,7 @@ export default class SPF extends TXT {
42
42
  data: TINYDNS.octalToChar(rdata),
43
43
  ttl: parseInt(ttl, 10),
44
44
  timestamp: ts,
45
- location: loc !== '' && loc !== '\n' ? loc : '',
45
+ location: loc?.trim() ?? '',
46
46
  })
47
47
  }
48
48
 
package/rr/srv.js CHANGED
@@ -54,22 +54,22 @@ export default class SRV extends RR {
54
54
  }
55
55
 
56
56
  /****** IMPORTERS *******/
57
- fromTinydns(opts) {
58
- const str = opts.tinyline
57
+ fromTinydns({ tinyline }) {
58
+ const str = tinyline
59
59
  let fqdn, addr, port, pri, weight, ttl, ts, loc, n, rdata
60
60
 
61
61
  if (str[0] === 'S') {
62
62
  // patched tinydns with S records
63
- ;[fqdn, addr, port, pri, weight, ttl, ts, loc] = str.substring(1).split(':')
63
+ ;[fqdn, addr, port, pri, weight, ttl, ts, loc] = str.slice(1).split(':')
64
64
  } else {
65
65
  // tinydns generic record format
66
- ;[fqdn, n, rdata, ttl, ts, loc] = str.substring(1).split(':')
66
+ ;[fqdn, n, rdata, ttl, ts, loc] = str.slice(1).split(':')
67
67
  if (n != 33) this.throwHelp('SRV fromTinydns: invalid n')
68
68
 
69
- pri = TINYDNS.octalToUInt16(rdata.substring(0, 8))
70
- weight = TINYDNS.octalToUInt16(rdata.substring(8, 16))
71
- port = TINYDNS.octalToUInt16(rdata.substring(16, 24))
72
- addr = TINYDNS.unpackDomainName(rdata.substring(24))[0]
69
+ pri = TINYDNS.octalToUInt16(rdata.slice(0, 8))
70
+ weight = TINYDNS.octalToUInt16(rdata.slice(8, 16))
71
+ port = TINYDNS.octalToUInt16(rdata.slice(16, 24))
72
+ addr = TINYDNS.unpackDomainName(rdata.slice(24))[0]
73
73
  }
74
74
 
75
75
  return new SRV({
@@ -81,13 +81,13 @@ export default class SRV extends RR {
81
81
  port: parseInt(port, 10),
82
82
  target: this.fullyQualify(addr),
83
83
  timestamp: ts,
84
- location: loc !== '' && loc !== '\n' ? loc : '',
84
+ location: loc?.trim() ?? '',
85
85
  })
86
86
  }
87
87
 
88
- fromBind(opts) {
88
+ fromBind({ bindline }) {
89
89
  // test.example.com 3600 IN SRV Priority Weight Port Target
90
- const [owner, ttl, c, type, pri, weight, port, target] = opts.bindline.split(/\s+/)
90
+ const [owner, ttl, c, type, pri, weight, port, target] = bindline.split(/\s+/)
91
91
  return new SRV({
92
92
  owner: owner,
93
93
  ttl: parseInt(ttl, 10),
package/rr/sshfp.js CHANGED
@@ -59,26 +59,26 @@ export default class SSHFP extends RR {
59
59
  }
60
60
 
61
61
  /****** IMPORTERS *******/
62
- fromTinydns(opts) {
62
+ fromTinydns({ tinyline }) {
63
63
  // SSHFP via generic, :fqdn:n:rdata:ttl:timestamp:lo
64
- const [fqdn, n, rdata, ttl, ts, loc] = opts.tinyline.substring(1).split(':')
64
+ const [fqdn, n, rdata, ttl, ts, loc] = tinyline.slice(1).split(':')
65
65
  if (n != 44) this.throwHelp('SSHFP fromTinydns, invalid n')
66
66
 
67
67
  return new SSHFP({
68
68
  owner: this.fullyQualify(fqdn),
69
69
  ttl: parseInt(ttl, 10),
70
70
  type: 'SSHFP',
71
- algorithm: TINYDNS.octalToUInt8(rdata.substring(0, 4)),
72
- fptype: TINYDNS.octalToUInt8(rdata.substring(4, 8)),
73
- fingerprint: TINYDNS.octalToHex(rdata.substring(8)),
71
+ algorithm: TINYDNS.octalToUInt8(rdata.slice(0, 4)),
72
+ fptype: TINYDNS.octalToUInt8(rdata.slice(4, 8)),
73
+ fingerprint: TINYDNS.octalToHex(rdata.slice(8)),
74
74
  timestamp: ts,
75
- location: loc !== '' && loc !== '\n' ? loc : '',
75
+ location: loc?.trim() ?? '',
76
76
  })
77
77
  }
78
78
 
79
- fromBind(opts) {
79
+ fromBind({ bindline }) {
80
80
  // test.example.com 3600 IN SSHFP algo fptype fp
81
- const [owner, ttl, c, type, algo, fptype, fp] = opts.bindline.split(/\s+/)
81
+ const [owner, ttl, c, type, algo, fptype, fp] = bindline.split(/\s+/)
82
82
  return new SSHFP({
83
83
  owner,
84
84
  ttl: parseInt(ttl, 10),