@helia/ipns 2.0.2 → 3.0.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 (60) hide show
  1. package/README.md +110 -0
  2. package/dist/index.min.js +26 -15
  3. package/dist/src/dns-resolvers/default.d.ts +3 -0
  4. package/dist/src/dns-resolvers/default.d.ts.map +1 -0
  5. package/dist/src/dns-resolvers/default.js +8 -0
  6. package/dist/src/dns-resolvers/default.js.map +1 -0
  7. package/dist/src/dns-resolvers/dns-json-over-https.d.ts +18 -0
  8. package/dist/src/dns-resolvers/dns-json-over-https.d.ts.map +1 -0
  9. package/dist/src/dns-resolvers/dns-json-over-https.js +72 -0
  10. package/dist/src/dns-resolvers/dns-json-over-https.js.map +1 -0
  11. package/dist/src/dns-resolvers/dns-over-https.d.ts +16 -0
  12. package/dist/src/dns-resolvers/dns-over-https.d.ts.map +1 -0
  13. package/dist/src/dns-resolvers/dns-over-https.js +123 -0
  14. package/dist/src/dns-resolvers/dns-over-https.js.map +1 -0
  15. package/dist/src/dns-resolvers/index.d.ts +3 -0
  16. package/dist/src/dns-resolvers/index.d.ts.map +1 -0
  17. package/dist/src/dns-resolvers/index.js +3 -0
  18. package/dist/src/dns-resolvers/index.js.map +1 -0
  19. package/dist/src/dns-resolvers/resolver.browser.d.ts +4 -0
  20. package/dist/src/dns-resolvers/resolver.browser.d.ts.map +1 -0
  21. package/dist/src/dns-resolvers/resolver.browser.js +39 -0
  22. package/dist/src/dns-resolvers/resolver.browser.js.map +1 -0
  23. package/dist/src/dns-resolvers/resolver.d.ts +4 -0
  24. package/dist/src/dns-resolvers/resolver.d.ts.map +1 -0
  25. package/dist/src/dns-resolvers/resolver.js +21 -0
  26. package/dist/src/dns-resolvers/resolver.js.map +1 -0
  27. package/dist/src/index.d.ts +102 -9
  28. package/dist/src/index.d.ts.map +1 -1
  29. package/dist/src/index.js +82 -12
  30. package/dist/src/index.js.map +1 -1
  31. package/dist/src/routing/dht.js.map +1 -1
  32. package/dist/src/routing/local-store.js +3 -3
  33. package/dist/src/routing/local-store.js.map +1 -1
  34. package/dist/src/routing/pubsub.js.map +1 -1
  35. package/dist/src/utils/dns.d.ts +35 -0
  36. package/dist/src/utils/dns.d.ts.map +1 -0
  37. package/dist/src/utils/dns.js +79 -0
  38. package/dist/src/utils/dns.js.map +1 -0
  39. package/dist/src/utils/tlru.js.map +1 -1
  40. package/dist/typedoc-urls.json +8 -0
  41. package/package.json +14 -5
  42. package/src/dns-resolvers/default.ts +9 -0
  43. package/src/dns-resolvers/dns-json-over-https.ts +90 -0
  44. package/src/dns-resolvers/dns-over-https.ts +146 -0
  45. package/src/dns-resolvers/index.ts +2 -0
  46. package/src/dns-resolvers/resolver.browser.ts +50 -0
  47. package/src/dns-resolvers/resolver.ts +25 -0
  48. package/src/index.ts +121 -13
  49. package/src/routing/local-store.ts +3 -3
  50. package/src/utils/dns.ts +126 -0
  51. package/dist/src/utils/resolve-dns-link.browser.d.ts +0 -6
  52. package/dist/src/utils/resolve-dns-link.browser.d.ts.map +0 -1
  53. package/dist/src/utils/resolve-dns-link.browser.js +0 -46
  54. package/dist/src/utils/resolve-dns-link.browser.js.map +0 -1
  55. package/dist/src/utils/resolve-dns-link.d.ts +0 -3
  56. package/dist/src/utils/resolve-dns-link.d.ts.map +0 -1
  57. package/dist/src/utils/resolve-dns-link.js +0 -54
  58. package/dist/src/utils/resolve-dns-link.js.map +0 -1
  59. package/src/utils/resolve-dns-link.browser.ts +0 -61
  60. package/src/utils/resolve-dns-link.ts +0 -65
