@nictool/dns-resource-record 1.1.6 → 1.2.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.
Files changed (74) hide show
  1. package/.prettierrc.yml +3 -0
  2. package/CHANGELOG.md +17 -43
  3. package/README.md +56 -62
  4. package/index.js +77 -29
  5. package/lib/tinydns.js +68 -61
  6. package/package.json +10 -6
  7. package/rr/a.js +19 -20
  8. package/rr/aaaa.js +35 -31
  9. package/rr/caa.js +41 -39
  10. package/rr/cert.js +21 -19
  11. package/rr/cname.js +19 -20
  12. package/rr/dname.js +19 -19
  13. package/rr/dnskey.js +48 -41
  14. package/rr/ds.js +38 -36
  15. package/rr/hinfo.js +26 -25
  16. package/rr/ipseckey.js +53 -45
  17. package/rr/key.js +21 -21
  18. package/rr/loc.js +67 -54
  19. package/rr/mx.js +26 -24
  20. package/rr/naptr.js +51 -52
  21. package/rr/ns.js +25 -22
  22. package/rr/nsec.js +26 -20
  23. package/rr/nsec3.js +90 -30
  24. package/rr/nsec3param.js +29 -26
  25. package/rr/nxt.js +67 -0
  26. package/rr/openpgpkey.js +13 -14
  27. package/rr/ptr.js +20 -21
  28. package/rr/rrsig.js +27 -21
  29. package/rr/sig.js +24 -19
  30. package/rr/smimea.js +35 -28
  31. package/rr/soa.js +57 -42
  32. package/rr/spf.js +20 -17
  33. package/rr/srv.js +41 -41
  34. package/rr/sshfp.js +29 -30
  35. package/rr/tlsa.js +47 -40
  36. package/rr/tsig.js +48 -0
  37. package/rr/txt.js +40 -33
  38. package/rr/uri.js +31 -31
  39. package/rr/wks.js +44 -0
  40. package/rr.js +116 -79
  41. package/.codeclimate.yml +0 -25
  42. package/DEVELOP.md +0 -23
  43. package/test/a.js +0 -76
  44. package/test/aaaa.js +0 -79
  45. package/test/base.js +0 -138
  46. package/test/caa.js +0 -104
  47. package/test/cert.js +0 -48
  48. package/test/cname.js +0 -41
  49. package/test/dname.js +0 -53
  50. package/test/dnskey.js +0 -44
  51. package/test/ds.js +0 -44
  52. package/test/fake.js +0 -26
  53. package/test/hinfo.js +0 -75
  54. package/test/ipseckey.js +0 -115
  55. package/test/key.js +0 -37
  56. package/test/loc.js +0 -71
  57. package/test/mx.js +0 -75
  58. package/test/naptr.js +0 -40
  59. package/test/ns.js +0 -53
  60. package/test/nsec.js +0 -38
  61. package/test/nsec3.js +0 -26
  62. package/test/nsec3param.js +0 -26
  63. package/test/openpgpkey.js +0 -35
  64. package/test/ptr.js +0 -54
  65. package/test/rr.js +0 -196
  66. package/test/smimea.js +0 -45
  67. package/test/soa.js +0 -77
  68. package/test/spf.js +0 -48
  69. package/test/srv.js +0 -81
  70. package/test/sshfp.js +0 -62
  71. package/test/tinydns.js +0 -140
  72. package/test/tlsa.js +0 -54
  73. package/test/txt.js +0 -70
  74. package/test/uri.js +0 -61
