@nictool/dns-resource-record 1.1.7 → 1.2.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.
Files changed (75) hide show
  1. package/CHANGELOG.md +26 -43
  2. package/README.md +48 -48
  3. package/index.js +83 -29
  4. package/lib/tinydns.js +68 -61
  5. package/package.json +1 -2
  6. package/rr/a.js +32 -23
  7. package/rr/aaaa.js +49 -35
  8. package/rr/caa.js +56 -44
  9. package/rr/cert.js +21 -19
  10. package/rr/cname.js +22 -23
  11. package/rr/dname.js +23 -23
  12. package/rr/dnskey.js +45 -43
  13. package/rr/ds.js +40 -40
  14. package/rr/hinfo.js +29 -28
  15. package/rr/https.js +62 -0
  16. package/rr/ipseckey.js +69 -50
  17. package/rr/key.js +23 -23
  18. package/rr/loc.js +71 -58
  19. package/rr/mx.js +41 -27
  20. package/rr/naptr.js +52 -53
  21. package/rr/ns.js +26 -23
  22. package/rr/nsec.js +24 -20
  23. package/rr/nsec3.js +59 -46
  24. package/rr/nsec3param.js +24 -26
  25. package/rr/nxt.js +65 -0
  26. package/rr/openpgpkey.js +18 -15
  27. package/rr/ptr.js +20 -21
  28. package/rr/rrsig.js +28 -23
  29. package/rr/sig.js +25 -20
  30. package/rr/smimea.js +36 -31
  31. package/rr/soa.js +56 -42
  32. package/rr/spf.js +21 -18
  33. package/rr/srv.js +45 -45
  34. package/rr/sshfp.js +30 -31
  35. package/rr/svcb.js +64 -0
  36. package/rr/tlsa.js +50 -45
  37. package/rr/tsig.js +56 -0
  38. package/rr/txt.js +42 -35
  39. package/rr/uri.js +33 -33
  40. package/rr/wks.js +45 -0
  41. package/rr.js +133 -87
  42. package/.codeclimate.yml +0 -25
  43. package/DEVELOP.md +0 -23
  44. package/test/a.js +0 -76
  45. package/test/aaaa.js +0 -79
  46. package/test/base.js +0 -138
  47. package/test/caa.js +0 -104
  48. package/test/cert.js +0 -48
  49. package/test/cname.js +0 -41
  50. package/test/dname.js +0 -53
  51. package/test/dnskey.js +0 -44
  52. package/test/ds.js +0 -44
  53. package/test/fake.js +0 -26
  54. package/test/hinfo.js +0 -75
  55. package/test/ipseckey.js +0 -115
  56. package/test/key.js +0 -37
  57. package/test/loc.js +0 -71
  58. package/test/mx.js +0 -75
  59. package/test/naptr.js +0 -40
  60. package/test/ns.js +0 -53
  61. package/test/nsec.js +0 -38
  62. package/test/nsec3.js +0 -40
  63. package/test/nsec3param.js +0 -26
  64. package/test/openpgpkey.js +0 -35
  65. package/test/ptr.js +0 -54
  66. package/test/rr.js +0 -196
  67. package/test/smimea.js +0 -45
  68. package/test/soa.js +0 -77
  69. package/test/spf.js +0 -48
  70. package/test/srv.js +0 -81
  71. package/test/sshfp.js +0 -62
  72. package/test/tinydns.js +0 -140
  73. package/test/tlsa.js +0 -54
  74. package/test/txt.js +0 -70
  75. package/test/uri.js +0 -61
