@helia/verified-fetch 0.0.0-8db7792 → 0.0.0-a04e041

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 (33) hide show
  1. package/README.md +33 -0
  2. package/dist/index.min.js +4 -4
  3. package/dist/src/index.d.ts +36 -0
  4. package/dist/src/index.d.ts.map +1 -1
  5. package/dist/src/index.js +33 -0
  6. package/dist/src/index.js.map +1 -1
  7. package/dist/src/utils/get-content-disposition-filename.d.ts +6 -0
  8. package/dist/src/utils/get-content-disposition-filename.d.ts.map +1 -0
  9. package/dist/src/utils/get-content-disposition-filename.js +16 -0
  10. package/dist/src/utils/get-content-disposition-filename.js.map +1 -0
  11. package/dist/src/utils/parse-url-string.d.ts +2 -0
  12. package/dist/src/utils/parse-url-string.d.ts.map +1 -1
  13. package/dist/src/utils/parse-url-string.js +6 -0
  14. package/dist/src/utils/parse-url-string.js.map +1 -1
  15. package/dist/src/utils/responses.d.ts +4 -0
  16. package/dist/src/utils/responses.d.ts.map +1 -0
  17. package/dist/src/utils/responses.js +21 -0
  18. package/dist/src/utils/responses.js.map +1 -0
  19. package/dist/src/utils/select-output-type.d.ts +12 -0
  20. package/dist/src/utils/select-output-type.d.ts.map +1 -0
  21. package/dist/src/utils/select-output-type.js +147 -0
  22. package/dist/src/utils/select-output-type.js.map +1 -0
  23. package/dist/src/verified-fetch.d.ts +17 -15
  24. package/dist/src/verified-fetch.d.ts.map +1 -1
  25. package/dist/src/verified-fetch.js +211 -129
  26. package/dist/src/verified-fetch.js.map +1 -1
  27. package/package.json +18 -12
  28. package/src/index.ts +37 -0
  29. package/src/utils/get-content-disposition-filename.ts +18 -0
  30. package/src/utils/parse-url-string.ts +11 -1
  31. package/src/utils/responses.ts +22 -0
  32. package/src/utils/select-output-type.ts +166 -0
  33. package/src/verified-fetch.ts +237 -134
@@ -19,6 +19,8 @@ export interface ParseUrlStringOptions extends ProgressOptions<ResolveProgressEv
19
19
 
20
20
  export interface ParsedUrlQuery extends Record<string, string | unknown> {
21
21
  format?: RequestFormatShorthand
22
+ download?: boolean
23
+ filename?: string
22
24
  }
23
25
 
