koa-files 4.0.6 → 4.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.
package/README.md CHANGED
@@ -29,6 +29,10 @@ interface IgnoreFunction {
29
29
  (path: string): boolean | Promise<boolean>;
30
30
  }
31
31
 
32
+ interface HighWaterMarkFunction {
33
+ (path: string, stats: Stats): Promise<number> | number;
34
+ }
35
+
32
36
  interface HeadersFunction {
33
37
  (path: string, stats: Stats): Promise<Headers | void> | Headers | void;
34
38
  }
@@ -41,14 +45,14 @@ export interface FileSystem {
41
45
  }
42
46
 
43
47
  export interface Options {
44
- fs?: FileSystem;
45
- defer?: boolean;
46
48
  etag?: boolean;
49
+ defer?: boolean;
50
+ fs?: FileSystem;
47
51
  acceptRanges?: boolean;
48
52
  lastModified?: boolean;
49
- highWaterMark?: number;
50
53
  ignore?: IgnoreFunction;
51
54
  headers?: Headers | HeadersFunction;
55
+ highWaterMark?: number | HighWaterMarkFunction;
52
56
  }
53
57
 
54
58
  export function server(root: string, options?: Options): Middleware;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @package koa-files
3
3
  * @license MIT
4
- * @version 4.0.6
4
+ * @version 4.1.0
5
5
  * @author nuintun <nuintun@qq.com>
6
6
  * @description A static files serving middleware for koa.
7
7
  * @see https://github.com/nuintun/koa-files#readme
@@ -70,20 +70,19 @@ class ReadStream extends stream.Readable {
70
70
  }
71
71
  /**
72
72
  * @private
73
- * @method readFilePadding
73
+ * @method readPadding
74
74
  * @param fd The file descriptor.
75
75
  * @param range The current range.
76
76
  * @param size The number of bytes to read.
77
77
  */
