@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/rr.js CHANGED
@@ -1,6 +1,7 @@
1
+ import util from 'node:util'
1
2
 
2
3
  export default class RR extends Map {
3
- constructor (opts) {
4
+ constructor(opts) {
4
5
  super()
5
6
 
6
7
  if (opts === null) return
@@ -15,44 +16,48 @@ export default class RR extends Map {
15
16
  this.setTimestamp(opts?.timestamp)
16
17
 
17
18
  this.setOwner(opts?.owner)
18
- this.setType (opts?.type)
19
- this.setTtl (opts?.ttl)
19
+ this.setType(opts?.type)
20
+ this.setTtl(opts?.ttl)
20
21
  this.setClass(opts?.class)
21
22
 
22
23
  for (const f of this.getFields('rdata')) {
23
24
  const fnName = `set${this.ucfirst(f)}`
24
- if (this[fnName] === undefined) throw new Error(`Missing ${fnName} in class ${this.get('type')}`)
25
+ if (this[fnName] === undefined)
26
+ this.throwHelp(`Missing ${fnName} in class ${this.get('type')}`)
25
27
  this[fnName](opts[f])
26
28
  }
27
29
 
28
30
  if (opts.comment) this.set('comment', opts.comment)
29
31
  }
30
32
 
31
- ucfirst (str) {
32
- return str.split(/\s/).map(w => w.charAt(0).toUpperCase() + w.slice(1)).join('')
33
+ ucfirst(str) {
34
+ return str
35
+ .split(/\s/)
36
+ .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
37
+ .join('')
33
38
  }
34
39
 
35
- setClass (c) {
40
+ setClass(c) {
36
41
  switch (c) {
37
- case 'IN': // 1
42
+ case 'IN': // 1
38
43
  case undefined:
39
44
  case null:
40
45
  case '':
41
46
  this.set('class', 'IN')
42
47
  break
43
- case 'CS': // 2
44
- case 'CH': // 3
45
- case 'HS': // 4
46
- case 'NONE': // 254
47
- case 'ANY': // 255
48
+ case 'CS': // 2
49
+ case 'CH': // 3
50
+ case 'HS': // 4
51
+ case 'NONE': // 254
52
+ case 'ANY': // 255
48
53
  this.set('class', c)
49
54
  break
50
55
  default:
51
- throw new Error(`invalid class ${c}`)
56
+ this.throwHelp(`invalid class ${c}`)
52
57
  }
53
58
  }
54
59
 
55
- setLocation (l) {
60
+ setLocation(l) {
56
61
  switch (l) {
57
62
  case undefined:
58
63
  return
@@ -61,7 +66,7 @@ export default class RR extends Map {
61
66
  }
62
67
  }
63
68
 
64
- setTimestamp (l) {
69
+ setTimestamp(l) {
65
70
  switch (l) {
66
71
  case undefined:
67
72
  return
@@ -70,32 +75,35 @@ export default class RR extends Map {
70
75
  }
71
76
  }
72
77
 
73
- setOwner (n) {
74
- if (n === undefined) throw new Error(`owner is required`)
78
+ setOwner(n) {
79
+ if (n === undefined) this.throwHelp(`owner is required`)
75
80
 
76
81
  if (n.length < 1 || n.length > 255)
77
- throw new Error('Domain names must have 1-255 octets (characters): RFC 2181')
82
+ this.throwHelp(
83
+ 'Domain names must have 1-255 octets (characters): RFC 2181',
84
+ )
78
85
 
79
- this.isFullyQualified('', 'owner', n)
86
+ this.isFullyQualified(this.constructor.name, 'owner', n)
80
87
  this.hasValidLabels(n)
81
88
 
82
89
  // wildcard records: RFC 1034, 4592
83
90
  if (/\*/.test(n)) {
84
- if (!/^\*\./.test(n) && !/\.\*\./.test(n)) throw new Error('only *.something or * (by itself) is a valid wildcard')
91
+ if (!/^\*\./.test(n) && !/\.\*\./.test(n))
92
+ this.throwHelp('only *.something or * (by itself) is a valid wildcard')
85
93
  }
86
94
 
87
95
  this.set('owner', n.toLowerCase())
88
96
  }
89
97
 
90
- setTtl (t) {
91
-
98
+ setTtl(t) {
92
99
  if (t === undefined) t = this?.default?.ttl
93
100
  if (t === undefined) {
94
- if ([ 'SOA', 'SSHPF' ].includes(this.get('type'))) return
95
- throw new Error('TTL is required, no default available')
101
+ if (['SOA', 'SSHPF'].includes(this.get('type'))) return
102
+ this.throwHelp('TTL is required, no default available')
96
103
  }
97
104
 
98
- if (typeof t !== 'number') throw new Error(`TTL must be numeric (${typeof t})`)
105
+ if (typeof t !== 'number')
106
+ this.throwHelp(`TTL must be numeric (${typeof t})`)
99
107
 
100
108
  // RFC 1035, 2181
101
109
  this.is32bitInt(this.owner, 'TTL', t)
@@ -103,24 +111,34 @@ export default class RR extends Map {
103
111
  this.set('ttl', t)
104
112
  }
105
113
 
106
- setType (t) {
114
+ setType(t) {
107
115
  switch (t) {
108
116
  case '':
109
117
  case undefined:
110
- throw new Error(`type is required`)
118
+ this.throwHelp(`type is required`)
111
119
  }
112
120
 
113
121
  if (t.toUpperCase() !== this.constructor.name)
114
- throw new Error(`type ${t} doesn't match ${this.constructor.name}`)
122
+ this.throwHelp(`type ${t} doesn't match ${this.constructor.name}`)
115
123
 
116
124
  this.set('type', t.toUpperCase())
117
125
  }
118
126
 
119
- citeRFC () {
120
- return `see RFC ${this.getRFCs()}`
127
+ throwHelp(e) {
128
+ if (this.constructor.name === 'RR') throw new Error(e)
129
+
130
+ const example = this.getCanonical
131
+ ? `Example ${this.constructor.name}:\n${util.inspect(this.getCanonical(), { depth: null })}\n\n`
132
+ : `${this.constructor.name} records have the fields: ${this.getFields().join(', ')}\n\n`
133
+
134
+ throw new Error(`${e}\n\n${example}${this.citeRFC()}\n`)
135
+ }
136
+
137
+ citeRFC() {
138
+ return `see RFC${this.getRFCs().length > 1 ? 's' : ''} ${this.getRFCs()}`
121
139
  }
122
140
 
123
- fullyQualify (hostname, origin) {
141
+ fullyQualify(hostname, origin) {
124
142
  if (!hostname) return hostname
125
143
  if (hostname === '@' && origin) hostname = origin
126
144
  if (hostname.endsWith('.')) return hostname.toLowerCase()
@@ -128,7 +146,7 @@ export default class RR extends Map {
128
146
  return `${hostname}.`
129
147
  }
130
148
 
131
- getPrefix (zone_opts = {}) {
149
+ getPrefix(zone_opts = {}) {
132
150
  const classVal = zone_opts.hide?.class ? '' : this.get('class')
133
151
 
134
152
  let rrTTL = this.get('ttl')
@@ -137,25 +155,24 @@ export default class RR extends Map {
137
155
  let owner = this.get('owner')
138
156
  if (zone_opts.hide?.sameOwner && zone_opts.previousOwner === owner) {
139
157
  owner = ''
140
- }
141
- else {
158
+ } else {
142
159
  owner = this.getFQDN('owner', zone_opts)
143
160
  }
144
161
 
145
162
  return `${owner}\t${rrTTL}\t${classVal}\t${this.get('type')}`
146
163
  }
147
164
 
148
- getEmpty (prop) {
165
+ getEmpty(prop) {
149
166
  return this.get(prop) === undefined ? '' : this.get(prop)
150
167
  }
151
168
 
152
- getComment (prop) {
169
+ getComment(prop) {
153
170
  const c = this.get('comment')
154
171
  if (!c || !c[prop]) return ''
155
172
  return c[prop]
156
173
  }
157
174
 
158
- getQuoted (prop) {
175
+ getQuoted(prop) {
159
176
  // if prop is not in quoted list, return bare
160
177
  if (!this.getQuotedFields().includes(prop)) return this.get(prop)
161
178
 
@@ -165,16 +182,16 @@ export default class RR extends Map {
165
182
  return `"${this.get(prop)}"` // add double quotes
166
183
  }
167
184
 
168
- getQuotedFields () {
185
+ getQuotedFields() {
169
186
  return []
170
187
  }
171
188
 
172
- getRdataFields () {
189
+ getRdataFields() {
173
190
  return []
174
191
  }
175
192
 
176
- getFields (arg) {
177
- const commonFields = [ 'owner', 'ttl', 'class', 'type' ]
193
+ getFields(arg) {
194
+ const commonFields = ['owner', 'ttl', 'class', 'type']
178
195
  Object.freeze(commonFields)
179
196
 
180
197
  switch (arg) {
@@ -187,23 +204,24 @@ export default class RR extends Map {
187
204
  }
188
205
  }
189
206
 
190
- getFQDN (field, zone_opts = {}) {
207
+ getFQDN(field, zone_opts = {}) {
191
208
  let fqdn = this.get(field)
192
- if (!fqdn) throw new Error(`empty value for field ${field}`)
209
+ if (!fqdn) this.throwHelp(`empty value for field ${field}`)
193
210
  if (!fqdn.endsWith('.')) fqdn += '.'
194
211
 
195
212
  if (zone_opts.hide?.origin && zone_opts.origin) {
196
213
  if (fqdn === zone_opts.origin) return '@'
197
- if (fqdn.endsWith(zone_opts.origin)) return fqdn.slice(0, fqdn.length - zone_opts.origin.length - 1)
214
+ if (fqdn.endsWith(zone_opts.origin))
215
+ return fqdn.slice(0, fqdn.length - zone_opts.origin.length - 1)
198
216
  }
199
217
 
200
218
  return fqdn
201
219
  }
202
220
 
203
- getTinyFQDN (field) {
221
+ getTinyFQDN(field) {
204
222
  const val = this.get(field)
205
- if (val === '') return val // empty
206
- if (val === '.') return val // null MX
223
+ if (val === '') return val // empty
224
+ if (val === '.') return val // null MX
207
225
 
208
226
  // strip off trailing ., tinydns doesn't require it for FQDN
209
227
  if (val.endsWith('.')) return val.slice(0, -1)
@@ -211,15 +229,17 @@ export default class RR extends Map {
211
229
  return val
212
230
  }
213
231
 
214
- getTinydnsGeneric (rdata) {
232
+ getTinydnsGeneric(rdata) {
215
233
  return `:${this.getTinyFQDN('owner')}:${this.getTypeId()}:${rdata}:${this.getTinydnsPostamble()}\n`
216
234
  }
217
235
 
218
- getTinydnsPostamble () {
219
- return [ 'ttl', 'timestamp', 'location' ].map(f => this.getEmpty(f)).join(':')
236
+ getTinydnsPostamble() {
237
+ return ['ttl', 'timestamp', 'location']
238
+ .map((f) => this.getEmpty(f))
239
+ .join(':')
220
240
  }
221
241
 
222
- hasValidLabels (hostname) {
242
+ hasValidLabels(hostname) {
223
243
  // RFC 952 defined valid hostnames
224
244
  // RFC 1035 limited domain label chars to letters, digits, and hyphen
225
245
  // RFC 1123 allowed hostnames to start with a digit
@@ -227,68 +247,94 @@ export default class RR extends Map {
227
247
  const fq = hostname.endsWith('.') ? hostname.slice(0, -1) : hostname
228
248
  for (const label of fq.split('.')) {
229
249
  if (label.length < 1 || label.length > 63)
230
- throw new Error('Labels must have 1-63 octets (characters), RFC 2181')
250
+ this.throwHelp('Labels must have 1-63 octets (characters), RFC 2181')
231
251
  }
232
252
  }
233
253
 
234
- is8bitInt (type, field, value) {
235
- if (typeof value === 'number'
236
- && parseInt(value, 10) === value // assure integer
237
- && value >= 0
238
- && value <= 255) return true
239
-
240
- throw new Error(`${type} ${field} must be a 8-bit integer (in the range 0-255)`)
254
+ is8bitInt(type, field, value) {
255
+ if (
256
+ typeof value === 'number' &&
257
+ parseInt(value, 10) === value && // assure integer
258
+ value >= 0 &&
259
+ value <= 255
260
+ )
261
+ return true
262
+
263
+ this.throwHelp(
264
+ `${type} ${field} must be a 8-bit integer (in the range 0-255)`,
265
+ )
241
266
  }
242
267
 
243
- is16bitInt (type, field, value) {
244
- if (typeof value === 'number'
245
- && parseInt(value, 10) === value // assure integer
246
- && value >= 0
247
- && value <= 65535) return true
248
-
249
- throw new Error(`${type} ${field} must be a 16-bit integer (in the range 0-65535)`)
268
+ is16bitInt(type, field, value) {
269
+ if (
270
+ typeof value === 'number' &&
271
+ parseInt(value, 10) === value && // assure integer
272
+ value >= 0 &&
273
+ value <= 65535
274
+ )
275
+ return true
276
+
277
+ this.throwHelp(
278
+ `${type} ${field} must be a 16-bit integer (in the range 0-65535)`,
279
+ )
250
280
  }
251
281
 
252
- is32bitInt (type, field, value) {
253
- if (typeof value === 'number'
254
- && parseInt(value, 10) === value // assure integer
255
- && value >= 0
256
- && value <= 2147483647) return true
257
-
258
- throw new Error(`${type} ${field} must be a 32-bit integer (in the range 0-2147483647)`)
282
+ is32bitInt(type, field, value) {
283
+ if (
284
+ typeof value === 'number' &&
285
+ parseInt(value, 10) === value && // assure integer
286
+ value >= 0 &&
287
+ value <= 2147483647
288
+ )
289
+ return true
290
+
291
+ this.throwHelp(
292
+ `${type} ${field} must be a 32-bit integer (in the range 0-2147483647)`,
293
+ )
259
294
  }
260
295
 
261
- isQuoted (val) {
296
+ isQuoted(val) {
262
297
  return /^["']/.test(val) && /["']$/.test(val)
263
298
  }
264
299
 
265
- isFullyQualified (type, blah, hostname) {
300
+ isFullyQualified(type, field, hostname) {
266
301
  if (hostname.endsWith('.')) return true
267
302
 
268
- throw new Error(`${type}: ${blah} must be fully qualified`)
303
+ this.throwHelp(`${type}: ${field} must be fully qualified`)
269
304
  }
270
305
 
271
- isValidHostname (type, field, hostname) {
306
+ isValidHostname(type, field, hostname) {
272
307
  const allowed = new RegExp(/[^a-zA-Z0-9\-._/\\]/)
273
308
  if (!allowed.test(hostname)) return true
274
309
 
275
310
  const matches = allowed.exec(hostname)
276
- throw new Error(`${type}, ${field} has invalid hostname character (${matches[0]})`)
311
+ this.throwHelp(
312
+ `${type}, ${field} has invalid hostname character (${matches[0]})`,
313
+ )
277
314
  }
278
315
 
279
- toBind (zone_opts) {
280
- return `${this.getPrefix(zone_opts)}\t${this.getRdataFields().map(f => this.getQuoted(f)).join('\t')}\n`
316
+ toBind(zone_opts) {
317
+ return `${this.getPrefix(zone_opts)}\t${this.getRdataFields()
318
+ .map((f) => this.getQuoted(f))
319
+ .join('\t')}\n`
281
320
  }
282
321
 
283
- toMaraDNS () {
322
+ toMaraDNS() {
284
323
  const type = this.get('type')
285
- const supportedTypes = 'A PTR MX AAAA SRV NAPTR NS SOA TXT SPF RAW FQDN4 FQDN6 CNAME HINFO WKS LOC'.split(/\s+/g)
324
+ const supportedTypes =
325
+ 'A PTR MX AAAA SRV NAPTR NS SOA TXT SPF RAW FQDN4 FQDN6 CNAME HINFO WKS LOC'.split(
326
+ /\s+/g,
327
+ )
286
328
  if (!supportedTypes.includes(type)) return this.toMaraGeneric()
287
- return `${this.get('owner')}\t+${this.get('ttl')}\t${type}\t${this.getRdataFields().map(f => this.getQuoted(f)).join('\t')} ~\n`
329
+ return `${this.get('owner')}\t+${this.get('ttl')}\t${type}\t${this.getRdataFields()
330
+ .map((f) => this.getQuoted(f))
331
+ .join('\t')} ~\n`
288
332
  }
289
333
 
290
- toMaraGeneric () {
291
- // throw new Error(`\nMaraDNS does not support ${type} records yet and this package does not support MaraDNS generic records. Yet.\n`)
292
- return `${this.get('owner')}\t+${this.get('ttl')}\tRAW ${this.getTypeId()}\t'${this.getRdataFields().map(f => this.getQuoted(f)).join(' ')}' ~\n`
334
+ toMaraGeneric() {
335
+ // this.throwHelp(`\nMaraDNS does not support ${type} records yet and this package does not support MaraDNS generic records. Yet.\n`)
336
+ return `${this.get('owner')}\t+${this.get('ttl')}\tRAW ${this.getTypeId()}\t'${this.getRdataFields()
337
+ .map((f) => this.getQuoted(f))
338
+ .join(' ')}' ~\n`
293
339
  }
294
340
  }
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: /type is required/ },
48
- { ...defaults, type: undefined, msg: /type is required/ },
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
- })