@helia/verified-fetch 5.1.1 → 6.1.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 (72) hide show
  1. package/dist/index.min.js +61 -61
  2. package/dist/index.min.js.map +4 -4
  3. package/dist/src/index.d.ts +29 -6
  4. package/dist/src/index.d.ts.map +1 -1
  5. package/dist/src/index.js.map +1 -1
  6. package/dist/src/plugins/plugin-handle-car.d.ts.map +1 -1
  7. package/dist/src/plugins/plugin-handle-car.js +7 -3
  8. package/dist/src/plugins/plugin-handle-car.js.map +1 -1
  9. package/dist/src/plugins/plugin-handle-ipld.d.ts.map +1 -1
  10. package/dist/src/plugins/plugin-handle-ipld.js +4 -15
  11. package/dist/src/plugins/plugin-handle-ipld.js.map +1 -1
  12. package/dist/src/plugins/plugin-handle-raw.d.ts +11 -0
  13. package/dist/src/plugins/plugin-handle-raw.d.ts.map +1 -0
  14. package/dist/src/plugins/plugin-handle-raw.js +41 -0
  15. package/dist/src/plugins/plugin-handle-raw.js.map +1 -0
  16. package/dist/src/plugins/plugin-handle-unixfs.d.ts.map +1 -1
  17. package/dist/src/plugins/plugin-handle-unixfs.js +36 -18
  18. package/dist/src/plugins/plugin-handle-unixfs.js.map +1 -1
  19. package/dist/src/url-resolver.d.ts +2 -3
  20. package/dist/src/url-resolver.d.ts.map +1 -1
  21. package/dist/src/url-resolver.js +20 -57
  22. package/dist/src/url-resolver.js.map +1 -1
  23. package/dist/src/utils/error-to-response.d.ts +1 -1
  24. package/dist/src/utils/error-to-response.d.ts.map +1 -1
  25. package/dist/src/utils/error-to-response.js +14 -12
  26. package/dist/src/utils/error-to-response.js.map +1 -1
  27. package/dist/src/utils/get-range-header.d.ts +2 -1
  28. package/dist/src/utils/get-range-header.d.ts.map +1 -1
  29. package/dist/src/utils/get-range-header.js.map +1 -1
  30. package/dist/src/utils/get-tar-stream.d.ts.map +1 -1
  31. package/dist/src/utils/get-tar-stream.js +22 -9
  32. package/dist/src/utils/get-tar-stream.js.map +1 -1
  33. package/dist/src/utils/parse-resource.d.ts +10 -0
  34. package/dist/src/utils/parse-resource.d.ts.map +1 -0
  35. package/dist/src/utils/parse-resource.js +52 -0
  36. package/dist/src/utils/parse-resource.js.map +1 -0
  37. package/dist/src/utils/responses.d.ts +14 -14
  38. package/dist/src/utils/responses.d.ts.map +1 -1
  39. package/dist/src/utils/responses.js +8 -3
  40. package/dist/src/utils/responses.js.map +1 -1
  41. package/dist/src/verified-fetch.d.ts +1 -0
  42. package/dist/src/verified-fetch.d.ts.map +1 -1
  43. package/dist/src/verified-fetch.js +117 -119
  44. package/dist/src/verified-fetch.js.map +1 -1
  45. package/package.json +3 -3
  46. package/src/index.ts +30 -6
  47. package/src/plugins/plugin-handle-car.ts +8 -3
  48. package/src/plugins/plugin-handle-ipld.ts +4 -14
  49. package/src/plugins/plugin-handle-raw.ts +52 -0
  50. package/src/plugins/plugin-handle-unixfs.ts +42 -19
  51. package/src/url-resolver.ts +22 -65
  52. package/src/utils/error-to-response.ts +15 -12
  53. package/src/utils/get-range-header.ts +2 -1
  54. package/src/utils/get-tar-stream.ts +26 -10
  55. package/src/utils/parse-resource.ts +62 -0
  56. package/src/utils/responses.ts +24 -19
  57. package/src/verified-fetch.ts +123 -122
  58. package/dist/src/utils/ipfs-path-to-url.d.ts +0 -16
  59. package/dist/src/utils/ipfs-path-to-url.d.ts.map +0 -1
  60. package/dist/src/utils/ipfs-path-to-url.js +0 -45
  61. package/dist/src/utils/ipfs-path-to-url.js.map +0 -1
  62. package/dist/src/utils/parse-url-string.d.ts +0 -23
  63. package/dist/src/utils/parse-url-string.d.ts.map +0 -1
  64. package/dist/src/utils/parse-url-string.js +0 -120
  65. package/dist/src/utils/parse-url-string.js.map +0 -1
  66. package/dist/src/utils/resource-to-cache-key.d.ts +0 -15
  67. package/dist/src/utils/resource-to-cache-key.d.ts.map +0 -1
  68. package/dist/src/utils/resource-to-cache-key.js +0 -27
  69. package/dist/src/utils/resource-to-cache-key.js.map +0 -1
  70. package/src/utils/ipfs-path-to-url.ts +0 -54
  71. package/src/utils/parse-url-string.ts +0 -165
  72. package/src/utils/resource-to-cache-key.ts +0 -30
