@eggjs/koa-static-cache 7.0.0-beta.34 → 7.0.0-beta.36
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/dist/index.d.ts +94 -92
- package/dist/index.js +153 -219
- package/package.json +30 -41
package/dist/index.d.ts
CHANGED
|
@@ -1,99 +1,101 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
//#region src/index.d.ts
|
|
2
|
+
type FileFilter = (path: string) => boolean;
|
|
3
|
+
interface FileMeta {
|
|
4
|
+
maxAge?: number;
|
|
5
|
+
cacheControl?: string | ((path: string) => string);
|
|
6
|
+
buffer?: Buffer;
|
|
7
|
+
zipBuffer?: Buffer;
|
|
8
|
+
type?: string;
|
|
9
|
+
mime?: string;
|
|
10
|
+
mtime?: Date;
|
|
11
|
+
path?: string;
|
|
12
|
+
md5?: string;
|
|
13
|
+
length?: number;
|
|
13
14
|
}
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
interface FileMap {
|
|
16
|
+
[path: string]: FileMeta;
|
|
16
17
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
interface FileStore {
|
|
19
|
+
get(key: string): unknown;
|
|
20
|
+
set(key: string, value: unknown): void;
|
|
20
21
|
}
|
|
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
|
-
|
|
22
|
+
interface Options {
|
|
23
|
+
/**
|
|
24
|
+
* The root directory from which to serve static assets
|
|
25
|
+
* Default to `process.cwd`
|
|
26
|
+
*/
|
|
27
|
+
dir?: string;
|
|
28
|
+
/**
|
|
29
|
+
* The max age for cache control
|
|
30
|
+
* Default to `0`
|
|
31
|
+
*/
|
|
32
|
+
maxAge?: number;
|
|
33
|
+
/**
|
|
34
|
+
* The cache control header for static files
|
|
35
|
+
* Default to `undefined`
|
|
36
|
+
* Overrides `options.maxAge`
|
|
37
|
+
*/
|
|
38
|
+
cacheControl?: string | ((path: string) => string);
|
|
39
|
+
/**
|
|
40
|
+
* store the files in memory instead of streaming from the filesystem on each request
|
|
41
|
+
*/
|
|
42
|
+
buffer?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* when request's accept-encoding include gzip, files will compressed by gzip
|
|
45
|
+
* Default to `false`
|
|
46
|
+
*/
|
|
47
|
+
gzip?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* try use gzip files, loaded from disk, like nginx gzip_static
|
|
50
|
+
* Default to `false`
|
|
51
|
+
*/
|
|
52
|
+
usePrecompiledGzip?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* object map of aliases
|
|
55
|
+
* Default to `{}`
|
|
56
|
+
*/
|
|
57
|
+
alias?: Record<string, string>;
|
|
58
|
+
/**
|
|
59
|
+
* the url prefix you wish to add
|
|
60
|
+
* Default to `''`
|
|
61
|
+
*/
|
|
62
|
+
prefix?: string;
|
|
63
|
+
/**
|
|
64
|
+
* filter files at init dir, for example - skip non build (source) files.
|
|
65
|
+
* If array set - allow only listed files
|
|
66
|
+
* Default to `undefined`
|
|
67
|
+
*/
|
|
68
|
+
filter?: FileFilter | string[];
|
|
69
|
+
/**
|
|
70
|
+
* dynamic load file which not cached on initialization
|
|
71
|
+
* Default to `false
|
|
72
|
+
*/
|
|
73
|
+
dynamic?: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* caches the assets on initialization or not,
|
|
76
|
+
* always work together with `options.dynamic`
|
|
77
|
+
* Default to `true`
|
|
78
|
+
*/
|
|
79
|
+
preload?: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* file store for caching
|
|
82
|
+
* Default to `undefined`
|
|
83
|
+
*/
|
|
84
|
+
files?: FileMap | FileStore;
|
|
84
85
|
}
|
|
85
86
|
type Next = () => Promise<void>;
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
87
|
+
declare class FileManager {
|
|
88
|
+
store?: FileStore;
|
|
89
|
+
map?: FileMap;
|
|
90
|
+
constructor(store?: FileStore | FileMap);
|
|
91
|
+
get(key: string): unknown;
|
|
92
|
+
set(key: string, value: FileMeta): void;
|
|
92
93
|
}
|
|
93
94
|
type MiddlewareFunc = (ctx: any, next: Next) => Promise<void> | void;
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
95
|
+
declare function staticCache(): MiddlewareFunc;
|
|
96
|
+
declare function staticCache(dir: string): MiddlewareFunc;
|
|
97
|
+
declare function staticCache(options: Options): MiddlewareFunc;
|
|
98
|
+
declare function staticCache(dir: string, options: Options): MiddlewareFunc;
|
|
99
|
+
declare function staticCache(dir: string, options: Options, files: FileMap | FileStore): MiddlewareFunc;
|
|
100
|
+
//#endregion
|
|
101
|
+
export { FileFilter, FileManager, FileMap, FileMeta, FileStore, Options, staticCache };
|
package/dist/index.js
CHANGED
|
@@ -1,224 +1,158 @@
|
|
|
1
|
-
import crypto from
|
|
2
|
-
import {
|
|
3
|
-
import fs from
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import {
|
|
11
|
-
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import { createReadStream, readFileSync, statSync } from "node:fs";
|
|
3
|
+
import fs from "node:fs/promises";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { debuglog, promisify } from "node:util";
|
|
6
|
+
import zlib from "node:zlib";
|
|
7
|
+
import { compressible } from "@eggjs/compressible";
|
|
8
|
+
import readDir from "fs-readdir-recursive";
|
|
9
|
+
import mime from "mime-types";
|
|
10
|
+
import { decodeURIComponent, exists } from "utility";
|
|
11
|
+
|
|
12
|
+
//#region src/index.ts
|
|
13
|
+
const debug = debuglog("egg/koa-static-cache");
|
|
12
14
|
const gzip = promisify(zlib.gzip);
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
file.length = stats.size;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
ctx.response.lastModified = file.mtime;
|
|
137
|
-
if (file.md5) {
|
|
138
|
-
ctx.response.etag = file.md5;
|
|
139
|
-
}
|
|
140
|
-
if (ctx.fresh) {
|
|
141
|
-
ctx.status = 304;
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
ctx.type = file.type;
|
|
145
|
-
ctx.length = file.zipBuffer ? file.zipBuffer.length : file.length;
|
|
146
|
-
ctx.set('cache-control', file.cacheControl ?? 'public, max-age=' + file.maxAge);
|
|
147
|
-
if (file.md5)
|
|
148
|
-
ctx.set('content-md5', file.md5);
|
|
149
|
-
if (ctx.method === 'HEAD') {
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
const acceptGzip = ctx.acceptsEncodings('gzip') === 'gzip';
|
|
153
|
-
if (file.zipBuffer) {
|
|
154
|
-
if (acceptGzip) {
|
|
155
|
-
ctx.set('content-encoding', 'gzip');
|
|
156
|
-
ctx.body = file.zipBuffer;
|
|
157
|
-
}
|
|
158
|
-
else {
|
|
159
|
-
ctx.body = file.buffer;
|
|
160
|
-
}
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
const shouldGzip = enableGzip && file.length > 1024 && acceptGzip && file.type && compressible(file.type);
|
|
164
|
-
if (file.buffer) {
|
|
165
|
-
if (shouldGzip) {
|
|
166
|
-
const gzFile = files.get(filename + '.gz');
|
|
167
|
-
if (options.usePrecompiledGzip && gzFile && gzFile.buffer) {
|
|
168
|
-
// if .gz file already read from disk
|
|
169
|
-
file.zipBuffer = gzFile.buffer;
|
|
170
|
-
}
|
|
171
|
-
else {
|
|
172
|
-
file.zipBuffer = await gzip(file.buffer);
|
|
173
|
-
}
|
|
174
|
-
ctx.set('content-encoding', 'gzip');
|
|
175
|
-
ctx.body = file.zipBuffer;
|
|
176
|
-
}
|
|
177
|
-
else {
|
|
178
|
-
ctx.body = file.buffer;
|
|
179
|
-
}
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
const stream = createReadStream(file.path);
|
|
183
|
-
// update file hash
|
|
184
|
-
if (!file.md5) {
|
|
185
|
-
const hash = crypto.createHash('md5');
|
|
186
|
-
stream.on('data', hash.update.bind(hash));
|
|
187
|
-
stream.on('end', () => {
|
|
188
|
-
file.md5 = hash.digest('base64');
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
ctx.body = stream;
|
|
192
|
-
// enable gzip will remove content length
|
|
193
|
-
if (shouldGzip) {
|
|
194
|
-
ctx.remove('content-length');
|
|
195
|
-
ctx.set('content-encoding', 'gzip');
|
|
196
|
-
ctx.body = stream.pipe(zlib.createGzip());
|
|
197
|
-
}
|
|
198
|
-
};
|
|
15
|
+
var FileManager = class {
|
|
16
|
+
store;
|
|
17
|
+
map;
|
|
18
|
+
constructor(store) {
|
|
19
|
+
if (store && typeof store.set === "function" && typeof store.get === "function") this.store = store;
|
|
20
|
+
else this.map = store || Object.create(null);
|
|
21
|
+
}
|
|
22
|
+
get(key) {
|
|
23
|
+
return this.store ? this.store.get(key) : this.map[key];
|
|
24
|
+
}
|
|
25
|
+
set(key, value) {
|
|
26
|
+
if (this.store) return this.store.set(key, value);
|
|
27
|
+
this.map[key] = value;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
function staticCache(dirOrOptions, options = {}, filesStoreOrMap) {
|
|
31
|
+
let dir = "";
|
|
32
|
+
if (typeof dirOrOptions === "string") dir = dirOrOptions;
|
|
33
|
+
else if (dirOrOptions) options = dirOrOptions;
|
|
34
|
+
if (!dir && options.dir) dir = options.dir;
|
|
35
|
+
if (!dir) dir = process.cwd();
|
|
36
|
+
dir = path.normalize(dir);
|
|
37
|
+
debug("staticCache dir: %s", dir);
|
|
38
|
+
options.prefix = (options.prefix ?? "").replace(/\/*$/, "/");
|
|
39
|
+
const files = new FileManager(filesStoreOrMap ?? options.files);
|
|
40
|
+
const enableGzip = !!options.gzip;
|
|
41
|
+
const filePrefix = path.normalize(options.prefix.replace(/^\//, ""));
|
|
42
|
+
let fileFilter = () => {
|
|
43
|
+
return true;
|
|
44
|
+
};
|
|
45
|
+
if (Array.isArray(options.filter)) fileFilter = (file) => {
|
|
46
|
+
return options.filter.includes(file);
|
|
47
|
+
};
|
|
48
|
+
if (typeof options.filter === "function") fileFilter = options.filter;
|
|
49
|
+
if (options.preload !== false) {
|
|
50
|
+
debug("preload: %s", dir);
|
|
51
|
+
readDir(dir, (filename) => {
|
|
52
|
+
return !filename.startsWith(".") && filename !== "node_modules";
|
|
53
|
+
}).filter(fileFilter).forEach((name) => {
|
|
54
|
+
loadFile(name, dir, options, files);
|
|
55
|
+
});
|
|
56
|
+
debug("preload end");
|
|
57
|
+
}
|
|
58
|
+
debug("prepare middleware");
|
|
59
|
+
return async (ctx, next) => {
|
|
60
|
+
if (ctx.method !== "HEAD" && ctx.method !== "GET") return await next();
|
|
61
|
+
if (!ctx.path.startsWith(options.prefix)) return await next();
|
|
62
|
+
let filename = path.normalize(decodeURIComponent(ctx.path));
|
|
63
|
+
if (options.alias && options.alias[filename]) filename = options.alias[filename];
|
|
64
|
+
let file = files.get(filename);
|
|
65
|
+
if (!file) {
|
|
66
|
+
if (!options.dynamic) return await next();
|
|
67
|
+
if (path.basename(filename)[0] === ".") return await next();
|
|
68
|
+
if (filename.charAt(0) === path.sep) filename = filename.slice(1);
|
|
69
|
+
if (options.prefix !== "/") {
|
|
70
|
+
if (filename.indexOf(filePrefix) !== 0) return await next();
|
|
71
|
+
filename = filename.slice(filePrefix.length);
|
|
72
|
+
}
|
|
73
|
+
const fullpath = path.join(dir, filename);
|
|
74
|
+
if (!fullpath.startsWith(dir)) return await next();
|
|
75
|
+
const stats = await exists(fullpath);
|
|
76
|
+
if (!stats) return await next();
|
|
77
|
+
if (!stats.isFile()) return await next();
|
|
78
|
+
file = loadFile(filename, dir, options, files);
|
|
79
|
+
}
|
|
80
|
+
ctx.status = 200;
|
|
81
|
+
if (enableGzip) ctx.vary("Accept-Encoding");
|
|
82
|
+
if (!file.buffer) {
|
|
83
|
+
const stats = await fs.stat(file.path);
|
|
84
|
+
if (stats.mtime.getTime() !== file.mtime.getTime()) {
|
|
85
|
+
file.mtime = stats.mtime;
|
|
86
|
+
file.md5 = void 0;
|
|
87
|
+
file.length = stats.size;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
ctx.response.lastModified = file.mtime;
|
|
91
|
+
if (file.md5) ctx.response.etag = file.md5;
|
|
92
|
+
if (ctx.fresh) {
|
|
93
|
+
ctx.status = 304;
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
ctx.type = file.type;
|
|
97
|
+
ctx.length = file.zipBuffer ? file.zipBuffer.length : file.length;
|
|
98
|
+
ctx.set("cache-control", file.cacheControl ?? "public, max-age=" + file.maxAge);
|
|
99
|
+
if (file.md5) ctx.set("content-md5", file.md5);
|
|
100
|
+
if (ctx.method === "HEAD") return;
|
|
101
|
+
const acceptGzip = ctx.acceptsEncodings("gzip") === "gzip";
|
|
102
|
+
if (file.zipBuffer) {
|
|
103
|
+
if (acceptGzip) {
|
|
104
|
+
ctx.set("content-encoding", "gzip");
|
|
105
|
+
ctx.body = file.zipBuffer;
|
|
106
|
+
} else ctx.body = file.buffer;
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const shouldGzip = enableGzip && file.length > 1024 && acceptGzip && file.type && compressible(file.type);
|
|
110
|
+
if (file.buffer) {
|
|
111
|
+
if (shouldGzip) {
|
|
112
|
+
const gzFile = files.get(filename + ".gz");
|
|
113
|
+
if (options.usePrecompiledGzip && gzFile && gzFile.buffer) file.zipBuffer = gzFile.buffer;
|
|
114
|
+
else file.zipBuffer = await gzip(file.buffer);
|
|
115
|
+
ctx.set("content-encoding", "gzip");
|
|
116
|
+
ctx.body = file.zipBuffer;
|
|
117
|
+
} else ctx.body = file.buffer;
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const stream = createReadStream(file.path);
|
|
121
|
+
if (!file.md5) {
|
|
122
|
+
const hash = crypto.createHash("md5");
|
|
123
|
+
stream.on("data", hash.update.bind(hash));
|
|
124
|
+
stream.on("end", () => {
|
|
125
|
+
file.md5 = hash.digest("base64");
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
ctx.body = stream;
|
|
129
|
+
if (shouldGzip) {
|
|
130
|
+
ctx.remove("content-length");
|
|
131
|
+
ctx.set("content-encoding", "gzip");
|
|
132
|
+
ctx.body = stream.pipe(zlib.createGzip());
|
|
133
|
+
}
|
|
134
|
+
};
|
|
199
135
|
}
|
|
200
136
|
/**
|
|
201
|
-
|
|
202
|
-
|
|
137
|
+
* load file and add file content to cache
|
|
138
|
+
*/
|
|
203
139
|
function loadFile(name, dir, options, fileManager) {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
if (options.buffer) {
|
|
220
|
-
obj.buffer = buffer;
|
|
221
|
-
}
|
|
222
|
-
return obj;
|
|
140
|
+
const pathname = path.normalize(path.join(options.prefix, name));
|
|
141
|
+
if (!fileManager.get(pathname)) fileManager.set(pathname, {});
|
|
142
|
+
const obj = fileManager.get(pathname);
|
|
143
|
+
const filename = obj.path = path.join(dir, name);
|
|
144
|
+
const stats = statSync(filename);
|
|
145
|
+
const buffer = readFileSync(filename);
|
|
146
|
+
obj.cacheControl = typeof options.cacheControl === "function" ? options.cacheControl(filename) : options.cacheControl;
|
|
147
|
+
obj.maxAge = (typeof obj.maxAge === "number" ? obj.maxAge : options.maxAge) || 0;
|
|
148
|
+
obj.type = obj.mime = mime.lookup(pathname) || "application/octet-stream";
|
|
149
|
+
obj.mtime = stats.mtime;
|
|
150
|
+
obj.length = stats.size;
|
|
151
|
+
obj.md5 = crypto.createHash("md5").update(buffer).digest("base64");
|
|
152
|
+
debug("file: %s", JSON.stringify(obj, null, 2));
|
|
153
|
+
if (options.buffer) obj.buffer = buffer;
|
|
154
|
+
return obj;
|
|
223
155
|
}
|
|
224
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxNQUFNLE1BQU0sYUFBYSxDQUFDO0FBQ2pDLE9BQU8sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ2hELE9BQU8sRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2xDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ25FLE9BQU8sSUFBSSxNQUFNLFdBQVcsQ0FBQztBQUM3QixPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFFN0IsT0FBTyxJQUFJLE1BQU0sWUFBWSxDQUFDO0FBQzlCLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNuRCxPQUFPLE9BQU8sTUFBTSxzQkFBc0IsQ0FBQztBQUMzQyxPQUFPLEVBQUUsTUFBTSxFQUFFLGtCQUFrQixJQUFJLHNCQUFzQixFQUFFLE1BQU0sU0FBUyxDQUFDO0FBRS9FLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO0FBRS9DLE1BQU0sSUFBSSxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7QUE2RmxDLE1BQU0sT0FBTyxXQUFXO0lBQ3RCLEtBQUssQ0FBYTtJQUNsQixHQUFHLENBQVc7SUFFZCxZQUFZLEtBQTJCO1FBQ3JDLElBQUksS0FBSyxJQUFJLE9BQU8sS0FBSyxDQUFDLEdBQUcsS0FBSyxVQUFVLElBQUksT0FBTyxLQUFLLENBQUMsR0FBRyxLQUFLLFVBQVUsRUFBRSxDQUFDO1lBQ2hGLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBa0IsQ0FBQztRQUNsQyxDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksQ0FBQyxHQUFHLEdBQUcsS0FBSyxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxD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
|
|
156
|
+
|
|
157
|
+
//#endregion
|
|
158
|
+
export { FileManager, staticCache };
|
package/package.json
CHANGED
|
@@ -1,28 +1,39 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eggjs/koa-static-cache",
|
|
3
|
+
"version": "7.0.0-beta.36",
|
|
3
4
|
"description": "Static cache middleware for koa",
|
|
4
|
-
"version": "7.0.0-beta.34",
|
|
5
5
|
"keywords": [
|
|
6
|
-
"koa",
|
|
7
|
-
"middleware",
|
|
8
|
-
"file",
|
|
9
|
-
"static",
|
|
10
6
|
"cache",
|
|
7
|
+
"file",
|
|
11
8
|
"gzip",
|
|
12
|
-
"
|
|
9
|
+
"koa",
|
|
10
|
+
"middleware",
|
|
11
|
+
"sendfile",
|
|
12
|
+
"static"
|
|
13
13
|
],
|
|
14
|
+
"homepage": "https://github.com/eggjs/egg/tree/next/packages/koa-static-cache",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/eggjs/egg/issues"
|
|
17
|
+
},
|
|
14
18
|
"license": "MIT",
|
|
15
19
|
"repository": {
|
|
16
20
|
"type": "git",
|
|
17
|
-
"url": "git://github.com/eggjs/egg.git",
|
|
21
|
+
"url": "git+https://github.com/eggjs/egg.git",
|
|
18
22
|
"directory": "packages/koa-static-cache"
|
|
19
23
|
},
|
|
20
|
-
"
|
|
21
|
-
"
|
|
24
|
+
"files": [
|
|
25
|
+
"dist"
|
|
26
|
+
],
|
|
27
|
+
"type": "module",
|
|
28
|
+
"main": "./dist/index.js",
|
|
29
|
+
"module": "./dist/index.js",
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"exports": {
|
|
32
|
+
".": "./dist/index.js",
|
|
33
|
+
"./package.json": "./package.json"
|
|
22
34
|
},
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
"node": ">=22.18.0"
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
26
37
|
},
|
|
27
38
|
"dependencies": {
|
|
28
39
|
"@eggjs/compressible": "^3.0.0",
|
|
@@ -33,39 +44,17 @@
|
|
|
33
44
|
"devDependencies": {
|
|
34
45
|
"@types/fs-readdir-recursive": "^1.1.3",
|
|
35
46
|
"@types/mime-types": "^3.0.0",
|
|
36
|
-
"@types/node": "^24.
|
|
37
|
-
"oxlint": "^1.24.0",
|
|
38
|
-
"oxlint-tsgolint": "^0.3.0",
|
|
39
|
-
"rimraf": "^6.0.1",
|
|
40
|
-
"tsdown": "0.15.11",
|
|
47
|
+
"@types/node": "^24.10.2",
|
|
41
48
|
"typescript": "^5.9.3",
|
|
42
|
-
"vitest": "4.0.5",
|
|
43
49
|
"ylru": "^2.0.0",
|
|
44
|
-
"@eggjs/
|
|
45
|
-
"@eggjs/
|
|
46
|
-
"@eggjs/tsconfig": "3.1.0-beta.
|
|
47
|
-
"@eggjs/supertest": "9.0.0-beta.34"
|
|
48
|
-
},
|
|
49
|
-
"type": "module",
|
|
50
|
-
"exports": {
|
|
51
|
-
".": "./dist/index.js",
|
|
52
|
-
"./package.json": "./package.json"
|
|
50
|
+
"@eggjs/koa": "3.1.0-beta.36",
|
|
51
|
+
"@eggjs/supertest": "9.0.0-beta.36",
|
|
52
|
+
"@eggjs/tsconfig": "3.1.0-beta.36"
|
|
53
53
|
},
|
|
54
|
-
"
|
|
55
|
-
"
|
|
54
|
+
"engines": {
|
|
55
|
+
"node": ">=22.18.0"
|
|
56
56
|
},
|
|
57
|
-
"files": [
|
|
58
|
-
"dist"
|
|
59
|
-
],
|
|
60
|
-
"types": "./dist/index.d.ts",
|
|
61
|
-
"main": "./dist/index.js",
|
|
62
|
-
"module": "./dist/index.js",
|
|
63
57
|
"scripts": {
|
|
64
|
-
"
|
|
65
|
-
"typecheck": "tsc --noEmit",
|
|
66
|
-
"lint": "oxlint --type-aware",
|
|
67
|
-
"lint:fix": "npm run lint -- --fix",
|
|
68
|
-
"test": "npm run lint:fix && vitest run",
|
|
69
|
-
"ci": "vitest run --coverage"
|
|
58
|
+
"typecheck": "tsgo --noEmit"
|
|
70
59
|
}
|
|
71
60
|
}
|