78
- readFilePadding(fd, range, size) {
78
+ readPadding(fd, range, size) {
79
79
  let bytesRead = 0;
80
80
  const padding = this.getPadding(range);
81
- const hasRangePadding = padding != null;
82
81
  // If padding exists.
83
- if (hasRangePadding) {
82
+ if (padding != null) {
84
83
  const { length } = padding;
85
84
  const begin = this.bytesRead;
86
- if (length > 0 && begin < length) {
85
+ if (begin < length) {
87
86
  bytesRead = Math.min(size, length - begin);
88
87
  const end = begin + bytesRead;
89
88
  this.push(padding.subarray(begin, end));
@@ -91,14 +90,13 @@ class ReadStream extends stream.Readable {
91
90
  }
92
91
  }
93
92
  // If no padding or read completed.
94
- if (bytesRead <= 0) {
93
+ if (bytesRead < size) {
95
94
  this.bytesRead = 0;
96
- const { readState } = this;
97
95
  // Change read state.
98
- switch (readState) {
96
+ switch (this.readState) {
99
97
  case 0 /* ReadState.PREFIX */:
100
98
  this.readState = 1 /* ReadState.RANGE */;
101
- this.readFileRange(fd, range, size);
99
+ this.readFileRange(fd, range, size - bytesRead);
102
100
  break;
103
101
  case 2 /* ReadState.SUFFIX */:
104
102
  this.currentRangeIndex++;
@@ -107,7 +105,7 @@ class ReadStream extends stream.Readable {
107
105
  if (nextRange == null) {
108
106
  this.push(null);
109
107
  } else {
110
- this.readFilePadding(fd, nextRange, size);
108
+ this.readPadding(fd, nextRange, size - bytesRead);
111
109
  }
112
110
  break;
113
111
  }
@@ -121,39 +119,40 @@ class ReadStream extends stream.Readable {
121
119
  * @param size The number of bytes to read.
122
120
  */
123
121
  readFileRange(fd, range, size) {
124
- this.reading = true;
122
+ const { length } = range;
125
123
  const { bytesRead } = this;
126
- const position = range.offset + bytesRead;
127
- const buffer$1 = buffer.Buffer.allocUnsafeSlow(Math.min(size, range.length - bytesRead));
128
- // Read file range.
129
- this.fs.read(fd, buffer$1, 0, buffer$1.length, position, (readError, bytesRead, buffer$1) => {
130
- this.reading = false;
131
- // Tell ._destroy() that it's safe to close the fd now.
132
- if (this.destroyed) {
133
- this.emit(DISPOSE_EVENT, readError);
134
- } else {
135
- if (readError != null) {
124
+ // File range not finished.
125
+ if (bytesRead < length) {
126
+ this.reading = true;
127
+ const bytesToRead = Math.min(size, length - bytesRead);
128
+ const buffer$1 = buffer.Buffer.allocUnsafeSlow(bytesToRead);
129
+ const position = range.offset + bytesRead;
130
+ // Read file range.
131
+ this.fs.read(fd, buffer$1, 0, bytesToRead, position, (readError, bytesRead, buffer) => {
132
+ this.reading = false;
133
+ // Tell ._destroy() that it's safe to close the fd now.
134
+ if (this.destroyed) {
135
+ this.emit(DISPOSE_EVENT, readError);
136
+ } else if (readError != null) {
136
137
  this.destroy(readError);
138
+ } else if (bytesRead !== bytesToRead) {
139
+ this.destroy(new RangeError('invalid read operation'));
137
140
  } else {
138
- if (bytesRead > 0) {
139
- if (bytesRead !== buffer$1.length) {
140
- // Slow path. Shrink to fit.
141
- // Copy instead of slice so that we don't retain
142
- // large backing buffer for small reads.
143
- const chunk = buffer.Buffer.allocUnsafeSlow(bytesRead);
144
- buffer$1.copy(chunk, 0, 0, bytesRead);
145
- buffer$1 = chunk;
146
- }
147
- this.push(buffer$1);
148
- this.bytesRead += bytesRead;
149
- } else {
141
+ this.push(buffer);
142
+ this.bytesRead += bytesRead;
143
+ // file range read completed.
144
+ if (bytesRead < size) {
150
145
  this.bytesRead = 0;
151
146
  this.readState = 2 /* ReadState.SUFFIX */;
152
- this.readFilePadding(fd, range, size);
147
+ this.readPadding(fd, range, size - bytesRead);
153
148
  }
154
149
  }
155
- }
156
- });
150
+ });
151
+ } else {
152
+ this.bytesRead = 0;
153
+ this.readState = 2 /* ReadState.SUFFIX */;
154
+ this.readPadding(fd, range, size);
155
+ }
157
156
  }
158
157
  /**
159
158
  * @override
@@ -168,12 +167,11 @@ class ReadStream extends stream.Readable {
168
167
  if (fd == null || range == null) {
169
168
  this.push(null);
170
169
  } else {
171
- const { readState } = this;
172
170
  // Read bytes from range.
173
- switch (readState) {
171
+ switch (this.readState) {
174
172
  case 0 /* ReadState.PREFIX */:
175
173
  case 2 /* ReadState.SUFFIX */:
176
- this.readFilePadding(fd, range, size);
174
+ this.readPadding(fd, range, size);
177
175
  break;
178
176
  case 1 /* ReadState.RANGE */:
179
177
  this.readFileRange(fd, range, size);
@@ -2,11 +2,12 @@
2
2
  * @module ReadStream
3
3
  */
4
4
  import { PathLike } from 'fs';
5
+ import { Readable } from 'stream';
5
6
  import { Range } from './utils/http.cjs';
6
7
  import { FileSystem } from './utils/fs.cjs';
7
- import { Readable, ReadableOptions } from 'stream';
8
- export interface Options extends Pick<ReadableOptions, 'highWaterMark'> {
8
+ export interface Options {
9
9
  fs: FileSystem;
10
+ highWaterMark?: number;
10
11
  }
11
12
  interface Callback {
12
13
  (error?: Error | null): void;
@@ -46,12 +47,12 @@ export declare class ReadStream extends Readable {
46
47
  private getPadding;
47
48
  /**
48
49
  * @private
49
- * @method readFilePadding
50
+ * @method readPadding
50
51
  * @param fd The file descriptor.
51
52
  * @param range The current range.
52
53
  * @param size The number of bytes to read.
53
54
  */
54
- private readFilePadding;
55
+ private readPadding;
55
56
  /**
56
57
  * @private
57
58
  * @method readFileRange
package/cjs/Service.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @package koa-files
3
3
  * @license MIT
4
- * @version 4.0.6
4
+ * @version 4.1.0
5
5
  * @author nuintun <nuintun@qq.com>
6
6
  * @description A static files serving middleware for koa.
7
7
  * @see https://github.com/nuintun/koa-files#readme
@@ -38,20 +38,15 @@ class Service {
38
38
  * @param root The file service root.
39
39
  * @param options The file service options.
40
40
  */
41
- constructor(root, options) {
41
+ constructor(root, options = {}) {
42
+ var _a;
42
43
  this.root = path.unixify(path$1.resolve(root));
43
- this.options = Object.assign({ fs: fs__default.default, highWaterMark: 65536 }, options);
44
- }
45
- /**
46
- * @private
47
- * @method isIgnore
48
- * @description Check if path is ignore.
49
- * @param path The path to check.
50
- */
51
- async isIgnore(path) {
52
- const { ignore } = this.options;
53
- const isIgnored = type.isFunction(ignore) ? await ignore(path) : false;
54
- return isIgnored === true;
44
+ const { ignore, highWaterMark = 65536 } = options;
45
+ this.options = Object.assign(Object.assign({}, options), {
46
+ fs: (_a = options.fs) !== null && _a !== void 0 ? _a : fs__default.default,
47
+ ignore: type.isFunction(ignore) ? ignore : () => false,
48
+ highWaterMark: type.isFunction(highWaterMark) ? highWaterMark : () => highWaterMark
49
+ });
55
50
  }
56
51
  /**
57
52
  * @private
@@ -131,12 +126,12 @@ class Service {
131
126
  if (path.isOutRoot(path$2, root)) {
132
127
  return false;
133
128
  }
129
+ // Get options.
130
+ const { options } = this;
134
131
  // Is ignore path or file (403).
135
- if (await this.isIgnore(path$2)) {
132
+ if (await options.ignore(path$2)) {
136
133
  return false;
137
134
  }
138
- // Get options.
139
- const { options } = this;
140
135
  // File stats.
141
136
  const stats = await fs$1.stat(options.fs, path$2);
142
137
  // Check file stats.
@@ -193,7 +188,10 @@ class Service {
193
188
  return context.throw(400);
194
189
  }
195
190
  // Set response body.
196
- response.body = new ReadStream.ReadStream(path$2, ranges, options);
191
+ response.body = new ReadStream.ReadStream(path$2, ranges, {
192
+ fs: options.fs,
193
+ highWaterMark: await options.highWaterMark(path$2, stats)
194
+ });
197
195
  // File found.
198
196
  return true;
199
197
  }
package/cjs/Service.d.cts CHANGED
@@ -10,17 +10,20 @@ interface Headers {
10
10
  interface IgnoreFunction {
11
11
  (path: string): boolean | Promise<boolean>;
12
12
  }
13
+ interface HighWaterMarkFunction {
14
+ (path: string, stats: Stats): Promise<number> | number;
15
+ }
13
16
  interface HeadersFunction {
14
17
  (path: string, stats: Stats): Promise<Headers | void> | Headers | void;
15
18
  }
16
19
  export interface Options {
17
- fs?: FileSystem;
18
20
  etag?: boolean;
21
+ fs?: FileSystem;
19
22
  acceptRanges?: boolean;
20
23
  lastModified?: boolean;
21
- highWaterMark?: number;
22
24
  ignore?: IgnoreFunction;
23
25
  headers?: Headers | HeadersFunction;
26
+ highWaterMark?: number | HighWaterMarkFunction;
24
27
  }
25
28
  /**
26
29
  * @class Service
@@ -35,13 +38,6 @@ export declare class Service {
35
38
  * @param options The file service options.
36
39
  */
37
40
  constructor(root: string, options?: Options);
38
- /**
39
- * @private
40
- * @method isIgnore
41
- * @description Check if path is ignore.
42
- * @param path The path to check.
43
- */
44
- private isIgnore;
45
41
  /**
46
42
  * @private
47
43
  * @method setupHeaders
package/cjs/index.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @package koa-files
3
3
  * @license MIT
4
- * @version 4.0.6
4
+ * @version 4.1.0
5
5
  * @author nuintun <nuintun@qq.com>
6
6
  * @description A static files serving middleware for koa.
7
7
  * @see https://github.com/nuintun/koa-files#readme
package/cjs/utils/fs.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @package koa-files
3
3
  * @license MIT
4
- * @version 4.0.6
4
+ * @version 4.1.0
5
5
  * @author nuintun <nuintun@qq.com>
6
6
  * @description A static files serving middleware for koa.
7
7
  * @see https://github.com/nuintun/koa-files#readme
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @package koa-files
3
3
  * @license MIT
4
- * @version 4.0.6
4
+ * @version 4.1.0
5
5
  * @author nuintun <nuintun@qq.com>
6
6
  * @description A static files serving middleware for koa.
7
7
  * @see https://github.com/nuintun/koa-files#readme
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @package koa-files
3
3
  * @license MIT
4
- * @version 4.0.6
4
+ * @version 4.1.0
5
5
  * @author nuintun <nuintun@qq.com>
6
6
  * @description A static files serving middleware for koa.
7
7
  * @see https://github.com/nuintun/koa-files#readme
@@ -34,4 +34,4 @@ export declare function isPreconditionFailed({ request, response }: Context): bo
34
34
  * @param context The koa context.
35
35
  * @param stats The file stats.
36
36
  */
37
- export declare function parseRanges(context: Context, stats: Stats): Range[] | -1 | -2;
37
+ export declare function parseRanges(context: Context, stats: Stats): -1 | -2 | Range[];
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @package koa-files
3
3
  * @license MIT
4
- * @version 4.0.6
4
+ * @version 4.1.0
5
5
  * @author nuintun <nuintun@qq.com>
6
6
  * @description A static files serving middleware for koa.
7
7
  * @see https://github.com/nuintun/koa-files#readme
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @package koa-files
3
3
  * @license MIT
4
- * @version 4.0.6
4
+ * @version 4.1.0
5
5
  * @author nuintun <nuintun@qq.com>
6
6
  * @description A static files serving middleware for koa.
7
7
  * @see https://github.com/nuintun/koa-files#readme
@@ -2,11 +2,12 @@
2
2
  * @module ReadStream
3
3
  */
4
4
  import { PathLike } from 'fs';
5
+ import { Readable } from 'stream';
5
6
  import { Range } from './utils/http.js';
6
7
  import { FileSystem } from './utils/fs.js';
7
- import { Readable, ReadableOptions } from 'stream';
8
- export interface Options extends Pick<ReadableOptions, 'highWaterMark'> {
8
+ export interface Options {
9
9
  fs: FileSystem;
10
+ highWaterMark?: number;
10
11
  }
11
12
  interface Callback {
12
13
  (error?: Error | null): void;
@@ -46,12 +47,12 @@ export declare class ReadStream extends Readable {
46
47
  private getPadding;
47
48
  /**
48
49
  * @private
49
- * @method readFilePadding
50
+ * @method readPadding
50
51
  * @param fd The file descriptor.
51
52
  * @param range The current range.
52
53
  * @param size The number of bytes to read.
53
54
  */
54
- private readFilePadding;
55
+ private readPadding;
55
56
  /**
56
57
  * @private
57
58
  * @method readFileRange
package/esm/ReadStream.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @package koa-files
3
3
  * @license MIT
4
- * @version 4.0.6
4
+ * @version 4.1.0
5
5
  * @author nuintun <nuintun@qq.com>
6
6
  * @description A static files serving middleware for koa.
7
7
  * @see https://github.com/nuintun/koa-files#readme
@@ -68,20 +68,19 @@ class ReadStream extends Readable {
68
68
  }
69
69
  /**
70
70
  * @private
71
- * @method readFilePadding
71
+ * @method readPadding
72
72
  * @param fd The file descriptor.
73
73
  * @param range The current range.
74
74
  * @param size The number of bytes to read.
75
75
  */
76
- readFilePadding(fd, range, size) {
76
+ readPadding(fd, range, size) {
77
77
  let bytesRead = 0;
78
78
  const padding = this.getPadding(range);
79
- const hasRangePadding = padding != null;
80
79
  // If padding exists.
81
- if (hasRangePadding) {
80
+ if (padding != null) {
82
81
  const { length } = padding;
83
82
  const begin = this.bytesRead;
84
- if (length > 0 && begin < length) {
83
+ if (begin < length) {
85
84
  bytesRead = Math.min(size, length - begin);
86
85
  const end = begin + bytesRead;
87
86
  this.push(padding.subarray(begin, end));
@@ -89,14 +88,13 @@ class ReadStream extends Readable {
89
88
  }
90
89
  }
91
90
  // If no padding or read completed.
92
- if (bytesRead <= 0) {
91
+ if (bytesRead < size) {
93
92
  this.bytesRead = 0;
94
- const { readState } = this;
95
93
  // Change read state.
96
- switch (readState) {
94
+ switch (this.readState) {
97
95
  case 0 /* ReadState.PREFIX */:
98
96
  this.readState = 1 /* ReadState.RANGE */;
99
- this.readFileRange(fd, range, size);
97
+ this.readFileRange(fd, range, size - bytesRead);
100
98
  break;
101
99
  case 2 /* ReadState.SUFFIX */:
102
100
  this.currentRangeIndex++;
@@ -105,7 +103,7 @@ class ReadStream extends Readable {
105
103
  if (nextRange == null) {
106
104
  this.push(null);
107
105
  } else {
108
- this.readFilePadding(fd, nextRange, size);
106
+ this.readPadding(fd, nextRange, size - bytesRead);
109
107
  }
110
108
  break;
111
109
  }
@@ -119,39 +117,40 @@ class ReadStream extends Readable {
119
117
  * @param size The number of bytes to read.
120
118
  */
121
119
  readFileRange(fd, range, size) {
122
- this.reading = true;
120
+ const { length } = range;
123
121
  const { bytesRead } = this;
124
- const position = range.offset + bytesRead;
125
- const buffer = Buffer.allocUnsafeSlow(Math.min(size, range.length - bytesRead));
126
- // Read file range.
127
- this.fs.read(fd, buffer, 0, buffer.length, position, (readError, bytesRead, buffer) => {
128
- this.reading = false;
129
- // Tell ._destroy() that it's safe to close the fd now.
130
- if (this.destroyed) {
131
- this.emit(DISPOSE_EVENT, readError);
132
- } else {
133
- if (readError != null) {
122
+ // File range not finished.
123
+ if (bytesRead < length) {
124
+ this.reading = true;
125
+ const bytesToRead = Math.min(size, length - bytesRead);
126
+ const buffer = Buffer.allocUnsafeSlow(bytesToRead);
127
+ const position = range.offset + bytesRead;
128
+ // Read file range.
129
+ this.fs.read(fd, buffer, 0, bytesToRead, position, (readError, bytesRead, buffer) => {
130
+ this.reading = false;
131
+ // Tell ._destroy() that it's safe to close the fd now.
132
+ if (this.destroyed) {
133
+ this.emit(DISPOSE_EVENT, readError);
134
+ } else if (readError != null) {
134
135
  this.destroy(readError);
136
+ } else if (bytesRead !== bytesToRead) {
137
+ this.destroy(new RangeError('invalid read operation'));
135
138
  } else {
136
- if (bytesRead > 0) {
137
- if (bytesRead !== buffer.length) {
138
- // Slow path. Shrink to fit.
139
- // Copy instead of slice so that we don't retain
140
- // large backing buffer for small reads.
141
- const chunk = Buffer.allocUnsafeSlow(bytesRead);
142
- buffer.copy(chunk, 0, 0, bytesRead);
143
- buffer = chunk;
144
- }
145
- this.push(buffer);
146
- this.bytesRead += bytesRead;
147
- } else {
139
+ this.push(buffer);
140
+ this.bytesRead += bytesRead;
141
+ // file range read completed.
142
+ if (bytesRead < size) {
148
143
  this.bytesRead = 0;
149
144
  this.readState = 2 /* ReadState.SUFFIX */;
150
- this.readFilePadding(fd, range, size);
145
+ this.readPadding(fd, range, size - bytesRead);
151
146
  }
152
147
  }
153
- }
154
- });
148
+ });
149
+ } else {
150
+ this.bytesRead = 0;
151
+ this.readState = 2 /* ReadState.SUFFIX */;
152
+ this.readPadding(fd, range, size);
153
+ }
155
154
  }
156
155
  /**
157
156
  * @override
@@ -166,12 +165,11 @@ class ReadStream extends Readable {
166
165
  if (fd == null || range == null) {
167
166
  this.push(null);
168
167
  } else {
169
- const { readState } = this;
170
168
  // Read bytes from range.
171
- switch (readState) {
169
+ switch (this.readState) {
172
170
  case 0 /* ReadState.PREFIX */:
173
171
  case 2 /* ReadState.SUFFIX */:
174
- this.readFilePadding(fd, range, size);
172
+ this.readPadding(fd, range, size);
175
173
  break;
176
174
  case 1 /* ReadState.RANGE */:
177
175
  this.readFileRange(fd, range, size);
package/esm/Service.d.ts CHANGED
@@ -10,17 +10,20 @@ interface Headers {
10
10
  interface IgnoreFunction {
11
11
  (path: string): boolean | Promise<boolean>;
12
12
  }
13
+ interface HighWaterMarkFunction {
14
+ (path: string, stats: Stats): Promise<number> | number;
15
+ }
13
16
  interface HeadersFunction {
14
17
  (path: string, stats: Stats): Promise<Headers | void> | Headers | void;
15
18
  }
16
19
  export interface Options {
17
- fs?: FileSystem;
18
20
  etag?: boolean;
21
+ fs?: FileSystem;
19
22
  acceptRanges?: boolean;
20
23
  lastModified?: boolean;
21
- highWaterMark?: number;
22
24
  ignore?: IgnoreFunction;
23
25
  headers?: Headers | HeadersFunction;
26
+ highWaterMark?: number | HighWaterMarkFunction;
24
27
  }
25
28
  /**
26
29
  * @class Service
@@ -35,13 +38,6 @@ export declare class Service {
35
38
  * @param options The file service options.
36
39
  */
37
40
  constructor(root: string, options?: Options);
38
- /**
39
- * @private
40
- * @method isIgnore
41
- * @description Check if path is ignore.
42
- * @param path The path to check.
43
- */
44
- private isIgnore;
45
41
  /**
46
42
  * @private
47
43
  * @method setupHeaders
package/esm/Service.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @package koa-files
3
3
  * @license MIT
4
- * @version 4.0.6
4
+ * @version 4.1.0
5
5
  * @author nuintun <nuintun@qq.com>
6
6
  * @description A static files serving middleware for koa.
7
7
  * @see https://github.com/nuintun/koa-files#readme
@@ -29,20 +29,15 @@ class Service {
29
29
  * @param root The file service root.
30
30
  * @param options The file service options.
31
31
  */
32
- constructor(root, options) {
32
+ constructor(root, options = {}) {
33
+ var _a;
33
34
  this.root = unixify(resolve(root));
34
- this.options = Object.assign({ fs, highWaterMark: 65536 }, options);
35
- }
36
- /**
37
- * @private
38
- * @method isIgnore
39
- * @description Check if path is ignore.
40
- * @param path The path to check.
41
- */
42
- async isIgnore(path) {
43
- const { ignore } = this.options;
44
- const isIgnored = isFunction(ignore) ? await ignore(path) : false;
45
- return isIgnored === true;
35
+ const { ignore, highWaterMark = 65536 } = options;
36
+ this.options = Object.assign(Object.assign({}, options), {
37
+ fs: (_a = options.fs) !== null && _a !== void 0 ? _a : fs,
38
+ ignore: isFunction(ignore) ? ignore : () => false,
39
+ highWaterMark: isFunction(highWaterMark) ? highWaterMark : () => highWaterMark
40
+ });
46
41
  }
47
42
  /**
48
43
  * @private
@@ -122,12 +117,12 @@ class Service {
122
117
  if (isOutRoot(path, root)) {
123
118
  return false;
124
119
  }
120
+ // Get options.
121
+ const { options } = this;
125
122
  // Is ignore path or file (403).
126
- if (await this.isIgnore(path)) {
123
+ if (await options.ignore(path)) {
127
124
  return false;
128
125
  }
129
- // Get options.
130
- const { options } = this;
131
126
  // File stats.
132
127
  const stats = await stat(options.fs, path);
133
128
  // Check file stats.
@@ -184,7 +179,10 @@ class Service {
184
179
  return context.throw(400);
185
180
  }
186
181
  // Set response body.
187
- response.body = new ReadStream(path, ranges, options);
182
+ response.body = new ReadStream(path, ranges, {
183
+ fs: options.fs,
184
+ highWaterMark: await options.highWaterMark(path, stats)
185
+ });
188
186
  // File found.
189
187
  return true;
190
188
  }
package/esm/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @package koa-files
3
3
  * @license MIT
4
- * @version 4.0.6
4
+ * @version 4.1.0
5
5
  * @author nuintun <nuintun@qq.com>
6
6
  * @description A static files serving middleware for koa.
7
7
  * @see https://github.com/nuintun/koa-files#readme
package/esm/utils/fs.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @package koa-files
3
3
  * @license MIT
4
- * @version 4.0.6
4
+ * @version 4.1.0
5
5
  * @author nuintun <nuintun@qq.com>
6
6
  * @description A static files serving middleware for koa.
7
7
  * @see https://github.com/nuintun/koa-files#readme
package/esm/utils/hash.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @package koa-files
3
3
  * @license MIT
4
- * @version 4.0.6
4
+ * @version 4.1.0
5
5
  * @author nuintun <nuintun@qq.com>
6
6
  * @description A static files serving middleware for koa.
7
7
  * @see https://github.com/nuintun/koa-files#readme
@@ -34,4 +34,4 @@ export declare function isPreconditionFailed({ request, response }: Context): bo
34
34
  * @param context The koa context.
35
35
  * @param stats The file stats.
36
36
  */
37
- export declare function parseRanges(context: Context, stats: Stats): Range[] | -1 | -2;
37
+ export declare function parseRanges(context: Context, stats: Stats): -1 | -2 | Range[];
package/esm/utils/http.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @package koa-files
3
3
  * @license MIT
4
- * @version 4.0.6
4
+ * @version 4.1.0
5
5
  * @author nuintun <nuintun@qq.com>
6
6
  * @description A static files serving middleware for koa.
7
7
  * @see https://github.com/nuintun/koa-files#readme
package/esm/utils/path.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @package koa-files
3
3
  * @license MIT
4
- * @version 4.0.6
4
+ * @version 4.1.0
5
5
  * @author nuintun <nuintun@qq.com>
6
6
  * @description A static files serving middleware for koa.
7
7
  * @see https://github.com/nuintun/koa-files#readme
package/esm/utils/type.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @package koa-files
3
3
  * @license MIT
4
- * @version 4.0.6
4
+ * @version 4.1.0
5
5
  * @author nuintun <nuintun@qq.com>
6
6
  * @description A static files serving middleware for koa.
7
7
  * @see https://github.com/nuintun/koa-files#readme
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koa-files",
3
- "version": "4.0.6",
3
+ "version": "4.1.0",
4
4
  "description": "A static files serving middleware for koa.",
5
5
  "type": "module",
6
6
  "main": "cjs/index.cjs",
@@ -48,17 +48,17 @@
48
48
  "tslib": "^2.8.1"
49
49
  },
50
50
  "devDependencies": {
51
- "@rollup/plugin-typescript": "^12.1.2",
51
+ "@rollup/plugin-typescript": "^12.1.4",
52
52
  "@types/etag": "^1.8.4",
53
53
  "@types/koa": "^2.15.0",
54
- "@types/node": "^24.0.1",
54
+ "@types/node": "^24.1.0",
55
55
  "@types/range-parser": "^1.2.7",
56
- "dts-paths": "^1.1.8",
57
- "koa": "^3.0.0",
56
+ "dts-paths": "^1.1.10",
57
+ "koa": "^3.0.1",
58
58
  "magic-string": "^0.30.17",
59
- "prettier": "^3.5.3",
59
+ "prettier": "^3.6.2",
60
60
  "rimraf": "^6.0.1",
61
- "rollup": "^4.43.0",
61
+ "rollup": "^4.46.1",
62
62
  "typescript": "^5.8.3"
63
63
  },
64
64
  "peerDependencies": {
@@ -71,8 +71,8 @@
71
71
  "build:cjs": "rollup -c tools/rollup.cjs.js",
72
72
  "build:esm": "rollup -c tools/rollup.esm.js",
73
73
  "build:fix-types": "node tools/fix-types.js",
74
+ "build": "pnpm clean && pnpm build:main && pnpm format",
74
75
  "format": "prettier --write . --ignore-path .prettierignore",
75
- "build": "npm run clean && npm run build:main && npm run format",
76
- "build:main": "npm run build:cjs && npm run build:esm && npm run build:fix-types"
76
+ "build:main": "pnpm build:cjs && pnpm build:esm && pnpm build:fix-types"
77
77
  }
78
78
  }