@nictool/dns-resource-record 1.3.1 → 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.js CHANGED
@@ -4,10 +4,10 @@ export default class RR extends Map {
4
4
 
5
5
  if (opts === null) return
6
6
 
7
- if (opts.default) this.default = opts.default
7
+ if (opts?.default) this.default = opts.default
8
8
 
9
- if (opts.bindline) return this.fromBind(opts)
10
- if (opts.tinyline) return this.fromTinydns(opts)
9
+ if (opts?.bindline) return this.fromBind(opts)
10
+ if (opts?.tinyline) return this.fromTinydns(opts)
11
11
 
12
12
  // tinydns specific
13
13
  this.setLocation(opts?.location)
@@ -21,10 +21,10 @@ export default class RR extends Map {
21
21
  for (const f of this.getFields('rdata')) {
22
22
  const fnName = `set${this.ucFirst(f)}`
23
23
  if (this[fnName] === undefined) this.throwHelp(`Missing ${fnName} in class ${this.get('type')}`)
24
- this[fnName](opts[f])
24
+ this[fnName](opts?.[f])
25
25
  }
26
26
 
27
- if (opts.comment) this.set('comment', opts.comment)
27
+ if (opts?.comment) this.set('comment', opts.comment)
28
28
  }
29
29
 
30
30
  ucFirst(str) {
@@ -91,7 +91,7 @@ export default class RR extends Map {
91
91
  }
92
92
 
93
93
  setTtl(t) {
94
- if (t === undefined) t = this?.default?.ttl
94
+ t = t ?? this.default?.ttl
95
95
  if (t === undefined) {
96
96
  if (['SOA', 'SSHPF'].includes(this.get('type'))) return
97
97
  this.throwHelp('TTL is required, no default available')
@@ -157,7 +157,7 @@ export default class RR extends Map {
157
157
  }
158
158
 
159
159
  getEmpty(prop) {
160
- return this.get(prop) === undefined ? '' : this.get(prop)
160
+ return this.get(prop) ?? ''
161
161
  }
162
162
 
163
163
  getComment(prop) {
@@ -307,6 +307,51 @@ export default class RR extends Map {
307
307
  )
308
308
  }
309
309
 
310
+ compressIPv6(val) {
311
+ // * RFC 5952
312
+ // * 4.1. Leading zeros MUST be suppressed...A single 16-bit 0000 field MUST be represented as 0.
313
+ // * 4.2.1 The use of the symbol "::" MUST be used to its maximum capability.
314
+ // * 4.2.2 The symbol "::" MUST NOT be used to shorten just one 16-bit 0 field.
315
+ // * 4.2.3 When choosing placement of a "::", the longest run...MUST be shortened
316
+ // * 4.3 The characters a-f in an IPv6 address MUST be represented in lowercase.
317
+
318
+ // 4.3 Lowercase and 4.1 remove leading zeros per segment
319
+ const segments = val
320
+ .toLowerCase()
321
+ .split(':')
322
+ .map((s) => s.replace(/^0+/, '') || '0')
323
+
324
+ let bestStart = -1
325
+ let bestLen = 0
326
+ let curStart = -1
327
+ let curLen = 0
328
+
329
+ // 4.2.1 & 4.2.3 Find the longest consecutive run of '0'
330
+ for (let i = 0; i < segments.length; i++) {
331
+ if (segments[i] === '0') {
332
+ if (curStart === -1) curStart = i
333
+ curLen++
334
+ if (curLen > bestLen) {
335
+ bestLen = curLen
336
+ bestStart = curStart
337
+ }
338
+ } else {
339
+ curStart = -1
340
+ curLen = 0
341
+ }
342
+ }
343
+
344
+ // 4.2.2 Don't shorten a single 16-bit 0 field
345
+ if (bestLen < 2) {
346
+ return segments.join(':')
347
+ }
348
+
349
+ const head = segments.slice(0, bestStart).join(':')
350
+ const tail = segments.slice(bestStart + bestLen).join(':')
351
+
352
+ return `${head}::${tail}`
353
+ }
354
+
310
355
  toBind(zone_opts) {
311
356
  return `${this.getPrefix(zone_opts)}\t${this.getRdataFields()
312
357
  .map((f) => this.getQuoted(f))