@helia/verified-fetch 4.1.1 → 5.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 (231) hide show
  1. package/README.md +6 -40
  2. package/dist/index.min.js +73 -534
  3. package/dist/index.min.js.map +4 -4
  4. package/dist/src/constants.d.ts +2 -0
  5. package/dist/src/constants.d.ts.map +1 -1
  6. package/dist/src/constants.js +2 -0
  7. package/dist/src/constants.js.map +1 -1
  8. package/dist/src/index.d.ts +162 -68
  9. package/dist/src/index.d.ts.map +1 -1
  10. package/dist/src/index.js +7 -40
  11. package/dist/src/index.js.map +1 -1
  12. package/dist/src/plugins/index.d.ts +0 -5
  13. package/dist/src/plugins/index.d.ts.map +1 -1
  14. package/dist/src/plugins/index.js +0 -4
  15. package/dist/src/plugins/index.js.map +1 -1
  16. package/dist/src/plugins/plugin-base.d.ts +8 -9
  17. package/dist/src/plugins/plugin-base.d.ts.map +1 -1
  18. package/dist/src/plugins/plugin-base.js +5 -6
  19. package/dist/src/plugins/plugin-base.js.map +1 -1
  20. package/dist/src/plugins/plugin-handle-car.d.ts +3 -3
  21. package/dist/src/plugins/plugin-handle-car.d.ts.map +1 -1
  22. package/dist/src/plugins/plugin-handle-car.js +38 -39
  23. package/dist/src/plugins/plugin-handle-car.js.map +1 -1
  24. package/dist/src/plugins/plugin-handle-ipld.d.ts +12 -0
  25. package/dist/src/plugins/plugin-handle-ipld.d.ts.map +1 -0
  26. package/dist/src/plugins/plugin-handle-ipld.js +83 -0
  27. package/dist/src/plugins/plugin-handle-ipld.js.map +1 -0
  28. package/dist/src/plugins/plugin-handle-ipns-record.d.ts +3 -3
  29. package/dist/src/plugins/plugin-handle-ipns-record.d.ts.map +1 -1
  30. package/dist/src/plugins/plugin-handle-ipns-record.js +25 -34
  31. package/dist/src/plugins/plugin-handle-ipns-record.js.map +1 -1
  32. package/dist/src/plugins/plugin-handle-tar.d.ts +3 -3
  33. package/dist/src/plugins/plugin-handle-tar.d.ts.map +1 -1
  34. package/dist/src/plugins/plugin-handle-tar.js +20 -22
  35. package/dist/src/plugins/plugin-handle-tar.js.map +1 -1
  36. package/dist/src/plugins/plugin-handle-unixfs.d.ts +14 -0
  37. package/dist/src/plugins/plugin-handle-unixfs.d.ts.map +1 -0
  38. package/dist/src/plugins/plugin-handle-unixfs.js +180 -0
  39. package/dist/src/plugins/plugin-handle-unixfs.js.map +1 -0
  40. package/dist/src/plugins/types.d.ts +1 -77
  41. package/dist/src/plugins/types.d.ts.map +1 -1
  42. package/dist/src/url-resolver.d.ts +29 -11
  43. package/dist/src/url-resolver.d.ts.map +1 -1
  44. package/dist/src/url-resolver.js +152 -74
  45. package/dist/src/url-resolver.js.map +1 -1
  46. package/dist/src/utils/content-type-parser.d.ts.map +1 -1
  47. package/dist/src/utils/content-type-parser.js +4 -3
  48. package/dist/src/utils/content-type-parser.js.map +1 -1
  49. package/dist/src/utils/content-types.d.ts +26 -0
  50. package/dist/src/utils/content-types.d.ts.map +1 -0
  51. package/dist/src/utils/content-types.js +137 -0
  52. package/dist/src/utils/content-types.js.map +1 -0
  53. package/dist/src/utils/convert-output.d.ts +17 -0
  54. package/dist/src/utils/convert-output.d.ts.map +1 -0
  55. package/dist/src/utils/convert-output.js +176 -0
  56. package/dist/src/utils/convert-output.js.map +1 -0
  57. package/dist/src/utils/error-to-response.d.ts +3 -0
  58. package/dist/src/utils/error-to-response.d.ts.map +1 -0
  59. package/dist/src/utils/error-to-response.js +40 -0
  60. package/dist/src/utils/error-to-response.js.map +1 -0
  61. package/dist/src/utils/get-content-disposition-filename.d.ts +1 -1
  62. package/dist/src/utils/get-content-disposition-filename.d.ts.map +1 -1
  63. package/dist/src/utils/get-content-disposition-filename.js +4 -0
  64. package/dist/src/utils/get-content-disposition-filename.js.map +1 -1
  65. package/dist/src/utils/get-e-tag.d.ts +20 -15
  66. package/dist/src/utils/get-e-tag.d.ts.map +1 -1
  67. package/dist/src/utils/get-e-tag.js +8 -22
  68. package/dist/src/utils/get-e-tag.js.map +1 -1
  69. package/dist/src/utils/get-offset-and-length.d.ts +12 -2
  70. package/dist/src/utils/get-offset-and-length.d.ts.map +1 -1
  71. package/dist/src/utils/get-offset-and-length.js +63 -21
  72. package/dist/src/utils/get-offset-and-length.js.map +1 -1
  73. package/dist/src/utils/get-range-header.d.ts +22 -0
  74. package/dist/src/utils/get-range-header.d.ts.map +1 -0
  75. package/dist/src/utils/get-range-header.js +69 -0
  76. package/dist/src/utils/get-range-header.js.map +1 -0
  77. package/dist/src/utils/parse-url-string.d.ts +2 -1
  78. package/dist/src/utils/parse-url-string.d.ts.map +1 -1
  79. package/dist/src/utils/parse-url-string.js +46 -71
  80. package/dist/src/utils/parse-url-string.js.map +1 -1
  81. package/dist/src/utils/resource-to-cache-key.d.ts +3 -3
  82. package/dist/src/utils/resource-to-cache-key.js +5 -5
  83. package/dist/src/utils/resource-to-cache-key.js.map +1 -1
  84. package/dist/src/utils/response-headers.d.ts +4 -14
  85. package/dist/src/utils/response-headers.d.ts.map +1 -1
  86. package/dist/src/utils/response-headers.js +36 -36
  87. package/dist/src/utils/response-headers.js.map +1 -1
  88. package/dist/src/utils/responses.d.ts +30 -11
  89. package/dist/src/utils/responses.d.ts.map +1 -1
  90. package/dist/src/utils/responses.js +146 -39
  91. package/dist/src/utils/responses.js.map +1 -1
  92. package/dist/src/verified-fetch.d.ts +16 -15
  93. package/dist/src/verified-fetch.d.ts.map +1 -1
  94. package/dist/src/verified-fetch.js +302 -238
  95. package/dist/src/verified-fetch.js.map +1 -1
  96. package/dist/typedoc-urls.json +64 -45
  97. package/package.json +4 -3
  98. package/src/constants.ts +3 -0
  99. package/src/index.ts +199 -68
  100. package/src/plugins/index.ts +0 -6
  101. package/src/plugins/plugin-base.ts +8 -10
  102. package/src/plugins/plugin-handle-car.ts +48 -46
  103. package/src/plugins/plugin-handle-ipld.ts +93 -0
  104. package/src/plugins/plugin-handle-ipns-record.ts +31 -41
  105. package/src/plugins/plugin-handle-tar.ts +25 -29
  106. package/src/plugins/plugin-handle-unixfs.ts +217 -0
  107. package/src/plugins/types.ts +0 -86
  108. package/src/url-resolver.ts +197 -83
  109. package/src/utils/content-type-parser.ts +4 -3
  110. package/src/utils/content-types.ts +159 -0
  111. package/src/utils/convert-output.ts +187 -0
  112. package/src/utils/error-to-response.ts +49 -0
  113. package/src/utils/get-content-disposition-filename.ts +7 -1
  114. package/src/utils/get-e-tag.ts +26 -35
  115. package/src/utils/get-offset-and-length.ts +75 -21
  116. package/src/utils/get-range-header.ts +107 -0
  117. package/src/utils/parse-url-string.ts +51 -80
  118. package/src/utils/resource-to-cache-key.ts +5 -5
  119. package/src/utils/response-headers.ts +40 -41
  120. package/src/utils/responses.ts +186 -45
  121. package/src/verified-fetch.ts +353 -270
  122. package/dist/src/plugins/plugin-handle-byte-range-context.d.ts +0 -14
  123. package/dist/src/plugins/plugin-handle-byte-range-context.d.ts.map +0 -1
  124. package/dist/src/plugins/plugin-handle-byte-range-context.js +0 -25
  125. package/dist/src/plugins/plugin-handle-byte-range-context.js.map +0 -1
  126. package/dist/src/plugins/plugin-handle-cbor.d.ts +0 -17
  127. package/dist/src/plugins/plugin-handle-cbor.d.ts.map +0 -1
  128. package/dist/src/plugins/plugin-handle-cbor.js +0 -94
  129. package/dist/src/plugins/plugin-handle-cbor.js.map +0 -1
  130. package/dist/src/plugins/plugin-handle-dag-cbor-html-preview.d.ts +0 -27
  131. package/dist/src/plugins/plugin-handle-dag-cbor-html-preview.d.ts.map +0 -1
  132. package/dist/src/plugins/plugin-handle-dag-cbor-html-preview.js +0 -279
  133. package/dist/src/plugins/plugin-handle-dag-cbor-html-preview.js.map +0 -1
  134. package/dist/src/plugins/plugin-handle-dag-cbor.d.ts +0 -17
  135. package/dist/src/plugins/plugin-handle-dag-cbor.d.ts.map +0 -1
  136. package/dist/src/plugins/plugin-handle-dag-cbor.js +0 -66
  137. package/dist/src/plugins/plugin-handle-dag-cbor.js.map +0 -1
  138. package/dist/src/plugins/plugin-handle-dag-pb.d.ts +0 -17
  139. package/dist/src/plugins/plugin-handle-dag-pb.d.ts.map +0 -1
  140. package/dist/src/plugins/plugin-handle-dag-pb.js +0 -209
  141. package/dist/src/plugins/plugin-handle-dag-pb.js.map +0 -1
  142. package/dist/src/plugins/plugin-handle-dag-walk.d.ts +0 -21
  143. package/dist/src/plugins/plugin-handle-dag-walk.d.ts.map +0 -1
  144. package/dist/src/plugins/plugin-handle-dag-walk.js +0 -95
  145. package/dist/src/plugins/plugin-handle-dag-walk.js.map +0 -1
  146. package/dist/src/plugins/plugin-handle-dir-index-html.d.ts +0 -10
  147. package/dist/src/plugins/plugin-handle-dir-index-html.d.ts.map +0 -1
  148. package/dist/src/plugins/plugin-handle-dir-index-html.js +0 -59
  149. package/dist/src/plugins/plugin-handle-dir-index-html.js.map +0 -1
  150. package/dist/src/plugins/plugin-handle-json.d.ts +0 -12
  151. package/dist/src/plugins/plugin-handle-json.d.ts.map +0 -1
  152. package/dist/src/plugins/plugin-handle-json.js +0 -73
  153. package/dist/src/plugins/plugin-handle-json.js.map +0 -1
  154. package/dist/src/plugins/plugin-handle-raw.d.ts +0 -9
  155. package/dist/src/plugins/plugin-handle-raw.d.ts.map +0 -1
  156. package/dist/src/plugins/plugin-handle-raw.js +0 -92
  157. package/dist/src/plugins/plugin-handle-raw.js.map +0 -1
  158. package/dist/src/plugins/plugins.d.ts +0 -6
  159. package/dist/src/plugins/plugins.d.ts.map +0 -1
  160. package/dist/src/plugins/plugins.js +0 -6
  161. package/dist/src/plugins/plugins.js.map +0 -1
  162. package/dist/src/utils/byte-range-context.d.ts +0 -103
  163. package/dist/src/utils/byte-range-context.d.ts.map +0 -1
  164. package/dist/src/utils/byte-range-context.js +0 -504
  165. package/dist/src/utils/byte-range-context.js.map +0 -1
  166. package/dist/src/utils/dag-cbor-to-safe-json.d.ts +0 -15
  167. package/dist/src/utils/dag-cbor-to-safe-json.d.ts.map +0 -1
  168. package/dist/src/utils/dag-cbor-to-safe-json.js +0 -54
  169. package/dist/src/utils/dag-cbor-to-safe-json.js.map +0 -1
  170. package/dist/src/utils/dir-index-html.d.ts +0 -19
  171. package/dist/src/utils/dir-index-html.d.ts.map +0 -1
  172. package/dist/src/utils/dir-index-html.js +0 -438
  173. package/dist/src/utils/dir-index-html.js.map +0 -1
  174. package/dist/src/utils/get-peer-id-from-string.d.ts +0 -3
  175. package/dist/src/utils/get-peer-id-from-string.d.ts.map +0 -1
  176. package/dist/src/utils/get-peer-id-from-string.js +0 -10
  177. package/dist/src/utils/get-peer-id-from-string.js.map +0 -1
  178. package/dist/src/utils/get-resolved-accept-header.d.ts +0 -9
  179. package/dist/src/utils/get-resolved-accept-header.d.ts.map +0 -1
  180. package/dist/src/utils/get-resolved-accept-header.js +0 -27
  181. package/dist/src/utils/get-resolved-accept-header.js.map +0 -1
  182. package/dist/src/utils/get-stream-from-async-iterable.d.ts +0 -9
  183. package/dist/src/utils/get-stream-from-async-iterable.d.ts.map +0 -1
  184. package/dist/src/utils/get-stream-from-async-iterable.js +0 -43
  185. package/dist/src/utils/get-stream-from-async-iterable.js.map +0 -1
  186. package/dist/src/utils/handle-redirects.d.ts +0 -16
  187. package/dist/src/utils/handle-redirects.d.ts.map +0 -1
  188. package/dist/src/utils/handle-redirects.js +0 -84
  189. package/dist/src/utils/handle-redirects.js.map +0 -1
  190. package/dist/src/utils/is-accept-explicit.d.ts +0 -15
  191. package/dist/src/utils/is-accept-explicit.d.ts.map +0 -1
  192. package/dist/src/utils/is-accept-explicit.js +0 -26
  193. package/dist/src/utils/is-accept-explicit.js.map +0 -1
  194. package/dist/src/utils/request-headers.d.ts +0 -13
  195. package/dist/src/utils/request-headers.d.ts.map +0 -1
  196. package/dist/src/utils/request-headers.js +0 -63
  197. package/dist/src/utils/request-headers.js.map +0 -1
  198. package/dist/src/utils/select-output-type.d.ts +0 -17
  199. package/dist/src/utils/select-output-type.d.ts.map +0 -1
  200. package/dist/src/utils/select-output-type.js +0 -153
  201. package/dist/src/utils/select-output-type.js.map +0 -1
  202. package/dist/src/utils/tlru.d.ts +0 -15
  203. package/dist/src/utils/tlru.d.ts.map +0 -1
  204. package/dist/src/utils/tlru.js +0 -34
  205. package/dist/src/utils/tlru.js.map +0 -1
  206. package/dist/src/utils/walk-path.d.ts +0 -27
  207. package/dist/src/utils/walk-path.d.ts.map +0 -1
  208. package/dist/src/utils/walk-path.js +0 -45
  209. package/dist/src/utils/walk-path.js.map +0 -1
  210. package/src/plugins/plugin-handle-byte-range-context.ts +0 -30
  211. package/src/plugins/plugin-handle-cbor.ts +0 -107
  212. package/src/plugins/plugin-handle-dag-cbor-html-preview.ts +0 -295
  213. package/src/plugins/plugin-handle-dag-cbor.ts +0 -83
  214. package/src/plugins/plugin-handle-dag-pb.ts +0 -248
  215. package/src/plugins/plugin-handle-dag-walk.ts +0 -110
  216. package/src/plugins/plugin-handle-dir-index-html.ts +0 -72
  217. package/src/plugins/plugin-handle-json.ts +0 -80
  218. package/src/plugins/plugin-handle-raw.ts +0 -110
  219. package/src/plugins/plugins.ts +0 -5
  220. package/src/utils/byte-range-context.ts +0 -597
  221. package/src/utils/dag-cbor-to-safe-json.ts +0 -63
  222. package/src/utils/dir-index-html.ts +0 -505
  223. package/src/utils/get-peer-id-from-string.ts +0 -12
  224. package/src/utils/get-resolved-accept-header.ts +0 -42
  225. package/src/utils/get-stream-from-async-iterable.ts +0 -49
  226. package/src/utils/handle-redirects.ts +0 -109
  227. package/src/utils/is-accept-explicit.ts +0 -38
  228. package/src/utils/request-headers.ts +0 -65
  229. package/src/utils/select-output-type.ts +0 -175
  230. package/src/utils/tlru.ts +0 -42
  231. package/src/utils/walk-path.ts +0 -69
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin-handle-raw.js","sourceRoot":"","sources":["../../../src/plugins/plugin-handle-raw.ts"],"names":[],"mappings":"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"}
@@ -1,6 +0,0 @@
1
- /**
2
- * Export extension (non-default) plugins here
3
- */
4
- export { DirIndexHtmlPlugin, dirIndexHtmlPluginFactory } from './plugin-handle-dir-index-html.js';
5
- export { DagCborHtmlPreviewPlugin, dagCborHtmlPreviewPluginFactory } from './plugin-handle-dag-cbor-html-preview.js';
6
- //# sourceMappingURL=plugins.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../../../src/plugins/plugins.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAA;AACjG,OAAO,EAAE,wBAAwB,EAAE,+BAA+B,EAAE,MAAM,0CAA0C,CAAA"}
@@ -1,6 +0,0 @@
1
- /**
2
- * Export extension (non-default) plugins here
3
- */
4
- export { DirIndexHtmlPlugin, dirIndexHtmlPluginFactory } from './plugin-handle-dir-index-html.js';
5
- export { DagCborHtmlPreviewPlugin, dagCborHtmlPreviewPluginFactory } from './plugin-handle-dag-cbor-html-preview.js';
6
- //# sourceMappingURL=plugins.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugins.js","sourceRoot":"","sources":["../../../src/plugins/plugins.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAA;AACjG,OAAO,EAAE,wBAAwB,EAAE,+BAA+B,EAAE,MAAM,0CAA0C,CAAA"}
@@ -1,103 +0,0 @@
1
- import type { SupportedBodyTypes } from '../index.js';
2
- import type { Logger } from '@libp2p/interface';
3
- interface RequestRange {
4
- start: number | undefined;
5
- end: number | undefined;
6
- }
7
- interface ByteRange extends RequestRange {
8
- size: number | undefined;
9
- }
10
- export declare class ByteRangeContext {
11
- private readonly headers?;
12
- readonly isRangeRequest: boolean;
13
- /**
14
- * This property is purposefully only set in `set fileSize` and should not be set directly.
15
- */
16
- private _fileSize;
17
- private _body;
18
- private readonly rangeRequestHeader;
19
- private readonly log;
20
- /**
21
- * multiPartBoundary is required for multipart responses
22
- */
23
- private readonly multiPartBoundary?;
24
- private readonly requestRanges;
25
- private byteRanges;
26
- readonly isMultiRangeRequest: boolean;
27
- private _isValidRangeRequest;
28
- constructor(logger: Logger, headers?: HeadersInit | undefined);
29
- getByteRanges(): ByteRange[];
30
- /**
31
- * You can pass a function when you need to support multi-range requests but have your own slicing logic, such as in the case of dag-pb/unixfs.
32
- *
33
- * @param bodyOrProvider - A supported body type or a function that returns a supported body type.
34
- * @param contentType - The content type of the body.
35
- */
36
- setBody(bodyOrProvider: SupportedBodyTypes | ((range: ByteRange) => AsyncGenerator<Uint8Array, void, unknown>), contentType?: string): void;
37
- getBody(responseContentType?: string): SupportedBodyTypes;
38
- private getSlicedBody;
39
- /**
40
- * Sometimes, we need to set the fileSize explicitly because we can't calculate
41
- * the size of the body (e.g. for unixfs content where we call .stat).
42
- *
43
- * This fileSize should otherwise only be called from `setBody`.
44
- */
45
- setFileSize(size: number | bigint | null): void;
46
- getFileSize(): number | null | undefined;
47
- private isValidByteStart;
48
- private isValidByteEnd;
49
- private isValidByteRange;
50
- /**
51
- * We may get the values required to determine if this is a valid range request at different times
52
- * so we need to calculate it when asked.
53
- */
54
- get isValidRangeRequest(): boolean;
55
- /**
56
- * Given all the information we have, this function returns the length that will be used when:
57
- * 1. calling unixfs.cat
58
- * 2. slicing the body
59
- */
60
- getLength(range?: ByteRange): number | undefined;
61
- /**
62
- * Converts a range request header into helia/unixfs supported range options
63
- * Note that the gateway specification says we "MAY" support multiple ranges (https://specs.ipfs.tech/http-gateways/path-gateway/#range-request-header) but we don't
64
- *
65
- * Also note that @helia/unixfs and ipfs-unixfs-exporter expect length and offset to be numbers, the range header is a string, and the size of the resource is likely a bigint.
66
- *
67
- * SUPPORTED:
68
- * Range: bytes=<range-start>-<range-end>
69
- * Range: bytes=<range-start>-
70
- * Range: bytes=-<suffix-length> // must pass size so we can calculate the offset. suffix-length is the number of bytes from the end of the file.
71
- * Range: bytes=<range-start>-<range-end>, <range-start>-<range-end>
72
- * Range: bytes=<range-start>-<range-end>, <range-start>-<range-end>, <range-start>-<range-end>
73
- *
74
- * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range#directives
75
- */
76
- private setOffsetDetails;
77
- /**
78
- * Helper to convert a SliceableBody to a Uint8Array
79
- */
80
- private convertToUint8Array;
81
- private getMultipartBody;
82
- private getSlicedBodyForRange;
83
- /**
84
- * Returns the content type for the response.
85
- * For multipart ranges, this will be multipart/byteranges with a boundary.
86
- */
87
- getContentType(): string | undefined;
88
- /**
89
- * This function returns the value of the "content-range" header.
90
- *
91
- * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range
92
- *
93
- * Returns a string representing the following content ranges:
94
- *
95
- * @example
96
- * - Content-Range: <unit> <byteStart>-<byteEnd>/<byteSize>
97
- * - Content-Range: <unit> <byteStart>-<byteEnd>/*
98
- */
99
- get contentRangeHeaderValue(): string;
100
- private createRangeStream;
101
- }
102
- export {};
103
- //# sourceMappingURL=byte-range-context.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"byte-range-context.d.ts","sourceRoot":"","sources":["../../../src/utils/byte-range-context.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAI/C,UAAU,YAAY;IACpB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;IACzB,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CACxB;AAED,UAAU,SAAU,SAAQ,YAAY;IACtC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;CACzB;AAuDD,qBAAa,gBAAgB;IAqBE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IApBtD,SAAgB,cAAc,EAAE,OAAO,CAAA;IAEvC;;OAEG;IACH,OAAO,CAAC,SAAS,CAA2B;IAC5C,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAoB;IACvD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAQ;IAC3C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA0D;IACxF,OAAO,CAAC,UAAU,CAAkB;IACpC,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAQ;IAG7C,OAAO,CAAC,oBAAoB,CAAiB;gBAEhC,MAAM,EAAE,MAAM,EAAmB,OAAO,CAAC,EAAE,WAAW,YAAA;IA8B5D,aAAa,IAAK,SAAS,EAAE;IAIpC;;;;;OAKG;IACI,OAAO,CACZ,cAAc,EAAE,kBAAkB,GAAG,CAAC,CAAC,KAAK,EAAE,SAAS,KAAK,cAAc,CAAC,UAAU,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,EACtG,WAAW,GAAE,MAAmC,GAC/C,IAAI;IAaA,OAAO,CAAE,mBAAmB,CAAC,EAAE,MAAM,GAAG,kBAAkB;IAsCjE,OAAO,CAAC,aAAa;IA+BrB;;;;;OAKG;IACI,WAAW,CAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,IAAI;IAQhD,WAAW,IAAK,MAAM,GAAG,IAAI,GAAG,SAAS;IAIhD,OAAO,CAAC,gBAAgB;IAexB,OAAO,CAAC,cAAc;IAkBtB,OAAO,CAAC,gBAAgB;IAcxB;;;OAGG;IACH,IAAW,mBAAmB,IAAK,OAAO,CAuBzC;IAcD;;;;OAIG;IACI,SAAS,CAAE,KAAK,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS;IA0BxD;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,gBAAgB;IAwBxB;;OAEG;YACW,mBAAmB;YAwBjB,gBAAgB;IAyChC,OAAO,CAAC,qBAAqB;IAwB7B;;;OAGG;IACI,cAAc,IAAK,MAAM,GAAG,SAAS;IAO5C;;;;;;;;;;OAUG;IAEH,IAAW,uBAAuB,IAAK,MAAM,CAuB5C;IAGD,OAAO,CAAC,iBAAiB;CA8D1B"}
@@ -1,504 +0,0 @@
1
- import toBrowserReadableStream from 'it-to-browser-readablestream';
2
- import { InvalidRangeError } from '../errors.js';
3
- import { calculateByteRangeIndexes, getHeader } from './request-headers.js';
4
- import { getContentRangeHeader } from './response-headers.js';
5
- /**
6
- * Gets the body size of a given body if it's possible to calculate it synchronously.
7
- */
8
- function getBodySizeSync(body) {
9
- if (typeof body === 'string') {
10
- return body.length;
11
- }
12
- if (body instanceof ArrayBuffer || body instanceof Uint8Array) {
13
- return body.byteLength;
14
- }
15
- if (body instanceof Blob) {
16
- return body.size;
17
- }
18
- if (body instanceof ReadableStream) {
19
- return null;
20
- }
21
- return null;
22
- }
23
- function getByteRangeFromHeader(rangeHeader) {
24
- /**
25
- * Range: bytes=<start>-<end> | bytes=<start2>- | bytes=-<end2> | bytes=<start1>-<end1>,<start2>-<end2>,...
26
- */
27
- if (!rangeHeader.startsWith('bytes=')) {
28
- throw new InvalidRangeError('Invalid range request');
29
- }
30
- const rangesStr = rangeHeader.substring(6); // Remove "bytes=" prefix
31
- const rangeParts = rangesStr.split(',').map(part => part.trim());
32
- const ranges = [];
33
- for (const part of rangeParts) {
34
- const match = part.match(/^(?<start>\d+)?-(?<end>\d+)?$/);
35
- if (match?.groups == null) {
36
- throw new InvalidRangeError(`Invalid range specification: ${part}`);
37
- }
38
- const { start, end } = match.groups;
39
- ranges.push({
40
- start: start ?? null,
41
- end: end ?? null
42
- });
43
- }
44
- if (ranges.length === 0) {
45
- throw new InvalidRangeError('No valid ranges found');
46
- }
47
- return { ranges };
48
- }
49
- export class ByteRangeContext {
50
- headers;
51
- isRangeRequest;
52
- /**
53
- * This property is purposefully only set in `set fileSize` and should not be set directly.
54
- */
55
- _fileSize;
56
- _body = null;
57
- rangeRequestHeader;
58
- log;
59
- /**
60
- * multiPartBoundary is required for multipart responses
61
- */
62
- multiPartBoundary;
63
- requestRanges = [];
64
- byteRanges = [];
65
- isMultiRangeRequest = false;
66
- // to be set by isValidRangeRequest so that we don't need to re-check the byteRanges
67
- _isValidRangeRequest = false;
68
- constructor(logger, headers) {
69
- this.headers = headers;
70
- this.log = logger.newScope('byte-range-context');
71
- this.rangeRequestHeader = getHeader(this.headers, 'Range');
72
- if (this.rangeRequestHeader != null) {
73
- this.isRangeRequest = true;
74
- this.log.trace('range request detected');
75
- try {
76
- const { ranges } = getByteRangeFromHeader(this.rangeRequestHeader);
77
- this.isMultiRangeRequest = ranges.length > 1;
78
- this.requestRanges = ranges.map(range => ({
79
- start: range.start != null ? parseInt(range.start) : null,
80
- end: range.end != null ? parseInt(range.end) : null
81
- }));
82
- this.multiPartBoundary = `multipart_byteranges_${Math.floor(Math.random() * 1000000000)}`;
83
- }
84
- catch (e) {
85
- this.log.error('error parsing range request header - %e', e);
86
- this.requestRanges = [];
87
- }
88
- this.setOffsetDetails();
89
- }
90
- else {
91
- this.log.trace('no range request detected');
92
- this.isRangeRequest = false;
93
- }
94
- }
95
- getByteRanges() {
96
- return this.byteRanges;
97
- }
98
- /**
99
- * You can pass a function when you need to support multi-range requests but have your own slicing logic, such as in the case of dag-pb/unixfs.
100
- *
101
- * @param bodyOrProvider - A supported body type or a function that returns a supported body type.
102
- * @param contentType - The content type of the body.
103
- */
104
- setBody(bodyOrProvider, contentType = 'application/octet-stream') {
105
- if (typeof bodyOrProvider === 'function') {
106
- this._body = this.createRangeStream(bodyOrProvider, contentType);
107
- }
108
- else {
109
- this._body = bodyOrProvider;
110
- // if fileSize was already set, don't recalculate it
111
- this.setFileSize(this._fileSize ?? getBodySizeSync(bodyOrProvider));
112
- }
113
- this.log.trace('set request body with fileSize %o', this._fileSize);
114
- }
115
- getBody(responseContentType) {
116
- const body = this._body;
117
- if (body == null) {
118
- this.log.trace('body is null');
119
- return body;
120
- }
121
- if (!this.isRangeRequest || !this.isValidRangeRequest) {
122
- this.log.trace('returning body unmodified for non-range, or invalid range, request');
123
- return body;
124
- }
125
- if (this.isMultiRangeRequest) {
126
- if (this._body instanceof ReadableStream) {
127
- return this._body;
128
- }
129
- return toBrowserReadableStream(this.getMultipartBody(responseContentType));
130
- }
131
- // Single range request handling
132
- if (this.byteRanges.length > 0) {
133
- const range = this.byteRanges[0];
134
- if (body instanceof ReadableStream) {
135
- // stream should already be spliced by `unixfs.cat`
136
- // TODO: if the content is not unixfs and unixfs.cat was not called, we need to slice the body here.
137
- return body;
138
- }
139
- if (range.start != null || range.end != null) {
140
- this.log.trace('returning body with byteStart=%o, byteEnd=%o, byteSize=%o', range.start, range.end, range.size);
141
- }
142
- return this.getSlicedBody(body, range);
143
- }
144
- // we should not reach this point, but return body untouched.
145
- this.log.error('returning unmodified body for valid range request');
146
- return body;
147
- }
148
- getSlicedBody(body, range) {
149
- const offset = range.start ?? 0;
150
- // Calculate the correct number of bytes to return
151
- // For a range like bytes=1000-2000, we want exactly 1001 bytes
152
- let length;
153
- if (range.end != null && range.start != null) {
154
- // Exact number of bytes is (end - start + 1) due to inclusive ranges
155
- length = range.end - range.start + 1;
156
- }
157
- else {
158
- length = undefined;
159
- }
160
- this.log.trace('slicing body with offset=%o and length=%o', offset, length);
161
- if (typeof body === 'string') {
162
- // String slicing works with start and end indices
163
- return body.slice(offset, length !== undefined ? offset + length : undefined);
164
- }
165
- else if (body instanceof Blob) {
166
- // Blob.slice takes start and end positions
167
- return body.slice(offset, length !== undefined ? offset + length : undefined);
168
- }
169
- else if (body instanceof ArrayBuffer || body instanceof Uint8Array) {
170
- // ArrayBuffer.slice and Uint8Array.slice take start and end positions
171
- return body.slice(offset, length !== undefined ? offset + length : undefined);
172
- }
173
- // This should never happen due to type constraints
174
- return body;
175
- }
176
- /**
177
- * Sometimes, we need to set the fileSize explicitly because we can't calculate
178
- * the size of the body (e.g. for unixfs content where we call .stat).
179
- *
180
- * This fileSize should otherwise only be called from `setBody`.
181
- */
182
- setFileSize(size) {
183
- this._fileSize = size != null ? Number(size) : null;
184
- this._isValidRangeRequest = false; // body has changed, so we need to re-validate the byte ranges
185
- this.log.trace('set _fileSize to %o', this._fileSize);
186
- // when fileSize changes, we need to recalculate the offset details
187
- this.setOffsetDetails();
188
- }
189
- getFileSize() {
190
- return this._fileSize;
191
- }
192
- isValidByteStart(byteStart, byteEnd) {
193
- if (byteStart != null) {
194
- if (byteStart < 0) {
195
- return false;
196
- }
197
- if (this._fileSize != null && byteStart >= this._fileSize) {
198
- return false;
199
- }
200
- if (byteEnd != null && byteStart > byteEnd) {
201
- return false;
202
- }
203
- }
204
- return true;
205
- }
206
- isValidByteEnd(byteStart, byteEnd) {
207
- if (byteEnd != null) {
208
- if (byteEnd < 0) {
209
- this.log.trace('invalid range request, byteEnd is less than 0');
210
- return false;
211
- }
212
- if (this._fileSize != null && byteEnd >= this._fileSize) {
213
- this.log.trace('invalid range request, byteEnd is greater than fileSize');
214
- return false;
215
- }
216
- if (byteStart != null && byteEnd < byteStart) {
217
- this.log.trace('invalid range request, byteEnd is less than byteStart');
218
- return false;
219
- }
220
- }
221
- return true;
222
- }
223
- isValidByteRange(range) {
224
- this.log.trace('validating byte range: %o', range);
225
- if (range.start != null && !this.isValidByteStart(range.start, range.end)) {
226
- this.log.trace('invalid range request, byteStart is less than 0 or greater than fileSize');
227
- return false;
228
- }
229
- if (range.end != null && !this.isValidByteEnd(range.start, range.end)) {
230
- this.log.trace('invalid range request, byteEnd is less than 0 or greater than fileSize');
231
- return false;
232
- }
233
- return true;
234
- }
235
- /**
236
- * We may get the values required to determine if this is a valid range request at different times
237
- * so we need to calculate it when asked.
238
- */
239
- get isValidRangeRequest() {
240
- if (this._isValidRangeRequest) {
241
- // prevent unnecessary re-validation of each byte range
242
- return true;
243
- }
244
- if (!this.isRangeRequest) {
245
- return false;
246
- }
247
- if (this.byteRanges.length === 0) {
248
- this.log.trace('invalid range request, no valid ranges');
249
- return false;
250
- }
251
- const isValid = this.byteRanges.every(range => this.isValidByteRange(range));
252
- if (!isValid) {
253
- this.log.trace('invalid range request, not all ranges are valid');
254
- return false;
255
- }
256
- this._isValidRangeRequest = true;
257
- return true;
258
- }
259
- // /**
260
- // * Given all the information we have, this function returns the offset that will be used when:
261
- // * 1. calling unixfs.cat
262
- // * 2. slicing the body
263
- // */
264
- // public offset (range: ByteRange): number {
265
- // if (this.byteRanges.length > 0) {
266
- // return this.byteRanges[0].start ?? 0
267
- // }
268
- // return 0
269
- // }
270
- /**
271
- * Given all the information we have, this function returns the length that will be used when:
272
- * 1. calling unixfs.cat
273
- * 2. slicing the body
274
- */
275
- getLength(range) {
276
- if (!this.isValidRangeRequest) {
277
- this.log.error('cannot get length for invalid range request');
278
- return undefined;
279
- }
280
- if (this.isMultiRangeRequest && range == null) {
281
- /**
282
- * The content-length for a multi-range request is the sum of the lengths of all the ranges, plus the boundaries and part headers and newlines.
283
- */
284
- // TODO: figure out a way to calculate the correct content-length for multi-range requests' response.
285
- return undefined;
286
- }
287
- range ??= this.byteRanges[0];
288
- this.log.trace('getting length for range: %o', range);
289
- if (range.end != null && range.start != null) {
290
- // For a range like bytes=1000-2000, we want a length of 1001 bytes
291
- return range.end - range.start + 1;
292
- }
293
- if (range.end != null) {
294
- return range.end + 1;
295
- }
296
- return range.size;
297
- }
298
- /**
299
- * Converts a range request header into helia/unixfs supported range options
300
- * Note that the gateway specification says we "MAY" support multiple ranges (https://specs.ipfs.tech/http-gateways/path-gateway/#range-request-header) but we don't
301
- *
302
- * Also note that @helia/unixfs and ipfs-unixfs-exporter expect length and offset to be numbers, the range header is a string, and the size of the resource is likely a bigint.
303
- *
304
- * SUPPORTED:
305
- * Range: bytes=<range-start>-<range-end>
306
- * Range: bytes=<range-start>-
307
- * Range: bytes=-<suffix-length> // must pass size so we can calculate the offset. suffix-length is the number of bytes from the end of the file.
308
- * Range: bytes=<range-start>-<range-end>, <range-start>-<range-end>
309
- * Range: bytes=<range-start>-<range-end>, <range-start>-<range-end>, <range-start>-<range-end>
310
- *
311
- * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range#directives
312
- */
313
- setOffsetDetails() {
314
- if (this.requestRanges.length === 0) {
315
- this.log.trace('no request ranges defined');
316
- return;
317
- }
318
- try {
319
- // Calculate byte ranges for all requests
320
- this.byteRanges = this.requestRanges.map(range => {
321
- const { start, end, byteSize } = calculateByteRangeIndexes(range.start ?? undefined, range.end ?? undefined, this._fileSize ?? undefined);
322
- return { start, end, size: byteSize };
323
- });
324
- this.log.trace('set byte ranges: %o', this.byteRanges);
325
- }
326
- catch (e) {
327
- this.log.error('error setting offset details: %o', e);
328
- this.byteRanges = [];
329
- }
330
- }
331
- /**
332
- * Helper to convert a SliceableBody to a Uint8Array
333
- */
334
- async convertToUint8Array(content) {
335
- if (typeof content === 'string') {
336
- return new TextEncoder().encode(content);
337
- }
338
- if ('arrayBuffer' in content && typeof content.arrayBuffer === 'function') {
339
- // This is a Blob
340
- const buffer = await content.arrayBuffer();
341
- return new Uint8Array(buffer);
342
- }
343
- if ('byteLength' in content && !('buffer' in content)) {
344
- // This is an ArrayBuffer
345
- return new Uint8Array(content);
346
- }
347
- if ('buffer' in content && 'byteLength' in content && 'byteOffset' in content) {
348
- // This is a Uint8Array
349
- return content;
350
- }
351
- throw new Error('Unsupported content type for multipart response');
352
- }
353
- async *getMultipartBody(responseContentType = 'application/octet-stream') {
354
- const body = this._body;
355
- if (body instanceof ReadableStream) {
356
- // in the case of unixfs, the body is a readable stream, and setBody is called with a function that returns a readable stream that generates the
357
- // correct multipartBody.. so we just return that body.
358
- return body;
359
- }
360
- if (body === null) {
361
- throw new Error('Cannot create multipart body from null');
362
- }
363
- const encoder = new TextEncoder();
364
- for (const range of this.byteRanges) {
365
- if (range.start === undefined || range.end === undefined) {
366
- continue;
367
- }
368
- // Calculate part headers
369
- const partHeaderString = `\r\n--${this.multiPartBoundary}\r\n` +
370
- `Content-Type: ${responseContentType}\r\n` +
371
- `Content-Range: ${getContentRangeHeader({
372
- byteStart: range.start,
373
- byteEnd: range.end,
374
- byteSize: this._fileSize ?? undefined
375
- })}\r\n\r\n`;
376
- // Convert header to Uint8Array
377
- yield encoder.encode(partHeaderString);
378
- // Get content for this range and convert to Uint8Array
379
- const slicedContent = this.getSlicedBodyForRange(body, range.start, range.end);
380
- yield await this.convertToUint8Array(slicedContent);
381
- }
382
- // Add final this.multiPartBoundary
383
- yield encoder.encode(`\r\n--${this.multiPartBoundary}--`);
384
- }
385
- getSlicedBodyForRange(body, start, end) {
386
- // Calculate the correct number of bytes to return
387
- // For a range like bytes=1000-2000, we want exactly 1001 bytes
388
- const offset = start;
389
- const length = end - start + 1;
390
- this.log.trace('slicing body with offset=%o and length=%o', offset, length);
391
- if (typeof body === 'string') {
392
- return body.slice(offset, offset + length);
393
- }
394
- else if (body instanceof Blob) {
395
- return body.slice(offset, offset + length);
396
- }
397
- else if (body instanceof ArrayBuffer || body instanceof Uint8Array) {
398
- return body.slice(offset, offset + length);
399
- }
400
- else {
401
- // This should never happen due to type constraints
402
- return body;
403
- }
404
- }
405
- /**
406
- * Returns the content type for the response.
407
- * For multipart ranges, this will be multipart/byteranges with a boundary.
408
- */
409
- getContentType() {
410
- if (this.isMultiRangeRequest && this.isValidRangeRequest) {
411
- return `multipart/byteranges; boundary=${this.multiPartBoundary}`;
412
- }
413
- return undefined;
414
- }
415
- /**
416
- * This function returns the value of the "content-range" header.
417
- *
418
- * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range
419
- *
420
- * Returns a string representing the following content ranges:
421
- *
422
- * @example
423
- * - Content-Range: <unit> <byteStart>-<byteEnd>/<byteSize>
424
- * - Content-Range: <unit> <byteStart>-<byteEnd>/*
425
- */
426
- // - Content-Range: <unit> */<byteSize> // this is purposefully not in jsdoc block
427
- get contentRangeHeaderValue() {
428
- // For multipart responses, this will be included in each part
429
- // So this method is only used for single-range responses
430
- if (!this.isValidRangeRequest) {
431
- this.log.error('cannot get contentRangeHeaderValue for invalid range request');
432
- throw new InvalidRangeError('Invalid range request');
433
- }
434
- if (this.isMultiRangeRequest) {
435
- this.log.error('contentRangeHeaderValue should not be called for multipart responses');
436
- throw new InvalidRangeError('Content-Range header not applicable for multipart responses');
437
- }
438
- if (this.byteRanges.length > 0) {
439
- const range = this.byteRanges[0];
440
- return getContentRangeHeader({
441
- byteStart: range.start,
442
- byteEnd: range.end,
443
- byteSize: this._fileSize ?? undefined
444
- });
445
- }
446
- throw new InvalidRangeError('No valid ranges found');
447
- }
448
- // Unified method to create a stream for either single or multi-range requests
449
- createRangeStream(contentProvider, contentType) {
450
- const encoder = new TextEncoder();
451
- const byteRanges = this.byteRanges;
452
- const multiPartBoundary = this.multiPartBoundary;
453
- const fileSize = this._fileSize;
454
- const log = this.log;
455
- const isMultiRangeRequest = this.isMultiRangeRequest;
456
- if (byteRanges.length === 0) {
457
- // TODO: create a stream with a range of *
458
- log.error('Cannot create range stream with no byte ranges');
459
- throw new InvalidRangeError('No valid ranges found');
460
- }
461
- return new ReadableStream({
462
- async start(controller) {
463
- try {
464
- // For multi-range requests, we need to handle multiple parts with headers
465
- for (const range of byteRanges) {
466
- // Write part header for multipart responses
467
- if (isMultiRangeRequest) {
468
- const partHeader = `\r\n--${multiPartBoundary}\r\n` +
469
- `Content-Type: ${contentType}\r\n` +
470
- `Content-Range: ${getContentRangeHeader({
471
- byteStart: range.start,
472
- byteEnd: range.end,
473
- byteSize: fileSize ?? undefined
474
- })}\r\n\r\n`;
475
- controller.enqueue(encoder.encode(partHeader));
476
- }
477
- // Get and stream content for this range
478
- try {
479
- // Get content for this range
480
- const rangeContent = contentProvider(range);
481
- for await (const chunk of rangeContent) {
482
- controller.enqueue(chunk);
483
- }
484
- }
485
- catch (err) {
486
- log.error('Error processing range %o: %o', range, err);
487
- throw err; // Re-throw to be caught by the outer try/catch
488
- }
489
- }
490
- if (isMultiRangeRequest) {
491
- // Write final boundary for multipart
492
- controller.enqueue(encoder.encode(`\r\n--${multiPartBoundary}--`));
493
- }
494
- controller.close();
495
- }
496
- catch (err) {
497
- log.error('Error processing range(s) - %e', err);
498
- controller.error(err);
499
- }
500
- }
501
- });
502
- }
503
- }
504
- //# sourceMappingURL=byte-range-context.js.map