@nictool/dns-resource-record 1.6.1 → 1.7.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 (54) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +323 -199
  3. package/dist/dns-rr.min.js +26 -0
  4. package/dist/dns-rr.min.js.map +7 -0
  5. package/index.js +12 -11
  6. package/lib/binary.js +108 -0
  7. package/lib/bind.js +94 -0
  8. package/lib/dns-query.js +67 -0
  9. package/lib/tinydns.js +128 -44
  10. package/lib/wire.js +519 -0
  11. package/package.json +23 -6
  12. package/rr/TEMPLATE.js +124 -0
  13. package/rr/a.js +8 -48
  14. package/rr/aaaa.js +13 -80
  15. package/rr/apl.js +123 -27
  16. package/rr/caa.js +27 -50
  17. package/rr/cert.js +58 -87
  18. package/rr/cname.js +7 -63
  19. package/rr/dhcid.js +20 -30
  20. package/rr/dname.js +9 -36
  21. package/rr/dnskey.js +38 -32
  22. package/rr/ds.js +43 -57
  23. package/rr/hinfo.js +21 -40
  24. package/rr/hip.js +88 -26
  25. package/rr/https.js +28 -40
  26. package/rr/ipseckey.js +97 -18
  27. package/rr/key.js +39 -29
  28. package/rr/kx.js +16 -27
  29. package/rr/loc.js +42 -12
  30. package/rr/mx.js +16 -51
  31. package/rr/naptr.js +58 -33
  32. package/rr/ns.js +8 -36
  33. package/rr/nsec.js +89 -18
  34. package/rr/nsec3.js +62 -26
  35. package/rr/nsec3param.js +56 -53
  36. package/rr/nxt.js +57 -18
  37. package/rr/openpgpkey.js +24 -30
  38. package/rr/ptr.js +7 -47
  39. package/rr/rp.js +17 -32
  40. package/rr/rrsig.js +80 -85
  41. package/rr/sig.js +70 -45
  42. package/rr/smimea.js +33 -33
  43. package/rr/soa.js +31 -49
  44. package/rr/spf.js +10 -17
  45. package/rr/srv.js +22 -62
  46. package/rr/sshfp.js +25 -53
  47. package/rr/svcb.js +27 -40
  48. package/rr/tlsa.js +34 -34
  49. package/rr/tsig.js +87 -24
  50. package/rr/txt.js +40 -59
  51. package/rr/uri.js +19 -29
  52. package/rr/wks.js +154 -22
  53. package/rr.js +290 -109
  54. package/lib/readme.js +0 -84
package/CHANGELOG.md CHANGED
@@ -4,6 +4,38 @@ Notable changes to this project are documented in this file.
4
4
 
5
5
  #### Unreleased
6
6
 
7
+ ### [1.7.0] - 2026-04-20
8
+
9
+ #### Fixes
10
+
11
+ - rr/txt: chunk by UTF-8 bytes (vs ASCII)
12
+ - rr/rrsig: validate "type covered" correctly
13
+
14
+ #### Changes
15
+
16
+ - RR is strictly a factory now
17
+ - no longer returns a different object based on bindLine or tinyLine
18
+ - doc(CAA, DS): added RFC 9619
19
+ - openpgpkey: reject keys with non-ASCII
20
+ - tinydns: name any out-of-range chars in error msg
21
+ - fromBind: use a tokenizing parser (vs regexes)
22
+
23
+ #### Additions
24
+
25
+ - add rr/TEMPLATE.js with lots of docs
26
+ - declarative rdataFields to remove lots of boilerplate from rr/all
27
+ - browser compat enhancements
28
+ - rollup dns-rr.min.js + min.js.map
29
+ - add `static typeName` as constructor.name doesn't survive minification
30
+ - feat(lib/binary): add shared binary functions
31
+ - change: replace `Buffer` with Uint8Array, DataView, and math
32
+ - feat(lib/wire): add wire format helpers
33
+ - feat(fromWire): added wire format parsers
34
+ - used to round-trip DNS and validate parsing & formatting
35
+ - feat(fromBind): use a parser (vs regexes)
36
+ - test: add dnsLiveTests, test `toWire()` against live NSD & tinydns
37
+ - uncovered edge cases in round trips between formats
38
+
7
39
  ### [1.6.1] - 2026-04-20