@@ -1,54 +0,0 @@
1
- import dns from 'dns';
2
- import { promisify } from 'util';
3
- import * as isIPFS from 'is-ipfs';
4
- const MAX_RECURSIVE_DEPTH = 32;
5
- export async function resolveDnslink(domain, options = {}) {
6
- return recursiveResolveDnslink(domain, MAX_RECURSIVE_DEPTH, options);
7
- }
8
- async function recursiveResolveDnslink(domain, depth, options = {}) {
9
- if (depth === 0) {
10
- throw new Error('recursion limit exceeded');
11
- }
12
- let dnslinkRecord;
13
- try {
14
- dnslinkRecord = await resolve(domain);
15
- }
16
- catch (err) {
17
- // If the code is not ENOTFOUND or ERR_DNSLINK_NOT_FOUND or ENODATA then throw the error
18
- if (err.code !== 'ENOTFOUND' && err.code !== 'ERR_DNSLINK_NOT_FOUND' && err.code !== 'ENODATA') {
19
- throw err;
20
- }
21
- if (domain.startsWith('_dnslink.')) {
22
- // The supplied domain contains a _dnslink component
23
- // Check the non-_dnslink domain
24
- dnslinkRecord = await resolve(domain.replace('_dnslink.', ''));
25
- }
26
- else {
27
- // Check the _dnslink subdomain
28
- const _dnslinkDomain = `_dnslink.${domain}`;
29
- // If this throws then we propagate the error
30
- dnslinkRecord = await resolve(_dnslinkDomain);
31
- }
32
- }
33
- const result = dnslinkRecord.replace('dnslink=', '');
34
- const domainOrCID = result.split('/')[2];
35
- const isIPFSCID = isIPFS.cid(domainOrCID);
36
- if (isIPFSCID || depth === 0) {
37
- return result;
38
- }
39
- return recursiveResolveDnslink(domainOrCID, depth - 1, options);
40
- }
41
- async function resolve(domain, options = {}) {
42
- const DNSLINK_REGEX = /^dnslink=.+$/;
43
- const records = await promisify(dns.resolveTxt)(domain);
44
- const dnslinkRecords = records.reduce((rs, r) => rs.concat(r), [])
45
- .filter(record => DNSLINK_REGEX.test(record));
46
- const dnslinkRecord = dnslinkRecords[0];
47
- // we now have dns text entries as an array of strings
48
- // only records passing the DNSLINK_REGEX text are included
49
- if (dnslinkRecord == null) {
50
- throw new Error(`No dnslink records found for domain: ${domain}`);
51
- }
52
- return dnslinkRecord;
53
- }
54
- //# sourceMappingURL=resolve-dns-link.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"resolve-dns-link.js","sourceRoot":"","sources":["../../../src/utils/resolve-dns-link.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAA;AAChC,OAAO,KAAK,MAAM,MAAM,SAAS,CAAA;AAGjC,MAAM,mBAAmB,GAAG,EAAE,CAAA;AAE9B,MAAM,CAAC,KAAK,UAAU,cAAc,CAAE,MAAc,EAAE,UAAwB,EAAE;IAC9E,OAAO,uBAAuB,CAAC,MAAM,EAAE,mBAAmB,EAAE,OAAO,CAAC,CAAA;AACtE,CAAC;AAED,KAAK,UAAU,uBAAuB,CAAE,MAAc,EAAE,KAAa,EAAE,UAAwB,EAAE;IAC/F,IAAI,KAAK,KAAK,CAAC,EAAE;QACf,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAA;KAC5C;IAED,IAAI,aAAa,CAAA;IAEjB,IAAI;QACF,aAAa,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;KACtC;IAAC,OAAO,GAAQ,EAAE;QACjB,wFAAwF;QACxF,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,IAAI,GAAG,CAAC,IAAI,KAAK,uBAAuB,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,EAAE;YAC9F,MAAM,GAAG,CAAA;SACV;QAED,IAAI,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE;YAClC,oDAAoD;YACpD,gCAAgC;YAChC,aAAa,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAA;SAC/D;aAAM;YACL,+BAA+B;YAC/B,MAAM,cAAc,GAAG,YAAY,MAAM,EAAE,CAAA;YAC3C,6CAA6C;YAC7C,aAAa,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,CAAA;SAC9C;KACF;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;IACpD,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;IACxC,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;IAEzC,IAAI,SAAS,IAAI,KAAK,KAAK,CAAC,EAAE;QAC5B,OAAO,MAAM,CAAA;KACd;IAED,OAAO,uBAAuB,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,EAAE,OAAO,CAAC,CAAA;AACjE,CAAC;AAED,KAAK,UAAU,OAAO,CAAE,MAAc,EAAE,UAAwB,EAAE;IAChE,MAAM,aAAa,GAAG,cAAc,CAAA;IACpC,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAA;IACvD,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;SAC/D,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;IAE/C,MAAM,aAAa,GAAG,cAAc,CAAC,CAAC,CAAC,CAAA;IAEvC,sDAAsD;IACtD,2DAA2D;IAC3D,IAAI,aAAa,IAAI,IAAI,EAAE;QACzB,MAAM,IAAI,KAAK,CAAC,wCAAwC,MAAM,EAAE,CAAC,CAAA;KAClE;IAED,OAAO,aAAa,CAAA;AACtB,CAAC"}
@@ -1,61 +0,0 @@
1
- /* eslint-env browser */
2
-
3
- import PQueue from 'p-queue'
4
- import { TLRU } from './tlru.js'
5
- import type { AbortOptions } from '@libp2p/interface'
6
-
7
- // Avoid sending multiple queries for the same hostname by caching results
8
- const cache = new TLRU<{ Path: string, Message: string }>(1000)
9
- // TODO: /api/v0/dns does not return TTL yet: https://github.com/ipfs/go-ipfs/issues/5884
10
- // However we know browsers themselves cache DNS records for at least 1 minute,
11
- // which acts a provisional default ttl: https://stackoverflow.com/a/36917902/11518426
12
- const ttl = 60 * 1000
13
-
14
- // browsers limit concurrent connections per host,
15
- // we don't want preload calls to exhaust the limit (~6)
16
- const httpQueue = new PQueue({ concurrency: 4 })
17
-
18
- const ipfsPath = (response: { Path: string, Message: string }): string => {
19
- if (response.Path != null) {
20
- return response.Path
21
- }
22
- throw new Error(response.Message)
23
- }
24
-
25
- export interface ResolveDnsLinkOptions extends AbortOptions {
26
- nocache?: boolean
27
- }
28
-
29
- export async function resolveDnslink (fqdn: string, opts: ResolveDnsLinkOptions = {}): Promise<string> { // eslint-disable-line require-await
30
- const resolve = async (fqdn: string, opts: ResolveDnsLinkOptions = {}): Promise<string> => {
31
- // @ts-expect-error - URLSearchParams does not take boolean options, only strings
32
- const searchParams = new URLSearchParams(opts)
33
- searchParams.set('arg', fqdn)
34
-
35
- // try cache first
36
- const query = searchParams.toString()
37
- if (opts.nocache !== true && cache.has(query)) {
38
- const response = cache.get(query)
39
-
40
- if (response != null) {
41
- return ipfsPath(response)
42
- }
43
- }
44
-
45
- // fallback to delegated DNS resolver
46
- const response = await httpQueue.add(async () => {
47
- // Delegated HTTP resolver sending DNSLink queries to ipfs.io
48
- // TODO: replace hardcoded host with configurable DNS over HTTPS: https://github.com/ipfs/js-ipfs/issues/2212
49
- const res = await fetch(`https://ipfs.io/api/v0/dns?${searchParams}`)
50
- const query = new URL(res.url).search.slice(1)
51
- const json = await res.json()
52
- cache.set(query, json, ttl)
53
-
54
- return json
55
- })
56
-
57
- return ipfsPath(response)
58
- }
59
-
60
- return resolve(fqdn, opts)
61
- }
@@ -1,65 +0,0 @@
1
- import dns from 'dns'
2
- import { promisify } from 'util'
3
- import * as isIPFS from 'is-ipfs'
4
- import type { AbortOptions } from '@libp2p/interface'
5
-
6
- const MAX_RECURSIVE_DEPTH = 32
7
-
8
- export async function resolveDnslink (domain: string, options: AbortOptions = {}): Promise<string> {
9
- return recursiveResolveDnslink(domain, MAX_RECURSIVE_DEPTH, options)
10
- }
11
-
12
- async function recursiveResolveDnslink (domain: string, depth: number, options: AbortOptions = {}): Promise<string> {
13
- if (depth === 0) {
14
- throw new Error('recursion limit exceeded')
15
- }
16
-
17
- let dnslinkRecord
18
-
19
- try {
20
- dnslinkRecord = await resolve(domain)
21
- } catch (err: any) {
22
- // If the code is not ENOTFOUND or ERR_DNSLINK_NOT_FOUND or ENODATA then throw the error
23
- if (err.code !== 'ENOTFOUND' && err.code !== 'ERR_DNSLINK_NOT_FOUND' && err.code !== 'ENODATA') {
24
- throw err
25
- }
26
-
27
- if (domain.startsWith('_dnslink.')) {
28
- // The supplied domain contains a _dnslink component
29
- // Check the non-_dnslink domain
30
- dnslinkRecord = await resolve(domain.replace('_dnslink.', ''))
31
- } else {
32
- // Check the _dnslink subdomain
33
- const _dnslinkDomain = `_dnslink.${domain}`
34
- // If this throws then we propagate the error
35
- dnslinkRecord = await resolve(_dnslinkDomain)
36
- }
37
- }
38
-
39
- const result = dnslinkRecord.replace('dnslink=', '')
40
- const domainOrCID = result.split('/')[2]
41
- const isIPFSCID = isIPFS.cid(domainOrCID)
42
-
43
- if (isIPFSCID || depth === 0) {
44
- return result
45
- }
46
-
47
- return recursiveResolveDnslink(domainOrCID, depth - 1, options)
48
- }
49
-
50
- async function resolve (domain: string, options: AbortOptions = {}): Promise<string> {
51
- const DNSLINK_REGEX = /^dnslink=.+$/
52
- const records = await promisify(dns.resolveTxt)(domain)
53
- const dnslinkRecords = records.reduce((rs, r) => rs.concat(r), [])
54
- .filter(record => DNSLINK_REGEX.test(record))
55
-
56
- const dnslinkRecord = dnslinkRecords[0]
57
-
58
- // we now have dns text entries as an array of strings
59
- // only records passing the DNSLINK_REGEX text are included
60
- if (dnslinkRecord == null) {
61
- throw new Error(`No dnslink records found for domain: ${domain}`)
62
- }
63
-
64
- return dnslinkRecord
65
- }