Skip to content

Commit 34e5bbf

Browse files
Adding a new "hyper" protocol
1 parent 2ab60f4 commit 34e5bbf

File tree

5 files changed

+133
-3
lines changed

5 files changed

+133
-3
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
# hyper-dns
22

33
Advanced resolving of decentralized web links using different name systems such as DNS Txt entries and `.well-known` https lookups locations.
4-
It implements various naming systems such as [dat][] or [cabal][] but is extensible to support other systems as well.
4+
It implements various naming systems such as [dat][], [hyper][] and [cabal][] but is extensible to support other systems as well.
55

6+
[hyper]: https://hypercore-protocol.org/
67
[dat]: https://www.datprotocol.com/deps/0005-dns/
78
[cabal]: https://cabal.chat/
89
[ara]: https://ara.one/

docs/protocol.md

+8
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,14 @@ const { cabal } = require('hyper-dns').protocols
120120

121121
The [cabal chat](https://cabal.chat/) protocol works the same way as `dat` does but has a different lookups for DNS entries (cabalkey=) and uses the `/.well-known/cabal` lookup.
122122

123+
### hyper
124+
125+
```javascript
126+
const { hyper } = require('hyper-dns').protocols
127+
```
128+
129+
The second version of the `dat` protocol that should be outphasing the first version over long time.
130+
123131
### See a missing protocol?
124132

125133
If you have an implementation that should really find its way into `hyper-dns`: feel free to open a Pull Request and suggest it as default for a protocol!

protocols.js

+26
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,32 @@ module.exports = Object.freeze({
1010
}
1111
return await context.fetchWellKnown(name, 'dat', /^\s*(?:(?:dat):)?(?:\/\/)?(?<key>[0-9a-f]{64})\s*$/i, 6)
1212
},
13+
async hyper (context, name) {
14+
let record = context.matchRegex(name, /^(?<key>[0-9a-f]{64})$/i)
15+
if (record !== undefined) {
16+
return record
17+
}
18+
if (!context.isLocal(name)) {
19+
const domain = `hyper-dns.${name}`
20+
record = await context.getDNSTxtRecord(domain, /^\s*"?(?:hyperkey)=(?<key>(?:[0-9a-f]{64}|well-known))"?\s*$/i)
21+
if (record === undefined) {
22+
return
23+
}
24+
if (record.key !== 'well-known') {
25+
return record
26+
}
27+
}
28+
const wk = await context.fetchWellKnown(name, 'hyper', /^\s*(?:(?:hyper):)?(?:\/\/)?(?<key>[0-9a-f]{64})\s*$/i, 6)
29+
if (wk === undefined) {
30+
return
31+
}
32+
if (typeof wk.ttl !== 'number') {
33+
wk.ttl = record.ttl
34+
} else if (typeof record.ttl === 'number') {
35+
wk.ttl = Math.min(wk.ttl, record.ttl)
36+
}
37+
return wk
38+
},
1339
async cabal (context, name) {
1440
let record = context.matchRegex(name, /^(?<key>[0-9a-f]{64})$/i)
1541
if (record !== undefined) {

test/integration.test.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ test(`Successful test against ${ecosystem}`, async t => {
1919
t.deepEquals(
2020
results,
2121
{
22-
dat: key,
22+
ara: null,
2323
cabal: null,
24-
ara: null
24+
dat: key,
25+
hyper: null
2526
}
2627
)
2728
})

test/protocols.test.js

+94
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,100 @@ const { matchRegex } = require('../resolve-context.js')
4848
})
4949
})()
5050

51+
;(() => {
52+
const { hyper } = protocols
53+
const key = '100c77d788fdaf07b89b28e9d276e47f2e44011f4adb981921056e1b3b40e99e'
54+
test('hyper: local urls', async t => {
55+
t.deepEquals(
56+
await hyper({ matchRegex }, key),
57+
{ key, ttl: null }
58+
)
59+
})
60+
test('hyper: looking for dns records', async t => {
61+
const name = 'dat-ecosystem.org'
62+
t.plan(4)
63+
t.deepEquals(
64+
await hyper({
65+
matchRegex,
66+
isLocal: (name) => {
67+
t.equals(name, 'dat-ecosystem.org')
68+
return false
69+
},
70+
async getDNSTxtRecord (domain, regex) {
71+
t.equals(domain, `hyper-dns.${name}`)
72+
t.match(`hyperkey=${key}`, regex)
73+
return { key, ttl: 10 }
74+
}
75+
}, name),
76+
{ key, ttl: 10 }
77+
)
78+
})
79+
test('hyper: allowing for miss of dns records', async t => {
80+
const name = 'dat-ecosystem.org'
81+
t.deepEquals(
82+
await hyper({
83+
matchRegex,
84+
isLocal: () => false,
85+
async getDNSTxtRecord () {}
86+
}, name),
87+
undefined
88+
)
89+
})
90+
test('hyper: looking for well-known record', async t => {
91+
const name = 'dat-ecosystem.org'
92+
t.deepEquals(
93+
await hyper({
94+
matchRegex,
95+
isLocal: () => false,
96+
async getDNSTxtRecord (_domain, regex) {
97+
t.match('hyperkey=well-known', regex)
98+
return { key: 'well-known', ttl: 2 }
99+
},
100+
async fetchWellKnown (domain, schema, regex, redirects) {
101+
t.equals(redirects, 6)
102+
t.equals(domain, name)
103+
t.equals(schema, 'hyper')
104+
t.match(key, regex)
105+
t.match(`hyper:${key}`, regex)
106+
t.match(`hyper://${key}`, regex)
107+
return { key, ttl: 10 }
108+
}
109+
}, name),
110+
{ key, ttl: 2 }
111+
)
112+
})
113+
test('hyper: looking for well-known may miss', async t => {
114+
const name = 'dat-ecosystem.org'
115+
t.deepEquals(
116+
await hyper({
117+
matchRegex,
118+
isLocal: () => false,
119+
async getDNSTxtRecord () {
120+
return { key: 'well-known', ttl: 2 }
121+
},
122+
async fetchWellKnown () {}
123+
}, name),
124+
undefined
125+
)
126+
})
127+
test('hyper: looking for well-known uses ttl of dns record if missing', async t => {
128+
const name = 'dat-ecosystem.org'
129+
t.deepEquals(
130+
await hyper({
131+
matchRegex,
132+
isLocal: () => false,
133+
async getDNSTxtRecord () {
134+
return { key: 'well-known', ttl: 2 }
135+
},
136+
async fetchWellKnown () {
137+
return { key, ttl: null }
138+
}
139+
}, name),
140+
{ key, ttl: 2 }
141+
)
142+
})
143+
})()
144+
51145
;(() => {
52146
const { cabal } = protocols
53147
const key = '100c77d788fdaf07b89b28e9d276e47f2e44011f4adb981921056e1b3b40e99e'

0 commit comments

Comments
 (0)