@@ -1,120 +0,0 @@
1
- import { InvalidParametersError } from '@libp2p/interface';
2
- import { peerIdFromCID, peerIdFromString } from '@libp2p/peer-id';
3
- import { CID } from 'multiformats/cid';
4
- import { decodeDNSLinkLabel, isInlinedDnsLink } from "./dnslink-label.js";
5
- import { ipfsPathToUrl, ipfsUrlToUrl } from "./ipfs-path-to-url.js";
6
- export const SUBDOMAIN_GATEWAY_REGEX = /^(?<cidOrPeerIdOrDnsLink>[^/?]+)\.(?<protocol>ip[fn]s)\.([^/?]+)$/;
7
- const CODEC_LIBP2P_KEY = 0x72;
8
- function matchSubdomainGroupsGuard(groups) {
9
- const protocol = groups?.protocol;
10
- if (protocol !== 'ipfs' && protocol !== 'ipns') {
11
- return false;
12
- }
13
- const cidOrPeerIdOrDnsLink = groups?.cidOrPeerIdOrDnsLink;
14
- if (cidOrPeerIdOrDnsLink == null) {
15
- return false;
16
- }
17
- return true;
18
- }
19
- /**
20
- * If the caller has passed a case-sensitive identifier (like a base58btc
21
- * encoded CID or PeerId) in a case-insensitive location (like a subdomain),
22
- * be nice and return the original identifier from the passed string
23
- */
24
- function findOriginalCidOrPeer(needle, haystack) {
25
- const start = haystack.toLowerCase().indexOf(needle);
26
- if (start === -1) {
27
- return needle;
28
- }
29
- return haystack.substring(start, start + needle.length);
30
- }
31
- function stringToUrl(urlString) {
32
- if (urlString instanceof URL) {
33
- return urlString;
34
- }
35
- // turn IPFS/IPNS path into gateway URL string
36
- if (urlString.startsWith('/ipfs/') || urlString.startsWith('/ipns/')) {
37
- urlString = ipfsPathToUrl(urlString);
38
- }
39
- // turn IPFS/IPNS URL into gateway URL string
40
- if (urlString.startsWith('ipfs://') || urlString.startsWith('ipns://')) {
41
- urlString = ipfsUrlToUrl(urlString);
42
- }
43
- if (urlString.startsWith('http://') || urlString.startsWith('https://')) {
44
- return new URL(urlString);
45
- }
46
- throw new InvalidParametersError(`Invalid URL: ${urlString}`);
47
- }
48
- function toURL(urlString) {
49
- // validate url
50
- const url = stringToUrl(urlString);
51
- // test for subdomain gateway URL
52
- const subdomainMatch = url.hostname.match(SUBDOMAIN_GATEWAY_REGEX);
53
- if (matchSubdomainGroupsGuard(subdomainMatch?.groups)) {
54
- const groups = subdomainMatch.groups;
55
- if (groups.protocol === 'ipns' && isInlinedDnsLink(groups.cidOrPeerIdOrDnsLink)) {
56
- // decode inline dnslink domain if present
57
- groups.cidOrPeerIdOrDnsLink = decodeDNSLinkLabel(groups.cidOrPeerIdOrDnsLink);
58
- }
59
- const cidOrPeerIdOrDnsLink = findOriginalCidOrPeer(groups.cidOrPeerIdOrDnsLink, urlString);
60
- // parse url as not http(s):// - this is necessary because URL makes
61
- // `.pathname` default to `/` for http URLs, even if no trailing slash was
62
- // present in the string URL and we need to be able to round-trip the user's
63
- // input while also maintaining a sane canonical URL for the resource. Phew.
64
- const wat = new URL(`not-${urlString}`);
65
- return new URL(`${groups.protocol}://${cidOrPeerIdOrDnsLink}${wat.pathname}${url.search}${url.hash}`);
66
- }
67
- // test for IPFS path gateway URL
68
- if (url.pathname.startsWith('/ipfs/')) {
69
- const parts = url.pathname.substring(6).split('/');
70
- const cid = parts.shift();
71
- if (cid == null) {
72
- throw new InvalidParametersError(`Path gateway URL ${urlString} had no CID`);
73
- }
74
- return new URL(`ipfs://${cid}${url.pathname.replace(`/ipfs/${cid}`, '')}${url.search}${url.hash}`);
75
- }
76
- // test for IPNS path gateway URL
77
- if (url.pathname.startsWith('/ipns/')) {
78
- const parts = url.pathname.substring(6).split('/');
79
- const name = parts.shift();
80
- if (name == null) {
81
- throw new InvalidParametersError(`Path gateway URL ${urlString} had no name`);
82
- }
83
- return new URL(`ipns://${name}${url.pathname.replace(`/ipns/${name}`, '')}${url.search}${url.hash}`);
84
- }
85
- throw new TypeError(`Invalid URL: ${urlString}, please use ipfs://, ipns://, or gateway URLs only`);
86
- }
87
- /**
88
- * Accepts the following url strings:
89
- *
90
- * - /ipfs/Qmfoo/path
91
- * - /ipns/Qmfoo/path
92
- * - ipfs://cid/path
93
- * - ipns://name/path
94
- * - http://cid.ipfs.example.com/path
95
- * - http://name.ipns.example.com/path
96
- * - http://example.com/ipfs/cid/path
97
- * - http://example.com/ipns/name/path
98
- */
99
- export function parseURLString(urlString) {
100
- // validate url
101
- const url = toURL(urlString);
102
- // treat IPNS keys that do not parse as PeerIds as DNSLink
103
- if (url.protocol === 'ipns:') {
104
- try {
105
- peerIdFromString(url.hostname);
106
- }
107
- catch {
108
- url.protocol = 'dnslink:';
109
- }
110
- }
111
- if (url.protocol === 'ipfs:') {
112
- const cid = CID.parse(url.hostname);
113
- // special case - peer id encoded as a CID
114
- if (cid.code === CODEC_LIBP2P_KEY) {
115
- return new URL(`ipns://${peerIdFromCID(cid)}${url.pathname}${url.search}${url.hash}`);
116
- }
117
- }
118
- return url;
119
- }
120
- //# sourceMappingURL=parse-url-string.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"parse-url-string.js","sourceRoot":"","sources":["../../../src/utils/parse-url-string.ts"],"names":[],"mappings":"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"}
@@ -1,15 +0,0 @@
1
- import { CID } from 'multiformats/cid';
2
- /**
3
- * Takes a resource and returns a session cache key as an IPFS or IPNS path with
4
- * any trailing segments removed.
5
- *
6
- * E.g.
7
- *
8
- * - Qmfoo -> /ipfs/Qmfoo
9
- * - https://Qmfoo.ipfs.gateway.org -> ipfs://Qmfoo
10
- * - https://gateway.org/ipfs/Qmfoo -> ipfs://Qmfoo
11
- * - https://gateway.org/ipfs/Qmfoo/bar.txt -> ipfs://Qmfoo
12
- * - etc
13
- */
14
- export declare function resourceToSessionCacheKey(url: string | CID): string;
15
- //# sourceMappingURL=resource-to-cache-key.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"resource-to-cache-key.d.ts","sourceRoot":"","sources":["../../../src/utils/resource-to-cache-key.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAGtC;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CAAE,GAAG,EAAE,MAAM,GAAG,GAAG,GAAG,MAAM,CAcpE"}
@@ -1,27 +0,0 @@
1
- import { CID } from 'multiformats/cid';
2
- import { parseURLString } from './parse-url-string.js';
3
- /**
4
- * Takes a resource and returns a session cache key as an IPFS or IPNS path with
5
- * any trailing segments removed.
6
- *
7
- * E.g.
8
- *
9
- * - Qmfoo -> /ipfs/Qmfoo
10
- * - https://Qmfoo.ipfs.gateway.org -> ipfs://Qmfoo
11
- * - https://gateway.org/ipfs/Qmfoo -> ipfs://Qmfoo
12
- * - https://gateway.org/ipfs/Qmfoo/bar.txt -> ipfs://Qmfoo
13
- * - etc
14
- */
15
- export function resourceToSessionCacheKey(url) {
16
- const cid = CID.asCID(url);
17
- if (cid != null) {
18
- return `ipfs://${cid}`;
19
- }
20
- try {
21
- return `ipfs://${CID.parse(url.toString())}`;
22
- }
23
- catch { }
24
- const { protocol, host } = parseURLString(url.toString());
25
- return `${protocol}//${host}`;
26
- }
27
- //# sourceMappingURL=resource-to-cache-key.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"resource-to-cache-key.js","sourceRoot":"","sources":["../../../src/utils/resource-to-cache-key.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAEtD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,yBAAyB,CAAE,GAAiB;IAC1D,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAE1B,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;QAChB,OAAO,UAAU,GAAG,EAAE,CAAA;IACxB,CAAC;IAED,IAAI,CAAC;QACH,OAAO,UAAU,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAA;IAC9C,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAEV,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,cAAc,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAA;IAEzD,OAAO,GAAG,QAAQ,KAAK,IAAI,EAAE,CAAA;AAC/B,CAAC"}
@@ -1,54 +0,0 @@
1
- import { InvalidParametersError } from '@libp2p/interface'
2
-
3
- /**
4
- * Turns an IPFS or IPNS path into a HTTP URL. Path gateway syntax is used to
5
- * preserve any case sensitivity
6
- *
7
- * - `/ipfs/cid` -> `https://example.org/ipfs/cid`
8
- * - `/ipns/name` -> `https://example.org/ipns/name`
9
- */
10
- export function ipfsPathToUrl (path: string): string {
11
- if (!path.startsWith('/ipfs/') && !path.startsWith('/ipns/')) {
12
- throw new InvalidParametersError(`Path ${path} did not start with /ipfs/ or /ipns/`)
13
- }
14
-
15
- // trim fragment
16
- const fragmentIndex = path.indexOf('#')
17
- let fragment = ''
18
-
19
- if (fragmentIndex > -1) {
20
- fragment = path.substring(fragmentIndex)
21
- path = path.substring(0, fragmentIndex)
22
- }
23
-
24
- // trim query
25
- const queryIndex = path.indexOf('?')
26
- let query = ''
27
-
28
- if (queryIndex > -1) {
29
- query = path.substring(queryIndex)
30
- path = path.substring(0, queryIndex)
31
- }
32
-
33
- const type = path.substring(1, 5)
34
- const rest = path.substring(6)
35
-
36
- return `https://example.org/${type}/${rest}${query}${fragment}`
37
- }
38
-
39
- /**
40
- * Turns an IPFS or IPNS URL into a HTTP URL. Path gateway syntax is used to
41
- * preserve and case sensitivity
42
- *
43
- * `ipfs://cid` -> `https://example.org/ipfs/cid`
44
- */
45
- export function ipfsUrlToUrl (url: string): string {
46
- if (!url.startsWith('ipfs://') && !url.startsWith('ipns://')) {
47
- throw new InvalidParametersError(`URL ${url} did not start with ipfs:// or ipns://`)
48
- }
49
-
50
- const type = url.substring(0, 4)
51
- const rest = url.substring(7)
52
-
53
- return `https://example.org/${type}/${rest}`
54
- }
@@ -1,165 +0,0 @@
1
- import { InvalidParametersError } from '@libp2p/interface'
2
- import { peerIdFromCID, peerIdFromString } from '@libp2p/peer-id'
3
- import { CID } from 'multiformats/cid'
4
- import { decodeDNSLinkLabel, isInlinedDnsLink } from './dnslink-label.ts'
5
- import { ipfsPathToUrl, ipfsUrlToUrl } from './ipfs-path-to-url.ts'
6
-
7
- interface SubdomainMatchGroups {
8
- protocol: 'ipfs' | 'ipns'
9
- cidOrPeerIdOrDnsLink: string
10
- }
11
-
12
- export const SUBDOMAIN_GATEWAY_REGEX = /^(?<cidOrPeerIdOrDnsLink>[^/?]+)\.(?<protocol>ip[fn]s)\.([^/?]+)$/
13
- const CODEC_LIBP2P_KEY = 0x72
14
-
15
- function matchSubdomainGroupsGuard (groups?: null | { [key in string]: string; } | SubdomainMatchGroups): groups is SubdomainMatchGroups {
16
- const protocol = groups?.protocol
17
-
18
- if (protocol !== 'ipfs' && protocol !== 'ipns') {
19
- return false
20
- }
21
-
22
- const cidOrPeerIdOrDnsLink = groups?.cidOrPeerIdOrDnsLink
23
-
24
- if (cidOrPeerIdOrDnsLink == null) {
25
- return false
26
- }
27
-
28
- return true
29
- }
30
-
31
- export interface ParsedURL {
32
- url: URL,
33
- protocol: 'ipfs' | 'ipns'
34
- cidOrPeerIdOrDnsLink: string
35
- path: string[]
36
- query: Record<string, any>
37
- fragment: string
38
- }
39
-
40
- /**
41
- * If the caller has passed a case-sensitive identifier (like a base58btc
42
- * encoded CID or PeerId) in a case-insensitive location (like a subdomain),
43
- * be nice and return the original identifier from the passed string
44
- */
45
- function findOriginalCidOrPeer (needle: string, haystack: string): string {
46
- const start = haystack.toLowerCase().indexOf(needle)
47
-
48
- if (start === -1) {
49
- return needle
50
- }
51
-
52
- return haystack.substring(start, start + needle.length)
53
- }
54
-
55
- function stringToUrl (urlString: string | URL): URL {
56
- if (urlString instanceof URL) {
57
- return urlString
58
- }
59
-
60
- // turn IPFS/IPNS path into gateway URL string
61
- if (urlString.startsWith('/ipfs/') || urlString.startsWith('/ipns/')) {
62
- urlString = ipfsPathToUrl(urlString)
63
- }
64
-
65
- // turn IPFS/IPNS URL into gateway URL string
66
- if (urlString.startsWith('ipfs://') || urlString.startsWith('ipns://')) {
67
- urlString = ipfsUrlToUrl(urlString)
68
- }
69
-
70
- if (urlString.startsWith('http://') || urlString.startsWith('https://')) {
71
- return new URL(urlString)
72
- }
73
-
74
- throw new InvalidParametersError(`Invalid URL: ${urlString}`)
75
- }
76
-
77
- function toURL (urlString: string): URL {
78
- // validate url
79
- const url = stringToUrl(urlString)
80
-
81
- // test for subdomain gateway URL
82
- const subdomainMatch = url.hostname.match(SUBDOMAIN_GATEWAY_REGEX)
83
-
84
- if (matchSubdomainGroupsGuard(subdomainMatch?.groups)) {
85
- const groups = subdomainMatch.groups
86
-
87
- if (groups.protocol === 'ipns' && isInlinedDnsLink(groups.cidOrPeerIdOrDnsLink)) {
88
- // decode inline dnslink domain if present
89
- groups.cidOrPeerIdOrDnsLink = decodeDNSLinkLabel(groups.cidOrPeerIdOrDnsLink)
90
- }
91
-
92
- const cidOrPeerIdOrDnsLink = findOriginalCidOrPeer(groups.cidOrPeerIdOrDnsLink, urlString)
93
-
94
- // parse url as not http(s):// - this is necessary because URL makes
95
- // `.pathname` default to `/` for http URLs, even if no trailing slash was
96
- // present in the string URL and we need to be able to round-trip the user's
97
- // input while also maintaining a sane canonical URL for the resource. Phew.
98
- const wat = new URL(`not-${urlString}`)
99
-
100
- return new URL(`${groups.protocol}://${cidOrPeerIdOrDnsLink}${wat.pathname}${url.search}${url.hash}`)
101
- }
102
-
103
- // test for IPFS path gateway URL
104
- if (url.pathname.startsWith('/ipfs/')) {
105
- const parts = url.pathname.substring(6).split('/')
106
- const cid = parts.shift()
107
-
108
- if (cid == null) {
109
- throw new InvalidParametersError(`Path gateway URL ${urlString} had no CID`)
110
- }
111
-
112
- return new URL(`ipfs://${cid}${url.pathname.replace(`/ipfs/${cid}`, '')}${url.search}${url.hash}`)
113
- }
114
-
115
- // test for IPNS path gateway URL
116
- if (url.pathname.startsWith('/ipns/')) {
117
- const parts = url.pathname.substring(6).split('/')
118
- const name = parts.shift()
119
-
120
- if (name == null) {
121
- throw new InvalidParametersError(`Path gateway URL ${urlString} had no name`)
122
- }
123
-
124
- return new URL(`ipns://${name}${url.pathname.replace(`/ipns/${name}`, '')}${url.search}${url.hash}`)
125
- }
126
-
127
- throw new TypeError(`Invalid URL: ${urlString}, please use ipfs://, ipns://, or gateway URLs only`)
128
- }
129
-
130
- /**
131
- * Accepts the following url strings:
132
- *
133
- * - /ipfs/Qmfoo/path
134
- * - /ipns/Qmfoo/path
135
- * - ipfs://cid/path
136
- * - ipns://name/path
137
- * - http://cid.ipfs.example.com/path
138
- * - http://name.ipns.example.com/path
139
- * - http://example.com/ipfs/cid/path
140
- * - http://example.com/ipns/name/path
141
- */
142
- export function parseURLString (urlString: string): URL {
143
- // validate url
144
- const url = toURL(urlString)
145
-
146
- // treat IPNS keys that do not parse as PeerIds as DNSLink
147
- if (url.protocol === 'ipns:') {
148
- try {
149
- peerIdFromString(url.hostname)
150
- } catch {
151
- url.protocol = 'dnslink:'
152
- }
153
- }
154
-
155
- if (url.protocol === 'ipfs:') {
156
- const cid = CID.parse(url.hostname)
157
-
158
- // special case - peer id encoded as a CID
159
- if (cid.code === CODEC_LIBP2P_KEY) {
160
- return new URL(`ipns://${peerIdFromCID(cid)}${url.pathname}${url.search}${url.hash}`)
161
- }
162
- }
163
-
164
- return url
165
- }
@@ -1,30 +0,0 @@
1
- import { CID } from 'multiformats/cid'
2
- import { parseURLString } from './parse-url-string.js'
3
-
4
- /**
5
- * Takes a resource and returns a session cache key as an IPFS or IPNS path with
6
- * any trailing segments removed.
7
- *
8
- * E.g.
9
- *
10
- * - Qmfoo -> /ipfs/Qmfoo
11
- * - https://Qmfoo.ipfs.gateway.org -> ipfs://Qmfoo
12
- * - https://gateway.org/ipfs/Qmfoo -> ipfs://Qmfoo
13
- * - https://gateway.org/ipfs/Qmfoo/bar.txt -> ipfs://Qmfoo
14
- * - etc
15
- */
16
- export function resourceToSessionCacheKey (url: string | CID): string {
17
- const cid = CID.asCID(url)
18
-
19
- if (cid != null) {
20
- return `ipfs://${cid}`
21
- }
22
-
23
- try {
24
- return `ipfs://${CID.parse(url.toString())}`
25
- } catch {}
26
-
27
- const { protocol, host } = parseURLString(url.toString())
28
-
29
- return `${protocol}//${host}`
30
- }