8
40
 
9
41
  - doc(README): add wire export format
@@ -385,3 +417,4 @@ Notable changes to this project are documented in this file.
385
417
  [1.5.0]: https://github.com/NicTool/dns-resource-record/releases/tag/v1.5.0
386
418
  [1.6.0]: https://github.com/NicTool/dns-resource-record/releases/tag/v1.6.0
387
419
  [1.6.1]: https://github.com/NicTool/dns-resource-record/releases/tag/v1.6.1
420
+ [1.7.0]: https://github.com/NicTool/dns-resource-record/releases/tag/v1.7.0
package/README.md CHANGED
@@ -1,272 +1,396 @@
1
- [![Module Tests](https://github.com/NicTool/dns-resource-record/actions/workflows/ci.yml/badge.svg)](https://github.com/NicTool/dns-resource-record/actions/workflows/ci.yml)
2
- [![Coverage Status](https://coveralls.io/repos/github/NicTool/dns-resource-record/badge.svg?branch=master)](https://coveralls.io/github/NicTool/dns-resource-record?branch=master)
1
+ [![Module Tests][ci-img]][ci-url]
2
+ [![Test Coverage][cov-img]][cov-url]
3
3
 
4
4
  # dns-resource-record
5
5
 
6
- DNS resource record parser, validator, importer, and exporter for node.js & browsers.
6
+ DNS resource record parser, validator, importer, and exporter for node.js & browsers
7
7
 
8
- ## SYNOPSIS
8
+ **Quick Links:** [Getting Started](#getting-started) | [API Reference](#api-reference) | [Browser/CDN](#browser--cdn) | [Supported Records](#supported-records) | [Contributing](#development)
9
9
 
10
- This module is used to:
10
+ ## Overview
11
11
 
12
- - validate well formedness and RFC compliance of DNS resource records
13
- - import RRs to and from the following formats:
12
+ This module validates, imports, and exports DNS resource records (RRs) with rigorous RFC compliance and robust test coverage.
14
13
 
15
- | **RR format** | **import** | **export** |
16
- | :------------------------------------------------------: | :----------------: | :----------------: |
17
- | **JSON** | :white_check_mark: | :white_check_mark: |
18
- | **[BIND](https://www.isc.org/bind/) / RFC 1035** | :white_check_mark: | :white_check_mark: |
19
- | **[Tinydns](https://cr.yp.to/djbdns/tinydns-data.html)** | :white_check_mark: | :white_check_mark: |
20
- | **MaraDNS** | | :white_check_mark: |
21
- | **JS** | :white_check_mark: | :white_check_mark: |
22
- | **PowerDNS** | | |
23
- | **Wire** | | :white_check_mark: |
14
+ **What you can do:**
24
15
 
25
- This package intends to import and export RFC compliant DNS resource records. Please [raise an issue](https://github.com/NicTool/dns-resource-record/issues) if a valid resource record fails to pass or an invalid resource record passes.
16
+ - **Validate** DNS records for RFC compliance and well-formedness
17
+ - **Parse/Import** records from BIND zone files, tinydns data files, or JS objects
18
+ - **Export** records to BIND, tinydns, MaraDNS, JSON, or wire format
19
+ - **Manipulate** validated records with type-safe setters
20
+ - **Convert** between formats seamlessly (e.g., tinydns → BIND -> wire)
26
21
 
27
- This package is for working with _individual_ Resource Records. For working with zones of RRs, use [dns-zone](https://github.com/NicTool/dns-zone).
22
+ **Scope:** This package handles individual Resource Records. For zone file operations, see [dns-zone](https://github.com/NicTool/dns-zone).
28
23
 
29
- ## USAGE
24
+ **Quality:** RFC compliance is a first-class concern. If you encounter a valid RR that fails to parse or an invalid RR that passes validation, please [open an issue](https://github.com/NicTool/dns-resource-record/issues).
30
25
 
31
- Load the index for access to all RR types:
26
+ ## Supported Records
27
+
28
+ This module supports all current DNS RRs in active use on the internet.
29
+
30
+ | Usage | **Resource Record Types** |
31
+ | :-----------: | :-----------------------------------------------------------: |
32
+ | _Common_ | A, AAAA, CNAME, HTTPS, MX, NS, PTR, SOA, SRV, TXT |
33
+ | _Less Common_ | APL, CERT, DHCID, DNAME, HIP, KX, LOC, NAPTR, SVCB, TSIG, URI |
34
+ | _Security_ | CAA, IPSECKEY, OPENPGPKEY, SMIMEA, SSHFP, TLSA |
35
+ | _DNSSEC_ | DNSKEY, DS, NSEC, NSEC3, NSEC3PARAM, RRSIG |
36
+ | _Obsolete_ | HINFO, KEY, NXT, RP, SIG, SPF, WKS |
37
+
38
+ ## Getting Started
39
+
40
+ ### Installation
41
+
42
+ ```sh
43
+ npm install @nictool/dns-resource-record
44
+ ```
45
+
46
+ ### Validation
47
+
48
+ Validate an A record:
32
49
 
33
50
  ```js
34
51
  import * as RR from '@nictool/dns-resource-record'
52
+
53
+ const validA = new RR.A({
54
+ owner: 'example.com.',
55
+ address: '192.0.2.1',
56
+ ttl: 3600,
57
+ })
58
+
59
+ console.log(validA.toBind())
60
+ // example.com 3600 IN A 192.0.2.1
35
61
  ```
36
62
 
37
- ### EXAMPLES
63
+ Invalid records throw immediately:
38
64
 
39
65
  ```js
40
- const exampleRRs = {
41
- A: {
42
- owner : 'test.example.com.',
43
- type : 'A',
44
- address: '192.0.2.127',
45
- ttl : 3600,
46
- },
47
- AAAA: {
48
- owner : 'test.example.com.',
49
- type : 'AAAA',
50
- address: '2605:7900:20:a::4',
51
- ttl : 3600,
52
- },
53
- SOA: {
54
- owner : 'example.com.',
55
- type : 'SOA',
56
- mname : 'matt.example.com.',
57
- rname : 'ns1.example.com.',
58
- serial : 1,
59
- refresh: 7200,
60
- retry : 3600,
61
- expire : 1209600,
62
- minimum: 3600,
63
- ttl : 3600,
64
- }
65
- }
66
66
  try {
67
- console.log(new RR.SOA(exampleRRs.SOA))
68
- SOA(11) [Map] {
69
- 'owner' => 'example.com.',
70
- 'ttl' => 3600,
71
- 'class' => 'IN',
72
- 'type' => 'SOA',
73
- 'mname' => 'matt.example.com.',
74
- 'rname' => 'ns1.example.com.',
75
- 'serial' => 1,
76
- 'refresh' => 7200,
77
- 'retry' => 3600,
78
- 'expire' => 1209600,
79
- 'minimum' => 3600
80
- }
81
- }
82
- catch (e) {
83
- console.error(e.message) // invalid RRs throw
67
+ new RR.A({ owner: 'example.com.', address: 'not-an-ip' })
68
+ } catch (err) {
69
+ console.error(err.message) // Error: A address must be IPv4
84
70
  }
85
71
  ```
86
72
 
87
- Validate records by passing a properly formatted JS object to the record-specific class. To validate an A record:
73
+ This library enforces RFC-compliance during construction, catching errors early.
74
+
75
+ ---
76
+
77
+ ## API Reference
78
+
79
+ ### Understanding Record Structure
80
+
81
+ Every DNS record has these standard fields:
82
+
83
+ - **owner** — The domain name this record belongs to (always fully qualified, e.g., `example.com.`)
84
+ - **type** — The record type (A, AAAA, MX, TXT, etc.)
85
+ - **ttl** — Time to live in seconds
86
+ - **class** — Almost always `IN` (Internet); omitted in examples
87
+
88
+ Plus **rdata fields** specific to each record type (e.g., `address` for A records, `preference`/`exchange` for MX records).
89
+
90
+ ### Core Workflows
91
+
92
+ #### 1. **Validate & Create** — Use the Constructor
93
+
94
+ When you have data in JavaScript object form:
88
95
 
89
96
  ```js
90
- const validatedA = new RR.A(exampleRRs.A)
97
+ new RR.SOA({
98
+ owner: 'example.com.',
99
+ mname: 'ns1.example.com.',
100
+ rname: 'hostmaster.example.com.',
101
+ serial: 2024042201,
102
+ refresh: 7200,
103
+ retry: 3600,
104
+ expire: 1209600,
105
+ minimum: 3600,
106
+ ttl: 3600,
107
+ })
91
108
  ```
92
109
 
93
- Manipulate the validated record using pattern named setters:
110
+ **When to use:** Building records programmatically, validating user input, working with API responses.
111
+
112
+ ---
113
+
114
+ #### 2. **Parse BIND Format** — Use `fromBind()`
115
+
116
+ When you have a line from a BIND zone file:
94
117
 
95
118
  ```js
96
- console.log(validatedA.toBind())
97
- test.example.com. 3600 IN A 192.0.2.127
119
+ const rr = RR.A.fromBind('www.example.com. 3600 IN A 192.0.2.1\n')
120
+ console.log(rr.get('address')) // '192.0.2.1'
121
+ ```
122
+
123
+ **When to use:** Processing BIND zone files, DNS configs, or standard zone file exports.
124
+
125
+ ---
126
+
127
+ #### 3. **Parse Tinydns Format** — Use `fromTinydns()`
128
+
129
+ When you have a line from a tinydns data file:
98
130
 
99
- validatedA.setAddress('192.0.2.128')
100
- console.log(validatedA.toBind())
101
- test.example.com. 3600 IN A 192.0.2.128
131
+ ```js
132
+ const rr = RR.A.fromTinydns('+www.example.com:192.0.2.1:3600::\n')
133
+ console.log(rr.get('address')) // '192.0.2.1'
102
134
  ```
103
135
 
104
- The setters are named: `set` + `Field`, where field is the resource record field name to modify. Multi-word names are camel cased, so a field named `Certificate Usage` has a setter named `setCertificateUsage`. The RFCs aren't always consistent regarding RR field names so aliases are permissible for interoperability.
136
+ **When to use:** Working with djbdns/tinydns configurations, or when parsing tinydns data files.
137
+
138
+ ---
105
139
 
106
- ## FUNCTIONS
140
+ #### 4. **Export to BIND** — Use `toBind()`
107
141
 
108
- ### getCanonical
142
+ Convert any validated record to BIND zone file format:
109
143
 
110
144
  ```js
111
- > console.log(new RR.AAAA(null).getCanonical())
112
- {
113
- owner: 'host.example.com.',
114
- address: '2001:0db8:0020:000a:0000:0000:0000:0004',
115
- class: 'IN',
145
+ new RR.MX({
146
+ owner: 'example.com.',
147
+ preference: 10,
148
+ exchange: 'mail.example.com.',
116
149
  ttl: 3600,
117
- type: 'AAAA'
118
- }
150
+ }).toBind()
151
+ // example.com 3600 IN MX 10 mail.example.com.
119
152
  ```
120
153
 
121
- ### getFields
154
+ **When to use:** Generating zone files, displaying records for editing, exporting to BIND nameservers.
122
155
 
123
- Get the field names for each RR type
156
+ ---
157
+
158
+ #### 5. **Export to Tinydns** — Use `toTinydns()`
159
+
160
+ Convert to tinydns data file format:
124
161
 
125
162
  ```js
126
- > import * as RR from 'dns-resource-record'
127
- > new RR.A(null).getFields() // [ 'owner', 'ttl', 'class', 'type', 'address' ]
163
+ new RR.A({
164
+ owner: 'example.com.',
165
+ address: '192.0.2.1',
166
+ ttl: 3600,
167
+ }).toTinydns()
168
+ // +example.com:192.0.2.1:3600::
169
+ ```
170
+
171
+ **When to use:** Generating tinydns data files, migrating to djbdns, or integrating with tinydns tooling.
172
+
173
+ ---
128
174
 
129
- > new RR.PTR(null).getFields() // [ 'owner', 'ttl', 'class', 'type', 'dname' ]
175
+ #### 6. **Round-Trip Conversion**
130
176
 
131
- > new RR.SSHFP(null).getFields()
132
- // [ 'owner', 'ttl', 'class', 'type', 'algorithm', 'fptype', 'fingerprint' ]
177
+ Parse from one format, export to another:
178
+
179
+ ```js
180
+ // tinydns → BIND
181
+ const fromTiny = RR.CAA.fromTinydns(
182
+ ':ns1.example.com:257:\\000\\005issue"http\\072\\057\\057letsencrypt.org":3600::\n',
183
+ )
184
+ console.log(fromTiny.toBind())
185
+ // ns1.example.com 3600 IN CAA 0 issue "http://letsencrypt.org"
133
186
  ```
134
187
 
135
- ### getRFCs
188
+ **When to use:** DNS migrations, format conversions, tool interoperability.
189
+
190
+ ---
136
191
 
137
- Get a list of RFCs references for each RR type
192
+ ### Manipulating Records
193
+
194
+ Use **setter methods** to modify validated records. Setter names follow the pattern `set` + `FieldName` (camelCased):
138
195
 
139
196
  ```js
140
- > new RR.A(null).getRFCs() // [ 1035 ]
141
- > new RR.SRV(null).getRFCs() // [ 2782 ]
142
- > new RR.MX(null).getRFCs() // [ 1035, 2181, 7505 ]
197
+ const a = new RR.A({
198
+ owner: 'example.com.',
199
+ address: '192.0.2.1',
200
+ ttl: 3600,
201
+ })
202
+
203
+ a.setAddress('192.0.2.2')
204
+ a.setTtl(7200)
205
+
206
+ console.log(a.toBind())
207
+ // example.com 7200 IN A 192.0.2.2
143
208
  ```
144
209
 
145
- ### toBind
210
+ Setters include validation. Invalid values throw with helpful error messages.
146
211
 
147
- Validate a record and export to BIND format.
212
+ For a list of available setters, check `getFields('rdata')` for your record type:
148
213
 
149
214
  ```js
150
- console.log(new RR.A(exampleRRs.A).toBind())
151
- // test.example.com 3600 IN A 192.0.2.127
215
+ new RR.SSHFP(null).getFields('rdata')
216
+ // ['algorithm', 'fptype', 'fingerprint']
217
+ // So use: setSshfp(), setFptype(), setFingerprint()
218
+ ```
219
+
220
+ ---
152
221
 
153
- console.log(new RR.AAAA(exampleRRs.AAAA).toBind())
154
- // test.example.com 3600 IN AAAA 2605:7900:20:a::4
222
+ ### Metadata Methods
223
+
224
+ Get information about record types:
225
+
226
+ #### `getFields([section])`
227
+
228
+ Get field names for a record type. Pass `'rdata'` to get only the custom fields:
229
+
230
+ ```js
231
+ new RR.A(null).getFields() // ['owner', 'ttl', 'class', 'type', 'address']
232
+ new RR.A(null).getFields('rdata') // ['address']
233
+ new RR.MX(null).getFields('rdata') // ['preference', 'exchange']
155
234
  ```
156
235
 
157
- ### toTinydns
236
+ #### `getRFCs()`
158
237
 
159
- Validate a record and export to tinydns format:
238
+ Get RFC references for a record type:
160
239
 
161
240
  ```js
162
- console.log(new RR.A(exampleRRs.A).toTinydns()) // +test.example.com:192.0.2.127:3600::
241
+ new RR.A(null).getRFCs() // [1035]
242
+ new RR.MX(null).getRFCs() // [1035, 2181, 7505]
243
+ new RR.SRV(null).getRFCs() // [2782]
163
244
  ```
164
245
 
165
- ### set
246
+ #### `getCanonical()`
166
247
 
167
- The DNS validation checks can be bypassed entirely by using 'set':
248
+ Get a record with all fields populated with default/canonical values:
168
249
 
169
250
  ```js
170
- > validatedA.set('address', 'oops')
171
- A(5) [Map] {
172
- 'owner' => 'test.example.com',
173
- 'ttl' => 3600,
174
- 'class' => 'IN',
175
- 'type' => 'A',
176
- 'address' => 'oops'
177
- }
251
+ new RR.AAAA(null).getCanonical()
252
+ // {
253
+ // owner: 'host.example.com.',
254
+ // address: '2001:0db8:0020:000a:0000:0000:0000:0004',
255
+ // class: 'IN',
256
+ // ttl: 3600,
257
+ // type: 'AAAA'
258
+ // }
178
259
  ```
179
260
 
180
- Consider this a "running with scissors" mode.
261
+ #### `toJSON()` / `JSON.stringify()`
181
262
 
182
- ### fromTinydns toBind
263
+ Serialize a record to a plain object:
183
264
 
184
- Convert a tinydns line to BIND:
265
+ ```js
266
+ const a = new RR.A({ owner: 'example.com.', address: '192.0.2.1', ttl: 3600 })
267
+ JSON.stringify(a)
268
+ // {"owner":"example.com.","ttl":3600,"class":"IN","type":"A","address":"192.0.2.1"}
269
+ ```
270
+
271
+ ---
272
+
273
+ ### Advanced: Bypassing Validation
274
+
275
+ The `set()` method bypasses validation (use carefully):
185
276
 
186
277
  ```js
187
- console.log(new RR.CAA({
188
- tinyline: ':ns1.example.com:257:\\000\\005issue"http\\072\\057\\057letsencrypt.org":3600::\n'
189
- }).toBind())
190
- ns1.example.com 3600 IN CAA 0 issue "http://letsencrypt.org"
278
+ record.set('address', 'invalid-value')
279
+ // Works, but now the record is malformed — useful only for testing or low-level manipulation
191
280
  ```
192
281
 
193
- ## Supported Records
282
+ **Note:** Validation is there to protect data integrity. Use at your own risk.
283
+
284
+ ---
285
+
286
+ ## Browser & CDN
287
+
288
+ Use this module directly in browsers via CDN:
289
+
290
+ ```html
291
+ <!DOCTYPE html>
292
+ <html>
293
+ <head>
294
+ <title>DNS Record Validator</title>
295
+ </head>
296
+ <body>
297
+ <h1>DNS Record Validator</h1>
298
+ <pre id="output"></pre>
299
+
300
+ <script type="module">
301
+ // Import from unpkg (or jsdelivr, esm.sh)
302
+ import * as RR from 'https://unpkg.com/@nictool/dns-resource-record@latest/dist/dns-rr.min.js'
303
+
304
+ // Use just like Node.js
305
+ const record = new RR.A({
306
+ owner: 'example.com.',
307
+ address: '192.0.2.1',
308
+ ttl: 3600,
309
+ })
310
+
311
+ document.getElementById('output').textContent = record.toBind()
312
+ </script>
313
+ </body>
314
+ </html>
315
+ ```
316
+
317
+ **Available CDNs:**
318
+
319
+ - **unpkg:** `https://unpkg.com/@nictool/dns-resource-record/dist/dns-rr.min.js`
320
+ - **jsdelivr:** `https://cdn.jsdelivr.net/npm/@nictool/dns-resource-record/dist/dns-rr.min.js`
321
+ - **esm.sh:** `https://esm.sh/@nictool/dns-resource-record`
322
+
323
+ **Live example:** See [nictool.github.io/builder/](https://nictool.github.io/builder/) for an interactive DNS record editor using this library.
324
+
325
+ ---
326
+
327
+ ## Important Concepts
328
+
329
+ ### Domain Name Normalization
330
+
331
+ Domain owner names are:
332
+
333
+ - **Stored fully qualified** (absolute), e.g., `example.com.` not `example.com`
334
+ - **Normalized to lowercase** because:
335
+ - DNS is case-insensitive (RFC 4343, RFC 1035)
336
+ - This library enforces automatic duplicate suppression
337
+ - DNSSEC canonicalization requires it (RFC 4034)
338
+ - Wire format for most RRs requires lowercase
339
+
340
+ **Example:**
341
+
342
+ ```js
343
+ new RR.A({ owner: 'EXAMPLE.COM', address: '192.0.2.1', ttl: 3600 })
344
+ // Automatically normalized to: 'example.com.'
345
+ ```
346
+
347
+ ### Relative vs Absolute Names
348
+
349
+ Master zone file expansions (relative domain names) are handled by [dns-zone](https://github.com/NicTool/dns-zone). This library works only with fully qualified names.
350
+
351
+ ### Export Options
352
+
353
+ The `toBind()` and `toMaraDNS()` methods accept an options object to customize output:
354
+
355
+ ```js
356
+ record.toBind({ suppressTtl: true, suppressClass: true, relativeName: true })
357
+ ```
358
+
359
+ See [dns-zone](https://github.com/NicTool/dns-zone) for full options documentation.
360
+
361
+ ## Development
362
+
363
+ No external dependencies. Runs on node.js and modern browsers.
364
+
365
+ **Key scripts:**
366
+
367
+ - `npm test` — Run all tests with node's built-in test runner
368
+ - `npm run watch` — Run tests in watch mode during development
369
+ - `npm run lint` — Check code with ESLint
370
+ - `npm run format` — Auto-format with Prettier and fix linting issues
371
+ - `npm run build` — Regenerate browser bundle and README
372
+ - `npm run test:coverage` — Generate test coverage report
373
+
374
+ **Architecture:**
375
+
376
+ - **rr.js** — Base class with shared DNS logic and validation
377
+ - **rr/\*.js** — Individual RR type implementations
378
+ - **test/\*.js** — Comprehensive test suite for each RR type
379
+
380
+ ## References
381
+
382
+ - [DNS Record Types (Wikipedia)](https://en.wikipedia.org/wiki/List_of_DNS_record_types)
383
+ - [DNS Terminology (NicTool Dictionary)](https://nictool.github.io/Dictionary)
384
+ - [dns-zone](https://www.npmjs.com/package/@nictool/dns-zone) — Zone file operations
385
+ - [dns-nameserver](https://www.npmjs.com/package/@nictool/dns-nameserver) — Nameserver management
386
+
387
+ ---
194
388
 
195
- This module intends to support all current (ie, not officially deprecated) DNS RRs **and** all RRs that are in active use on the internet.
196
-
197
- PRs are welcome, especially PRs with tests.
198
-
199
- | **RR** | **BIND / RFC 1035** | **Tinydns** |
200
- | :------------: | :-----------------: | :----------------: |
201
- | _Common_ |
202
- | **A** | :white_check_mark: | :white_check_mark: |
203
- | **AAAA** | :white_check_mark: | :white_check_mark: |
204
- | **CNAME** | :white_check_mark: | :white_check_mark: |
205
- | **HTTPS** | :white_check_mark: | :white_check_mark: |
206
- | **MX** | :white_check_mark: | :white_check_mark: |
207
- | **NS** | :white_check_mark: | :white_check_mark: |
208
- | **PTR** | :white_check_mark: | :white_check_mark: |
209
- | **SRV** | :white_check_mark: | :white_check_mark: |
210
- | **TXT** | :white_check_mark: | :white_check_mark: |
211
- | _Less Common_ |
212
- | **APL** | :white_check_mark: | :white_check_mark: |
213
- | **CERT** | :white_check_mark: | :white_check_mark: |
214
- | **DHCID** | :white_check_mark: | :white_check_mark: |
215
- | **DNAME** | :white_check_mark: | :white_check_mark: |
216
- | **HIP** | :white_check_mark: | :white_check_mark: |
217
- | **KEY** | :white_check_mark: | :white_check_mark: |
218
- | **KX** | :white_check_mark: | :white_check_mark: |
219
- | **LOC** | :white_check_mark: | :white_check_mark: |
220
- | **NAPTR** | :white_check_mark: | :white_check_mark: |
221
- | **SOA** | :white_check_mark: | :white_check_mark: |
222
- | **SVCB** | :white_check_mark: | :white_check_mark: |
223
- | **TSIG** | :white_check_mark: | :white_check_mark: |
224
- | **URI** | :white_check_mark: | :white_check_mark: |
225
- | _Security_ |
226
- | **CAA** | :white_check_mark: | :white_check_mark: |
227
- | **IPSECKEY** | :white_check_mark: | :white_check_mark: |
228
- | **OPENPGPKEY** | :white_check_mark: | :white_check_mark: |
229
- | **SMIMEA** | :white_check_mark: | :white_check_mark: |
230
- | **SSHFP** | :white_check_mark: | :white_check_mark: |
231
- | **TLSA** | :white_check_mark: | :white_check_mark: |
232
- | _DNSSEC_ |
233
- | **DNSKEY** | :white_check_mark: | :white_check_mark: |
234
- | **DS** | :white_check_mark: | :white_check_mark: |
235
- | **NSEC** | :white_check_mark: | :white_check_mark: |
236
- | **NSEC3** | :white_check_mark: | :white_check_mark: |
237
- | **NSEC3PARAM** | :white_check_mark: | :white_check_mark: |
238
- | **RRSIG** | :white_check_mark: | :white_check_mark: |
239
- | _Deprecated_ |
240
- | **NXT** | :white_check_mark: | :white_check_mark: |
241
- | **SPF** | :white_check_mark: | :white_check_mark: |
242
- | _Obsolete_ |
243
- | **HINFO** | :white_check_mark: | :white_check_mark: |
244
- | **RP** | :white_check_mark: | :white_check_mark: |
245
- | **SIG** | :white_check_mark: | :white_check_mark: |
246
- | **WKS** | :white_check_mark: | :white_check_mark: |
247
-
248
- ## TIPS
249
-
250
- - Domain owner names are:
251
- - stored fully qualified, aka absolute.
252
- - normalized to lower case, because:
253
- - DNS is case insensitive (see RFCs 4343, 1035, 1034)
254
- - this library enforces duplicate suppression
255
- - DNSSEC canonicalization (see RFC 4034)
256
- - wire format for most RRs require it
257
- - Master Zone File expansions exist in [dns-zone](https://github.com/NicTool/dns-zone)
258
- - to{Bind|MaraDNS} output can be influenced (suppress TTL, class, relative domain names) with an options object. See it in `bin/dns-zone` in the [dns-zone](https://github.com/NicTool/dns-zone) package.
259
-
260
- ## SEE ALSO
261
-
262
- - [Dictionary of DNS terms](https://nictool.github.io/web/Dictionary)
263
- - [Wikipedia, List of DNS Record Types](https://en.wikipedia.org/wiki/List_of_DNS_record_types)
264
- - @nictool/[dns-zone](https://www.npmjs.com/package/@nictool/dns-zone)
265
- - @nictool/[dns-nameserver](https://www.npmjs.com/package/@nictool/dns-nameserver)
266
-
267
- ## DEVELOP
268
-
269
- - There are no dependencies. That's no accident.
270
- - ESM browsers and node.js
271
- - Platform independence is a goal
272
- - [x] CI tests are on linux, windows, and macOS
389
+ [ci-img]: https://github.com/NicTool/dns-resource-record/actions/workflows/ci.yml/badge.svg
390
+ [ci-url]: https://github.com/NicTool/dns-resource-record/actions/workflows/ci.yml
391
+ [cov-img]: https://coveralls.io/repos/github/NicTool/dns-resource-record/badge.svg
392
+ [cov-url]: https://coveralls.io/github/NicTool/dns-resource-record
393
+ [bind-url]: https://www.isc.org/bind/
394
+ [knot-url]: https://www.knot-dns.cz
395
+ [nsd-url]: https://www.nlnetlabs.nl/projects/nsd/about/
396
+ [pdns-url]: https://www.powerdns.com/powerdns-authoritative-server