@eggjs/static 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017-present Alibaba Group Holding Limited and other contributors.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,69 @@
1
+ # @eggjs/static
2
+
3
+ [![NPM version][npm-image]][npm-url]
4
+ [![Node.js CI](https://github.com/eggjs/static/actions/workflows/nodejs.yml/badge.svg)](https://github.com/eggjs/static/actions/workflows/nodejs.yml)
5
+ [![Test coverage][codecov-image]][codecov-url]
6
+ [![Known Vulnerabilities][snyk-image]][snyk-url]
7
+ [![npm download][download-image]][download-url]
8
+ [![Node.js Version](https://img.shields.io/node/v/@eggjs/static.svg?style=flat)](https://nodejs.org/en/download/)
9
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://makeapullrequest.com)
10
+
11
+ [npm-image]: https://img.shields.io/npm/v/@eggjs/static.svg?style=flat-square
12
+ [npm-url]: https://npmjs.org/package/@eggjs/static
13
+ [codecov-image]: https://img.shields.io/codecov/c/github/eggjs/static.svg?style=flat-square
14
+ [codecov-url]: https://codecov.io/github/eggjs/static?branch=master
15
+ [snyk-image]: https://snyk.io/test/npm/@eggjs/static/badge.svg?style=flat-square
16
+ [snyk-url]: https://snyk.io/test/npm/@eggjs/static
17
+ [download-image]: https://img.shields.io/npm/dm/@eggjs/static.svg?style=flat-square
18
+ [download-url]: https://npmjs.org/package/@eggjs/static
19
+
20
+ Static server plugin for egg, base on [@eggjs/koa-static-cache](https://github.com/eggjs/koa-static-cache).
21
+
22
+ ## Install
23
+
24
+ `@eggjs/static` is a plugin that has been built-in for egg. It is enabled by default.
25
+
26
+ ## Configuration
27
+
28
+ `@eggjs/static` support all configurations in [@eggjs/koa-static-cache](https://github.com/eggjs/koa-static-cache).
29
+ And with default configurations below:
30
+
31
+ - prefix: `'/public/'`
32
+ - dir: `path.join(appInfo.baseDir, 'app/public')`
33
+ - dynamic: `true`
34
+ - preload: `false`
35
+ - maxAge: `31536000` in prod env, `0` in other envs
36
+ - buffer: `true` in prod env, `false` in other envs
37
+
38
+ `@eggjs/static` provides one more option:
39
+
40
+ - maxFiles: the maximum value of cache items, only effective when dynamic is true, default is `1000`.
41
+
42
+ **All static files in `$baseDir/app/public` can be visited with prefix `/public`, and all the files are lazy loaded.**
43
+
44
+ - In non-production environment, assets won't be cached, your modification can take effect immediately.
45
+ - In production environment, `@eggjs/static` will cache the assets after visited, you need to restart the process to update the assets.
46
+ - Dir default is `$baseDir/app/public` but you can also define **multiple directory** by use `dir: [dir1, dir2, ...]` or `dir: [dir1, { prefix: '/static2', dir: dir2 }]`, static server will use all these directories.
47
+
48
+ ```ts
49
+ // {app_root}/config/config.default.ts
50
+ export default {
51
+ static: {
52
+ // maxAge: 31536000,
53
+ },
54
+ };
55
+ ```
56
+
57
+ ## Questions & Suggestions
58
+
59
+ Please open an issue [here](https://github.com/eggjs/egg/issues).
60
+
61
+ ## License
62
+
63
+ [MIT](LICENSE)
64
+
65
+ ## Contributors
66
+
67
+ [![Contributors](https://contrib.rocks/image?repo=eggjs/static)](https://github.com/eggjs/static/graphs/contributors)
68
+
69
+ Made with [contributors-img](https://contrib.rocks).
@@ -0,0 +1,5 @@
1
+ import compose from 'koa-compose';
2
+ import type { EggCore, Context } from '@eggjs/core';
3
+ import type { StaticConfig } from '../../types.js';
4
+ declare const _default: (options: StaticConfig, app: EggCore) => compose.ComposedMiddleware<Context>;
5
+ export default _default;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_assert_1 = __importDefault(require("node:assert"));
7
+ const node_fs_1 = require("node:fs");
8
+ const koa_range_1 = __importDefault(require("koa-range"));
9
+ const koa_compose_1 = __importDefault(require("koa-compose"));
10
+ const koa_static_cache_1 = require("@eggjs/koa-static-cache");
11
+ const ylru_1 = require("ylru");
12
+ const is_type_of_1 = require("is-type-of");
13
+ exports.default = (options, app) => {
14
+ const dirs = (options.dirs ?? []).concat(options.dir);
15
+ const prefixes = [];
16
+ function rangeMiddleware(ctx, next) {
17
+ // if match static file, and use range middleware.
18
+ const isMatch = prefixes.some(p => ctx.path.startsWith(p));
19
+ if (isMatch) {
20
+ return (0, koa_range_1.default)(ctx, next);
21
+ }
22
+ return next();
23
+ }
24
+ const middlewares = [rangeMiddleware];
25
+ for (const dirObj of dirs) {
26
+ (0, node_assert_1.default)((0, is_type_of_1.isObject)(dirObj) || typeof dirObj === 'string', '`config.static.dir` must be `string | Array<string|object>`');
27
+ let newOptions;
28
+ if (typeof dirObj === 'string') {
29
+ // copy origin options to new options ensure the safety of objects
30
+ newOptions = {
31
+ ...options,
32
+ dir: dirObj,
33
+ };
34
+ }
35
+ else {
36
+ (0, node_assert_1.default)(typeof dirObj.dir === 'string', '`config.static.dirs` should contains `[].dir` property when object style');
37
+ newOptions = {
38
+ ...options,
39
+ ...dirObj,
40
+ };
41
+ }
42
+ if (newOptions.dynamic && !newOptions.files) {
43
+ newOptions.files = new ylru_1.LRU(newOptions.maxFiles);
44
+ }
45
+ if (newOptions.prefix) {
46
+ prefixes.push(newOptions.prefix);
47
+ }
48
+ // ensure directory exists
49
+ if (!(0, node_fs_1.existsSync)(newOptions.dir)) {
50
+ (0, node_fs_1.mkdirSync)(newOptions.dir, { recursive: true });
51
+ }
52
+ middlewares.push((0, koa_static_cache_1.staticCache)(newOptions));
53
+ app.coreLogger.info('[@eggjs/static] starting static serve %s -> %s', newOptions.prefix, newOptions.dir);
54
+ }
55
+ return (0, koa_compose_1.default)(middlewares);
56
+ };
57
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGljLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2FwcC9taWRkbGV3YXJlL3N0YXRpYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDhEQUFpQztBQUNqQyxxQ0FBZ0Q7QUFDaEQsMERBQThCO0FBQzlCLDhEQUFrQztBQUVsQyw4REFBc0Q7QUFDdEQsK0JBQTJCO0FBQzNCLDJDQUFzQztBQUd0QyxrQkFBZSxDQUFDLE9BQXFCLEVBQUUsR0FBWSxFQUFFLEVBQUU7SUFDckQsTUFBTSxJQUFJLEdBQUcsQ0FBQyxPQUFPLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7SUFFdEQsTUFBTSxRQUFRLEdBQWEsRUFBRSxDQUFDO0lBRTlCLFNBQVMsZUFBZSxDQUFDLEdBQVksRUFBRSxJQUFVO1FBQy9DLGtEQUFrRDtRQUNsRCxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMzRCxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQ1osT0FBTyxJQUFBLG1CQUFLLEVBQUMsR0FBVSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2pDLENBQUM7UUFDRCxPQUFPLElBQUksRUFBRSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxNQUFNLFdBQVcsR0FBRyxDQUFFLGVBQWUsQ0FBRSxDQUFDO0lBRXhDLEtBQUssTUFBTSxNQUFNLElBQUksSUFBSSxFQUFFLENBQUM7UUFDMUIsSUFBQSxxQkFBTSxFQUFDLElBQUEscUJBQVEsRUFBQyxNQUFNLENBQUMsSUFBSSxPQUFPLE1BQU0sS0FBSyxRQUFRLEVBQ25ELDZEQUE2RCxDQUFDLENBQUM7UUFFakUsSUFBSSxVQUE0QixDQUFDO1FBQ2pDLElBQUksT0FBTyxNQUFNLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDL0Isa0VBQWtFO1lBQ2xFLFVBQVUsR0FBRztnQkFDWCxHQUFHLE9BQU87Z0JBQ1YsR0FBRyxFQUFFLE1BQU07YUFDWixDQUFDO1FBQ0osQ0FBQzthQUFNLENBQUM7WUFDTixJQUFBLHFCQUFNLEVBQUMsT0FBTyxNQUFNLENBQUMsR0FBRyxLQUFLLFFBQVEsRUFDbkMsMEVBQTBFLENBQUMsQ0FBQztZQUM5RSxVQUFVLEdBQUc7Z0JBQ1gsR0FBRyxPQUFPO2dCQUNWLEdBQUcsTUFBTTthQUNWLENBQUM7UUFDSixDQUFDO1FBRUQsSUFBSSxVQUFVLENBQUMsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzVDLFVBQVUsQ0FBQyxLQUFLLEdBQUcsSUFBSSxVQUFHLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ2xELENBQUM7UUFFRCxJQUFJLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUN0QixRQUFRLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNuQyxDQUFDO1FBRUQsMEJBQTBCO1FBQzFCLElBQUksQ0FBQyxJQUFBLG9CQUFVLEVBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDaEMsSUFBQSxtQkFBUyxFQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNqRCxDQUFDO1FBQ0QsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFBLDhCQUFXLEVBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztRQUV6QyxHQUFXLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxnREFBZ0QsRUFDM0UsVUFBVSxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVELE9BQU8sSUFBQSxxQkFBTyxFQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQzlCLENBQUMsQ0FBQyJ9
@@ -0,0 +1,6 @@
1
+ import type { ILifecycleBoot, EggCore } from '@eggjs/core';
2
+ export default class AppBoot implements ILifecycleBoot {
3
+ private readonly app;
4
+ constructor(app: EggCore);
5
+ configWillLoad(): Promise<void>;
6
+ }
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class AppBoot {
4
+ app;
5
+ constructor(app) {
6
+ this.app = app;
7
+ }
8
+ async configWillLoad() {
9
+ const app = this.app;
10
+ // make sure static middleware is before bodyParser
11
+ const index = app.config.coreMiddleware.indexOf('bodyParser');
12
+ if (index === -1) {
13
+ app.config.coreMiddleware.push('static');
14
+ }
15
+ else {
16
+ app.config.coreMiddleware.splice(index, 0, 'static');
17
+ }
18
+ }
19
+ }
20
+ exports.default = AppBoot;
21
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUVBLE1BQXFCLE9BQU87SUFDVCxHQUFHLENBQUM7SUFDckIsWUFBWSxHQUFZO1FBQ3RCLElBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDO0lBQ2pCLENBQUM7SUFDRCxLQUFLLENBQUMsY0FBYztRQUNsQixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDO1FBQ3JCLG1EQUFtRDtRQUNuRCxNQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDOUQsSUFBSSxLQUFLLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUNqQixHQUFHLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDM0MsQ0FBQzthQUFNLENBQUM7WUFDTixHQUFHLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUN2RCxDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBZkQsMEJBZUMifQ==
@@ -0,0 +1,6 @@
1
+ import type { EggAppInfo } from '@eggjs/core';
2
+ import type { StaticConfig } from '../types.js';
3
+ declare const _default: (appInfo: EggAppInfo) => {
4
+ static: StaticConfig;
5
+ };
6
+ export default _default;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_path_1 = __importDefault(require("node:path"));
7
+ exports.default = (appInfo) => {
8
+ return {
9
+ static: {
10
+ prefix: '/public/',
11
+ dir: node_path_1.default.join(appInfo.baseDir, 'app/public'),
12
+ // dirs: [ dir1, dir2 ] or [ dir1, { prefix: '/static2', dir: dir2 } ],
13
+ dirs: undefined,
14
+ // support lazy load
15
+ dynamic: true,
16
+ preload: false,
17
+ buffer: false,
18
+ maxFiles: 1000,
19
+ },
20
+ };
21
+ };
22
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmRlZmF1bHQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29uZmlnL2NvbmZpZy5kZWZhdWx0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsMERBQTZCO0FBSTdCLGtCQUFlLENBQUMsT0FBbUIsRUFBRSxFQUFFO0lBQ3JDLE9BQU87UUFDTCxNQUFNLEVBQUU7WUFDTixNQUFNLEVBQUUsVUFBVTtZQUNsQixHQUFHLEVBQUUsbUJBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxZQUFZLENBQUM7WUFDN0MsdUVBQXVFO1lBQ3ZFLElBQUksRUFBRSxTQUFTO1lBQ2Ysb0JBQW9CO1lBQ3BCLE9BQU8sRUFBRSxJQUFJO1lBQ2IsT0FBTyxFQUFFLEtBQUs7WUFDZCxNQUFNLEVBQUUsS0FBSztZQUNiLFFBQVEsRUFBRSxJQUFJO1NBQ0M7S0FDbEIsQ0FBQztBQUNKLENBQUMsQ0FBQyJ9
@@ -0,0 +1,5 @@
1
+ import type { StaticConfig } from '../types.js';
2
+ declare const _default: {
3
+ static: StaticConfig;
4
+ };
5
+ export default _default;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = {
4
+ static: {
5
+ maxAge: 31536000,
6
+ buffer: true,
7
+ },
8
+ };
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLnByb2QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29uZmlnL2NvbmZpZy5wcm9kLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBRUEsa0JBQWU7SUFDYixNQUFNLEVBQUU7UUFDTixNQUFNLEVBQUUsUUFBUTtRQUNoQixNQUFNLEVBQUUsSUFBSTtLQUNHO0NBQ2xCLENBQUMifQ==
@@ -0,0 +1 @@
1
+ import './types.js';
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ require("./types.js");
4
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxzQkFBb0IifQ==
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,60 @@
1
+ import type { Options as StaticCacheOptions } from '@eggjs/koa-static-cache';
2
+ export interface StaticDirOptions extends Omit<StaticCacheOptions, 'dir'> {
3
+ /**
4
+ * static files store dir
5
+ */
6
+ dir: string;
7
+ /**
8
+ * static files prefix
9
+ * Default to `'/public/'`
10
+ */
11
+ prefix: string;
12
+ /**
13
+ * cache max age in `seconds`
14
+ * Default to `0` on development, `31536000` on production
15
+ */
16
+ maxAge: number;
17
+ /**
18
+ * dynamic load file which not cached on initialization
19
+ * Default to `true
20
+ */
21
+ dynamic: boolean;
22
+ /**
23
+ * caches the assets on initialization or not,
24
+ * always work together with `options.dynamic`
25
+ * Default to `false`
26
+ */
27
+ preload: boolean;
28
+ /**
29
+ * buffer the file content or not
30
+ * Default to `false` on development, `true` on production
31
+ */
32
+ buffer: boolean;
33
+ /**
34
+ * max files count in store
35
+ * Default to `1000`
36
+ */
37
+ maxFiles: number;
38
+ }
39
+ /**
40
+ * Static file serve
41
+ * @member Config#static
42
+ * @see https://github.com/koajs/static-cache
43
+ */
44
+ export interface StaticConfig extends Omit<StaticDirOptions, 'dir'> {
45
+ /**
46
+ * static files store dir
47
+ * Default to `${baseDir}/app/public`
48
+ */
49
+ dir: string | Array<string | StaticDirOptions>;
50
+ /**
51
+ * static files store dirs
52
+ * @deprecated use `dir` instead
53
+ */
54
+ dirs?: Array<string | StaticDirOptions>;
55
+ }
56
+ declare module '@eggjs/core' {
57
+ interface EggAppConfig {
58
+ static: StaticConfig;
59
+ }
60
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
@@ -0,0 +1,5 @@
1
+ import compose from 'koa-compose';
2
+ import type { EggCore, Context } from '@eggjs/core';
3
+ import type { StaticConfig } from '../../types.js';
4
+ declare const _default: (options: StaticConfig, app: EggCore) => compose.ComposedMiddleware<Context>;
5
+ export default _default;
@@ -0,0 +1,52 @@
1
+ import assert from 'node:assert';
2
+ import { mkdirSync, existsSync } from 'node:fs';
3
+ import range from 'koa-range';
4
+ import compose from 'koa-compose';
5
+ import { staticCache } from '@eggjs/koa-static-cache';
6
+ import { LRU } from 'ylru';
7
+ import { isObject } from 'is-type-of';
8
+ export default (options, app) => {
9
+ const dirs = (options.dirs ?? []).concat(options.dir);
10
+ const prefixes = [];
11
+ function rangeMiddleware(ctx, next) {
12
+ // if match static file, and use range middleware.
13
+ const isMatch = prefixes.some(p => ctx.path.startsWith(p));
14
+ if (isMatch) {
15
+ return range(ctx, next);
16
+ }
17
+ return next();
18
+ }
19
+ const middlewares = [rangeMiddleware];
20
+ for (const dirObj of dirs) {
21
+ assert(isObject(dirObj) || typeof dirObj === 'string', '`config.static.dir` must be `string | Array<string|object>`');
22
+ let newOptions;
23
+ if (typeof dirObj === 'string') {
24
+ // copy origin options to new options ensure the safety of objects
25
+ newOptions = {
26
+ ...options,
27
+ dir: dirObj,
28
+ };
29
+ }
30
+ else {
31
+ assert(typeof dirObj.dir === 'string', '`config.static.dirs` should contains `[].dir` property when object style');
32
+ newOptions = {
33
+ ...options,
34
+ ...dirObj,
35
+ };
36
+ }
37
+ if (newOptions.dynamic && !newOptions.files) {
38
+ newOptions.files = new LRU(newOptions.maxFiles);
39
+ }
40
+ if (newOptions.prefix) {
41
+ prefixes.push(newOptions.prefix);
42
+ }
43
+ // ensure directory exists
44
+ if (!existsSync(newOptions.dir)) {
45
+ mkdirSync(newOptions.dir, { recursive: true });
46
+ }
47
+ middlewares.push(staticCache(newOptions));
48
+ app.coreLogger.info('[@eggjs/static] starting static serve %s -> %s', newOptions.prefix, newOptions.dir);
49
+ }
50
+ return compose(middlewares);
51
+ };
52
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGljLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2FwcC9taWRkbGV3YXJlL3N0YXRpYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLE1BQU0sTUFBTSxhQUFhLENBQUM7QUFDakMsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDaEQsT0FBTyxLQUFLLE1BQU0sV0FBVyxDQUFDO0FBQzlCLE9BQU8sT0FBTyxNQUFNLGFBQWEsQ0FBQztBQUVsQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDdEQsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMzQixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBR3RDLGVBQWUsQ0FBQyxPQUFxQixFQUFFLEdBQVksRUFBRSxFQUFFO0lBQ3JELE1BQU0sSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRXRELE1BQU0sUUFBUSxHQUFhLEVBQUUsQ0FBQztJQUU5QixTQUFTLGVBQWUsQ0FBQyxHQUFZLEVBQUUsSUFBVTtRQUMvQyxrREFBa0Q7UUFDbEQsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDM0QsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNaLE9BQU8sS0FBSyxDQUFDLEdBQVUsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNqQyxDQUFDO1FBQ0QsT0FBTyxJQUFJLEVBQUUsQ0FBQztJQUNoQixDQUFDO0lBRUQsTUFBTSxXQUFXLEdBQUcsQ0FBRSxlQUFlLENBQUUsQ0FBQztJQUV4QyxLQUFLLE1BQU0sTUFBTSxJQUFJLElBQUksRUFBRSxDQUFDO1FBQzFCLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksT0FBTyxNQUFNLEtBQUssUUFBUSxFQUNuRCw2REFBNkQsQ0FBQyxDQUFDO1FBRWpFLElBQUksVUFBNEIsQ0FBQztRQUNqQyxJQUFJLE9BQU8sTUFBTSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQy9CLGtFQUFrRTtZQUNsRSxVQUFVLEdBQUc7Z0JBQ1gsR0FBRyxPQUFPO2dCQUNWLEdBQUcsRUFBRSxNQUFNO2FBQ1osQ0FBQztRQUNKLENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxDQUFDLE9BQU8sTUFBTSxDQUFDLEdBQUcsS0FBSyxRQUFRLEVBQ25DLDBFQUEwRSxDQUFDLENBQUM7WUFDOUUsVUFBVSxHQUFHO2dCQUNYLEdBQUcsT0FBTztnQkFDVixHQUFHLE1BQU07YUFDVixDQUFDO1FBQ0osQ0FBQztRQUVELElBQUksVUFBVSxDQUFDLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUM1QyxVQUFVLENBQUMsS0FBSyxHQUFHLElBQUksR0FBRyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNsRCxDQUFDO1FBRUQsSUFBSSxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDdEIsUUFBUSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDbkMsQ0FBQztRQUVELDBCQUEwQjtRQUMxQixJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ2hDLFNBQVMsQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDakQsQ0FBQztRQUNELFdBQVcsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFFekMsR0FBVyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsZ0RBQWdELEVBQzNFLFVBQVUsQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRCxPQUFPLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUM5QixDQUFDLENBQUMifQ==
@@ -0,0 +1,6 @@
1
+ import type { ILifecycleBoot, EggCore } from '@eggjs/core';
2
+ export default class AppBoot implements ILifecycleBoot {
3
+ private readonly app;
4
+ constructor(app: EggCore);
5
+ configWillLoad(): Promise<void>;
6
+ }
@@ -0,0 +1,18 @@
1
+ export default class AppBoot {
2
+ app;
3
+ constructor(app) {
4
+ this.app = app;
5
+ }
6
+ async configWillLoad() {
7
+ const app = this.app;
8
+ // make sure static middleware is before bodyParser
9
+ const index = app.config.coreMiddleware.indexOf('bodyParser');
10
+ if (index === -1) {
11
+ app.config.coreMiddleware.push('static');
12
+ }
13
+ else {
14
+ app.config.coreMiddleware.splice(index, 0, 'static');
15
+ }
16
+ }
17
+ }
18
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxNQUFNLENBQUMsT0FBTyxPQUFPLE9BQU87SUFDVCxHQUFHLENBQUM7SUFDckIsWUFBWSxHQUFZO1FBQ3RCLElBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDO0lBQ2pCLENBQUM7SUFDRCxLQUFLLENBQUMsY0FBYztRQUNsQixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDO1FBQ3JCLG1EQUFtRDtRQUNuRCxNQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDOUQsSUFBSSxLQUFLLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUNqQixHQUFHLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDM0MsQ0FBQzthQUFNLENBQUM7WUFDTixHQUFHLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUN2RCxDQUFDO0lBQ0gsQ0FBQztDQUNGIn0=
@@ -0,0 +1,6 @@
1
+ import type { EggAppInfo } from '@eggjs/core';
2
+ import type { StaticConfig } from '../types.js';
3
+ declare const _default: (appInfo: EggAppInfo) => {
4
+ static: StaticConfig;
5
+ };
6
+ export default _default;
@@ -0,0 +1,17 @@
1
+ import path from 'node:path';
2
+ export default (appInfo) => {
3
+ return {
4
+ static: {
5
+ prefix: '/public/',
6
+ dir: path.join(appInfo.baseDir, 'app/public'),
7
+ // dirs: [ dir1, dir2 ] or [ dir1, { prefix: '/static2', dir: dir2 } ],
8
+ dirs: undefined,
9
+ // support lazy load
10
+ dynamic: true,
11
+ preload: false,
12
+ buffer: false,
13
+ maxFiles: 1000,
14
+ },
15
+ };
16
+ };
17
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmRlZmF1bHQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29uZmlnL2NvbmZpZy5kZWZhdWx0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sSUFBSSxNQUFNLFdBQVcsQ0FBQztBQUk3QixlQUFlLENBQUMsT0FBbUIsRUFBRSxFQUFFO0lBQ3JDLE9BQU87UUFDTCxNQUFNLEVBQUU7WUFDTixNQUFNLEVBQUUsVUFBVTtZQUNsQixHQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLFlBQVksQ0FBQztZQUM3Qyx1RUFBdUU7WUFDdkUsSUFBSSxFQUFFLFNBQVM7WUFDZixvQkFBb0I7WUFDcEIsT0FBTyxFQUFFLElBQUk7WUFDYixPQUFPLEVBQUUsS0FBSztZQUNkLE1BQU0sRUFBRSxLQUFLO1lBQ2IsUUFBUSxFQUFFLElBQUk7U0FDQztLQUNsQixDQUFDO0FBQ0osQ0FBQyxDQUFDIn0=
@@ -0,0 +1,5 @@
1
+ import type { StaticConfig } from '../types.js';
2
+ declare const _default: {
3
+ static: StaticConfig;
4
+ };
5
+ export default _default;
@@ -0,0 +1,7 @@
1
+ export default {
2
+ static: {
3
+ maxAge: 31536000,
4
+ buffer: true,
5
+ },
6
+ };
7
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLnByb2QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29uZmlnL2NvbmZpZy5wcm9kLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLGVBQWU7SUFDYixNQUFNLEVBQUU7UUFDTixNQUFNLEVBQUUsUUFBUTtRQUNoQixNQUFNLEVBQUUsSUFBSTtLQUNHO0NBQ2xCLENBQUMifQ==
@@ -0,0 +1 @@
1
+ import './types.js';
@@ -0,0 +1,2 @@
1
+ import './types.js';
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxZQUFZLENBQUMifQ==
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
@@ -0,0 +1,60 @@
1
+ import type { Options as StaticCacheOptions } from '@eggjs/koa-static-cache';
2
+ export interface StaticDirOptions extends Omit<StaticCacheOptions, 'dir'> {
3
+ /**
4
+ * static files store dir
5
+ */
6
+ dir: string;
7
+ /**
8
+ * static files prefix
9
+ * Default to `'/public/'`
10
+ */
11
+ prefix: string;
12
+ /**
13
+ * cache max age in `seconds`
14
+ * Default to `0` on development, `31536000` on production
15
+ */
16
+ maxAge: number;
17
+ /**
18
+ * dynamic load file which not cached on initialization
19
+ * Default to `true
20
+ */
21
+ dynamic: boolean;
22
+ /**
23
+ * caches the assets on initialization or not,
24
+ * always work together with `options.dynamic`
25
+ * Default to `false`
26
+ */
27
+ preload: boolean;
28
+ /**
29
+ * buffer the file content or not
30
+ * Default to `false` on development, `true` on production
31
+ */
32
+ buffer: boolean;
33
+ /**
34
+ * max files count in store
35
+ * Default to `1000`
36
+ */
37
+ maxFiles: number;
38
+ }
39
+ /**
40
+ * Static file serve
41
+ * @member Config#static
42
+ * @see https://github.com/koajs/static-cache
43
+ */
44
+ export interface StaticConfig extends Omit<StaticDirOptions, 'dir'> {
45
+ /**
46
+ * static files store dir
47
+ * Default to `${baseDir}/app/public`
48
+ */
49
+ dir: string | Array<string | StaticDirOptions>;
50
+ /**
51
+ * static files store dirs
52
+ * @deprecated use `dir` instead
53
+ */
54
+ dirs?: Array<string | StaticDirOptions>;
55
+ }
56
+ declare module '@eggjs/core' {
57
+ interface EggAppConfig {
58
+ static: StaticConfig;
59
+ }
60
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "@eggjs/static",
3
+ "version": "3.0.0"
4
+ }
package/package.json ADDED
@@ -0,0 +1,93 @@
1
+ {
2
+ "name": "@eggjs/static",
3
+ "version": "3.0.0",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "description": "static server plugin for egg",
8
+ "eggPlugin": {
9
+ "name": "static",
10
+ "exports": {
11
+ "import": "./dist/esm",
12
+ "require": "./dist/commonjs",
13
+ "typescript": "./src"
14
+ }
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/eggjs/static.git"
19
+ },
20
+ "keywords": [
21
+ "egg",
22
+ "egg-plugin",
23
+ "eggPlugin",
24
+ "static"
25
+ ],
26
+ "author": "dead_horse",
27
+ "license": "MIT",
28
+ "engines": {
29
+ "node": ">= 18.19.0"
30
+ },
31
+ "dependencies": {
32
+ "@eggjs/core": "^6.2.13",
33
+ "@eggjs/koa-static-cache": "^6.0.0",
34
+ "is-type-of": "^2.2.0",
35
+ "koa-compose": "^4.1.0",
36
+ "koa-range": "^0.3.0",
37
+ "ylru": "^2.0.0"
38
+ },
39
+ "devDependencies": {
40
+ "@arethetypeswrong/cli": "^0.17.1",
41
+ "@eggjs/bin": "7",
42
+ "@eggjs/mock": "^6.0.5",
43
+ "@eggjs/tsconfig": "1",
44
+ "@types/koa-compose": "^3.2.8",
45
+ "@types/koa-range": "^0.3.5",
46
+ "@types/mocha": "10",
47
+ "@types/node": "22",
48
+ "egg": "4",
49
+ "eslint": "8",
50
+ "eslint-config-egg": "14",
51
+ "rimraf": "6",
52
+ "tshy": "3",
53
+ "tshy-after": "1",
54
+ "typescript": "5"
55
+ },
56
+ "scripts": {
57
+ "lint": "eslint --cache src test --ext .ts",
58
+ "pretest": "npm run clean && npm run lint -- --fix",
59
+ "test": "egg-bin test",
60
+ "preci": "npm run clean && npm run lint",
61
+ "ci": "egg-bin cov",
62
+ "postci": "npm run prepublishOnly && npm run clean",
63
+ "clean": "rimraf dist",
64
+ "prepublishOnly": "tshy && tshy-after && attw --pack"
65
+ },
66
+ "type": "module",
67
+ "tshy": {
68
+ "exports": {
69
+ ".": "./src/index.ts",
70
+ "./package.json": "./package.json"
71
+ }
72
+ },
73
+ "exports": {
74
+ ".": {
75
+ "import": {
76
+ "types": "./dist/esm/index.d.ts",
77
+ "default": "./dist/esm/index.js"
78
+ },
79
+ "require": {
80
+ "types": "./dist/commonjs/index.d.ts",
81
+ "default": "./dist/commonjs/index.js"
82
+ }
83
+ },
84
+ "./package.json": "./package.json"
85
+ },
86
+ "files": [
87
+ "dist",
88
+ "src"
89
+ ],
90
+ "types": "./dist/commonjs/index.d.ts",
91
+ "main": "./dist/commonjs/index.js",
92
+ "module": "./dist/esm/index.js"
93
+ }
@@ -0,0 +1,66 @@
1
+ import assert from 'node:assert';
2
+ import { mkdirSync, existsSync } from 'node:fs';
3
+ import range from 'koa-range';
4
+ import compose from 'koa-compose';
5
+ import type { EggCore, Context, Next } from '@eggjs/core';
6
+ import { staticCache } from '@eggjs/koa-static-cache';
7
+ import { LRU } from 'ylru';
8
+ import { isObject } from 'is-type-of';
9
+ import type { StaticConfig, StaticDirOptions } from '../../types.js';
10
+
11
+ export default (options: StaticConfig, app: EggCore) => {
12
+ const dirs = (options.dirs ?? []).concat(options.dir);
13
+
14
+ const prefixes: string[] = [];
15
+
16
+ function rangeMiddleware(ctx: Context, next: Next) {
17
+ // if match static file, and use range middleware.
18
+ const isMatch = prefixes.some(p => ctx.path.startsWith(p));
19
+ if (isMatch) {
20
+ return range(ctx as any, next);
21
+ }
22
+ return next();
23
+ }
24
+
25
+ const middlewares = [ rangeMiddleware ];
26
+
27
+ for (const dirObj of dirs) {
28
+ assert(isObject(dirObj) || typeof dirObj === 'string',
29
+ '`config.static.dir` must be `string | Array<string|object>`');
30
+
31
+ let newOptions: StaticDirOptions;
32
+ if (typeof dirObj === 'string') {
33
+ // copy origin options to new options ensure the safety of objects
34
+ newOptions = {
35
+ ...options,
36
+ dir: dirObj,
37
+ };
38
+ } else {
39
+ assert(typeof dirObj.dir === 'string',
40
+ '`config.static.dirs` should contains `[].dir` property when object style');
41
+ newOptions = {
42
+ ...options,
43
+ ...dirObj,
44
+ };
45
+ }
46
+
47
+ if (newOptions.dynamic && !newOptions.files) {
48
+ newOptions.files = new LRU(newOptions.maxFiles);
49
+ }
50
+
51
+ if (newOptions.prefix) {
52
+ prefixes.push(newOptions.prefix);
53
+ }
54
+
55
+ // ensure directory exists
56
+ if (!existsSync(newOptions.dir)) {
57
+ mkdirSync(newOptions.dir, { recursive: true });
58
+ }
59
+ middlewares.push(staticCache(newOptions));
60
+
61
+ (app as any).coreLogger.info('[@eggjs/static] starting static serve %s -> %s',
62
+ newOptions.prefix, newOptions.dir);
63
+ }
64
+
65
+ return compose(middlewares);
66
+ };
package/src/app.ts ADDED
@@ -0,0 +1,18 @@
1
+ import type { ILifecycleBoot, EggCore } from '@eggjs/core';
2
+
3
+ export default class AppBoot implements ILifecycleBoot {
4
+ private readonly app;
5
+ constructor(app: EggCore) {
6
+ this.app = app;
7
+ }
8
+ async configWillLoad() {
9
+ const app = this.app;
10
+ // make sure static middleware is before bodyParser
11
+ const index = app.config.coreMiddleware.indexOf('bodyParser');
12
+ if (index === -1) {
13
+ app.config.coreMiddleware.push('static');
14
+ } else {
15
+ app.config.coreMiddleware.splice(index, 0, 'static');
16
+ }
17
+ }
18
+ }
@@ -0,0 +1,19 @@
1
+ import path from 'node:path';
2
+ import type { EggAppInfo } from '@eggjs/core';
3
+ import type { StaticConfig } from '../types.js';
4
+
5
+ export default (appInfo: EggAppInfo) => {
6
+ return {
7
+ static: {
8
+ prefix: '/public/',
9
+ dir: path.join(appInfo.baseDir, 'app/public'),
10
+ // dirs: [ dir1, dir2 ] or [ dir1, { prefix: '/static2', dir: dir2 } ],
11
+ dirs: undefined,
12
+ // support lazy load
13
+ dynamic: true,
14
+ preload: false,
15
+ buffer: false,
16
+ maxFiles: 1000,
17
+ } as StaticConfig,
18
+ };
19
+ };
@@ -0,0 +1,8 @@
1
+ import type { StaticConfig } from '../types.js';
2
+
3
+ export default {
4
+ static: {
5
+ maxAge: 31536000,
6
+ buffer: true,
7
+ } as StaticConfig,
8
+ };
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ import './types.js';
package/src/types.ts ADDED
@@ -0,0 +1,64 @@
1
+ import type { Options as StaticCacheOptions } from '@eggjs/koa-static-cache';
2
+
3
+ export interface StaticDirOptions extends Omit<StaticCacheOptions, 'dir'> {
4
+ /**
5
+ * static files store dir
6
+ */
7
+ dir: string;
8
+ /**
9
+ * static files prefix
10
+ * Default to `'/public/'`
11
+ */
12
+ prefix: string;
13
+ /**
14
+ * cache max age in `seconds`
15
+ * Default to `0` on development, `31536000` on production
16
+ */
17
+ maxAge: number;
18
+ /**
19
+ * dynamic load file which not cached on initialization
20
+ * Default to `true
21
+ */
22
+ dynamic: boolean;
23
+ /**
24
+ * caches the assets on initialization or not,
25
+ * always work together with `options.dynamic`
26
+ * Default to `false`
27
+ */
28
+ preload: boolean;
29
+ /**
30
+ * buffer the file content or not
31
+ * Default to `false` on development, `true` on production
32
+ */
33
+ buffer: boolean;
34
+ /**
35
+ * max files count in store
36
+ * Default to `1000`
37
+ */
38
+ maxFiles: number;
39
+ }
40
+
41
+ /**
42
+ * Static file serve
43
+ * @member Config#static
44
+ * @see https://github.com/koajs/static-cache
45
+ */
46
+ export interface StaticConfig extends Omit<StaticDirOptions, 'dir'> {
47
+ /**
48
+ * static files store dir
49
+ * Default to `${baseDir}/app/public`
50
+ */
51
+ dir: string | Array<string | StaticDirOptions>;
52
+ /**
53
+ * static files store dirs
54
+ * @deprecated use `dir` instead
55
+ */
56
+ dirs?: Array<string | StaticDirOptions>;
57
+ }
58
+
59
+ declare module '@eggjs/core' {
60
+ // add EggAppConfig overrides types
61
+ interface EggAppConfig {
62
+ static: StaticConfig;
63
+ }
64
+ }
@@ -0,0 +1,4 @@
1
+ // make sure to import egg typings and let typescript know about it
2
+ // @see https://github.com/whxaxes/blog/issues/11
3
+ // and https://www.typescriptlang.org/docs/handbook/declaration-merging.html
4
+ import 'egg';