koa-files 2.3.6 → 2.3.7
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/cjs/Send.cjs +330 -331
- package/cjs/index.cjs +11 -11
- package/cjs/utils.cjs +51 -52
- package/esm/Send.js +325 -324
- package/esm/index.js +11 -11
- package/esm/utils.js +49 -48
- package/package.json +15 -14
- package/types/Send.d.ts +73 -73
- package/types/index.d.ts +1 -1
package/esm/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package koa-files
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 2.3.
|
|
4
|
+
* @version 2.3.7
|
|
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
|
|
@@ -20,18 +20,18 @@ import Send from './Send.js';
|
|
|
20
20
|
* @param {Options} options
|
|
21
21
|
*/
|
|
22
22
|
function server(root, options) {
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
const send = new Send(root, options);
|
|
24
|
+
if (options && options.defer) {
|
|
25
|
+
return async (context, next) => {
|
|
26
|
+
await next();
|
|
27
|
+
await send.response(context);
|
|
28
|
+
};
|
|
29
|
+
}
|
|
25
30
|
return async (context, next) => {
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
if (!(await send.response(context))) {
|
|
32
|
+
await next();
|
|
33
|
+
}
|
|
28
34
|
};
|
|
29
|
-
}
|
|
30
|
-
return async (context, next) => {
|
|
31
|
-
if (!(await send.response(context))) {
|
|
32
|
-
await next();
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
export { server as default };
|
package/esm/utils.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package koa-files
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 2.3.
|
|
4
|
+
* @version 2.3.7
|
|
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
|
|
@@ -24,8 +24,8 @@ const CHARS = Array.from('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr
|
|
|
24
24
|
* @returns {boolean}
|
|
25
25
|
*/
|
|
26
26
|
function isOutRoot(path, root) {
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
path = relative(root, path);
|
|
28
|
+
return /\.\.(?:[\\/]|$)/.test(path) || isAbsolute(path);
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
31
|
* @function unixify
|
|
@@ -34,7 +34,7 @@ function isOutRoot(path, root) {
|
|
|
34
34
|
* @returns {string}
|
|
35
35
|
*/
|
|
36
36
|
function unixify(path) {
|
|
37
|
-
|
|
37
|
+
return path.replace(/\\/g, '/');
|
|
38
38
|
}
|
|
39
39
|
/**
|
|
40
40
|
* @function decodeURI
|
|
@@ -43,11 +43,12 @@ function unixify(path) {
|
|
|
43
43
|
* @returns {string|-1}
|
|
44
44
|
*/
|
|
45
45
|
function decodeURI(URI) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
try {
|
|
47
|
+
return decodeURIComponent(URI);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
return -1;
|
|
51
|
+
}
|
|
51
52
|
}
|
|
52
53
|
/**
|
|
53
54
|
* @function boundaryGenerator
|
|
@@ -55,13 +56,13 @@ function decodeURI(URI) {
|
|
|
55
56
|
* @returns {string}
|
|
56
57
|
*/
|
|
57
58
|
function boundaryGenerator() {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
59
|
+
let boundary = '';
|
|
60
|
+
// Create boundary
|
|
61
|
+
for (let i = 0; i < 38; i++) {
|
|
62
|
+
boundary += CHARS[Math.floor(Math.random() * 62)];
|
|
63
|
+
}
|
|
64
|
+
// Return boundary
|
|
65
|
+
return boundary;
|
|
65
66
|
}
|
|
66
67
|
/**
|
|
67
68
|
* @function fstat
|
|
@@ -69,11 +70,11 @@ function boundaryGenerator() {
|
|
|
69
70
|
* @returns {Promise<Stats>}
|
|
70
71
|
*/
|
|
71
72
|
function fstat(path) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
return new Promise((resolve, reject) => {
|
|
74
|
+
fs.stat(path, (error, stats) => {
|
|
75
|
+
error ? reject(error) : resolve(stats);
|
|
76
|
+
});
|
|
75
77
|
});
|
|
76
|
-
});
|
|
77
78
|
}
|
|
78
79
|
/**
|
|
79
80
|
* @function hasTrailingSlash
|
|
@@ -81,7 +82,7 @@ function fstat(path) {
|
|
|
81
82
|
* @returns {boolean}
|
|
82
83
|
*/
|
|
83
84
|
function hasTrailingSlash(path) {
|
|
84
|
-
|
|
85
|
+
return /\/$/.test(path);
|
|
85
86
|
}
|
|
86
87
|
/**
|
|
87
88
|
* @function parseTokens
|
|
@@ -89,31 +90,31 @@ function hasTrailingSlash(path) {
|
|
|
89
90
|
* @param {string[]} value
|
|
90
91
|
*/
|
|
91
92
|
function parseTokens(value) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
93
|
+
let end = 0;
|
|
94
|
+
let start = 0;
|
|
95
|
+
let tokens = [];
|
|
96
|
+
// gather tokens
|
|
97
|
+
for (let i = 0, length = value.length; i < length; i++) {
|
|
98
|
+
switch (value.charCodeAt(i)) {
|
|
99
|
+
case 0x20:
|
|
100
|
+
// ' '
|
|
101
|
+
if (start === end) {
|
|
102
|
+
start = end = i + 1;
|
|
103
|
+
}
|
|
104
|
+
break;
|
|
105
|
+
case 0x2c:
|
|
106
|
+
// ','
|
|
107
|
+
tokens.push(value.substring(start, end));
|
|
108
|
+
start = end = i + 1;
|
|
109
|
+
break;
|
|
110
|
+
default:
|
|
111
|
+
end = i + 1;
|
|
112
|
+
break;
|
|
102
113
|
}
|
|
103
|
-
break;
|
|
104
|
-
case 0x2c:
|
|
105
|
-
// ','
|
|
106
|
-
tokens.push(value.substring(start, end));
|
|
107
|
-
start = end = i + 1;
|
|
108
|
-
break;
|
|
109
|
-
default:
|
|
110
|
-
end = i + 1;
|
|
111
|
-
break;
|
|
112
114
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
return tokens;
|
|
115
|
+
// final token
|
|
116
|
+
tokens.push(value.substring(start, end));
|
|
117
|
+
return tokens;
|
|
117
118
|
}
|
|
118
119
|
/**
|
|
119
120
|
* @function isETagFresh
|
|
@@ -122,9 +123,9 @@ function parseTokens(value) {
|
|
|
122
123
|
* @returns {boolean}
|
|
123
124
|
*/
|
|
124
125
|
function isETagFresh(match, etag) {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
126
|
+
return parseTokens(match).some(match => {
|
|
127
|
+
return match === etag || match === 'W/' + etag || 'W/' + match === etag;
|
|
128
|
+
});
|
|
128
129
|
}
|
|
129
130
|
/**
|
|
130
131
|
* @function isETag
|
|
@@ -132,7 +133,7 @@ function isETagFresh(match, etag) {
|
|
|
132
133
|
* @returns {boolean}
|
|
133
134
|
*/
|
|
134
135
|
function isETag(etag) {
|
|
135
|
-
|
|
136
|
+
return /(?:W\/)?"(?:[ !#-\x7E\x80-\xFF]*|\r\n[\t ]|\\.)*"/.test(etag);
|
|
136
137
|
}
|
|
137
138
|
|
|
138
139
|
export { boundaryGenerator, decodeURI, fstat, hasTrailingSlash, isETag, isETagFresh, isOutRoot, parseTokens, unixify };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koa-files",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.7",
|
|
4
4
|
"description": "A static files serving middleware for koa.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "cjs/index.cjs",
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"types": "types/index.d.ts",
|
|
9
9
|
"exports": {
|
|
10
10
|
"import": "./esm/index.js",
|
|
11
|
-
"require": "./cjs/index.cjs"
|
|
11
|
+
"require": "./cjs/index.cjs",
|
|
12
|
+
"types": "./types/index.d.ts"
|
|
12
13
|
},
|
|
13
14
|
"files": [
|
|
14
15
|
"cjs",
|
|
@@ -56,20 +57,20 @@
|
|
|
56
57
|
"destroy": "^1.2.0",
|
|
57
58
|
"etag": "^1.8.1",
|
|
58
59
|
"range-parser": "^1.2.1",
|
|
59
|
-
"tslib": "^2.
|
|
60
|
+
"tslib": "^2.6.2"
|
|
60
61
|
},
|
|
61
62
|
"devDependencies": {
|
|
62
|
-
"@rollup/plugin-typescript": "^11.
|
|
63
|
-
"@types/destroy": "^1.0.
|
|
64
|
-
"@types/etag": "^1.8.
|
|
65
|
-
"@types/koa": "^2.
|
|
66
|
-
"@types/range-parser": "^1.2.
|
|
67
|
-
"koa": "^2.
|
|
68
|
-
"magic-string": "^0.30.
|
|
69
|
-
"prettier": "^2.
|
|
70
|
-
"rimraf": "^
|
|
71
|
-
"rollup": "^
|
|
72
|
-
"typescript": "^5.
|
|
63
|
+
"@rollup/plugin-typescript": "^11.1.6",
|
|
64
|
+
"@types/destroy": "^1.0.3",
|
|
65
|
+
"@types/etag": "^1.8.3",
|
|
66
|
+
"@types/koa": "^2.15.0",
|
|
67
|
+
"@types/range-parser": "^1.2.7",
|
|
68
|
+
"koa": "^2.15.0",
|
|
69
|
+
"magic-string": "^0.30.8",
|
|
70
|
+
"prettier": "^3.2.5",
|
|
71
|
+
"rimraf": "^5.0.5",
|
|
72
|
+
"rollup": "^4.12.0",
|
|
73
|
+
"typescript": "^5.3.3"
|
|
73
74
|
},
|
|
74
75
|
"peerDependencies": {
|
|
75
76
|
"koa": "^2.0.0"
|
package/types/Send.d.ts
CHANGED
|
@@ -5,82 +5,82 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { Context } from 'koa';
|
|
7
7
|
export interface Options {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
etag?: boolean;
|
|
9
|
+
cacheControl?: string;
|
|
10
|
+
acceptRanges?: boolean;
|
|
11
|
+
lastModified?: boolean;
|
|
12
|
+
ignore?: (path: string) => boolean;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
15
|
* @class Send
|
|
16
16
|
*/
|
|
17
17
|
export default class Send {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
18
|
+
private root;
|
|
19
|
+
private options;
|
|
20
|
+
/**
|
|
21
|
+
* @constructor
|
|
22
|
+
* @param {string} root
|
|
23
|
+
* @param {Options} options
|
|
24
|
+
*/
|
|
25
|
+
constructor(root: string, options?: Options);
|
|
26
|
+
/**
|
|
27
|
+
* @method isConditionalGET
|
|
28
|
+
* @param {Context} context
|
|
29
|
+
* @returns {boolean}
|
|
30
|
+
*/
|
|
31
|
+
private isConditionalGET;
|
|
32
|
+
/**
|
|
33
|
+
* @method isPreconditionFailure
|
|
34
|
+
* @param {Context} context
|
|
35
|
+
* @returns {boolean}
|
|
36
|
+
*/
|
|
37
|
+
private isPreconditionFailure;
|
|
38
|
+
/**
|
|
39
|
+
* @method isRangeFresh
|
|
40
|
+
* @param {Context} context
|
|
41
|
+
* @returns {boolean}
|
|
42
|
+
*/
|
|
43
|
+
private isRangeFresh;
|
|
44
|
+
/**
|
|
45
|
+
* @method isIgnore
|
|
46
|
+
* @param {string} path
|
|
47
|
+
* @returns {boolean}
|
|
48
|
+
*/
|
|
49
|
+
private isIgnore;
|
|
50
|
+
/**
|
|
51
|
+
* @method parseRange
|
|
52
|
+
* @param {Context} context
|
|
53
|
+
* @param {Stats} stats
|
|
54
|
+
* @returns {Ranges}
|
|
55
|
+
*/
|
|
56
|
+
private parseRange;
|
|
57
|
+
/**
|
|
58
|
+
* @method setupHeaders
|
|
59
|
+
* @param {Context} context
|
|
60
|
+
* @param {string} path
|
|
61
|
+
* @param {Stats} stats
|
|
62
|
+
*/
|
|
63
|
+
private setupHeaders;
|
|
64
|
+
/**
|
|
65
|
+
* @method read
|
|
66
|
+
* @param {string} path
|
|
67
|
+
* @param {Range} range
|
|
68
|
+
* @param {PassThrough} buffer
|
|
69
|
+
* @param {boolean} end
|
|
70
|
+
* @returns {Promise<true>}
|
|
71
|
+
*/
|
|
72
|
+
private read;
|
|
73
|
+
/**
|
|
74
|
+
* @method send
|
|
75
|
+
* @param {Context} context
|
|
76
|
+
* @param {string} path
|
|
77
|
+
* @param {Range[]} ranges
|
|
78
|
+
*/
|
|
79
|
+
private send;
|
|
80
|
+
/**
|
|
81
|
+
* @method response
|
|
82
|
+
* @param {Context} context
|
|
83
|
+
* @returns {Promise<boolean>}
|
|
84
|
+
*/
|
|
85
|
+
response(context: Context): Promise<boolean>;
|
|
86
86
|
}
|