@helia/verified-fetch 1.1.3 → 1.2.1

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/dist/index.min.js +7 -7
  2. package/dist/src/types.d.ts +1 -0
  3. package/dist/src/types.d.ts.map +1 -1
  4. package/dist/src/utils/byte-range-context.d.ts +80 -0
  5. package/dist/src/utils/byte-range-context.d.ts.map +1 -0
  6. package/dist/src/utils/byte-range-context.js +277 -0
  7. package/dist/src/utils/byte-range-context.js.map +1 -0
  8. package/dist/src/utils/get-stream-from-async-iterable.js +1 -1
  9. package/dist/src/utils/parse-url-string.js +4 -4
  10. package/dist/src/utils/request-headers.d.ts +13 -0
  11. package/dist/src/utils/request-headers.d.ts.map +1 -0
  12. package/dist/src/utils/request-headers.js +62 -0
  13. package/dist/src/utils/request-headers.js.map +1 -0
  14. package/dist/src/utils/response-headers.d.ts +12 -0
  15. package/dist/src/utils/response-headers.d.ts.map +1 -0
  16. package/dist/src/utils/response-headers.js +37 -0
  17. package/dist/src/utils/response-headers.js.map +1 -0
  18. package/dist/src/utils/responses.d.ts +21 -4
  19. package/dist/src/utils/responses.d.ts.map +1 -1
  20. package/dist/src/utils/responses.js +58 -0
  21. package/dist/src/utils/responses.js.map +1 -1
  22. package/dist/src/verified-fetch.d.ts.map +1 -1
  23. package/dist/src/verified-fetch.js +60 -18
  24. package/dist/src/verified-fetch.js.map +1 -1
  25. package/package.json +1 -1
  26. package/src/types.ts +2 -0
  27. package/src/utils/byte-range-context.ts +301 -0
  28. package/src/utils/get-stream-from-async-iterable.ts +1 -1
  29. package/src/utils/parse-url-string.ts +4 -4
  30. package/src/utils/request-headers.ts +63 -0
  31. package/src/utils/response-headers.ts +42 -0
  32. package/src/utils/responses.ts +82 -4
  33. package/src/verified-fetch.ts +65 -21
@@ -1,2 +1,3 @@
1
1
  export type RequestFormatShorthand = 'raw' | 'car' | 'tar' | 'ipns-record' | 'dag-json' | 'dag-cbor' | 'json' | 'cbor';