24
26
  export interface ParsedUrlStringResults {
@@ -109,7 +111,7 @@ export async function parseUrlString ({ urlString, ipns, logger }: ParseUrlStrin
109
111
  }
110
112
 
111
113
  // parse query string
112
- const query: Record<string, string> = {}
114
+ const query: Record<string, any> = {}
113
115
 
114
116
  if (queryString != null && queryString.length > 0) {
115
117
  const queryParts = queryString.split('&')
@@ -117,6 +119,14 @@ export async function parseUrlString ({ urlString, ipns, logger }: ParseUrlStrin
117
119
  const [key, value] = part.split('=')
118
120
  query[key] = decodeURIComponent(value)
119
121
  }
122
+
123
+ if (query.download != null) {
124
+ query.download = query.download === 'true'
125
+ }
126
+
127
+ if (query.filename != null) {
128
+ query.filename = query.filename.toString()
129
+ }
120
130
  }
121
131
 
122
132
  /**
@@ -0,0 +1,22 @@
1
+ export function okResponse (body?: BodyInit | null): Response {
2
+ return new Response(body, {
3
+ status: 200,
4
+ statusText: 'OK'
5
+ })
6
+ }
7
+
8
+ export function notSupportedResponse (body?: BodyInit | null): Response {
9
+ const response = new Response(body, {
10
+ status: 501,
11
+ statusText: 'Not Implemented'
12
+ })
13
+ response.headers.set('X-Content-Type-Options', 'nosniff') // see https://specs.ipfs.tech/http-gateways/path-gateway/#x-content-type-options-response-header
14
+ return response
15
+ }
16
+
17
+ export function notAcceptableResponse (body?: BodyInit | null): Response {
18
+ return new Response(body, {
19
+ status: 406,
20
+ statusText: 'Not Acceptable'
21
+ })
22
+ }
@@ -0,0 +1,166 @@
1
+ import { code as dagCborCode } from '@ipld/dag-cbor'
2
+ import { code as dagJsonCode } from '@ipld/dag-json'
3
+ import { code as dagPbCode } from '@ipld/dag-pb'
4
+ import { code as jsonCode } from 'multiformats/codecs/json'
5
+ import { code as rawCode } from 'multiformats/codecs/raw'
6
+ import type { RequestFormatShorthand } from '../types.js'
7
+ import type { CID } from 'multiformats/cid'
8
+
9
+ /**
10
+ * This maps supported response types for each codec supported by verified-fetch
11
+ */
12
+ const CID_TYPE_MAP: Record<number, string[]> = {
13
+ [dagCborCode]: [
14
+ 'application/json',
15
+ 'application/vnd.ipld.dag-cbor',
16
+ 'application/cbor',
17
+ 'application/vnd.ipld.dag-json',
18
+ 'application/octet-stream',
19
+ 'application/vnd.ipld.raw',
20
+ 'application/vnd.ipfs.ipns-record',
21
+ 'application/vnd.ipld.car'
22
+ ],
23
+ [dagJsonCode]: [
24
+ 'application/json',
25
+ 'application/vnd.ipld.dag-cbor',
26
+ 'application/cbor',
27
+ 'application/vnd.ipld.dag-json',
28
+ 'application/octet-stream',
29
+ 'application/vnd.ipld.raw',
30
+ 'application/vnd.ipfs.ipns-record',
31
+ 'application/vnd.ipld.car'
32
+ ],
33
+ [jsonCode]: [
34
+ 'application/json',
35
+ 'application/vnd.ipld.dag-cbor',
36
+ 'application/cbor',
37
+ 'application/vnd.ipld.dag-json',
38
+ 'application/octet-stream',
39
+ 'application/vnd.ipld.raw',
40
+ 'application/vnd.ipfs.ipns-record',
41
+ 'application/vnd.ipld.car'
42
+ ],
43
+ [dagPbCode]: [
44
+ 'application/octet-stream',
45
+ 'application/json',
46
+ 'application/vnd.ipld.dag-cbor',
47
+ 'application/cbor',
48
+ 'application/vnd.ipld.dag-json',
49
+ 'application/vnd.ipld.raw',
50
+ 'application/vnd.ipfs.ipns-record',
51
+ 'application/vnd.ipld.car',
52
+ 'application/x-tar'
53
+ ],
54
+ [rawCode]: [
55
+ 'application/octet-stream',
56
+ 'application/vnd.ipld.raw',
57
+ 'application/vnd.ipfs.ipns-record',
58
+ 'application/vnd.ipld.car'
59
+ ]
60
+ }
61
+
62
+ /**
63
+ * Selects an output mime-type based on the CID and a passed `Accept` header
64
+ */
65
+ export function selectOutputType (cid: CID, accept?: string): string | undefined {
66
+ const cidMimeTypes = CID_TYPE_MAP[cid.code]
67
+
68
+ if (accept != null) {
69
+ return chooseMimeType(accept, cidMimeTypes)
70
+ }
71
+ }
72
+
73
+ function chooseMimeType (accept: string, validMimeTypes: string[]): string | undefined {
74
+ const requestedMimeTypes = accept
75
+ .split(',')
76
+ .map(s => {
77
+ const parts = s.trim().split(';')
78
+
79
+ return {
80
+ mimeType: `${parts[0]}`.trim(),
81
+ weight: parseQFactor(parts[1])
82
+ }
83
+ })
84
+ .sort((a, b) => {
85
+ if (a.weight === b.weight) {
86
+ return 0
87
+ }
88
+
89
+ if (a.weight > b.weight) {
90
+ return -1
91
+ }
92
+
93
+ return 1
94
+ })
95
+ .map(s => s.mimeType)
96
+
97
+ for (const headerFormat of requestedMimeTypes) {
98
+ for (const mimeType of validMimeTypes) {
99
+ if (headerFormat.includes(mimeType)) {
100
+ return mimeType
101
+ }
102
+
103
+ if (headerFormat === '*/*') {
104
+ return mimeType
105
+ }
106
+
107
+ if (headerFormat.startsWith('*/') && mimeType.split('/')[1] === headerFormat.split('/')[1]) {
108
+ return mimeType
109
+ }
110
+
111
+ if (headerFormat.endsWith('/*') && mimeType.split('/')[0] === headerFormat.split('/')[0]) {
112
+ return mimeType
113
+ }
114
+ }
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Parses q-factor weighting from the accept header to allow letting some mime
120
+ * types take precedence over others.
121
+ *
122
+ * If the q-factor for an acceptable mime representation is omitted it defaults
123
+ * to `1`.
124
+ *
125
+ * All specified values should be in the range 0-1.
126
+ *
127
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept#q
128
+ */
129
+ function parseQFactor (str?: string): number {
130
+ if (str != null) {
131
+ str = str.trim()
132
+ }
133
+
134
+ if (str == null || !str.startsWith('q=')) {
135
+ return 1
136
+ }
137
+
138
+ const factor = parseFloat(str.replace('q=', ''))
139
+
140
+ if (isNaN(factor)) {
141
+ return 0
142
+ }
143
+
144
+ return factor
145
+ }
146
+
147
+ const FORMAT_TO_MIME_TYPE: Record<RequestFormatShorthand, string> = {
148
+ raw: 'application/vnd.ipld.raw',
149
+ car: 'application/vnd.ipld.car',
150
+ 'dag-json': 'application/vnd.ipld.dag-json',
151
+ 'dag-cbor': 'application/vnd.ipld.dag-cbor',
152
+ json: 'application/json',
153
+ cbor: 'application/cbor',
154
+ 'ipns-record': 'application/vnd.ipfs.ipns-record',
155
+ tar: 'application/x-tar'
156
+ }
157
+
158
+ /**
159
+ * Converts a `format=...` query param to a mime type as would be found in the
160
+ * `Accept` header, if a valid mapping is available
161
+ */
162
+ export function queryFormatToAcceptHeader (format?: RequestFormatShorthand): string | undefined {
163
+ if (format != null) {
164
+ return FORMAT_TO_MIME_TYPE[format]
165
+ }
166
+ }