package/lib/tinydns.js CHANGED
@@ -1,83 +1,88 @@
1
-
2
- export const SPECIALCHARS = {
3
- '+': [ 'A' ],
4
- '-': [ undefined ], // disabled RR
5
- '%': [ 'location' ],
6
- '.': [ 'SOA', 'NS', 'A' ],
7
- '&': [ 'NS', 'A' ],
8
- '=': [ 'A', 'PTR' ],
9
- '@': [ 'MX', 'A' ],
10
- '#': [ 'comment' ],
11
- "'": [ 'TXT' ],
12
- '^': [ 'PTR' ],
13
- 'C': [ 'CNAME' ],
14
- 'Z': [ 'SOA' ],
15
- ':': [ 'generic' ],
16
- '3': [ 'AAAA' ],
17
- '6': [ 'AAAA', 'PTR' ],
18
- 'S': [ 'SRV' ],
1
+ export const SPECIAL_CHARS = {
2
+ '+': ['A'],
3
+ '-': [undefined], // disabled RR
4
+ '%': ['location'],
5
+ '.': ['SOA', 'NS', 'A'],
6
+ '&': ['NS', 'A'],
7
+ '=': ['A', 'PTR'],
8
+ '@': ['MX', 'A'],
9
+ '#': ['comment'],
10
+ "'": ['TXT'],
11
+ '^': ['PTR'],
12
+ C: ['CNAME'],
13
+ Z: ['SOA'],
14
+ ':': ['generic'],
15
+ 3: ['AAAA'],
16
+ 6: ['AAAA', 'PTR'],
17
+ S: ['SRV'],
19
18
  }
20
19
 
21
20
  const octalRe = new RegExp(/\\(?:[1-7][0-7]{0,2}|[0-7]{2,3})/, 'g')
22
21
 
23
- export function escapeOctal (re, str) {
22
+ export function escapeOctal(re, str) {
24
23
  let escaped = ''
25
- str.split(/(.{1})/g).map(c => {
24
+ str.split(/(.{1})/g).map((c) => {
26
25
  escaped += re.test(c) ? charToOctal(c) : c
27
26
  })
28
27
  return escaped
29
28
  }
30
29
 
31
- export function octalToChar (str) {
30
+ export function octalToChar(str) {
32
31
  // relace instances of \NNN with ASCII
33
- return str.replace(octalRe, o => String.fromCharCode(parseInt(o.substring(1), 8)))
32
+ return str.replace(octalRe, (o) =>
33
+ String.fromCharCode(parseInt(o.substring(1), 8)),
34
+ )
34
35
  }
35
36
 
36
- export function octalToHex (str) {
37
+ export function octalToHex(str) {
37
38
  // relace instances of \NNN with Hex
38
- return str.replace(octalRe, o => {
39
+ return str.replace(octalRe, (o) => {
39
40
  // parseInt(n, 8) -> from octal to decimal
40
41
  // .toString(16) -> decimal to hex
41
42
  return parseInt(o.substring(1), 8).toString(16).padStart(2, 0)
42
43
  })
43
44
  }
44
45
 
45
- export function octalToUInt8 (str) {
46
+ export function octalToUInt8(str) {
46
47
  const b = Buffer.alloc(1)
47
- b.writeUInt8(parseInt(str.substring(1,4), 8), 0)
48
+ b.writeUInt8(parseInt(str.substring(1, 4), 8), 0)
48
49
  return b.readUInt8()
49
50
  }
50
51
 
51
- export function octalToUInt16 (str) {
52
+ export function octalToUInt16(str) {
52
53
  const b = Buffer.alloc(2)
53
- b.writeUInt8(parseInt(str.substring(1,4), 8), 0)
54
- b.writeUInt8(parseInt(str.substring(5,8), 8), 1)
54
+ b.writeUInt8(parseInt(str.substring(1, 4), 8), 0)
55
+ b.writeUInt8(parseInt(str.substring(5, 8), 8), 1)
55
56
  return b.readUInt16BE()
56
57
  }
57
58
 
58
- export function octalToUInt32 (str) {
59
+ export function octalToUInt32(str) {
59
60
  const b = Buffer.alloc(4)
60
- b.writeUInt8(parseInt(str.substring(1,4), 8), 0)
61
- b.writeUInt8(parseInt(str.substring(5,8), 8), 1)
62
- b.writeUInt8(parseInt(str.substring(9,12), 8), 2)
63
- b.writeUInt8(parseInt(str.substring(13,16), 8), 3)
61
+ b.writeUInt8(parseInt(str.substring(1, 4), 8), 0)
62
+ b.writeUInt8(parseInt(str.substring(5, 8), 8), 1)
63
+ b.writeUInt8(parseInt(str.substring(9, 12), 8), 2)
64
+ b.writeUInt8(parseInt(str.substring(13, 16), 8), 3)
64
65
  return b.readUInt32BE()
65
66
  }
66
67
 
67
- export function packString (str) {
68
- return str.match(/(.{1,255})/g).map(s => {
69
- const len = Buffer.alloc(1)
70
- len.writeUInt8(s.length)
71
- return `${UInt8toOctal(len.readUInt8(0))}${s}`
72
- }).join('')
68
+ export function packString(str) {
69
+ return str
70
+ .match(/(.{1,255})/g)
71
+ .map((s) => {
72
+ const len = Buffer.alloc(1)
73
+ len.writeUInt8(s.length)
74
+ return `${UInt8toOctal(len.readUInt8(0))}${s}`
75
+ })
76
+ .join('')
73
77
  }
74
78
 
75
- export function unpackString (str) {
79
+ export function unpackString(str) {
76
80
  const asBuf = Buffer.from(octalToChar(str.toString()))
77
81
  const res = []
78
82
  let pos = 0
79
83
  let len
80
- while ((len = asBuf.readUInt8(pos))) { // encoded length byte
84
+ while ((len = asBuf.readUInt8(pos))) {
85
+ // encoded length byte
81
86
  pos++
82
87
  res.push(asBuf.slice(pos, pos + len).toString())
83
88
  pos = +(pos + len)
@@ -86,13 +91,13 @@ export function unpackString (str) {
86
91
  return res
87
92
  }
88
93
 
89
- export function packDomainName (fqdn) {
94
+ export function packDomainName(fqdn) {
90
95
  const labelRegEx = new RegExp(/[^A-Za-z0-9-.]/, 'g')
91
96
 
92
97
  // RFC 1035, 3.3 Standard RRs
93
98
  // The standard wire format for DNS names. (1 octet length + octets)
94
99
  let packed = ''
95
- fqdn.split('.').map(label => {
100
+ fqdn.split('.').map((label) => {
96
101
  if (label === undefined || !label.length) return
97
102
 
98
103
  const len = Buffer.alloc(1)
@@ -105,14 +110,14 @@ export function packDomainName (fqdn) {
105
110
  return packed
106
111
  }
107
112
 
108
- export function unpackDomainName (fqdn) {
109
-
113
+ export function unpackDomainName(fqdn) {
110
114
  fqdn = Buffer.from(octalToChar(fqdn.toString()))
111
115
 
112
116
  const labels = []
113
117
  let pos = 0
114
118
  let len
115
- while ((len = fqdn.readUInt8(pos))) { // encoded length byte
119
+ while ((len = fqdn.readUInt8(pos))) {
120
+ // encoded length byte
116
121
  pos++
117
122
  labels.push(fqdn.slice(pos, pos + len).toString())
118
123
  pos = +(pos + len)
@@ -120,31 +125,31 @@ export function unpackDomainName (fqdn) {
120
125
  const r = `${labels.join('.')}.`
121
126
  // char position + length of last label + label length chars + null byte
122
127
  const strLen = pos + len + labels.length * 4 + 1
123
- return [ r, strLen ]
128
+ return [r, strLen]
124
129
  }
125
130
 
126
- export function packHex (str) {
131
+ export function packHex(str) {
127
132
  let r = ''
128
- for (let i = 0; i < str.length; i = i+2) {
133
+ for (let i = 0; i < str.length; i = i + 2) {
129
134
  // nibble off 2 hex bytes, encode to octal
130
- r += UInt8toOctal(parseInt(str.slice(i, i+2), 16))
135
+ r += UInt8toOctal(parseInt(str.slice(i, i + 2), 16))
131
136
  }
132
137
  return r
133
138
  }
134
139
 
135
- export function charToOctal (c) {
140
+ export function charToOctal(c) {
136
141
  if (typeof c === 'number') return UInt8toOctal(c)
137
142
 
138
143
  return UInt8toOctal(c.charCodeAt(0))
139
144
  }
140
145
 
141
- export function UInt8toOctal (n) {
146
+ export function UInt8toOctal(n) {
142
147
  if (n > 255) throw new Error('UInt8toOctal does not work on numbers > 255')
143
148
 
144
149
  return `\\${parseInt(n, 10).toString(8).padStart(3, 0)}`
145
150
  }
146
151
 
147
- export function UInt16toOctal (n) {
152
+ export function UInt16toOctal(n) {
148
153
  let r = ''
149
154
  const pri = Buffer.alloc(2)
150
155
  pri.writeUInt16BE(n)
@@ -153,7 +158,7 @@ export function UInt16toOctal (n) {
153
158
  return r
154
159
  }
155
160
 
156
- export function UInt32toOctal (n) {
161
+ export function UInt32toOctal(n) {
157
162
  let r = ''
158
163
  const pri = Buffer.alloc(4)
159
164
  pri.writeUInt32BE(n)
@@ -163,24 +168,26 @@ export function UInt32toOctal (n) {
163
168
  return r
164
169
  }
165
170
 
166
- export function ipv4toOctal (ip) {
171
+ export function ipv4toOctal(ip) {
167
172
  return UInt32toOctal(ip.split`.`.reduce((int, value) => int * 256 + +value))
168
173
  }
169
174
 
170
- export function octalToIPv4 (str) {
175
+ export function octalToIPv4(str) {
171
176
  const asInt = octalToUInt32(str)
172
- return [ 24,16,8,0 ].map(n => (asInt >> n) & 0xff).join('.')
177
+ return [24, 16, 8, 0].map((n) => (asInt >> n) & 0xff).join('.')
173
178
  }
174
179
 
175
- export function base64toOctal (str) {
180
+ export function base64toOctal(str) {
176
181
  const bytes = Buffer.from(str, 'base64')
177
182
  let escaped = ''
178
183
  for (const b of bytes) {
179
- escaped += /[A-Za-z0-9\-.]/.test(String.fromCharCode(b)) ? String.fromCharCode(b) : UInt8toOctal(b)
184
+ escaped += /[A-Za-z0-9\-.]/.test(String.fromCharCode(b))
185
+ ? String.fromCharCode(b)
186
+ : UInt8toOctal(b)
180
187
  }
181
188
  return escaped
182
189
  }
183
190
 
184
- export function octalToBase64 (str) {
191
+ export function octalToBase64(str) {
185
192
  return Buffer.from(octalToChar(str), 'binary').toString('base64')
186
193
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nictool/dns-resource-record",
3
- "version": "1.1.7",
3
+ "version": "1.2.1",
4
4
  "description": "DNS Resource Records",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -39,7 +39,6 @@
39
39
  },
40
40
  "homepage": "https://github.com/NicTool/dns-resource-record#readme",
41
41
  "devDependencies": {
42
- "eslint": "^8.56.0",
43
42
  "mocha": "^10.3.0"
44
43
  }
45
44
  }
package/rr/a.js CHANGED
@@ -1,57 +1,66 @@
1
-
2
- import net from 'net'
1
+ import net from 'node:net'
3
2
 
4
3
  import RR from '../rr.js'
5
4
 
6
5
  export default class A extends RR {
7
- constructor (opts) {
6
+ constructor(opts) {
8
7
  super(opts)
9
8
  }
10
9
 
11
10
  /****** Resource record specific setters *******/
12
- setAddress (val) {
13
- if (!val) throw new Error('A: address is required')
14
- if (!net.isIPv4(val)) throw new Error('A address must be IPv4')
11
+ setAddress(val) {
12
+ if (!val) this.throwHelp('A: address is required')
13
+ if (!net.isIPv4(val)) this.throwHelp('A address must be IPv4')
15
14
  this.set('address', val)
16
15
  }
17
16
 
18
- getDescription () {
17
+ getDescription() {
19
18
  return 'Address'
20
19
  }
21
20
 
22
- getRdataFields (arg) {
23
- return [ 'address' ]
21
+ getRdataFields(arg) {
22
+ return ['address']
24
23
  }
25
24
 
26
- getRFCs () {
27
- return [ 1035 ]
25
+ getRFCs() {
26
+ return [1035]
28
27
  }
29
28
 
30
- getTypeId () {
29
+ getTypeId() {
31
30
  return 1
32
31
  }
33
32
 
33
+ getCanonical() {
34
+ return {
35
+ owner: 'host.example.com.',
36
+ class: 'IN',
37
+ ttl: 3600,
38
+ type: 'A',
39
+ address: '192.0.2.127',
40
+ }
41
+ }
42
+
34
43
  /****** IMPORTERS *******/
35
- fromTinydns (opts) {
44
+ fromTinydns(opts) {
36
45
  // +fqdn:ip:ttl:timestamp:lo
37
- const [ owner, ip, ttl, ts, loc ] = opts.tinyline.substring(1).split(':')
46
+ const [owner, ip, ttl, ts, loc] = opts.tinyline.substring(1).split(':')
38
47
 
39
48
  return new A({
40
- owner : this.fullyQualify(owner),
41
- type : 'A',
42
- address : ip,
43
- ttl : parseInt(ttl, 10),
49
+ owner: this.fullyQualify(owner),
50
+ type: 'A',
51
+ address: ip,
52
+ ttl: parseInt(ttl, 10),
44
53
  timestamp: ts,
45
- location : loc !== '' && loc !== '\n' ? loc : '',
54
+ location: loc !== '' && loc !== '\n' ? loc : '',
46
55
  })
47
56
  }
48
57
 
49
- fromBind (opts) {
58
+ fromBind(opts) {
50
59
  // test.example.com 3600 IN A 192.0.2.127
51
- const [ owner, ttl, c, type, address ] = opts.bindline.split(/\s+/)
60
+ const [owner, ttl, c, type, address] = opts.bindline.split(/\s+/)
52
61
  return new A({
53
62
  owner,
54
- ttl : parseInt(ttl, 10),
63
+ ttl: parseInt(ttl, 10),
55
64
  class: c,
56
65
  type,
57
66
  address,
@@ -59,7 +68,7 @@ export default class A extends RR {
59
68
  }
60
69
 
61
70
  /****** EXPORTERS *******/
62
- toTinydns () {
71
+ toTinydns() {
63
72
  return `+${this.getTinyFQDN('owner')}:${this.get('address')}:${this.getTinydnsPostamble()}\n`
64
73
  }
65
74
  }
package/rr/aaaa.js CHANGED
@@ -1,86 +1,97 @@
1
-
2
- import net from 'net'
1
+ import net from 'node:net'
3
2
 
4
3
  import RR from '../rr.js'
5
4
  import * as TINYDNS from '../lib/tinydns.js'
6
5
 
7
6
  export default class AAAA extends RR {
8
- constructor (opts) {
7
+ constructor(opts) {
9
8
  super(opts)
10
9
  }
11
10
 
12
11
  /****** Resource record specific setters *******/
13
- setAddress (val) {
14
- if (!val) throw new Error('AAAA: address is required')
15
- if (!net.isIPv6(val)) throw new Error(`AAAA: address must be IPv6 (${val})`)
12
+ setAddress(val) {
13
+ if (!val) this.throwHelp('AAAA: address is required')
14
+ if (!net.isIPv6(val)) this.throwHelp(`AAAA: address must be IPv6 (${val})`)
16
15
 
17
16
  this.set('address', this.expand(val.toLowerCase())) // lower case: RFC 5952
18
17
  }
19
18
 
20
- getCompressed (val) {
19
+ getCompressed(val) {
21
20
  this.compress(val || this.get('address'))
22
21
  }
23
22
 
24
- getDescription () {
23
+ getDescription() {
25
24
  return 'Address IPv6'
26
25
  }
27
26
 
28
- getRdataFields (arg) {
29
- return [ 'address' ]
27
+ getRdataFields(arg) {
28
+ return ['address']
30
29
  }
31
30
 
32
- getRFCs () {
33
- return [ 3596 ]
31
+ getRFCs() {
32
+ return [3596]
34
33
  }
35
34
 
36
- getTypeId () {
35
+ getTypeId() {
37
36
  return 28
38
37
  }
39
38
 
39
+ getCanonical() {
40
+ return {
41
+ owner: 'host.example.com.',
42
+ address: '2001:0db8:0020:000a:0000:0000:0000:0004',
43
+ class: 'IN',
44
+ ttl: 3600,
45
+ type: 'A',
46
+ }
47
+ }
48
+
40
49
  /****** IMPORTERS *******/
41
- fromTinydns (opts) {
50
+ fromTinydns(opts) {
42
51
  const str = opts.tinyline
43
52
  let fqdn, ip, n, rdata, ttl, ts, loc
44
53
 
45
54
  switch (str[0]) {
46
55
  case ':':
47
56
  // GENERIC => :fqdn:28:rdata:ttl:timestamp:lo
48
- [ fqdn, n, rdata, ttl, ts, loc ] = str.substring(1).split(':')
49
- if (n != 28) throw new Error('AAAA fromTinydns, invalid n')
50
- ip = TINYDNS.octalToHex(rdata).match(/([0-9a-fA-F]{4})/g).join(':')
57
+ ;[fqdn, n, rdata, ttl, ts, loc] = str.substring(1).split(':')
58
+ if (n != 28) this.throwHelp('AAAA fromTinydns, invalid n')
59
+ ip = TINYDNS.octalToHex(rdata)
60
+ .match(/([0-9a-fA-F]{4})/g)
61
+ .join(':')
51
62
  break
52
63
  case '3':
53
64
  case '6':
54
65
  // AAAA => 3fqdn:ip:x:ttl:timestamp:lo
55
66
  // AAAA,PTR => 6fqdn:ip:x:ttl:timestamp:lo
56
- [ fqdn, rdata, ttl, ts, loc ] = str.substring(1).split(':')
67
+ ;[fqdn, rdata, ttl, ts, loc] = str.substring(1).split(':')
57
68
  ip = rdata.match(/(.{4})/g).join(':')
58
69
  break
59
70
  }
60
71
 
61
72
  return new AAAA({
62
- owner : this.fullyQualify(fqdn),
63
- ttl : parseInt(ttl, 10),
64
- type : 'AAAA',
65
- address : ip,
73
+ owner: this.fullyQualify(fqdn),
74
+ ttl: parseInt(ttl, 10),
75
+ type: 'AAAA',
76
+ address: ip,
66
77
  timestamp: ts,
67
- location : loc !== '' && loc !== '\n' ? loc : '',
78
+ location: loc !== '' && loc !== '\n' ? loc : '',
68
79
  })
69
80
  }
70
81
 
71
- fromBind (opts) {
82
+ fromBind(opts) {
72
83
  // test.example.com 3600 IN AAAA ...
73
- const [ owner, ttl, c, type, ip ] = opts.bindline.split(/\s+/)
84
+ const [owner, ttl, c, type, ip] = opts.bindline.split(/\s+/)
74
85
  return new AAAA({
75
86
  owner,
76
- ttl : parseInt(ttl, 10),
77
- class : c,
87
+ ttl: parseInt(ttl, 10),
88
+ class: c,
78
89
  type,
79
90
  address: this.expand(ip),
80
91
  })
81
92
  }
82
93
 
83
- compress (val) {
94
+ compress(val) {
84
95
  /*
85
96
  * RFC 5952
86
97
  * 4.1. Leading zeros MUST be suppressed...A single 16-bit 0000 field MUST be represented as 0.
@@ -88,10 +99,10 @@ export default class AAAA extends RR {
88
99
  * 4.2.2 The symbol "::" MUST NOT be used to shorten just one 16-bit 0 field.
89
100
  * 4.2.3 When choosing placement of a "::", the longest run...MUST be shortened
90
101
  * 4.3 The characters a-f in an IPv6 address MUST be represented in lowercase.
91
- */
102
+ */
92
103
  let r = val
93
- .replace(/0000/g, '0') // 4.1 0000 -> 0
94
- .replace(/:0+([1-9a-fA-F])/g, ':$1') // 4.1 remove leading zeros
104
+ .replace(/0000/g, '0') // 4.1 0000 -> 0
105
+ .replace(/:0+([1-9a-fA-F])/g, ':$1') // 4.1 remove leading zeros
95
106
 
96
107
  const mostConsecutiveZeros = [
97
108
  new RegExp(/0?(?::0){6,}:0?/),
@@ -111,7 +122,7 @@ export default class AAAA extends RR {
111
122
  return r
112
123
  }
113
124
 
114
- expand (val, delimiter) {
125
+ expand(val, delimiter) {
115
126
  if (delimiter === undefined) delimiter = ':'
116
127
 
117
128
  const colons = val.match(/:/g)
@@ -121,15 +132,18 @@ export default class AAAA extends RR {
121
132
  }
122
133
 
123
134
  // restore compressed leading zeros
124
- return val.split(':').map(s => s.padStart(4, 0)).join(delimiter)
135
+ return val
136
+ .split(':')
137
+ .map((s) => s.padStart(4, 0))
138
+ .join(delimiter)
125
139
  }
126
140
 
127
141
  /****** EXPORTERS *******/
128
- toBind (zone_opts) {
142
+ toBind(zone_opts) {
129
143
  return `${this.getPrefix(zone_opts)}\t${this.compress(this.get('address'))}\n`
130
144
  }
131
145
 
132
- toTinydns () {
146
+ toTinydns() {
133
147
  // from AAAA notation (8 groups of 4 hex digits) to 16 escaped octals
134
148
  const rdata = TINYDNS.packHex(this.expand(this.get('address'), ''))
135
149
  return this.getTinydnsGeneric(rdata)