@eggjs/multipart 5.0.0-beta.20 → 5.0.0-beta.21
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/app/extend/context.d.ts +97 -2
- package/dist/app/extend/context.js +273 -6
- package/dist/app/middleware/multipart.d.ts +3 -6
- package/dist/app/middleware/multipart.js +17 -14
- package/dist/app/schedule/clean_tmpdir.d.ts +21 -27
- package/dist/app/schedule/clean_tmpdir.js +53 -56
- package/dist/app.d.ts +5 -9
- package/dist/app.js +18 -21
- package/dist/config/config.default.d.ts +89 -2
- package/dist/config/config.default.js +26 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +4 -8
- package/dist/lib/LimitError.d.ts +4 -7
- package/dist/lib/LimitError.js +12 -3
- package/dist/lib/MultipartFileTooLargeError.d.ts +5 -8
- package/dist/lib/MultipartFileTooLargeError.js +14 -3
- package/dist/lib/utils.d.ts +4 -8
- package/dist/lib/utils.js +91 -3
- package/dist/types.d.ts +22 -3
- package/dist/types.js +2 -3
- package/package.json +6 -6
- package/dist/LimitError-BZqeZJ5w.js +0 -15
- package/dist/MultipartFileTooLargeError-CFG577Bz.js +0 -17
- package/dist/config.default-AMmYIt7n.js +0 -28
- package/dist/config.default-CPo4ogXL.d.ts +0 -92
- package/dist/context-CLeGGj9o.js +0 -199
- package/dist/context-COfddVcC.d.ts +0 -101
- package/dist/types-BsuPrIpu.js +0 -1
- package/dist/types-DNLuS6JZ.d.ts +0 -24
- package/dist/utils-BwL2JNe7.js +0 -71
package/dist/app.js
CHANGED
|
@@ -1,21 +1,18 @@
|
|
|
1
|
-
import { normalizeOptions } from "./utils
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
//#endregion
|
|
21
|
-
export { AppBootHook as default };
|
|
1
|
+
import { normalizeOptions } from "./lib/utils.js";
|
|
2
|
+
export default class AppBootHook {
|
|
3
|
+
app;
|
|
4
|
+
constructor(app) {
|
|
5
|
+
this.app = app;
|
|
6
|
+
}
|
|
7
|
+
configWillLoad() {
|
|
8
|
+
this.app.config.multipart = normalizeOptions(this.app.config.multipart);
|
|
9
|
+
const options = this.app.config.multipart;
|
|
10
|
+
this.app.coreLogger.info('[@eggjs/multipart] %s mode enable', options.mode);
|
|
11
|
+
if (options.mode === 'file' || options.fileModeMatch) {
|
|
12
|
+
this.app.coreLogger.info('[@eggjs/multipart] will save temporary files to %j, cleanup job cron: %j', options.tmpdir, options.cleanSchedule.cron);
|
|
13
|
+
// enable multipart middleware
|
|
14
|
+
this.app.config.coreMiddleware.push('multipart');
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2FwcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUVsRCxNQUFNLENBQUMsT0FBTyxPQUFPLFdBQVc7SUFDYixHQUFHLENBQUM7SUFDckIsWUFBWSxHQUFnQjtRQUMxQixJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztJQUNqQixDQUFDO0lBRUQsY0FBYztRQUNaLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLFNBQVMsR0FBRyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN4RSxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUM7UUFFMUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLG1DQUFtQyxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM1RSxJQUFJLE9BQU8sQ0FBQyxJQUFJLEtBQUssTUFBTSxJQUFJLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUNyRCxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQ3RCLDBFQUEwRSxFQUMxRSxPQUFPLENBQUMsTUFBTSxFQUNkLE9BQU8sQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUMzQixDQUFDO1lBQ0YsOEJBQThCO1lBQzlCLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDbkQsQ0FBQztJQUNILENBQUM7Q0FDRiJ9
|
|
@@ -1,2 +1,89 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import type { Context, EggAppInfo } from 'egg';
|
|
2
|
+
import type { PathMatchingPattern } from 'egg-path-matching';
|
|
3
|
+
export type MatchItem = string | RegExp | ((ctx: Context) => boolean);
|
|
4
|
+
export interface MultipartConfig {
|
|
5
|
+
/**
|
|
6
|
+
* which mode to handle multipart request, default is `stream`, the hard way.
|
|
7
|
+
* If set mode to `file`, it's the easy way to handle multipart request and save it to local files.
|
|
8
|
+
* If you don't know the Node.js Stream work, maybe you should use the `file` mode to get started.
|
|
9
|
+
*/
|
|
10
|
+
mode: 'stream' | 'file';
|
|
11
|
+
/**
|
|
12
|
+
* special url to use file mode when global `mode` is `stream`.
|
|
13
|
+
*/
|
|
14
|
+
fileModeMatch?: PathMatchingPattern;
|
|
15
|
+
/**
|
|
16
|
+
* Auto set fields to parts, default is `false`.
|
|
17
|
+
* Only work on `stream` mode.
|
|
18
|
+
* If set true,all fields will be auto handle and can access by `parts.fields`
|
|
19
|
+
*/
|
|
20
|
+
autoFields: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* default charset encoding, don't change it before you real know about it
|
|
23
|
+
* Default is `utf8`
|
|
24
|
+
*/
|
|
25
|
+
defaultCharset: string;
|
|
26
|
+
/**
|
|
27
|
+
* For multipart forms, the default character set to use for values of part header parameters (e.g. filename)
|
|
28
|
+
* that are not extended parameters (that contain an explicit charset), don't change it before you real know about it
|
|
29
|
+
* Default is `utf8`
|
|
30
|
+
*/
|
|
31
|
+
defaultParamCharset: string;
|
|
32
|
+
/**
|
|
33
|
+
* Max field name size (in bytes), default is `100`
|
|
34
|
+
*/
|
|
35
|
+
fieldNameSize: number;
|
|
36
|
+
/**
|
|
37
|
+
* Max field value size (in bytes), default is `100kb`
|
|
38
|
+
*/
|
|
39
|
+
fieldSize: string | number;
|
|
40
|
+
/**
|
|
41
|
+
* Max number of non-file fields, default is `10`
|
|
42
|
+
*/
|
|
43
|
+
fields: number;
|
|
44
|
+
/**
|
|
45
|
+
* Max file size (in bytes), default is `10mb`
|
|
46
|
+
*/
|
|
47
|
+
fileSize: string | number;
|
|
48
|
+
/**
|
|
49
|
+
* Max number of file fields, default is `10`
|
|
50
|
+
*/
|
|
51
|
+
files: number;
|
|
52
|
+
/**
|
|
53
|
+
* Add more ext file names to the `whitelist`, default is `[]`, only valid when `whitelist` is `null`
|
|
54
|
+
*/
|
|
55
|
+
fileExtensions: string[];
|
|
56
|
+
/**
|
|
57
|
+
* The white ext file names, default is `null`
|
|
58
|
+
*/
|
|
59
|
+
whitelist: string[] | ((filename: string) => boolean) | null;
|
|
60
|
+
/**
|
|
61
|
+
* Allow array field, default is `false`
|
|
62
|
+
*/
|
|
63
|
+
allowArrayField: boolean;
|
|
64
|
+
/**
|
|
65
|
+
* The directory for temporary files. Only work on `file` mode.
|
|
66
|
+
* Default is `os.tmpdir()/egg-multipart-tmp/${appInfo.name}`
|
|
67
|
+
*/
|
|
68
|
+
tmpdir: string;
|
|
69
|
+
/**
|
|
70
|
+
* The schedule for cleaning temporary files. Only work on `file` mode.
|
|
71
|
+
*/
|
|
72
|
+
cleanSchedule: {
|
|
73
|
+
/**
|
|
74
|
+
* The cron expression for the schedule.
|
|
75
|
+
* Default is `0 30 4 * * *`
|
|
76
|
+
* @see https://github.com/eggjs/egg/tree/next/plugins/schedule#cron-style-scheduling
|
|
77
|
+
*/
|
|
78
|
+
cron: string;
|
|
79
|
+
/**
|
|
80
|
+
* Default is `false`
|
|
81
|
+
*/
|
|
82
|
+
disable: boolean;
|
|
83
|
+
};
|
|
84
|
+
checkFile?(fieldname: string, file: any, filename: string, encoding: string, mimetype: string): void | Error;
|
|
85
|
+
}
|
|
86
|
+
declare const _default: (appInfo: EggAppInfo) => {
|
|
87
|
+
multipart: MultipartConfig;
|
|
88
|
+
};
|
|
89
|
+
export default _default;
|
|
@@ -1,3 +1,26 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
export
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
export default (appInfo) => {
|
|
4
|
+
return {
|
|
5
|
+
multipart: {
|
|
6
|
+
mode: 'stream',
|
|
7
|
+
autoFields: false,
|
|
8
|
+
defaultCharset: 'utf8',
|
|
9
|
+
defaultParamCharset: 'utf8',
|
|
10
|
+
fieldNameSize: 100,
|
|
11
|
+
fieldSize: '100kb',
|
|
12
|
+
fields: 10,
|
|
13
|
+
fileSize: '10mb',
|
|
14
|
+
files: 10,
|
|
15
|
+
fileExtensions: [],
|
|
16
|
+
whitelist: null,
|
|
17
|
+
allowArrayField: false,
|
|
18
|
+
tmpdir: path.join(os.tmpdir(), 'egg-multipart-tmp', appInfo.name),
|
|
19
|
+
cleanSchedule: {
|
|
20
|
+
cron: '0 30 4 * * *',
|
|
21
|
+
disable: false,
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmRlZmF1bHQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29uZmlnL2NvbmZpZy5kZWZhdWx0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN6QixPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUEwRjdCLGVBQWUsQ0FBQyxPQUFtQixFQUFFLEVBQUU7SUFDckMsT0FBTztRQUNMLFNBQVMsRUFBRTtZQUNULElBQUksRUFBRSxRQUFRO1lBQ2QsVUFBVSxFQUFFLEtBQUs7WUFDakIsY0FBYyxFQUFFLE1BQU07WUFDdEIsbUJBQW1CLEVBQUUsTUFBTTtZQUMzQixhQUFhLEVBQUUsR0FBRztZQUNsQixTQUFTLEVBQUUsT0FBTztZQUNsQixNQUFNLEVBQUUsRUFBRTtZQUNWLFFBQVEsRUFBRSxNQUFNO1lBQ2hCLEtBQUssRUFBRSxFQUFFO1lBQ1QsY0FBYyxFQUFFLEVBQUU7WUFDbEIsU0FBUyxFQUFFLElBQUk7WUFDZixlQUFlLEVBQUUsS0FBSztZQUN0QixNQUFNLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLEVBQUUsbUJBQW1CLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQztZQUNqRSxhQUFhLEVBQUU7Z0JBQ2IsSUFBSSxFQUFFLGNBQWM7Z0JBQ3BCLE9BQU8sRUFBRSxLQUFLO2FBQ2Y7U0FDaUI7S0FDckIsQ0FBQztBQUNKLENBQUMsQ0FBQyJ9
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import './config/config.default.ts';
|
|
2
|
+
import './app/extend/context.ts';
|
|
3
|
+
import './types.ts';
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import "./
|
|
2
|
-
import "./
|
|
3
|
-
import "./
|
|
4
|
-
|
|
5
|
-
import "./context-CLeGGj9o.js";
|
|
6
|
-
import "./types-BsuPrIpu.js";
|
|
7
|
-
|
|
8
|
-
export { };
|
|
1
|
+
import "./config/config.default.js";
|
|
2
|
+
import "./app/extend/context.js";
|
|
3
|
+
import "./types.js";
|
|
4
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyw0QkFBNEIsQ0FBQztBQUNwQyxPQUFPLHlCQUF5QixDQUFDO0FBQ2pDLE9BQU8sWUFBWSxDQUFDIn0=
|
package/dist/lib/LimitError.d.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
constructor(code: string, message: string);
|
|
1
|
+
export declare class LimitError extends Error {
|
|
2
|
+
code: string;
|
|
3
|
+
status: number;
|
|
4
|
+
constructor(code: string, message: string);
|
|
6
5
|
}
|
|
7
|
-
//#endregion
|
|
8
|
-
export { LimitError };
|
package/dist/lib/LimitError.js
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
export class LimitError extends Error {
|
|
2
|
+
code;
|
|
3
|
+
status;
|
|
4
|
+
constructor(code, message) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.code = code;
|
|
7
|
+
this.status = 413;
|
|
8
|
+
this.name = this.constructor.name;
|
|
9
|
+
Error.captureStackTrace(this, this.constructor);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTGltaXRFcnJvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvTGltaXRFcnJvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLE9BQU8sVUFBVyxTQUFRLEtBQUs7SUFDbkMsSUFBSSxDQUFTO0lBQ2IsTUFBTSxDQUFTO0lBRWYsWUFBWSxJQUFZLEVBQUUsT0FBZTtRQUN2QyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDZixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixJQUFJLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQztRQUNsQixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDO1FBQ2xDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ2xELENBQUM7Q0FDRiJ9
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
constructor(message: string, fields: Record<string, any>, filename: string);
|
|
1
|
+
export declare class MultipartFileTooLargeError extends Error {
|
|
2
|
+
status: number;
|
|
3
|
+
fields: Record<string, any>;
|
|
4
|
+
filename: string;
|
|
5
|
+
constructor(message: string, fields: Record<string, any>, filename: string);
|
|
7
6
|
}
|
|
8
|
-
//#endregion
|
|
9
|
-
export { MultipartFileTooLargeError };
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
export class MultipartFileTooLargeError extends Error {
|
|
2
|
+
status;
|
|
3
|
+
fields;
|
|
4
|
+
filename;
|
|
5
|
+
constructor(message, fields, filename) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = this.constructor.name;
|
|
8
|
+
this.status = 413;
|
|
9
|
+
this.fields = fields;
|
|
10
|
+
this.filename = filename;
|
|
11
|
+
Error.captureStackTrace(this, this.constructor);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTXVsdGlwYXJ0RmlsZVRvb0xhcmdlRXJyb3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL011bHRpcGFydEZpbGVUb29MYXJnZUVycm9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE1BQU0sT0FBTywwQkFBMkIsU0FBUSxLQUFLO0lBQ25ELE1BQU0sQ0FBUztJQUNmLE1BQU0sQ0FBc0I7SUFDNUIsUUFBUSxDQUFTO0lBRWpCLFlBQVksT0FBZSxFQUFFLE1BQTJCLEVBQUUsUUFBZ0I7UUFDeEUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2YsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQztRQUNsQyxJQUFJLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQztRQUNsQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUN6QixLQUFLLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUNsRCxDQUFDO0NBQ0YifQ==
|
package/dist/lib/utils.d.ts
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import { MultipartConfig } from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
declare
|
|
5
|
-
declare function humanizeBytes(size: number | string): number;
|
|
6
|
-
declare function normalizeOptions(options: MultipartConfig): MultipartConfig;
|
|
7
|
-
//#endregion
|
|
8
|
-
export { humanizeBytes, normalizeOptions, whitelist };
|
|
1
|
+
import type { MultipartConfig } from '../config/config.default.ts';
|
|
2
|
+
export declare const whitelist: string[];
|
|
3
|
+
export declare function humanizeBytes(size: number | string): number;
|
|
4
|
+
export declare function normalizeOptions(options: MultipartConfig): MultipartConfig;
|
package/dist/lib/utils.js
CHANGED
|
@@ -1,3 +1,91 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import assert from 'node:assert';
|
|
3
|
+
import bytes from 'bytes';
|
|
4
|
+
export const whitelist = [
|
|
5
|
+
// images
|
|
6
|
+
'.jpg',
|
|
7
|
+
'.jpeg', // image/jpeg
|
|
8
|
+
'.png', // image/png, image/x-png
|
|
9
|
+
'.gif', // image/gif
|
|
10
|
+
'.bmp', // image/bmp
|
|
11
|
+
'.wbmp', // image/vnd.wap.wbmp
|
|
12
|
+
'.webp',
|
|
13
|
+
'.tif',
|
|
14
|
+
'.psd',
|
|
15
|
+
// text
|
|
16
|
+
'.svg',
|
|
17
|
+
'.js',
|
|
18
|
+
'.jsx',
|
|
19
|
+
'.json',
|
|
20
|
+
'.css',
|
|
21
|
+
'.less',
|
|
22
|
+
'.html',
|
|
23
|
+
'.htm',
|
|
24
|
+
'.xml',
|
|
25
|
+
// tar
|
|
26
|
+
'.zip',
|
|
27
|
+
'.gz',
|
|
28
|
+
'.tgz',
|
|
29
|
+
'.gzip',
|
|
30
|
+
// video
|
|
31
|
+
'.mp3',
|
|
32
|
+
'.mp4',
|
|
33
|
+
'.avi',
|
|
34
|
+
];
|
|
35
|
+
export function humanizeBytes(size) {
|
|
36
|
+
if (typeof size === 'number') {
|
|
37
|
+
return size;
|
|
38
|
+
}
|
|
39
|
+
return bytes(size);
|
|
40
|
+
}
|
|
41
|
+
export function normalizeOptions(options) {
|
|
42
|
+
// make sure to cast the value of config **Size to number
|
|
43
|
+
options.fileSize = humanizeBytes(options.fileSize);
|
|
44
|
+
options.fieldSize = humanizeBytes(options.fieldSize);
|
|
45
|
+
options.fieldNameSize = humanizeBytes(options.fieldNameSize);
|
|
46
|
+
// validate mode
|
|
47
|
+
options.mode = options.mode || 'stream';
|
|
48
|
+
assert(['stream', 'file'].includes(options.mode), `Expect mode to be 'stream' or 'file', but got '${options.mode}'`);
|
|
49
|
+
if (options.mode === 'file') {
|
|
50
|
+
assert(!options.fileModeMatch, '`fileModeMatch` options only work on stream mode, please remove it');
|
|
51
|
+
}
|
|
52
|
+
// normalize whitelist
|
|
53
|
+
if (Array.isArray(options.whitelist)) {
|
|
54
|
+
options.whitelist = options.whitelist.map(extname => extname.toLowerCase());
|
|
55
|
+
}
|
|
56
|
+
// normalize fileExtensions
|
|
57
|
+
if (Array.isArray(options.fileExtensions)) {
|
|
58
|
+
options.fileExtensions = options.fileExtensions.map(extname => {
|
|
59
|
+
return extname.startsWith('.') || extname === '' ? extname.toLowerCase() : `.${extname.toLowerCase()}`;
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function checkExt(fileName) {
|
|
63
|
+
if (typeof options.whitelist === 'function') {
|
|
64
|
+
return options.whitelist(fileName);
|
|
65
|
+
}
|
|
66
|
+
const extname = path.extname(fileName).toLowerCase();
|
|
67
|
+
if (Array.isArray(options.whitelist)) {
|
|
68
|
+
return options.whitelist.includes(extname);
|
|
69
|
+
}
|
|
70
|
+
// only if user don't provide whitelist, we will use default whitelist + fileExtensions
|
|
71
|
+
return whitelist.includes(extname) || options.fileExtensions.includes(extname);
|
|
72
|
+
}
|
|
73
|
+
options.checkFile = (_fieldName, fileStream, fileName) => {
|
|
74
|
+
// just ignore, if no file
|
|
75
|
+
if (!fileStream || !fileName)
|
|
76
|
+
return;
|
|
77
|
+
try {
|
|
78
|
+
if (!checkExt(fileName)) {
|
|
79
|
+
const err = new Error('Invalid filename: ' + fileName);
|
|
80
|
+
Reflect.set(err, 'status', 400);
|
|
81
|
+
return err;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
err.status = 400;
|
|
86
|
+
return err;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
return options;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sSUFBSSxNQUFNLFdBQVcsQ0FBQztBQUM3QixPQUFPLE1BQU0sTUFBTSxhQUFhLENBQUM7QUFFakMsT0FBTyxLQUFLLE1BQU0sT0FBTyxDQUFDO0FBRzFCLE1BQU0sQ0FBQyxNQUFNLFNBQVMsR0FBRztJQUN2QixTQUFTO0lBQ1QsTUFBTTtJQUNOLE9BQU8sRUFBRSxhQUFhO0lBQ3RCLE1BQU0sRUFBRSx5QkFBeUI7SUFDakMsTUFBTSxFQUFFLFlBQVk7SUFDcEIsTUFBTSxFQUFFLFlBQVk7SUFDcEIsT0FBTyxFQUFFLHFCQUFxQjtJQUM5QixPQUFPO0lBQ1AsTUFBTTtJQUNOLE1BQU07SUFDTixPQUFPO0lBQ1AsTUFBTTtJQUNOLEtBQUs7SUFDTCxNQUFNO0lBQ04sT0FBTztJQUNQLE1BQU07SUFDTixPQUFPO0lBQ1AsT0FBTztJQUNQLE1BQU07SUFDTixNQUFNO0lBQ04sTUFBTTtJQUNOLE1BQU07SUFDTixLQUFLO0lBQ0wsTUFBTTtJQUNOLE9BQU87SUFDUCxRQUFRO0lBQ1IsTUFBTTtJQUNOLE1BQU07SUFDTixNQUFNO0NBQ1AsQ0FBQztBQUVGLE1BQU0sVUFBVSxhQUFhLENBQUMsSUFBcUI7SUFDakQsSUFBSSxPQUFPLElBQUksS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUM3QixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQVcsQ0FBQztBQUMvQixDQUFDO0FBRUQsTUFBTSxVQUFVLGdCQUFnQixDQUFDLE9BQXdCO0lBQ3ZELHlEQUF5RDtJQUN6RCxPQUFPLENBQUMsUUFBUSxHQUFHLGFBQWEsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDbkQsT0FBTyxDQUFDLFNBQVMsR0FBRyxhQUFhLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FB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
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
1
|
+
import type { MultipartConfig } from './config/config.default.ts';
|
|
2
|
+
import type { EggFile, MultipartFileStream, MultipartOptions } from './app/extend/context.ts';
|
|
3
|
+
declare module 'egg' {
|
|
4
|
+
interface EggAppConfig {
|
|
5
|
+
/**
|
|
6
|
+
* multipart parser options
|
|
7
|
+
* @member Config#multipart
|
|
8
|
+
*/
|
|
9
|
+
multipart: MultipartConfig;
|
|
10
|
+
}
|
|
11
|
+
interface Request {
|
|
12
|
+
/**
|
|
13
|
+
* Files Object Array
|
|
14
|
+
*/
|
|
15
|
+
files?: EggFile[];
|
|
16
|
+
}
|
|
17
|
+
interface Context {
|
|
18
|
+
saveRequestFiles(options?: MultipartOptions): Promise<void>;
|
|
19
|
+
getFileStream(options?: MultipartOptions): Promise<MultipartFileStream>;
|
|
20
|
+
cleanupRequestFiles(files?: EggFile[]): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
}
|
package/dist/types.js
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export { };
|
|
1
|
+
export {};
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eggjs/multipart",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.21",
|
|
4
4
|
"description": "multipart plugin for egg",
|
|
5
5
|
"eggPlugin": {
|
|
6
6
|
"name": "multipart",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"egg-path-matching": "^2.0.0"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
|
-
"egg": "4.1.0-beta.
|
|
55
|
+
"egg": "4.1.0-beta.21"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@types/bytes": "^3.1.5",
|
|
@@ -64,9 +64,9 @@
|
|
|
64
64
|
"typescript": "^5.9.3",
|
|
65
65
|
"urllib": "^4.8.2",
|
|
66
66
|
"vitest": "4.0.0-beta.16",
|
|
67
|
-
"@eggjs/mock": "7.0.0-beta.
|
|
68
|
-
"@eggjs/schedule": "6.0.0-beta.
|
|
69
|
-
"@eggjs/tsconfig": "3.1.0-beta.
|
|
67
|
+
"@eggjs/mock": "7.0.0-beta.21",
|
|
68
|
+
"@eggjs/schedule": "6.0.0-beta.21",
|
|
69
|
+
"@eggjs/tsconfig": "3.1.0-beta.21"
|
|
70
70
|
},
|
|
71
71
|
"files": [
|
|
72
72
|
"dist"
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"module": "./dist/index.js",
|
|
76
76
|
"types": "./dist/index.d.ts",
|
|
77
77
|
"scripts": {
|
|
78
|
-
"build": "tsdown",
|
|
78
|
+
"build": "tsdown && rimraf dist && tsc -b --clean && tsc",
|
|
79
79
|
"typecheck": "tsc --noEmit",
|
|
80
80
|
"lint": "oxlint --type-aware",
|
|
81
81
|
"lint:fix": "npm run lint -- --fix",
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
//#region src/lib/LimitError.ts
|
|
2
|
-
var LimitError = class extends Error {
|
|
3
|
-
code;
|
|
4
|
-
status;
|
|
5
|
-
constructor(code, message) {
|
|
6
|
-
super(message);
|
|
7
|
-
this.code = code;
|
|
8
|
-
this.status = 413;
|
|
9
|
-
this.name = this.constructor.name;
|
|
10
|
-
Error.captureStackTrace(this, this.constructor);
|
|
11
|
-
}
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
//#endregion
|
|
15
|
-
export { LimitError };
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
//#region src/lib/MultipartFileTooLargeError.ts
|
|
2
|
-
var MultipartFileTooLargeError = class extends Error {
|
|
3
|
-
status;
|
|
4
|
-
fields;
|
|
5
|
-
filename;
|
|
6
|
-
constructor(message, fields, filename) {
|
|
7
|
-
super(message);
|
|
8
|
-
this.name = this.constructor.name;
|
|
9
|
-
this.status = 413;
|
|
10
|
-
this.fields = fields;
|
|
11
|
-
this.filename = filename;
|
|
12
|
-
Error.captureStackTrace(this, this.constructor);
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
//#endregion
|
|
17
|
-
export { MultipartFileTooLargeError };
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import os from "node:os";
|
|
3
|
-
|
|
4
|
-
//#region src/config/config.default.ts
|
|
5
|
-
var config_default_default = (appInfo) => {
|
|
6
|
-
return { multipart: {
|
|
7
|
-
mode: "stream",
|
|
8
|
-
autoFields: false,
|
|
9
|
-
defaultCharset: "utf8",
|
|
10
|
-
defaultParamCharset: "utf8",
|
|
11
|
-
fieldNameSize: 100,
|
|
12
|
-
fieldSize: "100kb",
|
|
13
|
-
fields: 10,
|
|
14
|
-
fileSize: "10mb",
|
|
15
|
-
files: 10,
|
|
16
|
-
fileExtensions: [],
|
|
17
|
-
whitelist: null,
|
|
18
|
-
allowArrayField: false,
|
|
19
|
-
tmpdir: path.join(os.tmpdir(), "egg-multipart-tmp", appInfo.name),
|
|
20
|
-
cleanSchedule: {
|
|
21
|
-
cron: "0 30 4 * * *",
|
|
22
|
-
disable: false
|
|
23
|
-
}
|
|
24
|
-
} };
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
//#endregion
|
|
28
|
-
export { config_default_default };
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import { Context, EggAppInfo } from "egg";
|
|
2
|
-
import { PathMatchingPattern } from "egg-path-matching";
|
|
3
|
-
|
|
4
|
-
//#region src/config/config.default.d.ts
|
|
5
|
-
type MatchItem = string | RegExp | ((ctx: Context) => boolean);
|
|
6
|
-
interface MultipartConfig {
|
|
7
|
-
/**
|
|
8
|
-
* which mode to handle multipart request, default is `stream`, the hard way.
|
|
9
|
-
* If set mode to `file`, it's the easy way to handle multipart request and save it to local files.
|
|
10
|
-
* If you don't know the Node.js Stream work, maybe you should use the `file` mode to get started.
|
|
11
|
-
*/
|
|
12
|
-
mode: 'stream' | 'file';
|
|
13
|
-
/**
|
|
14
|
-
* special url to use file mode when global `mode` is `stream`.
|
|
15
|
-
*/
|
|
16
|
-
fileModeMatch?: PathMatchingPattern;
|
|
17
|
-
/**
|
|
18
|
-
* Auto set fields to parts, default is `false`.
|
|
19
|
-
* Only work on `stream` mode.
|
|
20
|
-
* If set true,all fields will be auto handle and can access by `parts.fields`
|
|
21
|
-
*/
|
|
22
|
-
autoFields: boolean;
|
|
23
|
-
/**
|
|
24
|
-
* default charset encoding, don't change it before you real know about it
|
|
25
|
-
* Default is `utf8`
|
|
26
|
-
*/
|
|
27
|
-
defaultCharset: string;
|
|
28
|
-
/**
|
|
29
|
-
* For multipart forms, the default character set to use for values of part header parameters (e.g. filename)
|
|
30
|
-
* that are not extended parameters (that contain an explicit charset), don't change it before you real know about it
|
|
31
|
-
* Default is `utf8`
|
|
32
|
-
*/
|
|
33
|
-
defaultParamCharset: string;
|
|
34
|
-
/**
|
|
35
|
-
* Max field name size (in bytes), default is `100`
|
|
36
|
-
*/
|
|
37
|
-
fieldNameSize: number;
|
|
38
|
-
/**
|
|
39
|
-
* Max field value size (in bytes), default is `100kb`
|
|
40
|
-
*/
|
|
41
|
-
fieldSize: string | number;
|
|
42
|
-
/**
|
|
43
|
-
* Max number of non-file fields, default is `10`
|
|
44
|
-
*/
|
|
45
|
-
fields: number;
|
|
46
|
-
/**
|
|
47
|
-
* Max file size (in bytes), default is `10mb`
|
|
48
|
-
*/
|
|
49
|
-
fileSize: string | number;
|
|
50
|
-
/**
|
|
51
|
-
* Max number of file fields, default is `10`
|
|
52
|
-
*/
|
|
53
|
-
files: number;
|
|
54
|
-
/**
|
|
55
|
-
* Add more ext file names to the `whitelist`, default is `[]`, only valid when `whitelist` is `null`
|
|
56
|
-
*/
|
|
57
|
-
fileExtensions: string[];
|
|
58
|
-
/**
|
|
59
|
-
* The white ext file names, default is `null`
|
|
60
|
-
*/
|
|
61
|
-
whitelist: string[] | ((filename: string) => boolean) | null;
|
|
62
|
-
/**
|
|
63
|
-
* Allow array field, default is `false`
|
|
64
|
-
*/
|
|
65
|
-
allowArrayField: boolean;
|
|
66
|
-
/**
|
|
67
|
-
* The directory for temporary files. Only work on `file` mode.
|
|
68
|
-
* Default is `os.tmpdir()/egg-multipart-tmp/${appInfo.name}`
|
|
69
|
-
*/
|
|
70
|
-
tmpdir: string;
|
|
71
|
-
/**
|
|
72
|
-
* The schedule for cleaning temporary files. Only work on `file` mode.
|
|
73
|
-
*/
|
|
74
|
-
cleanSchedule: {
|
|
75
|
-
/**
|
|
76
|
-
* The cron expression for the schedule.
|
|
77
|
-
* Default is `0 30 4 * * *`
|
|
78
|
-
* @see https://github.com/eggjs/egg/tree/next/plugins/schedule#cron-style-scheduling
|
|
79
|
-
*/
|
|
80
|
-
cron: string;
|
|
81
|
-
/**
|
|
82
|
-
* Default is `false`
|
|
83
|
-
*/
|
|
84
|
-
disable: boolean;
|
|
85
|
-
};
|
|
86
|
-
checkFile?(fieldname: string, file: any, filename: string, encoding: string, mimetype: string): void | Error;
|
|
87
|
-
}
|
|
88
|
-
declare const _default: (appInfo: EggAppInfo) => {
|
|
89
|
-
multipart: MultipartConfig;
|
|
90
|
-
};
|
|
91
|
-
//#endregion
|
|
92
|
-
export { MatchItem, MultipartConfig, _default };
|