2
+ export type SupportedBodyTypes = string | ArrayBuffer | Blob | ReadableStream<Uint8Array> | null;
2
3
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,sBAAsB,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,aAAa,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,sBAAsB,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,aAAa,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAA;AAEtH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,WAAW,GAAG,IAAI,GAAG,cAAc,CAAC,UAAU,CAAC,GAAG,IAAI,CAAA"}
@@ -0,0 +1,80 @@
1
+ import type { SupportedBodyTypes } from '../types.js';
2
+ import type { ComponentLogger } from '@libp2p/interface';
3
+ export declare class ByteRangeContext {
4
+ private readonly headers?;
5
+ readonly isRangeRequest: boolean;
6
+ /**
7
+ * This property is purposefully only set in `set fileSize` and should not be set directly.
8
+ */
9
+ private _fileSize;
10
+ private _body;
11
+ private readonly rangeRequestHeader;
12
+ private readonly log;
13
+ private readonly requestRangeStart;
14
+ private readonly requestRangeEnd;
15
+ private byteStart;
16
+ private byteEnd;
17
+ private byteSize;
18
+ constructor(logger: ComponentLogger, headers?: HeadersInit | undefined);
19
+ setBody(body: SupportedBodyTypes): void;
20
+ getBody(): SupportedBodyTypes;
21
+ private getSlicedBody;
22
+ /**
23
+ * Sometimes, we need to set the fileSize explicitly because we can't calculate
24
+ * the size of the body (e.g. for unixfs content where we call .stat).
25
+ *
26
+ * This fileSize should otherwise only be called from `setBody`.
27
+ */
28
+ setFileSize(size: number | bigint | null): void;
29
+ getFileSize(): number | null | undefined;
30
+ private isValidByteStart;
31
+ private isValidByteEnd;
32
+ /**
33
+ * We may get the values required to determine if this is a valid range request at different times
34
+ * so we need to calculate it when asked.
35
+ */
36
+ get isValidRangeRequest(): boolean;
37
+ /**
38
+ * Given all the information we have, this function returns the offset that will be used when:
39
+ * 1. calling unixfs.cat
40
+ * 2. slicing the body
41
+ */
42
+ get offset(): number;
43
+ /**
44
+ * Given all the information we have, this function returns the length that will be used when:
45
+ * 1. calling unixfs.cat
46
+ * 2. slicing the body
47
+ */
48
+ get length(): number | undefined;
49
+ /**
50
+ * Converts a range request header into helia/unixfs supported range options
51
+ * 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
52
+ *
53
+ * 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.
54
+ *
55
+ * SUPPORTED:
56
+ * Range: bytes=<range-start>-<range-end>
57
+ * Range: bytes=<range-start>-
58
+ * 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.
59
+ *
60
+ * NOT SUPPORTED:
61
+ * Range: bytes=<range-start>-<range-end>, <range-start>-<range-end>
62
+ * Range: bytes=<range-start>-<range-end>, <range-start>-<range-end>, <range-start>-<range-end>
63
+ *
64
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range#directives
65
+ */
66
+ private setOffsetDetails;
67
+ /**
68
+ * This function returns the value of the "content-range" header.
69
+ *
70
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range
71
+ *
72
+ * Returns a string representing the following content ranges:
73
+ *
74
+ * @example
75
+ * - Content-Range: <unit> <byteStart>-<byteEnd>/<byteSize>
76
+ * - Content-Range: <unit> <byteStart>-<byteEnd>/*
77
+ */
78
+ get contentRangeHeaderValue(): string;
79
+ }
80
+ //# sourceMappingURL=byte-range-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"byte-range-context.d.ts","sourceRoot":"","sources":["../../../src/utils/byte-range-context.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,KAAK,EAAE,eAAe,EAAU,MAAM,mBAAmB,CAAA;AAuChE,qBAAa,gBAAgB;IAgBW,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IAf/D,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,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAe;IACjD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAe;IAC/C,OAAO,CAAC,SAAS,CAAoB;IACrC,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,QAAQ,CAAoB;gBAEvB,MAAM,EAAE,eAAe,EAAmB,OAAO,CAAC,yBAAa;IAyBrE,OAAO,CAAE,IAAI,EAAE,kBAAkB,GAAG,IAAI;IAQxC,OAAO,IAAK,kBAAkB;IA4BrC,OAAO,CAAC,aAAa;IAOrB;;;;;OAKG;IACI,WAAW,CAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,IAAI;IAOhD,WAAW,IAAK,MAAM,GAAG,IAAI,GAAG,SAAS;IAIhD,OAAO,CAAC,gBAAgB;IAexB,OAAO,CAAC,cAAc;IAetB;;;OAGG;IACH,IAAW,mBAAmB,IAAK,OAAO,CAmCzC;IAED;;;;OAIG;IACH,IAAW,MAAM,IAAK,MAAM,CAE3B;IAED;;;;OAIG;IACH,IAAW,MAAM,IAAK,MAAM,GAAG,SAAS,CASvC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,gBAAgB;IAoBxB;;;;;;;;;;OAUG;IAEH,IAAW,uBAAuB,IAAK,MAAM,CAW5C;CACF"}
@@ -0,0 +1,277 @@
1
+ import { calculateByteRangeIndexes, getHeader } from './request-headers.js';
2
+ import { getContentRangeHeader } from './response-headers.js';
3
+ /**
4
+ * Gets the body size of a given body if it's possible to calculate it synchronously.
5
+ */
6
+ function getBodySizeSync(body) {
7
+ if (typeof body === 'string') {
8
+ return body.length;
9
+ }
10
+ if (body instanceof ArrayBuffer || body instanceof Uint8Array) {
11
+ return body.byteLength;
12
+ }
13
+ if (body instanceof Blob) {
14
+ return body.size;
15
+ }
16
+ if (body instanceof ReadableStream) {
17
+ return null;
18
+ }
19
+ return null;
20
+ }
21
+ function getByteRangeFromHeader(rangeHeader) {
22
+ /**
23
+ * Range: bytes=<start>-<end> | bytes=<start2>- | bytes=-<end2>
24
+ */
25
+ const match = rangeHeader.match(/^bytes=(?<start>\d+)?-(?<end>\d+)?$/);
26
+ if (match?.groups == null) {
27
+ throw new Error('Invalid range request');
28
+ }
29
+ const { start, end } = match.groups;
30
+ return { start, end };
31
+ }
32
+ export class ByteRangeContext {
33
+ headers;
34
+ isRangeRequest;
35
+ /**
36
+ * This property is purposefully only set in `set fileSize` and should not be set directly.
37
+ */
38
+ _fileSize;
39
+ _body = null;
40
+ rangeRequestHeader;
41
+ log;
42
+ requestRangeStart;
43
+ requestRangeEnd;
44
+ byteStart;
45
+ byteEnd;
46
+ byteSize;
47
+ constructor(logger, headers) {
48
+ this.headers = headers;
49
+ this.log = logger.forComponent('helia:verified-fetch:byte-range-context');
50
+ this.rangeRequestHeader = getHeader(this.headers, 'Range');
51
+ if (this.rangeRequestHeader != null) {
52
+ this.isRangeRequest = true;
53
+ this.log.trace('range request detected');
54
+ try {
55
+ const { start, end } = getByteRangeFromHeader(this.rangeRequestHeader);
56
+ this.requestRangeStart = start != null ? parseInt(start) : null;
57
+ this.requestRangeEnd = end != null ? parseInt(end) : null;
58
+ }
59
+ catch (e) {
60
+ this.log.error('error parsing range request header: %o', e);
61
+ this.requestRangeStart = null;
62
+ this.requestRangeEnd = null;
63
+ }
64
+ this.setOffsetDetails();
65
+ }
66
+ else {
67
+ this.log.trace('no range request detected');
68
+ this.isRangeRequest = false;
69
+ this.requestRangeStart = null;
70
+ this.requestRangeEnd = null;
71
+ }
72
+ }
73
+ setBody(body) {
74
+ this._body = body;
75
+ // if fileSize was already set, don't recalculate it
76
+ this.setFileSize(this._fileSize ?? getBodySizeSync(body));
77
+ this.log.trace('set request body with fileSize %o', this._fileSize);
78
+ }
79
+ getBody() {
80
+ const body = this._body;
81
+ if (body == null) {
82
+ this.log.trace('body is null');
83
+ return body;
84
+ }
85
+ if (!this.isRangeRequest || !this.isValidRangeRequest) {
86
+ this.log.trace('returning body unmodified for non-range, or invalid range, request');
87
+ return body;
88
+ }
89
+ const byteStart = this.byteStart;
90
+ const byteEnd = this.byteEnd;
91
+ const byteSize = this.byteSize;
92
+ if (byteStart != null || byteEnd != null) {
93
+ this.log.trace('returning body with byteStart=%o, byteEnd=%o, byteSize=%o', byteStart, byteEnd, byteSize);
94
+ if (body instanceof ReadableStream) {
95
+ // stream should already be spliced by `unixfs.cat`
96
+ return body;
97
+ }
98
+ return this.getSlicedBody(body);
99
+ }
100
+ // we should not reach this point, but return body untouched.
101
+ this.log.error('returning unmodified body for valid range request');
102
+ return body;
103
+ }
104
+ // TODO: we should be able to use this.offset and this.length to slice the body
105
+ getSlicedBody(body) {
106
+ const offset = this.byteStart ?? 0;
107
+ const length = this.byteEnd == null ? undefined : this.byteEnd + 1;
108
+ this.log.trace('returning body with offset %o and length %o', offset, length);
109
+ return body.slice(offset, length);
110
+ }
111
+ /**
112
+ * Sometimes, we need to set the fileSize explicitly because we can't calculate
113
+ * the size of the body (e.g. for unixfs content where we call .stat).
114
+ *
115
+ * This fileSize should otherwise only be called from `setBody`.
116
+ */
117
+ setFileSize(size) {
118
+ this._fileSize = size != null ? Number(size) : null;
119
+ this.log.trace('set _fileSize to %o', this._fileSize);
120
+ // when fileSize changes, we need to recalculate the offset details
121
+ this.setOffsetDetails();
122
+ }
123
+ getFileSize() {
124
+ return this._fileSize;
125
+ }
126
+ isValidByteStart() {
127
+ if (this.byteStart != null) {
128
+ if (this.byteStart < 0) {
129
+ return false;
130
+ }
131
+ if (this._fileSize != null && this.byteStart >= this._fileSize) {
132
+ return false;
133
+ }
134
+ if (this.byteEnd != null && this.byteStart > this.byteEnd) {
135
+ return false;
136
+ }
137
+ }
138
+ return true;
139
+ }
140
+ isValidByteEnd() {
141
+ if (this.byteEnd != null) {
142
+ if (this.byteEnd < 0) {
143
+ return false;
144
+ }
145
+ if (this._fileSize != null && this.byteEnd >= this._fileSize) {
146
+ return false;
147
+ }
148
+ if (this.byteStart != null && this.byteEnd < this.byteStart) {
149
+ return false;
150
+ }
151
+ }
152
+ return true;
153
+ }
154
+ /**
155
+ * We may get the values required to determine if this is a valid range request at different times
156
+ * so we need to calculate it when asked.
157
+ */
158
+ get isValidRangeRequest() {
159
+ if (!this.isRangeRequest) {
160
+ return false;
161
+ }
162
+ if (this.requestRangeStart == null && this.requestRangeEnd == null) {
163
+ this.log.trace('invalid range request, range request values not provided');
164
+ return false;
165
+ }
166
+ if (!this.isValidByteStart()) {
167
+ this.log.trace('invalid range request, byteStart is less than 0 or greater than fileSize');
168
+ return false;
169
+ }
170
+ if (!this.isValidByteEnd()) {
171
+ this.log.trace('invalid range request, byteEnd is less than 0 or greater than fileSize');
172
+ return false;
173
+ }
174
+ if (this.requestRangeEnd != null && this.requestRangeStart != null) {
175
+ // we may not have enough info.. base check on requested bytes
176
+ if (this.requestRangeStart > this.requestRangeEnd) {
177
+ this.log.trace('invalid range request, start is greater than end');
178
+ return false;
179
+ }
180
+ else if (this.requestRangeStart < 0) {
181
+ this.log.trace('invalid range request, start is less than 0');
182
+ return false;
183
+ }
184
+ else if (this.requestRangeEnd < 0) {
185
+ this.log.trace('invalid range request, end is less than 0');
186
+ return false;
187
+ }
188
+ }
189
+ if (this.byteEnd == null && this.byteStart == null && this.byteSize == null) {
190
+ this.log.trace('invalid range request, could not calculate byteStart, byteEnd, or byteSize');
191
+ return false;
192
+ }
193
+ return true;
194
+ }
195
+ /**
196
+ * Given all the information we have, this function returns the offset that will be used when:
197
+ * 1. calling unixfs.cat
198
+ * 2. slicing the body
199
+ */
200
+ get offset() {
201
+ return this.byteStart ?? 0;
202
+ }
203
+ /**
204
+ * Given all the information we have, this function returns the length that will be used when:
205
+ * 1. calling unixfs.cat
206
+ * 2. slicing the body
207
+ */
208
+ get length() {
209
+ if (this.byteEnd != null && this.byteStart != null && this.byteStart === this.byteEnd) {
210
+ return 1;
211
+ }
212
+ if (this.byteEnd != null) {
213
+ return this.byteEnd + 1;
214
+ }
215
+ return this.byteSize != null ? this.byteSize - 1 : undefined;
216
+ }
217
+ /**
218
+ * Converts a range request header into helia/unixfs supported range options
219
+ * 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
220
+ *
221
+ * 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.
222
+ *
223
+ * SUPPORTED:
224
+ * Range: bytes=<range-start>-<range-end>
225
+ * Range: bytes=<range-start>-
226
+ * 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.
227
+ *
228
+ * NOT SUPPORTED:
229
+ * Range: bytes=<range-start>-<range-end>, <range-start>-<range-end>
230
+ * Range: bytes=<range-start>-<range-end>, <range-start>-<range-end>, <range-start>-<range-end>
231
+ *
232
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range#directives
233
+ */
234
+ setOffsetDetails() {
235
+ if (this.requestRangeStart == null && this.requestRangeEnd == null) {
236
+ this.log.trace('requestRangeStart and requestRangeEnd are null');
237
+ return;
238
+ }
239
+ try {
240
+ const { start, end, byteSize } = calculateByteRangeIndexes(this.requestRangeStart ?? undefined, this.requestRangeEnd ?? undefined, this._fileSize ?? undefined);
241
+ this.log.trace('set byteStart to %o, byteEnd to %o, byteSize to %o', start, end, byteSize);
242
+ this.byteStart = start;
243
+ this.byteEnd = end;
244
+ this.byteSize = byteSize;
245
+ }
246
+ catch (e) {
247
+ this.log.error('error setting offset details: %o', e);
248
+ this.byteStart = undefined;
249
+ this.byteEnd = undefined;
250
+ this.byteSize = undefined;
251
+ }
252
+ }
253
+ /**
254
+ * This function returns the value of the "content-range" header.
255
+ *
256
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range
257
+ *
258
+ * Returns a string representing the following content ranges:
259
+ *
260
+ * @example
261
+ * - Content-Range: <unit> <byteStart>-<byteEnd>/<byteSize>
262
+ * - Content-Range: <unit> <byteStart>-<byteEnd>/*
263
+ */
264
+ // - Content-Range: <unit> */<byteSize> // this is purposefully not in jsdoc block
265
+ get contentRangeHeaderValue() {
266
+ if (!this.isValidRangeRequest) {
267
+ this.log.error('cannot get contentRangeHeaderValue for invalid range request');
268
+ throw new Error('Invalid range request');
269
+ }
270
+ return getContentRangeHeader({
271
+ byteStart: this.byteStart,
272
+ byteEnd: this.byteEnd,
273
+ byteSize: this._fileSize ?? undefined
274
+ });
275
+ }
276
+ }
277
+ //# sourceMappingURL=byte-range-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"byte-range-context.js","sourceRoot":"","sources":["../../../src/utils/byte-range-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAC3E,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAM7D;;GAEG;AACH,SAAS,eAAe,CAAE,IAAwB;IAChD,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,MAAM,CAAA;IACpB,CAAC;IACD,IAAI,IAAI,YAAY,WAAW,IAAI,IAAI,YAAY,UAAU,EAAE,CAAC;QAC9D,OAAO,IAAI,CAAC,UAAU,CAAA;IACxB,CAAC;IACD,IAAI,IAAI,YAAY,IAAI,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC,IAAI,CAAA;IAClB,CAAC;IAED,IAAI,IAAI,YAAY,cAAc,EAAE,CAAC;QACnC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,sBAAsB,CAAE,WAAmB;IAClD;;OAEG;IACH,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAA;IACtE,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAA;IAC1C,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,MAAM,CAAA;IAEnC,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAA;AACvB,CAAC;AAED,MAAM,OAAO,gBAAgB;IAgB4B;IAfvC,cAAc,CAAS;IAEvC;;OAEG;IACK,SAAS,CAA2B;IACpC,KAAK,GAAuB,IAAI,CAAA;IACvB,kBAAkB,CAAoB;IACtC,GAAG,CAAQ;IACX,iBAAiB,CAAe;IAChC,eAAe,CAAe;IACvC,SAAS,CAAoB;IAC7B,OAAO,CAAoB;IAC3B,QAAQ,CAAoB;IAEpC,YAAa,MAAuB,EAAmB,OAAqB;QAArB,YAAO,GAAP,OAAO,CAAc;QAC1E,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,yCAAyC,CAAC,CAAA;QACzE,IAAI,CAAC,kBAAkB,GAAG,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QAC1D,IAAI,IAAI,CAAC,kBAAkB,IAAI,IAAI,EAAE,CAAC;YACpC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAA;YAC1B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAA;YACxC,IAAI,CAAC;gBACH,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,sBAAsB,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;gBACtE,IAAI,CAAC,iBAAiB,GAAG,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;gBAC/D,IAAI,CAAC,eAAe,GAAG,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;YAC3D,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,wCAAwC,EAAE,CAAC,CAAC,CAAA;gBAC3D,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAA;gBAC7B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAA;YAC7B,CAAC;YAED,IAAI,CAAC,gBAAgB,EAAE,CAAA;QACzB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAA;YAC3C,IAAI,CAAC,cAAc,GAAG,KAAK,CAAA;YAC3B,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAA;YAC7B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAA;QAC7B,CAAC;IACH,CAAC;IAEM,OAAO,CAAE,IAAwB;QACtC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;QACjB,oDAAoD;QACpD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,CAAA;QAEzD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,mCAAmC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;IACrE,CAAC;IAEM,OAAO;QACZ,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAA;QACvB,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;YACjB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,CAAA;YAC9B,OAAO,IAAI,CAAA;QACb,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;YACtD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,oEAAoE,CAAC,CAAA;YACpF,OAAO,IAAI,CAAA;QACb,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAA;QAChC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;QAC9B,IAAI,SAAS,IAAI,IAAI,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;YACzC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,2DAA2D,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAA;YACzG,IAAI,IAAI,YAAY,cAAc,EAAE,CAAC;gBACnC,mDAAmD;gBACnD,OAAO,IAAI,CAAA;YACb,CAAC;YACD,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAA;QACjC,CAAC;QAED,6DAA6D;QAC7D,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAA;QACnE,OAAO,IAAI,CAAA;IACb,CAAC;IAED,+EAA+E;IACvE,aAAa,CAA2B,IAAO;QACrD,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,IAAI,CAAC,CAAA;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAA;QAClE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,6CAA6C,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;QAC7E,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAyB,CAAA;IAC3D,CAAC;IAED;;;;;OAKG;IACI,WAAW,CAAE,IAA4B;QAC9C,IAAI,CAAC,SAAS,GAAG,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QACnD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,qBAAqB,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;QACrD,mEAAmE;QACnE,IAAI,CAAC,gBAAgB,EAAE,CAAA;IACzB,CAAC;IAEM,WAAW;QAChB,OAAO,IAAI,CAAC,SAAS,CAAA;IACvB,CAAC;IAEO,gBAAgB;QACtB,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,EAAE,CAAC;YAC3B,IAAI,IAAI,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;gBACvB,OAAO,KAAK,CAAA;YACd,CAAC;YACD,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBAC/D,OAAO,KAAK,CAAA;YACd,CAAC;YACD,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;gBAC1D,OAAO,KAAK,CAAA;YACd,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAEO,cAAc;QACpB,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;gBACrB,OAAO,KAAK,CAAA;YACd,CAAC;YACD,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBAC7D,OAAO,KAAK,CAAA;YACd,CAAC;YACD,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;gBAC5D,OAAO,KAAK,CAAA;YACd,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;;OAGG;IACH,IAAW,mBAAmB;QAC5B,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACzB,OAAO,KAAK,CAAA;QACd,CAAC;QACD,IAAI,IAAI,CAAC,iBAAiB,IAAI,IAAI,IAAI,IAAI,CAAC,eAAe,IAAI,IAAI,EAAE,CAAC;YACnE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAA;YAC1E,OAAO,KAAK,CAAA;QACd,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC;YAC7B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,0EAA0E,CAAC,CAAA;YAC1F,OAAO,KAAK,CAAA;QACd,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;YAC3B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,wEAAwE,CAAC,CAAA;YACxF,OAAO,KAAK,CAAA;QACd,CAAC;QACD,IAAI,IAAI,CAAC,eAAe,IAAI,IAAI,IAAI,IAAI,CAAC,iBAAiB,IAAI,IAAI,EAAE,CAAC;YACnE,8DAA8D;YAC9D,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;gBAClD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAA;gBAClE,OAAO,KAAK,CAAA;YACd,CAAC;iBAAM,IAAI,IAAI,CAAC,iBAAiB,GAAG,CAAC,EAAE,CAAC;gBACtC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAA;gBAC7D,OAAO,KAAK,CAAA;YACd,CAAC;iBAAM,IAAI,IAAI,CAAC,eAAe,GAAG,CAAC,EAAE,CAAC;gBACpC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAA;gBAC3D,OAAO,KAAK,CAAA;YACd,CAAC;QACH,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;YAC5E,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,4EAA4E,CAAC,CAAA;YAC5F,OAAO,KAAK,CAAA;QACd,CAAC;QAED,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;;;OAIG;IACH,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,SAAS,IAAI,CAAC,CAAA;IAC5B,CAAC;IAED;;;;OAIG;IACH,IAAW,MAAM;QACf,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;YACtF,OAAO,CAAC,CAAA;QACV,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC,OAAO,GAAG,CAAC,CAAA;QACzB,CAAC;QAED,OAAO,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAC9D,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACK,gBAAgB;QACtB,IAAI,IAAI,CAAC,iBAAiB,IAAI,IAAI,IAAI,IAAI,CAAC,eAAe,IAAI,IAAI,EAAE,CAAC;YACnE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAA;YAChE,OAAM;QACR,CAAC;QAED,IAAI,CAAC;YACH,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,yBAAyB,CAAC,IAAI,CAAC,iBAAiB,IAAI,SAAS,EAAE,IAAI,CAAC,eAAe,IAAI,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,CAAA;YAC/J,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,oDAAoD,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAA;YAC1F,IAAI,CAAC,SAAS,GAAG,KAAK,CAAA;YACtB,IAAI,CAAC,OAAO,GAAG,GAAG,CAAA;YAClB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QAC1B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,kCAAkC,EAAE,CAAC,CAAC,CAAA;YACrD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;YAC1B,IAAI,CAAC,OAAO,GAAG,SAAS,CAAA;YACxB,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAA;QAC3B,CAAC;IACH,CAAC;IAED;;;;;;;;;;OAUG;IACH,kFAAkF;IAClF,IAAW,uBAAuB;QAChC,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC9B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,8DAA8D,CAAC,CAAA;YAC9E,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAA;QAC1C,CAAC;QAED,OAAO,qBAAqB,CAAC;YAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,QAAQ,EAAE,IAAI,CAAC,SAAS,IAAI,SAAS;SACtC,CAAC,CAAA;IACJ,CAAC;CACF"}
@@ -7,7 +7,7 @@ export async function getStreamFromAsyncIterable(iterator, path, logger, options
7
7
  const reader = iterator[Symbol.asyncIterator]();
8
8
  const { value: firstChunk, done } = await reader.next();
9
9
  if (done === true) {
10
- log.error('No content found for path', path);
10
+ log.error('no content found for path', path);
11
11
  throw new Error('No content found');
12
12
  }
13
13
  const stream = new ReadableStream({
@@ -70,7 +70,7 @@ export async function parseUrlString({ urlString, ipns, logger }, options) {
70
70
  }
71
71
  else {
72
72
  // protocol is ipns
73
- log.trace('Attempting to resolve PeerId for %s', cidOrPeerIdOrDnsLink);
73
+ log.trace('attempting to resolve PeerId for %s', cidOrPeerIdOrDnsLink);
74
74
  let peerId = null;
75
75
  try {
76
76
  peerId = peerIdFromString(cidOrPeerIdOrDnsLink);
@@ -82,11 +82,11 @@ export async function parseUrlString({ urlString, ipns, logger }, options) {
82
82
  }
83
83
  catch (err) {
84
84
  if (peerId == null) {
85
- log.error('Could not parse PeerId string "%s"', cidOrPeerIdOrDnsLink, err);
85
+ log.error('could not parse PeerId string "%s"', cidOrPeerIdOrDnsLink, err);
86
86
  errors.push(new TypeError(`Could not parse PeerId in ipns url "${cidOrPeerIdOrDnsLink}", ${err.message}`));
87
87
  }
88
88
  else {
89
- log.error('Could not resolve PeerId %c', peerId, err);
89
+ log.error('could not resolve PeerId %c', peerId, err);
90
90
  errors.push(new TypeError(`Could not resolve PeerId "${cidOrPeerIdOrDnsLink}", ${err.message}`));
91
91
  }
92
92
  }
@@ -105,7 +105,7 @@ export async function parseUrlString({ urlString, ipns, logger }, options) {
105
105
  ipnsCache.set(cidOrPeerIdOrDnsLink, resolveResult, 60 * 1000 * 2);
106
106
  }
107
107
  catch (err) {
108
- log.error('Could not resolve DnsLink for "%s"', cidOrPeerIdOrDnsLink, err);
108
+ log.error('could not resolve DnsLink for "%s"', cidOrPeerIdOrDnsLink, err);
109
109
  errors.push(err);
110
110
  }
111
111
  }
@@ -0,0 +1,13 @@
1
+ export declare function getHeader(headers: HeadersInit | undefined, header: string): string | undefined;
2
+ /**
3
+ * Given two ints from a Range header, and potential fileSize, returns:
4
+ * 1. number of bytes the response should contain.
5
+ * 2. the start index of the range. // inclusive
6
+ * 3. the end index of the range. // inclusive
7
+ */
8
+ export declare function calculateByteRangeIndexes(start: number | undefined, end: number | undefined, fileSize?: number): {
9
+ byteSize?: number;
10
+ start?: number;
11
+ end?: number;
12
+ };
13
+ //# sourceMappingURL=request-headers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-headers.d.ts","sourceRoot":"","sources":["../../../src/utils/request-headers.ts"],"names":[],"mappings":"AAAA,wBAAgB,SAAS,CAAE,OAAO,EAAE,WAAW,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAiB/F;AAED;;;;;GAKG;AAEH,wBAAgB,yBAAyB,CAAE,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAoCrK"}
@@ -0,0 +1,62 @@
1
+ export function getHeader(headers, header) {
2
+ if (headers == null) {
3
+ return undefined;
4
+ }
5
+ if (headers instanceof Headers) {
6
+ return headers.get(header) ?? undefined;
7
+ }
8
+ if (Array.isArray(headers)) {
9
+ const entry = headers.find(([key]) => key.toLowerCase() === header.toLowerCase());
10
+ return entry?.[1];
11
+ }
12
+ const key = Object.keys(headers).find(k => k.toLowerCase() === header.toLowerCase());
13
+ if (key == null) {
14
+ return undefined;
15
+ }
16
+ return headers[key];
17
+ }
18
+ /**
19
+ * Given two ints from a Range header, and potential fileSize, returns:
20
+ * 1. number of bytes the response should contain.
21
+ * 2. the start index of the range. // inclusive
22
+ * 3. the end index of the range. // inclusive
23
+ */
24
+ // eslint-disable-next-line complexity
25
+ export function calculateByteRangeIndexes(start, end, fileSize) {
26
+ if ((start ?? 0) > (end ?? Infinity)) {
27
+ throw new Error('Invalid range: Range-start index is greater than range-end index.');
28
+ }
29
+ if (start != null && (end ?? 0) >= (fileSize ?? Infinity)) {
30
+ throw new Error('Invalid range: Range-end index is greater than or equal to the size of the file.');
31
+ }
32
+ if (start == null && (end ?? 0) > (fileSize ?? Infinity)) {
33
+ throw new Error('Invalid range: Range-end index is greater than the size of the file.');
34
+ }
35
+ if (start != null && start < 0) {
36
+ throw new Error('Invalid range: Range-start index cannot be negative.');
37
+ }
38
+ if (start != null && end != null) {
39
+ return { byteSize: end - start + 1, start, end };
40
+ }
41
+ else if (start == null && end != null) {
42
+ // suffix byte range requested
43
+ if (fileSize == null) {
44
+ return { end };
45
+ }
46
+ if (end === fileSize) {
47
+ return { byteSize: fileSize, start: 0, end: fileSize - 1 };
48
+ }
49
+ return { byteSize: end, start: fileSize - end, end: fileSize - 1 };
50
+ }
51
+ else if (start != null && end == null) {
52
+ if (fileSize == null) {
53
+ // we only have the start index, and no fileSize, so we can't return a valid range.
54
+ return { start };
55
+ }
56
+ const end = fileSize - 1;
57
+ const byteSize = fileSize - start;
58
+ return { byteSize, start, end };
59
+ }
60
+ return { byteSize: fileSize, start: 0, end: fileSize != null ? fileSize - 1 : 0 };
61
+ }
62
+ //# sourceMappingURL=request-headers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-headers.js","sourceRoot":"","sources":["../../../src/utils/request-headers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * This function returns the value of the `Content-Range` header for a given range.
3
+ * If you know the total size of the body, pass it as `byteSize`
4
+ *
5
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range
6
+ */
7
+ export declare function getContentRangeHeader({ byteStart, byteEnd, byteSize }: {
8
+ byteStart: number | undefined;
9
+ byteEnd: number | undefined;
10
+ byteSize: number | undefined;
11
+ }): string;
12
+ //# sourceMappingURL=response-headers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response-headers.d.ts","sourceRoot":"","sources":["../../../src/utils/response-headers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAE,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;IAAE,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GAAG,MAAM,CAmC7K"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * This function returns the value of the `Content-Range` header for a given range.
3
+ * If you know the total size of the body, pass it as `byteSize`
4
+ *
5
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range
6
+ */
7
+ export function getContentRangeHeader({ byteStart, byteEnd, byteSize }) {
8
+ const total = byteSize ?? '*'; // if we don't know the total size, we should use *
9
+ if ((byteEnd ?? 0) >= (byteSize ?? Infinity)) {
10
+ throw new Error('Invalid range: Range-end index is greater than or equal to the size of the file.');
11
+ }
12
+ if ((byteStart ?? 0) >= (byteSize ?? Infinity)) {
13
+ throw new Error('Invalid range: Range-start index is greater than or equal to the size of the file.');
14
+ }
15
+ if (byteStart != null && byteEnd == null) {
16
+ // only byteStart in range
17
+ if (byteSize == null) {
18
+ return `bytes */${total}`;
19
+ }
20
+ return `bytes ${byteStart}-${byteSize - 1}/${byteSize}`;
21
+ }
22
+ if (byteStart == null && byteEnd != null) {
23
+ // only byteEnd in range
24
+ if (byteSize == null) {
25
+ return `bytes */${total}`;
26
+ }
27
+ const end = byteSize - 1;
28
+ const start = end - byteEnd + 1;
29
+ return `bytes ${start}-${end}/${byteSize}`;
30
+ }
31
+ if (byteStart == null && byteEnd == null) {
32
+ // neither are provided, we can't return a valid range.
33
+ return `bytes */${total}`;
34
+ }
35
+ return `bytes ${byteStart}-${byteEnd}/${total}`;
36
+ }
37
+ //# sourceMappingURL=response-headers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response-headers.js","sourceRoot":"","sources":["../../../src/utils/response-headers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAE,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAgG;IACnK,MAAM,KAAK,GAAG,QAAQ,IAAI,GAAG,CAAA,CAAC,mDAAmD;IAEjF,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,kFAAkF,CAAC,CAAA;IACrG,CAAC;IACD,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,oFAAoF,CAAC,CAAA;IACvG,CAAC;IAED,IAAI,SAAS,IAAI,IAAI,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;QACzC,0BAA0B;QAC1B,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;YACrB,OAAO,WAAW,KAAK,EAAE,CAAA;QAC3B,CAAC;QACD,OAAO,SAAS,SAAS,IAAI,QAAQ,GAAG,CAAC,IAAI,QAAQ,EAAE,CAAA;IACzD,CAAC;IAED,IAAI,SAAS,IAAI,IAAI,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;QACzC,wBAAwB;QACxB,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;YACrB,OAAO,WAAW,KAAK,EAAE,CAAA;QAC3B,CAAC;QACD,MAAM,GAAG,GAAG,QAAQ,GAAG,CAAC,CAAA;QACxB,MAAM,KAAK,GAAG,GAAG,GAAG,OAAO,GAAG,CAAC,CAAA;QAE/B,OAAO,SAAS,KAAK,IAAI,GAAG,IAAI,QAAQ,EAAE,CAAA;IAC5C,CAAC;IAED,IAAI,SAAS,IAAI,IAAI,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;QACzC,uDAAuD;QACvD,OAAO,WAAW,KAAK,EAAE,CAAA;IAC3B,CAAC;IAED,OAAO,SAAS,SAAS,IAAI,OAAO,IAAI,KAAK,EAAE,CAAA;AACjD,CAAC"}
@@ -1,9 +1,26 @@
1
+ import type { ByteRangeContext } from './byte-range-context';
2
+ import type { SupportedBodyTypes } from '../types.js';
3
+ import type { Logger } from '@libp2p/interface';
1
4
  export interface ResponseOptions extends ResponseInit {
2
5
  redirected?: boolean;
3
6
  }
4
- export declare function okResponse(url: string, body?: BodyInit | null, init?: ResponseOptions): Response;
5
- export declare function notSupportedResponse(url: string, body?: BodyInit | null, init?: ResponseInit): Response;
6
- export declare function notAcceptableResponse(url: string, body?: BodyInit | null, init?: ResponseInit): Response;
7
- export declare function badRequestResponse(url: string, body?: BodyInit | null, init?: ResponseInit): Response;
7
+ export declare function okResponse(url: string, body?: SupportedBodyTypes, init?: ResponseOptions): Response;
8
+ export declare function badGatewayResponse(url: string, body?: SupportedBodyTypes, init?: ResponseInit): Response;
9
+ export declare function notSupportedResponse(url: string, body?: SupportedBodyTypes, init?: ResponseInit): Response;
10
+ export declare function notAcceptableResponse(url: string, body?: SupportedBodyTypes, init?: ResponseInit): Response;
11
+ export declare function badRequestResponse(url: string, body?: SupportedBodyTypes, init?: ResponseInit): Response;
8
12
  export declare function movedPermanentlyResponse(url: string, location: string, init?: ResponseInit): Response;
13
+ interface RangeOptions {
14
+ byteRangeContext: ByteRangeContext;
15
+ log?: Logger;
16
+ }
17
+ export declare function okRangeResponse(url: string, body: SupportedBodyTypes, { byteRangeContext, log }: RangeOptions, init?: ResponseOptions): Response;
18
+ /**
19
+ * We likely need to catch errors handled by upstream helia libraries if range-request throws an error. Some examples:
20
+ * * The range is out of bounds
21
+ * * The range is invalid
22
+ * * The range is not supported for the given type
23
+ */
24
+ export declare function badRangeResponse(url: string, body?: SupportedBodyTypes, init?: ResponseInit): Response;
25
+ export {};
9
26
  //# sourceMappingURL=responses.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"responses.d.ts","sourceRoot":"","sources":["../../../src/utils/responses.ts"],"names":[],"mappings":"AAqBA,MAAM,WAAW,eAAgB,SAAQ,YAAY;IACnD,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,wBAAgB,UAAU,CAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,IAAI,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,QAAQ,CAejG;AAED,wBAAgB,oBAAoB,CAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,IAAI,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,QAAQ,CAYxG;AAED,wBAAgB,qBAAqB,CAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,IAAI,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,QAAQ,CAWzG;AAED,wBAAgB,kBAAkB,CAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,IAAI,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,QAAQ,CAWtG;AAED,wBAAgB,wBAAwB,CAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,QAAQ,CAetG"}
1
+ {"version":3,"file":"responses.d.ts","sourceRoot":"","sources":["../../../src/utils/responses.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAuB/C,MAAM,WAAW,eAAgB,SAAQ,YAAY;IACnD,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,wBAAgB,UAAU,CAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,kBAAkB,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,QAAQ,CAgBpG;AAED,wBAAgB,kBAAkB,CAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,kBAAkB,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,QAAQ,CAWzG;AAED,wBAAgB,oBAAoB,CAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,kBAAkB,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,QAAQ,CAY3G;AAED,wBAAgB,qBAAqB,CAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,kBAAkB,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,QAAQ,CAW5G;AAED,wBAAgB,kBAAkB,CAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,kBAAkB,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,QAAQ,CAWzG;AAED,wBAAgB,wBAAwB,CAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,QAAQ,CAetG;AAED,UAAU,YAAY;IACpB,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,wBAAgB,eAAe,CAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,gBAAgB,EAAE,GAAG,EAAE,EAAE,YAAY,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,QAAQ,CAkCjJ;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,kBAAkB,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,QAAQ,CAWvG"}