package/rr.js CHANGED
@@ -1,6 +1,5 @@
1
-
2
1
  export default class RR extends Map {
3
- constructor (opts) {
2
+ constructor(opts) {
4
3
  super()
5
4
 
6
5
  if (opts === null) return
@@ -15,36 +14,40 @@ export default class RR extends Map {
15
14
  this.setTimestamp(opts?.timestamp)
16
15
 
17
16
  this.setOwner(opts?.owner)
18
- this.setType (opts?.type)
19
- this.setTtl (opts?.ttl)
17
+ this.setType(opts?.type)
18
+ this.setTtl(opts?.ttl)
20
19
  this.setClass(opts?.class)
21
20
 
22
21
  for (const f of this.getFields('rdata')) {
23
22
  const fnName = `set${this.ucfirst(f)}`
24
- if (this[fnName] === undefined) throw new Error(`Missing ${fnName} in class ${this.get('type')}`)
23
+ if (this[fnName] === undefined)
24
+ throw new Error(`Missing ${fnName} in class ${this.get('type')}`)
25
25
  this[fnName](opts[f])
26
26
  }
27
27
 
28
28
  if (opts.comment) this.set('comment', opts.comment)
29
29
  }
30
30
 
31
- ucfirst (str) {
32
- return str.split(/\s/).map(w => w.charAt(0).toUpperCase() + w.slice(1)).join('')
31
+ ucfirst(str) {
32
+ return str
33
+ .split(/\s/)
34
+ .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
35
+ .join('')
33
36
  }
34
37
 
35
- setClass (c) {
38
+ setClass(c) {
36
39
  switch (c) {
37
- case 'IN': // 1
40
+ case 'IN': // 1
38
41
  case undefined:
39
42
  case null:
40
43
  case '':
41
44
  this.set('class', 'IN')
42
45
  break
43
- case 'CS': // 2
44
- case 'CH': // 3
45
- case 'HS': // 4
46
- case 'NONE': // 254
47
- case 'ANY': // 255
46
+ case 'CS': // 2
47
+ case 'CH': // 3
48
+ case 'HS': // 4
49
+ case 'NONE': // 254
50
+ case 'ANY': // 255
48
51
  this.set('class', c)
49
52
  break
50
53
  default:
@@ -52,7 +55,7 @@ export default class RR extends Map {
52
55
  }
53
56
  }
54
57
 
55
- setLocation (l) {
58
+ setLocation(l) {
56
59
  switch (l) {
57
60
  case undefined:
58
61
  return
@@ -61,7 +64,7 @@ export default class RR extends Map {
61
64
  }
62
65
  }
63
66
 
64
- setTimestamp (l) {
67
+ setTimestamp(l) {
65
68
  switch (l) {
66
69
  case undefined:
67
70
  return
@@ -70,32 +73,35 @@ export default class RR extends Map {
70
73
  }
71
74
  }
72
75
 
73
- setOwner (n) {
76
+ setOwner(n) {
74
77
  if (n === undefined) throw new Error(`owner is required`)
75
78
 
76
79
  if (n.length < 1 || n.length > 255)
77
- throw new Error('Domain names must have 1-255 octets (characters): RFC 2181')
80
+ throw new Error(
81
+ 'Domain names must have 1-255 octets (characters): RFC 2181',
82
+ )
78
83
 
79
84
  this.isFullyQualified('', 'owner', n)
80
85
  this.hasValidLabels(n)
81
86
 
82
87
  // wildcard records: RFC 1034, 4592
83
88
  if (/\*/.test(n)) {
84
- if (!/^\*\./.test(n) && !/\.\*\./.test(n)) throw new Error('only *.something or * (by itself) is a valid wildcard')
89
+ if (!/^\*\./.test(n) && !/\.\*\./.test(n))
90
+ throw new Error('only *.something or * (by itself) is a valid wildcard')
85
91
  }
86
92
 
87
93
  this.set('owner', n.toLowerCase())
88
94
  }
89
95
 
90
- setTtl (t) {
91
-
96
+ setTtl(t) {
92
97
  if (t === undefined) t = this?.default?.ttl
93
98
  if (t === undefined) {
94
- if ([ 'SOA', 'SSHPF' ].includes(this.get('type'))) return
99
+ if (['SOA', 'SSHPF'].includes(this.get('type'))) return
95
100
  throw new Error('TTL is required, no default available')
96
101
  }
97
102
 
98
- if (typeof t !== 'number') throw new Error(`TTL must be numeric (${typeof t})`)
103
+ if (typeof t !== 'number')
104
+ throw new Error(`TTL must be numeric (${typeof t})`)
99
105
 
100
106
  // RFC 1035, 2181
101
107
  this.is32bitInt(this.owner, 'TTL', t)
@@ -103,9 +109,12 @@ export default class RR extends Map {
103
109
  this.set('ttl', t)
104
110
  }
105
111
 
106
- setType (t) {
107
- if ([ undefined, '' ].includes(t))
108
- throw new Error(`type ${t} not supported (yet)`)
112
+ setType(t) {
113
+ switch (t) {
114
+ case '':
115
+ case undefined:
116
+ throw new Error(`type is required`)
117
+ }
109
118
 
110
119
  if (t.toUpperCase() !== this.constructor.name)
111
120
  throw new Error(`type ${t} doesn't match ${this.constructor.name}`)
@@ -113,11 +122,11 @@ export default class RR extends Map {
113
122
  this.set('type', t.toUpperCase())
114
123
  }
115
124
 
116
- citeRFC () {
125
+ citeRFC() {
117
126
  return `see RFC ${this.getRFCs()}`
118
127
  }
119
128
 
120
- fullyQualify (hostname, origin) {
129
+ fullyQualify(hostname, origin) {
121
130
  if (!hostname) return hostname
122
131
  if (hostname === '@' && origin) hostname = origin
123
132
  if (hostname.endsWith('.')) return hostname.toLowerCase()
@@ -125,7 +134,7 @@ export default class RR extends Map {
125
134
  return `${hostname}.`
126
135
  }
127
136
 
128
- getPrefix (zone_opts = {}) {
137
+ getPrefix(zone_opts = {}) {
129
138
  const classVal = zone_opts.hide?.class ? '' : this.get('class')
130
139
 
131
140
  let rrTTL = this.get('ttl')
@@ -134,25 +143,24 @@ export default class RR extends Map {
134
143
  let owner = this.get('owner')
135
144
  if (zone_opts.hide?.sameOwner && zone_opts.previousOwner === owner) {
136
145
  owner = ''
137
- }
138
- else {
146
+ } else {
139
147
  owner = this.getFQDN('owner', zone_opts)
140
148
  }
141
149
 
142
150
  return `${owner}\t${rrTTL}\t${classVal}\t${this.get('type')}`
143
151
  }
144
152
 
145
- getEmpty (prop) {
153
+ getEmpty(prop) {
146
154
  return this.get(prop) === undefined ? '' : this.get(prop)
147
155
  }
148
156
 
149
- getComment (prop) {
157
+ getComment(prop) {
150
158
  const c = this.get('comment')
151
159
  if (!c || !c[prop]) return ''
152
160
  return c[prop]
153
161
  }
154
162
 
155
- getQuoted (prop) {
163
+ getQuoted(prop) {
156
164
  // if prop is not in quoted list, return bare
157
165
  if (!this.getQuotedFields().includes(prop)) return this.get(prop)
158
166
 
@@ -162,16 +170,16 @@ export default class RR extends Map {
162
170
  return `"${this.get(prop)}"` // add double quotes
163
171
  }
164
172
 
165
- getQuotedFields () {
173
+ getQuotedFields() {
166
174
  return []
167
175
  }
168
176
 
169
- getRdataFields () {
177
+ getRdataFields() {
170
178
  return []
171
179
  }
172
180
 
173
- getFields (arg) {
174
- const commonFields = [ 'owner', 'ttl', 'class', 'type' ]
181
+ getFields(arg) {
182
+ const commonFields = ['owner', 'ttl', 'class', 'type']
175
183
  Object.freeze(commonFields)
176
184
 
177
185
  switch (arg) {
@@ -184,23 +192,24 @@ export default class RR extends Map {
184
192
  }
185
193
  }
186
194
 
187
- getFQDN (field, zone_opts = {}) {
195
+ getFQDN(field, zone_opts = {}) {
188
196
  let fqdn = this.get(field)
189
197
  if (!fqdn) throw new Error(`empty value for field ${field}`)
190
198
  if (!fqdn.endsWith('.')) fqdn += '.'
191
199
 
192
200
  if (zone_opts.hide?.origin && zone_opts.origin) {
193
201
  if (fqdn === zone_opts.origin) return '@'
194
- if (fqdn.endsWith(zone_opts.origin)) return fqdn.slice(0, fqdn.length - zone_opts.origin.length - 1)
202
+ if (fqdn.endsWith(zone_opts.origin))
203
+ return fqdn.slice(0, fqdn.length - zone_opts.origin.length - 1)
195
204
  }
196
205
 
197
206
  return fqdn
198
207
  }
199
208
 
200
- getTinyFQDN (field) {
209
+ getTinyFQDN(field) {
201
210
  const val = this.get(field)
202
- if (val === '') return val // empty
203
- if (val === '.') return val // null MX
211
+ if (val === '') return val // empty
212
+ if (val === '.') return val // null MX
204
213
 
205
214
  // strip off trailing ., tinydns doesn't require it for FQDN
206
215
  if (val.endsWith('.')) return val.slice(0, -1)
@@ -208,15 +217,17 @@ export default class RR extends Map {
208
217
  return val
209
218
  }
210
219
 
211
- getTinydnsGeneric (rdata) {
220
+ getTinydnsGeneric(rdata) {
212
221
  return `:${this.getTinyFQDN('owner')}:${this.getTypeId()}:${rdata}:${this.getTinydnsPostamble()}\n`
213
222
  }
214
223
 
215
- getTinydnsPostamble () {
216
- return [ 'ttl', 'timestamp', 'location' ].map(f => this.getEmpty(f)).join(':')
224
+ getTinydnsPostamble() {
225
+ return ['ttl', 'timestamp', 'location']
226
+ .map((f) => this.getEmpty(f))
227
+ .join(':')
217
228
  }
218
229
 
219
- hasValidLabels (hostname) {
230
+ hasValidLabels(hostname) {
220
231
  // RFC 952 defined valid hostnames
221
232
  // RFC 1035 limited domain label chars to letters, digits, and hyphen
222
233
  // RFC 1123 allowed hostnames to start with a digit
@@ -228,64 +239,90 @@ export default class RR extends Map {
228
239
  }
229
240
  }
230
241
 
231
- is8bitInt (type, field, value) {
232
- if (typeof value === 'number'
233
- && parseInt(value, 10) === value // assure integer
234
- && value >= 0
235
- && value <= 255) return true
236
-
237
- throw new Error(`${type} ${field} must be a 8-bit integer (in the range 0-255)`)
242
+ is8bitInt(type, field, value) {
243
+ if (
244
+ typeof value === 'number' &&
245
+ parseInt(value, 10) === value && // assure integer
246
+ value >= 0 &&
247
+ value <= 255
248
+ )
249
+ return true
250
+
251
+ throw new Error(
252
+ `${type} ${field} must be a 8-bit integer (in the range 0-255)`,
253
+ )
238
254
  }
239
255
 
240
- is16bitInt (type, field, value) {
241
- if (typeof value === 'number'
242
- && parseInt(value, 10) === value // assure integer
243
- && value >= 0
244
- && value <= 65535) return true
245
-
246
- throw new Error(`${type} ${field} must be a 16-bit integer (in the range 0-65535)`)
256
+ is16bitInt(type, field, value) {
257
+ if (
258
+ typeof value === 'number' &&
259
+ parseInt(value, 10) === value && // assure integer
260
+ value >= 0 &&
261
+ value <= 65535
262
+ )
263
+ return true
264
+
265
+ throw new Error(
266
+ `${type} ${field} must be a 16-bit integer (in the range 0-65535)`,
267
+ )
247
268
  }
248
269
 
249
- is32bitInt (type, field, value) {
250
- if (typeof value === 'number'
251
- && parseInt(value, 10) === value // assure integer
252
- && value >= 0
253
- && value <= 2147483647) return true
254
-
255
- throw new Error(`${type} ${field} must be a 32-bit integer (in the range 0-2147483647)`)
270
+ is32bitInt(type, field, value) {
271
+ if (
272
+ typeof value === 'number' &&
273
+ parseInt(value, 10) === value && // assure integer
274
+ value >= 0 &&
275
+ value <= 2147483647
276
+ )
277
+ return true
278
+
279
+ throw new Error(
280
+ `${type} ${field} must be a 32-bit integer (in the range 0-2147483647)`,
281
+ )
256
282
  }
257
283
 
258
- isQuoted (val) {
284
+ isQuoted(val) {
259
285
  return /^["']/.test(val) && /["']$/.test(val)
260
286
  }
261
287
 
262
- isFullyQualified (type, blah, hostname) {
288
+ isFullyQualified(type, blah, hostname) {
263
289
  if (hostname.endsWith('.')) return true
264
290
 
265
291
  throw new Error(`${type}: ${blah} must be fully qualified`)
266
292
  }
267
293
 
268
- isValidHostname (type, field, hostname) {
294
+ isValidHostname(type, field, hostname) {
269
295
  const allowed = new RegExp(/[^a-zA-Z0-9\-._/\\]/)
270
296
  if (!allowed.test(hostname)) return true
271
297
 
272
298
  const matches = allowed.exec(hostname)
273
- throw new Error(`${type}, ${field} has invalid hostname character (${matches[0]})`)
299
+ throw new Error(
300
+ `${type}, ${field} has invalid hostname character (${matches[0]})`,
301
+ )
274
302
  }
275
303
 
276
- toBind (zone_opts) {
277
- return `${this.getPrefix(zone_opts)}\t${this.getRdataFields().map(f => this.getQuoted(f)).join('\t')}\n`
304
+ toBind(zone_opts) {
305
+ return `${this.getPrefix(zone_opts)}\t${this.getRdataFields()
306
+ .map((f) => this.getQuoted(f))
307
+ .join('\t')}\n`
278
308
  }
279
309
 
280
- toMaraDNS () {
310
+ toMaraDNS() {
281
311
  const type = this.get('type')
282
- const supportedTypes = 'A PTR MX AAAA SRV NAPTR NS SOA TXT SPF RAW FQDN4 FQDN6 CNAME HINFO WKS LOC'.split(/\s+/g)
312
+ const supportedTypes =
313
+ 'A PTR MX AAAA SRV NAPTR NS SOA TXT SPF RAW FQDN4 FQDN6 CNAME HINFO WKS LOC'.split(
314
+ /\s+/g,
315
+ )
283
316
  if (!supportedTypes.includes(type)) return this.toMaraGeneric()
284
- return `${this.get('owner')}\t+${this.get('ttl')}\t${type}\t${this.getRdataFields().map(f => this.getQuoted(f)).join('\t')} ~\n`
317
+ return `${this.get('owner')}\t+${this.get('ttl')}\t${type}\t${this.getRdataFields()
318
+ .map((f) => this.getQuoted(f))
319
+ .join('\t')} ~\n`
285
320
  }
286
321
 
287
- toMaraGeneric () {
322
+ toMaraGeneric() {
288
323
  // throw new Error(`\nMaraDNS does not support ${type} records yet and this package does not support MaraDNS generic records. Yet.\n`)
289
- return `${this.get('owner')}\t+${this.get('ttl')}\tRAW ${this.getTypeId()}\t'${this.getRdataFields().map(f => this.getQuoted(f)).join(' ')}' ~\n`
324
+ return `${this.get('owner')}\t+${this.get('ttl')}\tRAW ${this.getTypeId()}\t'${this.getRdataFields()
325
+ .map((f) => this.getQuoted(f))
326
+ .join(' ')}' ~\n`
290
327
  }
291
328
  }
package/.codeclimate.yml DELETED
@@ -1,25 +0,0 @@
1
- checks:
2
- return-statements:
3
- enabled: false
4
- similar-code:
5
- enabled: false
6
- file-lines:
7
- config:
8
- threshold: 500
9
- method-lines:
10
- config:
11
- threshold: 50
12
- method-complexity:
13
- config:
14
- threshold: 10
15
-
16
- plugins:
17
- eslint:
18
- enabled: true
19
- channel: "eslint-8"
20
- config:
21
- config: ".eslintrc.yaml"
22
-
23
- ratings:
24
- paths:
25
- - "**.js"
package/DEVELOP.md DELETED
@@ -1,23 +0,0 @@
1
-
2
- # Release process
3
-
4
- In your local repo:
5
-
6
- - make your changes
7
- - git add .
8
- - `.release/do.sh` {major|minor|patch}
9
- - fill in the blanks in CHANGELOG.md
10
- - `.release/push.sh`
11
-
12
- Upon merge to `master`:
13
-
14
- - the new version will be published to NPM.
15
- - a GitHub release will be published.
16
- - a release tag will be committed to the repo.
17
-
18
- ## Clean
19
-
20
- `.release/cleanup.sh`
21
-
22
- - will switch to the master branch
23
- - delete the release branch
package/test/a.js DELETED
@@ -1,76 +0,0 @@
1
-
2
- import A from '../rr/a.js'
3
- import * as base from './base.js'
4
-
5
- const defaults = { class: 'IN', ttl: 3600, type: 'A', address: '192.0.2.127' }
6
-
7
- const validRecords = [
8
- {
9
- ...defaults,
10
- owner: 'test.example.com.',
11
- testB: 'test.example.com.\t3600\tIN\tA\t192.0.2.127\n',
12
- testT: '+test.example.com:192.0.2.127:3600::\n',
13
- },
14
- {
15
- ...defaults,
16
- owner: 'test.example.com.',
17
- ttl : 2147483647,
18
- testB: 'test.example.com.\t2147483647\tIN\tA\t192.0.2.127\n',
19
- testT: '+test.example.com:192.0.2.127:2147483647::\n',
20
- },
21
- {
22
- ...defaults,
23
- owner: 'a.',
24
- ttl : 86400,
25
- testB: 'a.\t86400\tIN\tA\t192.0.2.127\n',
26
- testT: '+a:192.0.2.127:86400::\n',
27
- },
28
- {
29
- ...defaults,
30
- owner: '*.example.com.',
31
- testB: '*.example.com.\t3600\tIN\tA\t192.0.2.127\n',
32
- testT: '+*.example.com:192.0.2.127:3600::\n',
33
- },
34
- ]
35
-
36
- const invalidRecords = [
37
- { ...defaults, owner: '', msg: /RFC/ },
38
- { ...defaults, owner: 'something*', msg: /fully/ },
39
- { ...defaults, owner: 'some*thing', msg: /fully/ },
40
- { ...defaults, owner: '*something', msg: /fully/ },
41
- { ...defaults, owner: 'something.*', msg: /fully/ },
42
- { ...defaults, address: 'hosts.not.valid.here', msg: /address must be IPv4/ },
43
- { ...defaults, address: '', msg: /address is required/ },
44
- { ...defaults, address: undefined, msg: /address is required/ },
45
- { ...defaults, address: '1.x.2.3', msg: /address must be IPv4/ },
46
- { ...defaults, address: '.1.2.3', msg: /address must be IPv4/ },
47
- { ...defaults, type: '', msg: /not supported/ },
48
- { ...defaults, type: undefined, msg: /type undefined not supported/ },
49
- { ...defaults, ttl: '', msg: /TTL must be numeric/ },
50
- { ...defaults, ttl: -299, msg: /TTL must be a 32-bit integer/ },
51
- { ...defaults, ttl: 2147483648, msg: /TTL must be a 32-bit integer/ },
52
- ]
53
-
54
- // copy invalid properties to a valid object
55
- for (let i = 0; i < invalidRecords.length; i++) {
56
- const temp = JSON.parse(JSON.stringify(validRecords[0]))
57
- Object.assign(temp, invalidRecords[i])
58
- invalidRecords[i] = temp
59
- }
60
-
61
- describe('A record', function () {
62
- base.valid(A, validRecords)
63
- base.invalid(A, invalidRecords)
64
-
65
- base.getDescription(A)
66
- base.getRFCs(A, validRecords[0])
67
- base.getRdataFields(A, [ 'address' ])
68
- base.getFields(A, [ 'address' ])
69
- base.getTypeId(A, 1)
70
-
71
- base.toBind(A, validRecords)
72
- base.toTinydns(A, validRecords)
73
-
74
- base.fromBind(A, validRecords)
75
- base.fromTinydns(A, validRecords)
76
- })
package/test/aaaa.js DELETED
@@ -1,79 +0,0 @@
1
-
2
- import assert from 'assert'
3
-
4
- import * as base from './base.js'
5
- import AAAA from '../rr/aaaa.js'
6
-
7
- const defaults = { class: 'IN', ttl: 3600, type: 'AAAA' }
8
-
9
- const validRecords = [
10
- {
11
- ...defaults,
12
- owner : 'test.example.com.',
13
- address: '2001:0db8:0020:000a:0000:0000:0000:0004',
14
- testB : 'test.example.com.\t3600\tIN\tAAAA\t2001:db8:20:a::4\n',
15
- testT : ':test.example.com:28:\\040\\001\\015\\270\\000\\040\\000\\012\\000\\000\\000\\000\\000\\000\\000\\004:3600::\n',
16
- },
17
- ]
18
-
19
- const invalidRecords = [
20
- {
21
- ...defaults,
22
- owner : 'test.example.com.',
23
- address: '192.0.2.204',
24
- msg : /address must be IPv6/,
25
- },
26
- ]
27
-
28
- describe('AAAA record', function () {
29
- base.valid(AAAA, validRecords)
30
- base.invalid(AAAA, invalidRecords)
31
-
32
- base.getDescription(AAAA)
33
- base.getRFCs(AAAA, validRecords[0])
34
- base.getFields(AAAA, [ 'address' ])
35
- base.getTypeId(AAAA, 28)
36
-
37
- base.toBind(AAAA, validRecords)
38
- base.toTinydns(AAAA, validRecords)
39
-
40
- base.fromBind(AAAA, validRecords)
41
- base.fromTinydns(AAAA, validRecords)
42
-
43
- for (const val of validRecords) {
44
- it(`imports tinydns AAAA (generic) record (${val.owner})`, async function () {
45
- const r = new AAAA({ tinyline: val.testT })
46
- if (process.env.DEBUG) console.dir(r)
47
- for (const f of [ 'owner', 'address', 'ttl' ]) {
48
- assert.deepStrictEqual(r.get(f), val[f], `${f}: ${r.get(f)} !== ${val[f]}`)
49
- }
50
- })
51
- }
52
-
53
- const tests = [
54
- { e: '2001:0db8:0020:000a:0000:0000:0000:0004', c: '2001:db8:20:a::4' },
55
- { e: '0000:0000:0000:0000:0000:0000:0000:0000', c: '::' },
56
- { e: '0000:0000:0000:0000:0000:0000:0000:0001', c: '::1' },
57
- { e: '2001:0db8:0000:0000:0000:0000:0002:0001', c: '2001:db8::2:1' },
58
- { e: '2001:0db8:0000:0001:0001:0001:0001:0001', c: '2001:db8:0:1:1:1:1:1' },
59
- { e: '2001:0DB8:0000:0000:0008:0800:200C:417A', c: '2001:DB8::8:800:200C:417A' },
60
- ]
61
-
62
- describe('compress', function () {
63
- const r = new AAAA(null)
64
- for (const t of tests) {
65
- it(`compresses IPv6 address (${t.e})`, function () {
66
- assert.equal(r.compress(t.e), t.c)
67
- })
68
- }
69
- })
70
-
71
- describe('expand', function () {
72
- const r = new AAAA(null)
73
- for (const t of tests) {
74
- it(`expands IPv6 address (${t.c})`, function () {
75
- assert.equal(r.expand(t.c), t.e)
76
- })
77
- }
78
- })
79
- })