@midwayjs/upload 3.0.0-beta.9 → 3.0.3
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 +21 -0
- package/{readme.md → README.md} +7 -15
- package/dist/config/config.default.js +4 -34
- package/dist/config/config.default.js.map +1 -0
- package/dist/configuration.d.ts +3 -1
- package/dist/configuration.js +9 -3
- package/dist/configuration.js.map +1 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +36 -0
- package/dist/constants.js.map +1 -0
- package/dist/error.d.ts +5 -0
- package/dist/error.js +11 -0
- package/dist/error.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/interface.d.ts +5 -8
- package/dist/interface.js +0 -7
- package/dist/interface.js.map +1 -0
- package/dist/middleware.d.ts +1 -0
- package/dist/middleware.js +46 -40
- package/dist/middleware.js.map +1 -0
- package/dist/{upload.d.ts → parse.d.ts} +2 -2
- package/dist/{upload.js → parse.js} +4 -4
- package/dist/parse.js.map +1 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +71 -0
- package/dist/utils.js.map +1 -0
- package/index.d.ts +39 -0
- package/package.json +18 -16
- package/CHANGELOG.md +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2013 - Now midwayjs
|
|
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 → README.md}
RENAMED
|
@@ -10,21 +10,12 @@ tnpm i @midwayjs/upload --save
|
|
|
10
10
|
```
|
|
11
11
|
2. 在 configuration 中引入组件,
|
|
12
12
|
```ts
|
|
13
|
-
import * as upload from '
|
|
13
|
+
import * as upload from '@midwayjs/upload';
|
|
14
14
|
@Configuration({
|
|
15
15
|
imports: [
|
|
16
16
|
// ...other components
|
|
17
17
|
upload
|
|
18
18
|
],
|
|
19
|
-
importConfigs: [
|
|
20
|
-
{
|
|
21
|
-
default: {
|
|
22
|
-
upload: { // 上传组件的配置
|
|
23
|
-
mode: upload.UploadMode.File, // 默认为 file 模式
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
]
|
|
28
19
|
})
|
|
29
20
|
export class AutoConfiguration {}
|
|
30
21
|
```
|
|
@@ -38,20 +29,19 @@ export class HomeController {
|
|
|
38
29
|
ctx;
|
|
39
30
|
|
|
40
31
|
@Post('/upload')
|
|
41
|
-
async upload() {
|
|
42
|
-
const { files, fields } = this.ctx;
|
|
32
|
+
async upload(@Files() files: upload.UploadFileInfo[], @Fields() fields) {
|
|
43
33
|
/*
|
|
44
34
|
files = [
|
|
45
35
|
{
|
|
46
36
|
filename: 'test.pdf', // 文件原名
|
|
47
37
|
data: '/var/tmp/xxx.pdf', // mode 为 file 时为服务器临时文件地址
|
|
48
|
-
|
|
38
|
+
fieldName: 'test1', // 表单 field 名
|
|
49
39
|
mimeType: 'application/pdf', // mime
|
|
50
40
|
},
|
|
51
41
|
{
|
|
52
42
|
filename: 'test.pdf', // 文件原名
|
|
53
43
|
data: ReadStream, // mode 为 stream 时为服务器临时文件地址
|
|
54
|
-
|
|
44
|
+
fieldName: 'test2', // 表单 field 名
|
|
55
45
|
mimeType: 'application/pdf', // mime
|
|
56
46
|
},
|
|
57
47
|
// ...file 下支持同时上传多个文件
|
|
@@ -78,5 +68,7 @@ export const upload = {
|
|
|
78
68
|
whitelist: null,
|
|
79
69
|
// tmpdir: string,上传的文件临时存储路径
|
|
80
70
|
tmpdir: join(tmpdir(), 'midway-upload-files'),
|
|
71
|
+
// cleanTimeout: number,上传的文件在临时目录中多久之后自动删除,默认为 5 分钟
|
|
72
|
+
cleanTimeout: 5 * 60 * 1000,
|
|
81
73
|
}
|
|
82
|
-
```
|
|
74
|
+
```
|
|
@@ -1,44 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.upload = void 0;
|
|
4
|
-
const interface_1 = require("../interface");
|
|
5
4
|
const path_1 = require("path");
|
|
6
5
|
const os_1 = require("os");
|
|
6
|
+
const constants_1 = require("../constants");
|
|
7
7
|
exports.upload = {
|
|
8
|
-
mode:
|
|
8
|
+
mode: 'file',
|
|
9
9
|
fileSize: '10mb',
|
|
10
|
-
whitelist:
|
|
11
|
-
// images
|
|
12
|
-
'.jpg',
|
|
13
|
-
'.jpeg',
|
|
14
|
-
'.png',
|
|
15
|
-
'.gif',
|
|
16
|
-
'.bmp',
|
|
17
|
-
'.wbmp',
|
|
18
|
-
'.webp',
|
|
19
|
-
'.tif',
|
|
20
|
-
'.psd',
|
|
21
|
-
// text
|
|
22
|
-
'.svg',
|
|
23
|
-
'.js',
|
|
24
|
-
'.jsx',
|
|
25
|
-
'.json',
|
|
26
|
-
'.css',
|
|
27
|
-
'.less',
|
|
28
|
-
'.html',
|
|
29
|
-
'.htm',
|
|
30
|
-
'.xml',
|
|
31
|
-
'.pdf',
|
|
32
|
-
// tar
|
|
33
|
-
'.zip',
|
|
34
|
-
'.gz',
|
|
35
|
-
'.tgz',
|
|
36
|
-
'.gzip',
|
|
37
|
-
// video
|
|
38
|
-
'.mp3',
|
|
39
|
-
'.mp4',
|
|
40
|
-
'.avi',
|
|
41
|
-
],
|
|
10
|
+
whitelist: constants_1.uploadWhiteList,
|
|
42
11
|
tmpdir: (0, path_1.join)((0, os_1.tmpdir)(), 'midway-upload-files'),
|
|
12
|
+
cleanTimeout: 5 * 60 * 1000,
|
|
43
13
|
};
|
|
44
14
|
//# sourceMappingURL=config.default.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.default.js","sourceRoot":"","sources":["../../src/config/config.default.ts"],"names":[],"mappings":";;;AACA,+BAA4B;AAC5B,2BAA4B;AAC5B,4CAA+C;AAElC,QAAA,MAAM,GAAkB;IACnC,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,MAAM;IAChB,SAAS,EAAE,2BAAe;IAC1B,MAAM,EAAE,IAAA,WAAI,EAAC,IAAA,WAAM,GAAE,EAAE,qBAAqB,CAAC;IAC7C,YAAY,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI;CAC5B,CAAC","sourcesContent":["import { UploadOptions } from '../interface';\nimport { join } from 'path';\nimport { tmpdir } from 'os';\nimport { uploadWhiteList } from '../constants';\n\nexport const upload: UploadOptions = {\n mode: 'file',\n fileSize: '10mb',\n whitelist: uploadWhiteList,\n tmpdir: join(tmpdir(), 'midway-upload-files'),\n cleanTimeout: 5 * 60 * 1000,\n};\n"]}
|
package/dist/configuration.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { MidwayApplicationManager } from '@midwayjs/core';
|
|
2
|
+
import { UploadOptions } from './interface';
|
|
2
3
|
export declare class UploadConfiguration {
|
|
3
4
|
applicationManager: MidwayApplicationManager;
|
|
4
|
-
uploadConfig:
|
|
5
|
+
uploadConfig: UploadOptions;
|
|
5
6
|
onReady(): Promise<void>;
|
|
7
|
+
onStop(): Promise<void>;
|
|
6
8
|
}
|
|
7
9
|
//# sourceMappingURL=configuration.d.ts.map
|
package/dist/configuration.js
CHANGED
|
@@ -14,12 +14,15 @@ const decorator_1 = require("@midwayjs/decorator");
|
|
|
14
14
|
const DefaultConfig = require("./config/config.default");
|
|
15
15
|
const core_1 = require("@midwayjs/core");
|
|
16
16
|
const middleware_1 = require("./middleware");
|
|
17
|
-
const
|
|
17
|
+
const utils_1 = require("./utils");
|
|
18
18
|
let UploadConfiguration = class UploadConfiguration {
|
|
19
19
|
async onReady() {
|
|
20
|
-
const { tmpdir } = this.uploadConfig;
|
|
20
|
+
const { tmpdir, cleanTimeout } = this.uploadConfig;
|
|
21
21
|
if (tmpdir) {
|
|
22
|
-
await (0,
|
|
22
|
+
await (0, utils_1.ensureDir)(tmpdir);
|
|
23
|
+
if (cleanTimeout) {
|
|
24
|
+
(0, utils_1.autoRemoveUploadTmpFile)(tmpdir, cleanTimeout);
|
|
25
|
+
}
|
|
23
26
|
}
|
|
24
27
|
this.applicationManager
|
|
25
28
|
.getApplications(['koa', 'faas', 'express', 'egg'])
|
|
@@ -27,6 +30,9 @@ let UploadConfiguration = class UploadConfiguration {
|
|
|
27
30
|
app.useMiddleware(middleware_1.UploadMiddleware);
|
|
28
31
|
});
|
|
29
32
|
}
|
|
33
|
+
async onStop() {
|
|
34
|
+
await (0, utils_1.stopAutoRemoveUploadTmpFile)();
|
|
35
|
+
}
|
|
30
36
|
};
|
|
31
37
|
__decorate([
|
|
32
38
|
(0, decorator_1.Inject)(),
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configuration.js","sourceRoot":"","sources":["../src/configuration.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,mDAAoE;AACpE,yDAAyD;AACzD,yCAA0D;AAC1D,6CAAgD;AAChD,mCAIiB;AAUjB,IAAa,mBAAmB,GAAhC,MAAa,mBAAmB;IAO9B,KAAK,CAAC,OAAO;QACX,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC;QACnD,IAAI,MAAM,EAAE;YACV,MAAM,IAAA,iBAAS,EAAC,MAAM,CAAC,CAAC;YACxB,IAAI,YAAY,EAAE;gBAChB,IAAA,+BAAuB,EAAC,MAAM,EAAE,YAAY,CAAC,CAAC;aAC/C;SACF;QACD,IAAI,CAAC,kBAAkB;aACpB,eAAe,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;aAClD,OAAO,CAAC,GAAG,CAAC,EAAE;YACb,GAAG,CAAC,aAAa,CAAC,6BAAgB,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,MAAM;QACV,MAAM,IAAA,mCAA2B,GAAE,CAAC;IACtC,CAAC;CACF,CAAA;AAvBC;IADC,IAAA,kBAAM,GAAE;8BACW,+BAAwB;+DAAC;AAG7C;IADC,IAAA,kBAAM,EAAC,QAAQ,CAAC;;yDACW;AALjB,mBAAmB;IAR/B,IAAA,yBAAa,EAAC;QACb,SAAS,EAAE,QAAQ;QACnB,aAAa,EAAE;YACb;gBACE,OAAO,EAAE,aAAa;aACvB;SACF;KACF,CAAC;GACW,mBAAmB,CAyB/B;AAzBY,kDAAmB","sourcesContent":["import { Config, Configuration, Inject } from '@midwayjs/decorator';\nimport * as DefaultConfig from './config/config.default';\nimport { MidwayApplicationManager } from '@midwayjs/core';\nimport { UploadMiddleware } from './middleware';\nimport {\n autoRemoveUploadTmpFile,\n ensureDir,\n stopAutoRemoveUploadTmpFile,\n} from './utils';\nimport { UploadOptions } from './interface';\n@Configuration({\n namespace: 'upload',\n importConfigs: [\n {\n default: DefaultConfig,\n },\n ],\n})\nexport class UploadConfiguration {\n @Inject()\n applicationManager: MidwayApplicationManager;\n\n @Config('upload')\n uploadConfig: UploadOptions;\n\n async onReady() {\n const { tmpdir, cleanTimeout } = this.uploadConfig;\n if (tmpdir) {\n await ensureDir(tmpdir);\n if (cleanTimeout) {\n autoRemoveUploadTmpFile(tmpdir, cleanTimeout);\n }\n }\n this.applicationManager\n .getApplications(['koa', 'faas', 'express', 'egg'])\n .forEach(app => {\n app.useMiddleware(UploadMiddleware);\n });\n }\n\n async onStop() {\n await stopAutoRemoveUploadTmpFile();\n }\n}\n"]}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.uploadWhiteList = void 0;
|
|
4
|
+
exports.uploadWhiteList = [
|
|
5
|
+
// images
|
|
6
|
+
'.jpg',
|
|
7
|
+
'.jpeg',
|
|
8
|
+
'.png',
|
|
9
|
+
'.gif',
|
|
10
|
+
'.bmp',
|
|
11
|
+
'.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
|
+
'.pdf',
|
|
26
|
+
// tar
|
|
27
|
+
'.zip',
|
|
28
|
+
'.gz',
|
|
29
|
+
'.tgz',
|
|
30
|
+
'.gzip',
|
|
31
|
+
// video
|
|
32
|
+
'.mp3',
|
|
33
|
+
'.mp4',
|
|
34
|
+
'.avi',
|
|
35
|
+
];
|
|
36
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,eAAe,GAAG;IAC7B,SAAS;IACT,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,MAAM;IACN,OAAO;IACP,OAAO;IACP,MAAM;IACN,MAAM;IACN,OAAO;IACP,MAAM;IACN,KAAK;IACL,MAAM;IACN,OAAO;IACP,MAAM;IACN,OAAO;IACP,OAAO;IACP,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,KAAK;IACL,MAAM;IACN,OAAO;IACP,QAAQ;IACR,MAAM;IACN,MAAM;IACN,MAAM;CACP,CAAC","sourcesContent":["export const uploadWhiteList = [\n // images\n '.jpg',\n '.jpeg', // image/jpeg\n '.png', // image/png, image/x-png\n '.gif', // image/gif\n '.bmp', // image/bmp\n '.wbmp', // image/vnd.wap.wbmp\n '.webp',\n '.tif',\n '.psd',\n // text\n '.svg',\n '.js',\n '.jsx',\n '.json',\n '.css',\n '.less',\n '.html',\n '.htm',\n '.xml',\n '.pdf',\n // tar\n '.zip',\n '.gz',\n '.tgz',\n '.gzip',\n // video\n '.mp3',\n '.mp4',\n '.avi',\n];\n"]}
|
package/dist/error.d.ts
ADDED
package/dist/error.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MultipartInvalidFilenameError = void 0;
|
|
4
|
+
const core_1 = require("@midwayjs/core");
|
|
5
|
+
class MultipartInvalidFilenameError extends core_1.httpError.BadRequestError {
|
|
6
|
+
constructor(filename) {
|
|
7
|
+
super(`Invalid update file name ${filename}, please check it`);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.MultipartInvalidFilenameError = MultipartInvalidFilenameError;
|
|
11
|
+
//# sourceMappingURL=error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":";;;AAAA,yCAA2C;AAE3C,MAAa,6BAA8B,SAAQ,gBAAS,CAAC,eAAe;IAC1E,YAAY,QAAgB;QAC1B,KAAK,CAAC,4BAA4B,QAAQ,mBAAmB,CAAC,CAAC;IACjE,CAAC;CACF;AAJD,sEAIC","sourcesContent":["import { httpError } from '@midwayjs/core';\n\nexport class MultipartInvalidFilenameError extends httpError.BadRequestError {\n constructor(filename: string) {\n super(`Invalid update file name ${filename}, please check it`);\n }\n}\n"]}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -15,4 +15,6 @@ var configuration_1 = require("./configuration");
|
|
|
15
15
|
Object.defineProperty(exports, "Configuration", { enumerable: true, get: function () { return configuration_1.UploadConfiguration; } });
|
|
16
16
|
__exportStar(require("./interface"), exports);
|
|
17
17
|
__exportStar(require("./middleware"), exports);
|
|
18
|
+
__exportStar(require("./error"), exports);
|
|
19
|
+
__exportStar(require("./constants"), exports);
|
|
18
20
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,iDAAuE;AAA9D,8GAAA,mBAAmB,OAAiB;AAC7C,8CAA4B;AAC5B,+CAA6B;AAC7B,0CAAwB;AACxB,8CAA4B","sourcesContent":["export { UploadConfiguration as Configuration } from './configuration';\nexport * from './interface';\nexport * from './middleware';\nexport * from './error';\nexport * from './constants';\n"]}
|
package/dist/interface.d.ts
CHANGED
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { Readable } from "stream";
|
|
3
|
-
export declare
|
|
4
|
-
Stream = "stream",
|
|
5
|
-
File = "file",
|
|
6
|
-
Buffer = "buffer"
|
|
7
|
-
}
|
|
3
|
+
export declare type UploadMode = 'stream' | 'file';
|
|
8
4
|
export interface UploadOptions {
|
|
9
5
|
mode?: UploadMode;
|
|
10
6
|
fileSize?: string;
|
|
11
7
|
whitelist?: string[];
|
|
12
8
|
tmpdir?: string;
|
|
9
|
+
cleanTimeout?: number;
|
|
13
10
|
}
|
|
14
|
-
export interface UploadFileInfo {
|
|
11
|
+
export interface UploadFileInfo<T> {
|
|
15
12
|
filename: string;
|
|
16
|
-
|
|
13
|
+
fieldName: string;
|
|
17
14
|
mimeType: string;
|
|
18
|
-
data:
|
|
15
|
+
data: T extends string ? string : Readable;
|
|
19
16
|
}
|
|
20
17
|
//# sourceMappingURL=interface.d.ts.map
|
package/dist/interface.js
CHANGED
|
@@ -1,10 +1,3 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.UploadMode = void 0;
|
|
4
|
-
var UploadMode;
|
|
5
|
-
(function (UploadMode) {
|
|
6
|
-
UploadMode["Stream"] = "stream";
|
|
7
|
-
UploadMode["File"] = "file";
|
|
8
|
-
UploadMode["Buffer"] = "buffer";
|
|
9
|
-
})(UploadMode = exports.UploadMode || (exports.UploadMode = {}));
|
|
10
3
|
//# sourceMappingURL=interface.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interface.js","sourceRoot":"","sources":["../src/interface.ts"],"names":[],"mappings":"","sourcesContent":["import { Readable } from \"stream\";\n\nexport type UploadMode = 'stream' | 'file';\n\nexport interface UploadOptions {\n mode?: UploadMode,\n fileSize?: string; // Max file size (in bytes), default is `10mb`\n whitelist?: string[]; // The white ext file names, default is `null`\n tmpdir?: string; // 临时文件目录\n cleanTimeout?: number; // 临时文件自动清理时间\n}\n\nexport interface UploadFileInfo<T> {\n filename: string;\n fieldName: string;\n mimeType: string;\n data: T extends string ? string : Readable ;\n}\n"]}
|
package/dist/middleware.d.ts
CHANGED
|
@@ -8,5 +8,6 @@ export declare class UploadMiddleware implements IMiddleware<any, any> {
|
|
|
8
8
|
getUploadBoundary(request: any): false | string;
|
|
9
9
|
isReadableStream(req: any, isExpress: any): boolean;
|
|
10
10
|
checkExt(filename: any): boolean;
|
|
11
|
+
static getName(): string;
|
|
11
12
|
}
|
|
12
13
|
//# sourceMappingURL=middleware.d.ts.map
|
package/dist/middleware.js
CHANGED
|
@@ -15,8 +15,9 @@ const path_1 = require("path");
|
|
|
15
15
|
const fs_1 = require("fs");
|
|
16
16
|
const stream_1 = require("stream");
|
|
17
17
|
const _1 = require(".");
|
|
18
|
-
const
|
|
18
|
+
const parse_1 = require("./parse");
|
|
19
19
|
const getRawBody = require("raw-body");
|
|
20
|
+
const { unlink, writeFile } = fs_1.promises;
|
|
20
21
|
let UploadMiddleware = class UploadMiddleware {
|
|
21
22
|
resolve(app) {
|
|
22
23
|
if (app.getFrameworkType() === decorator_1.MidwayFrameworkType.WEB_EXPRESS) {
|
|
@@ -39,19 +40,31 @@ let UploadMiddleware = class UploadMiddleware {
|
|
|
39
40
|
return next();
|
|
40
41
|
}
|
|
41
42
|
ctx.fields = {};
|
|
43
|
+
ctx.files = [];
|
|
44
|
+
ctx.cleanupRequestFiles = async () => {
|
|
45
|
+
var _a;
|
|
46
|
+
if (!((_a = ctx.files) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
return Promise.all(ctx.files.map(async (fileInfo) => {
|
|
50
|
+
if (typeof fileInfo.data !== 'string') {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
await unlink(fileInfo.data);
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
catch (_a) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}));
|
|
61
|
+
};
|
|
42
62
|
let body;
|
|
43
63
|
if (this.isReadableStream(req, isExpress)) {
|
|
44
|
-
if (mode ===
|
|
45
|
-
const { fields, fileInfo } = await (0,
|
|
64
|
+
if (mode === 'stream') {
|
|
65
|
+
const { fields, fileInfo } = await (0, parse_1.parseFromReadableStream)(req, boundary);
|
|
46
66
|
if (!this.checkExt(fileInfo.filename)) {
|
|
47
|
-
|
|
48
|
-
const errorMessage = 'Invalid filename: ' + fileInfo.filename;
|
|
49
|
-
const err = new Error(errorMessage);
|
|
50
|
-
this.logger.error(err);
|
|
51
|
-
if (isExpress) {
|
|
52
|
-
return res.sendStatus(400);
|
|
53
|
-
}
|
|
54
|
-
return;
|
|
67
|
+
throw new _1.MultipartInvalidFilenameError(fileInfo.filename);
|
|
55
68
|
}
|
|
56
69
|
else {
|
|
57
70
|
ctx.fields = fields;
|
|
@@ -66,7 +79,7 @@ let UploadMiddleware = class UploadMiddleware {
|
|
|
66
79
|
else {
|
|
67
80
|
body = req.body;
|
|
68
81
|
}
|
|
69
|
-
const data = await (0,
|
|
82
|
+
const data = await (0, parse_1.parseMultipart)(body, boundary);
|
|
70
83
|
if (!data) {
|
|
71
84
|
return next();
|
|
72
85
|
}
|
|
@@ -79,36 +92,26 @@ let UploadMiddleware = class UploadMiddleware {
|
|
|
79
92
|
}
|
|
80
93
|
});
|
|
81
94
|
if (notCheckFile) {
|
|
82
|
-
|
|
83
|
-
const errorMessage = 'Invalid filename: ' + notCheckFile.filename;
|
|
84
|
-
const err = new Error(errorMessage);
|
|
85
|
-
this.logger.error(err);
|
|
86
|
-
if (isExpress) {
|
|
87
|
-
return res.sendStatus(400);
|
|
88
|
-
}
|
|
89
|
-
return;
|
|
95
|
+
throw new _1.MultipartInvalidFilenameError(notCheckFile.filename);
|
|
90
96
|
}
|
|
91
|
-
ctx.files =
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
this.push(data);
|
|
106
|
-
this.push(null);
|
|
107
|
-
},
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
return file;
|
|
97
|
+
ctx.files = await Promise.all(files.map(async (file, index) => {
|
|
98
|
+
const { data, filename } = file;
|
|
99
|
+
if (mode === 'file') {
|
|
100
|
+
const ext = (0, path_1.extname)(filename);
|
|
101
|
+
const tmpFileName = (0, path_1.resolve)(tmpdir, `${requireId}.${index}${ext}`);
|
|
102
|
+
await writeFile(tmpFileName, data, 'binary');
|
|
103
|
+
file.data = tmpFileName;
|
|
104
|
+
}
|
|
105
|
+
else if (mode === 'stream') {
|
|
106
|
+
file.data = new stream_1.Readable({
|
|
107
|
+
read() {
|
|
108
|
+
this.push(data);
|
|
109
|
+
this.push(null);
|
|
110
|
+
},
|
|
111
111
|
});
|
|
112
|
+
}
|
|
113
|
+
return file;
|
|
114
|
+
}));
|
|
112
115
|
return next();
|
|
113
116
|
}
|
|
114
117
|
getUploadBoundary(request) {
|
|
@@ -148,6 +151,9 @@ let UploadMiddleware = class UploadMiddleware {
|
|
|
148
151
|
}
|
|
149
152
|
return whitelist.includes(ext);
|
|
150
153
|
}
|
|
154
|
+
static getName() {
|
|
155
|
+
return 'upload';
|
|
156
|
+
}
|
|
151
157
|
};
|
|
152
158
|
__decorate([
|
|
153
159
|
(0, decorator_1.Config)('upload'),
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Config,\n Logger,\n Middleware,\n MidwayFrameworkType,\n} from '@midwayjs/decorator';\nimport { IMiddleware, IMidwayLogger } from '@midwayjs/core';\nimport { resolve, extname } from 'path';\nimport { promises } from 'fs';\nimport { Readable, Stream } from 'stream';\nimport {\n MultipartInvalidFilenameError,\n UploadFileInfo,\n UploadOptions,\n} from '.';\nimport { parseFromReadableStream, parseMultipart } from './parse';\nimport * as getRawBody from 'raw-body';\nconst { unlink, writeFile } = promises;\n\n@Middleware()\nexport class UploadMiddleware implements IMiddleware<any, any> {\n @Config('upload')\n upload: UploadOptions;\n\n @Logger()\n logger: IMidwayLogger;\n\n resolve(app) {\n if (app.getFrameworkType() === MidwayFrameworkType.WEB_EXPRESS) {\n return async (req: any, res: any, next: any) => {\n return this.execUpload(req, req, res, next, true);\n };\n } else {\n return async (ctx, next) => {\n const req = ctx.request?.req || ctx.request;\n return this.execUpload(ctx, req, ctx, next, false);\n };\n }\n }\n\n async execUpload(ctx, req, res, next, isExpress) {\n const { mode, tmpdir, fileSize } = this.upload;\n const boundary = this.getUploadBoundary(req);\n if (!boundary) {\n return next();\n }\n ctx.fields = {};\n ctx.files = [];\n ctx.cleanupRequestFiles = async (): Promise<Array<boolean>> => {\n if (!ctx.files?.length) {\n return [];\n }\n return Promise.all(\n ctx.files.map(async (fileInfo: UploadFileInfo<any>) => {\n if (typeof fileInfo.data !== 'string') {\n return false;\n }\n try {\n await unlink(fileInfo.data);\n return true;\n } catch {\n return false;\n }\n })\n );\n };\n\n let body;\n if (this.isReadableStream(req, isExpress)) {\n if (mode === 'stream') {\n const { fields, fileInfo } = await parseFromReadableStream(\n req,\n boundary\n );\n if (!this.checkExt(fileInfo.filename)) {\n throw new MultipartInvalidFilenameError(fileInfo.filename);\n } else {\n ctx.fields = fields;\n ctx.files = [fileInfo];\n return next();\n }\n }\n body = await getRawBody(req, {\n limit: fileSize,\n });\n } else {\n body = req.body;\n }\n\n const data = await parseMultipart(body, boundary);\n if (!data) {\n return next();\n }\n\n ctx.fields = data.fields;\n const requireId = `upload_${Date.now()}.${Math.random()}`;\n const files = data.files;\n const notCheckFile = files.find(fileInfo => {\n if (!this.checkExt(fileInfo.filename)) {\n return fileInfo;\n }\n });\n\n if (notCheckFile) {\n throw new MultipartInvalidFilenameError(notCheckFile.filename);\n }\n ctx.files = await Promise.all(\n files.map(async (file, index) => {\n const { data, filename } = file;\n if (mode === 'file') {\n const ext = extname(filename);\n const tmpFileName = resolve(tmpdir, `${requireId}.${index}${ext}`);\n await writeFile(tmpFileName, data, 'binary');\n file.data = tmpFileName;\n } else if (mode === 'stream') {\n file.data = new Readable({\n read() {\n this.push(data);\n this.push(null);\n },\n });\n }\n return file;\n })\n );\n\n return next();\n }\n\n getUploadBoundary(request): false | string {\n const method = (request.method || request.httpMethod || '').toUpperCase();\n if (!request.headers?.['content-type'] || method !== 'POST') {\n return false;\n }\n const contentType: string = request.headers['content-type'];\n if (!contentType.startsWith('multipart/form-data;')) {\n return false;\n }\n\n const boundaryMatch = /boundary=(.*)(;|\\s|$)/.exec(contentType);\n if (!boundaryMatch?.[1]) {\n return false;\n }\n return boundaryMatch[1];\n }\n\n isReadableStream(req: any, isExpress): boolean {\n // ref: https://github.com/rvagg/isstream/blob/master/isstream.js#L10\n if (\n req instanceof Stream &&\n typeof (req as any)._read === 'function' &&\n typeof (req as any)._readableState === 'object' &&\n (!(req as any).body || isExpress)\n ) {\n return true;\n }\n if (req.pipe && req.on && !req.body) {\n return true;\n }\n return false;\n }\n\n checkExt(filename): boolean {\n const ext = extname(filename).toLowerCase();\n const { whitelist } = this.upload;\n if (!Array.isArray(whitelist)) {\n return true;\n }\n return whitelist.includes(ext);\n }\n\n static getName() {\n return 'upload';\n }\n}\n"]}
|
|
@@ -7,9 +7,9 @@ export declare const parseMultipart: (body: any, boundary: string) => Promise<{
|
|
|
7
7
|
}>;
|
|
8
8
|
export declare const parseFromReadableStream: (readStream: Readable, boundary: any) => Promise<{
|
|
9
9
|
fields: any;
|
|
10
|
-
fileInfo: UploadFileInfo
|
|
10
|
+
fileInfo: UploadFileInfo<Readable>;
|
|
11
11
|
}>;
|
|
12
12
|
export declare const bufferIndexOf: (buffer: Buffer, search: Buffer, offset?: number) => number;
|
|
13
13
|
export declare const bufferSplit: (buffer: Buffer, separator: Buffer, limit?: number) => Buffer[];
|
|
14
14
|
export declare const parseHead: (headBuf: Buffer) => {};
|
|
15
|
-
//# sourceMappingURL=
|
|
15
|
+
//# sourceMappingURL=parse.d.ts.map
|
|
@@ -25,7 +25,7 @@ const parseMultipart = async (body, boundary) => {
|
|
|
25
25
|
files.push({
|
|
26
26
|
filename: head['content-disposition'].filename,
|
|
27
27
|
data,
|
|
28
|
-
|
|
28
|
+
fieldName: head['content-disposition'].name,
|
|
29
29
|
mimeType: head['content-type'],
|
|
30
30
|
});
|
|
31
31
|
});
|
|
@@ -42,7 +42,7 @@ const parseFromReadableStream = (readStream, boundary) => {
|
|
|
42
42
|
const fileInfo = {
|
|
43
43
|
filename: '',
|
|
44
44
|
data: null,
|
|
45
|
-
|
|
45
|
+
fieldName: '',
|
|
46
46
|
mimeType: '',
|
|
47
47
|
};
|
|
48
48
|
const emptyBuf = Buffer.alloc(0);
|
|
@@ -108,7 +108,7 @@ const parseFromReadableStream = (readStream, boundary) => {
|
|
|
108
108
|
continue;
|
|
109
109
|
}
|
|
110
110
|
fileInfo.filename = head['content-disposition'].filename;
|
|
111
|
-
fileInfo.
|
|
111
|
+
fileInfo.fieldName = head['content-disposition'].name;
|
|
112
112
|
fileInfo.mimeType = head['content-type'];
|
|
113
113
|
isTransformFileData = true;
|
|
114
114
|
lastChunk = data;
|
|
@@ -186,4 +186,4 @@ const parseHead = (headBuf) => {
|
|
|
186
186
|
return head;
|
|
187
187
|
};
|
|
188
188
|
exports.parseHead = parseHead;
|
|
189
|
-
//# sourceMappingURL=
|
|
189
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"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","sourcesContent":["import { Readable, Transform, Writable } from 'stream';\nimport { UploadFileInfo } from './interface';\nconst headSeparator = Buffer.from('\\r\\n\\r\\n');\nexport const parseMultipart = async (body: any, boundary: string) => {\n if (typeof body === 'string') {\n body = Buffer.from(body);\n }\n const bufferSeparator = Buffer.from('\\r\\n--' + boundary);\n const fields = {};\n const files = [];\n bufferSplit(body, bufferSeparator).forEach(buf => {\n const [headerBuf, data] = bufferSplit(buf, headSeparator, 2);\n const head = parseHead(headerBuf);\n if (!head['content-disposition']) {\n return;\n }\n if (!head['content-disposition'].filename) {\n if (head['content-disposition'].name) {\n fields[head['content-disposition'].name] = data.toString();\n }\n return;\n }\n files.push({\n filename: head['content-disposition'].filename,\n data,\n fieldName: head['content-disposition'].name,\n mimeType: head['content-type'],\n });\n });\n\n return {\n files,\n fields,\n };\n};\n\nconst pre = Buffer.from('\\r\\n');\nexport const parseFromReadableStream = (\n readStream: Readable,\n boundary\n): Promise<{ fields: any; fileInfo: UploadFileInfo<Readable> }> => {\n const bufferSeparator = Buffer.from(`\\r\\n--${boundary}`);\n const fields = {};\n const fileInfo: UploadFileInfo<Readable> = {\n filename: '',\n data: null,\n fieldName: '',\n mimeType: '',\n };\n const emptyBuf = Buffer.alloc(0);\n // 上一次遗留的 chunk\n let lastChunk = emptyBuf;\n // 前一个chunk的后缀\n let preChunk = emptyBuf;\n let isTransformFileData = false;\n let isTransformFileDataEnd = false;\n // let isEnd = false;\n let isFirst = true;\n let allChuns = Buffer.alloc(0);\n return new Promise(resolve => {\n fileInfo.data = new Transform({\n highWaterMark: 1000,\n transform(chunk, encoding, callback) {\n if (isFirst) {\n chunk = Buffer.concat([pre, chunk]);\n isFirst = false;\n }\n // 已经结束了\n if (isTransformFileDataEnd) {\n return callback(null, null);\n }\n\n // 正在传输中的话\n if (isTransformFileData) {\n if (lastChunk.length) {\n chunk = Buffer.concat([lastChunk, chunk]);\n lastChunk = emptyBuf;\n }\n const newPreChunk = Buffer.concat([preChunk, chunk]);\n const newBlockIndex = bufferIndexOf(newPreChunk, bufferSeparator);\n // 存在新的块则代表已经结束了\n if (newBlockIndex !== -1) {\n // 上一个块的最后一部分数据,需要追加写入\n const lastDataBlock = newPreChunk.slice(\n preChunk.length,\n newBlockIndex\n );\n isTransformFileDataEnd = true;\n callback(null, lastDataBlock);\n return;\n }\n // 块尚未结束,则继续写入\n callback(null, chunk);\n preChunk = newPreChunk.slice(-bufferSeparator.length);\n return;\n }\n\n // 未在传输过程中\n allChuns = Buffer.concat([allChuns, chunk]);\n\n const splitAllChuns = bufferSplit(allChuns, bufferSeparator);\n for (\n let chunkIndex = 0;\n chunkIndex < splitAllChuns.length;\n chunkIndex++\n ) {\n const [headerBuf, data] = bufferSplit(\n splitAllChuns[chunkIndex],\n headSeparator\n );\n const head = parseHead(headerBuf);\n if (!head['content-disposition']) {\n continue;\n }\n if (!head['content-disposition'].filename) {\n if (head['content-disposition'].name) {\n fields[head['content-disposition'].name] = data.toString();\n }\n continue;\n }\n // 这里就是找到了 file 的段,如果没有数据,则需要继续等待\n if (!data.length) {\n continue;\n }\n\n fileInfo.filename = head['content-disposition'].filename;\n fileInfo.fieldName = head['content-disposition'].name;\n fileInfo.mimeType = head['content-type'];\n isTransformFileData = true;\n lastChunk = data;\n allChuns = emptyBuf;\n this.pause();\n resolve({ fileInfo, fields });\n break;\n }\n\n callback(null, emptyBuf);\n },\n });\n readStream.pipe(fileInfo.data as any);\n const empty = new Writable();\n empty._write = function (chunk, encoding, cb) {\n cb();\n };\n fileInfo.data.pipe(empty);\n });\n};\n\n// search buffer index\nexport const bufferIndexOf = (\n buffer: Buffer,\n search: Buffer,\n offset?: number\n) => {\n return buffer.indexOf(search, offset);\n};\n\n// split buffer to buffer list\nexport const bufferSplit = (\n buffer: Buffer,\n separator: Buffer,\n limit?: number\n) => {\n let index = 0;\n const result: Buffer[] = [];\n let find: number = bufferIndexOf(buffer, separator, index);\n\n while (find !== -1) {\n result.push(buffer.slice(index, find));\n index = find + separator.length;\n if (limit && result.length + 1 === limit) {\n break;\n }\n find = bufferIndexOf(buffer, separator, index);\n }\n\n result.push(buffer.slice(index));\n return result;\n};\n\nconst headReg = /^([^:]+):[ \\t]?(.+)?$/;\nexport const parseHead = (headBuf: Buffer) => {\n const head = {};\n const headStrList = headBuf.toString().split('\\r\\n');\n for (const headStr of headStrList) {\n const matched = headReg.exec(headStr);\n if (!matched) {\n continue;\n }\n const name = matched[1].toLowerCase();\n const value = matched[2]\n ? matched[2].replace(/&#(\\d+);/g, (origin: string, code: string) => {\n try {\n return String.fromCharCode(parseInt(code));\n } catch {\n return origin;\n }\n })\n : '';\n if (name === 'content-disposition') {\n const headCol = {};\n value.split(/;\\s+/).forEach((kv: string) => {\n const [k, v] = kv.split('=');\n headCol[k] = v ? v.replace(/^\"/, '').replace(/\"$/, '') : v ?? true;\n });\n head[name] = headCol;\n } else {\n head[name] = value;\n }\n }\n return head;\n};\n"]}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const autoRemoveUploadTmpFile: (tmpDir: string, cleanTimeout: number) => Promise<void>;
|
|
2
|
+
export declare const stopAutoRemoveUploadTmpFile: () => Promise<void>;
|
|
3
|
+
export declare const checkExists: (path: string) => Promise<boolean>;
|
|
4
|
+
export declare const ensureDir: (dirPath: string) => Promise<boolean>;
|
|
5
|
+
//# sourceMappingURL=utils.d.ts.map
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ensureDir = exports.checkExists = exports.stopAutoRemoveUploadTmpFile = exports.autoRemoveUploadTmpFile = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const { readdir, access, stat, unlink, mkdir } = fs_1.promises;
|
|
7
|
+
let autoRemoveUploadTmpFileTimeoutHandler;
|
|
8
|
+
let autoRemoveUploadTmpFilePromise;
|
|
9
|
+
const autoRemoveUploadTmpFile = async (tmpDir, cleanTimeout) => {
|
|
10
|
+
clearTimeout(autoRemoveUploadTmpFileTimeoutHandler);
|
|
11
|
+
let waitTime = cleanTimeout / 3;
|
|
12
|
+
if (waitTime < 1000) {
|
|
13
|
+
waitTime = 1000;
|
|
14
|
+
}
|
|
15
|
+
if (autoRemoveUploadTmpFilePromise) {
|
|
16
|
+
const exists = await (0, exports.checkExists)(tmpDir);
|
|
17
|
+
if (exists) {
|
|
18
|
+
const paths = await readdir(tmpDir);
|
|
19
|
+
const now = Date.now();
|
|
20
|
+
await Promise.all(paths.map(async (path) => {
|
|
21
|
+
const filePath = (0, path_1.join)(tmpDir, path);
|
|
22
|
+
try {
|
|
23
|
+
const statInfo = await stat(filePath);
|
|
24
|
+
if (statInfo.isFile() && now - statInfo.ctimeMs > cleanTimeout) {
|
|
25
|
+
await unlink(filePath);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch (_a) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
autoRemoveUploadTmpFileTimeoutHandler = setTimeout(() => {
|
|
35
|
+
autoRemoveUploadTmpFilePromise = (0, exports.autoRemoveUploadTmpFile)(tmpDir, cleanTimeout);
|
|
36
|
+
}, waitTime);
|
|
37
|
+
};
|
|
38
|
+
exports.autoRemoveUploadTmpFile = autoRemoveUploadTmpFile;
|
|
39
|
+
const stopAutoRemoveUploadTmpFile = async () => {
|
|
40
|
+
if (autoRemoveUploadTmpFilePromise) {
|
|
41
|
+
await autoRemoveUploadTmpFilePromise;
|
|
42
|
+
autoRemoveUploadTmpFilePromise = null;
|
|
43
|
+
}
|
|
44
|
+
clearTimeout(autoRemoveUploadTmpFileTimeoutHandler);
|
|
45
|
+
};
|
|
46
|
+
exports.stopAutoRemoveUploadTmpFile = stopAutoRemoveUploadTmpFile;
|
|
47
|
+
const checkExists = async (path) => {
|
|
48
|
+
try {
|
|
49
|
+
await access(path, fs_1.constants.W_OK | fs_1.constants.R_OK);
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
catch (_a) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
exports.checkExists = checkExists;
|
|
57
|
+
const ensureDir = async (dirPath) => {
|
|
58
|
+
const isExists = await (0, exports.checkExists)(dirPath);
|
|
59
|
+
if (isExists) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
await mkdir(dirPath, { recursive: true });
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
catch (_a) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
exports.ensureDir = ensureDir;
|
|
71
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;AAAA,2BAAyC;AACzC,+BAA4B;AAC5B,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,aAAQ,CAAC;AAC1D,IAAI,qCAAqC,CAAC;AAC1C,IAAI,8BAA8B,CAAC;AAC5B,MAAM,uBAAuB,GAAG,KAAK,EAC1C,MAAc,EACd,YAAoB,EACpB,EAAE;IACF,YAAY,CAAC,qCAAqC,CAAC,CAAC;IACpD,IAAI,QAAQ,GAAG,YAAY,GAAG,CAAC,CAAC;IAChC,IAAI,QAAQ,GAAG,IAAI,EAAE;QACnB,QAAQ,GAAG,IAAI,CAAC;KACjB;IAED,IAAI,8BAA8B,EAAE;QAClC,MAAM,MAAM,GAAG,MAAM,IAAA,mBAAW,EAAC,MAAM,CAAC,CAAC;QACzC,IAAI,MAAM,EAAE;YACV,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;YACpC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,MAAM,OAAO,CAAC,GAAG,CACf,KAAK,CAAC,GAAG,CAAC,KAAK,EAAC,IAAI,EAAC,EAAE;gBACrB,MAAM,QAAQ,GAAG,IAAA,WAAI,EAAC,MAAM,EAAE,IAAI,CAAC,CAAC;gBACpC,IAAI;oBACF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;oBACtC,IAAI,QAAQ,CAAC,MAAM,EAAE,IAAI,GAAG,GAAG,QAAQ,CAAC,OAAO,GAAG,YAAY,EAAE;wBAC9D,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;qBACxB;iBACF;gBAAC,WAAM;oBACN,OAAO,KAAK,CAAC;iBACd;YACH,CAAC,CAAC,CACH,CAAC;SACH;KACF;IAED,qCAAqC,GAAG,UAAU,CAAC,GAAG,EAAE;QACtD,8BAA8B,GAAG,IAAA,+BAAuB,EACtD,MAAM,EACN,YAAY,CACb,CAAC;IACJ,CAAC,EAAE,QAAQ,CAAC,CAAC;AACf,CAAC,CAAC;AArCW,QAAA,uBAAuB,2BAqClC;AAEK,MAAM,2BAA2B,GAAG,KAAK,IAAI,EAAE;IACpD,IAAI,8BAA8B,EAAE;QAClC,MAAM,8BAA8B,CAAC;QACrC,8BAA8B,GAAG,IAAI,CAAC;KACvC;IACD,YAAY,CAAC,qCAAqC,CAAC,CAAC;AACtD,CAAC,CAAC;AANW,QAAA,2BAA2B,+BAMtC;AAEK,MAAM,WAAW,GAAG,KAAK,EAAE,IAAY,EAAoB,EAAE;IAClE,IAAI;QACF,MAAM,MAAM,CAAC,IAAI,EAAE,cAAS,CAAC,IAAI,GAAG,cAAS,CAAC,IAAI,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC;KACb;IAAC,WAAM;QACN,OAAO,KAAK,CAAC;KACd;AACH,CAAC,CAAC;AAPW,QAAA,WAAW,eAOtB;AAEK,MAAM,SAAS,GAAG,KAAK,EAAE,OAAe,EAAoB,EAAE;IACnE,MAAM,QAAQ,GAAG,MAAM,IAAA,mBAAW,EAAC,OAAO,CAAC,CAAC;IAC5C,IAAI,QAAQ,EAAE;QACZ,OAAO,IAAI,CAAC;KACb;IACD,IAAI;QACF,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC;KACb;IAAC,WAAM;QACN,OAAO,KAAK,CAAC;KACd;AACH,CAAC,CAAC;AAXW,QAAA,SAAS,aAWpB","sourcesContent":["import { promises, constants } from 'fs';\nimport { join } from 'path';\nconst { readdir, access, stat, unlink, mkdir } = promises;\nlet autoRemoveUploadTmpFileTimeoutHandler;\nlet autoRemoveUploadTmpFilePromise;\nexport const autoRemoveUploadTmpFile = async (\n tmpDir: string,\n cleanTimeout: number\n) => {\n clearTimeout(autoRemoveUploadTmpFileTimeoutHandler);\n let waitTime = cleanTimeout / 3;\n if (waitTime < 1000) {\n waitTime = 1000;\n }\n\n if (autoRemoveUploadTmpFilePromise) {\n const exists = await checkExists(tmpDir);\n if (exists) {\n const paths = await readdir(tmpDir);\n const now = Date.now();\n await Promise.all(\n paths.map(async path => {\n const filePath = join(tmpDir, path);\n try {\n const statInfo = await stat(filePath);\n if (statInfo.isFile() && now - statInfo.ctimeMs > cleanTimeout) {\n await unlink(filePath);\n }\n } catch {\n return false;\n }\n })\n );\n }\n }\n\n autoRemoveUploadTmpFileTimeoutHandler = setTimeout(() => {\n autoRemoveUploadTmpFilePromise = autoRemoveUploadTmpFile(\n tmpDir,\n cleanTimeout\n );\n }, waitTime);\n};\n\nexport const stopAutoRemoveUploadTmpFile = async () => {\n if (autoRemoveUploadTmpFilePromise) {\n await autoRemoveUploadTmpFilePromise;\n autoRemoveUploadTmpFilePromise = null;\n }\n clearTimeout(autoRemoveUploadTmpFileTimeoutHandler);\n};\n\nexport const checkExists = async (path: string): Promise<boolean> => {\n try {\n await access(path, constants.W_OK | constants.R_OK);\n return true;\n } catch {\n return false;\n }\n};\n\nexport const ensureDir = async (dirPath: string): Promise<boolean> => {\n const isExists = await checkExists(dirPath);\n if (isExists) {\n return true;\n }\n try {\n await mkdir(dirPath, { recursive: true });\n return true;\n } catch {\n return false;\n }\n};\n"]}
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { UploadFileInfo, UploadOptions } from './dist/index';
|
|
2
|
+
export * from './dist/index';
|
|
3
|
+
|
|
4
|
+
declare module '@midwayjs/core/dist/interface' {
|
|
5
|
+
interface MidwayConfig {
|
|
6
|
+
upload?: Partial<UploadOptions>;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
declare module '@midwayjs/koa/dist/interface' {
|
|
10
|
+
interface Context {
|
|
11
|
+
files?: UploadFileInfo<any>[];
|
|
12
|
+
fields?: { [fieldName: string]: any };
|
|
13
|
+
cleanupRequestFiles?: () => Promise<Array<boolean>>;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
declare module '@midwayjs/web/dist/interface' {
|
|
18
|
+
interface Context {
|
|
19
|
+
files?: UploadFileInfo<any>[];
|
|
20
|
+
fields?: { [fieldName: string]: any };
|
|
21
|
+
cleanupRequestFiles?: () => Promise<Array<boolean>>;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
declare module '@midwayjs/faas/dist/interface' {
|
|
26
|
+
interface Context {
|
|
27
|
+
files?: UploadFileInfo<any>[];
|
|
28
|
+
fields?: { [fieldName: string]: any };
|
|
29
|
+
cleanupRequestFiles?: () => Promise<Array<boolean>>;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
declare module '@midwayjs/express/dist/interface' {
|
|
34
|
+
interface Context {
|
|
35
|
+
files?: UploadFileInfo<any>[];
|
|
36
|
+
fields?: { [fieldName: string]: any };
|
|
37
|
+
cleanupRequestFiles?: () => Promise<Array<boolean>>;
|
|
38
|
+
}
|
|
39
|
+
}
|
package/package.json
CHANGED
|
@@ -1,37 +1,39 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@midwayjs/upload",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.3",
|
|
4
4
|
"description": "Midway Component for upload",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
|
-
"typings": "
|
|
6
|
+
"typings": "index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "tsc",
|
|
9
|
-
"test": "node --require=ts-node/register ../../node_modules/.bin/jest",
|
|
10
|
-
"cov": "node --require=ts-node/register ../../node_modules/.bin/jest --coverage --forceExit",
|
|
9
|
+
"test": "node --require=ts-node/register ../../node_modules/.bin/jest --runInBand",
|
|
10
|
+
"cov": "node --require=ts-node/register ../../node_modules/.bin/jest --runInBand --coverage --forceExit",
|
|
11
11
|
"ci": "npm run test"
|
|
12
12
|
},
|
|
13
13
|
"keywords": [],
|
|
14
14
|
"author": "",
|
|
15
15
|
"files": [
|
|
16
16
|
"dist/**/*.js",
|
|
17
|
-
"dist/**/*.d.ts"
|
|
17
|
+
"dist/**/*.d.ts",
|
|
18
|
+
"index.d.ts",
|
|
19
|
+
"dist/**/*.js.map"
|
|
18
20
|
],
|
|
19
21
|
"engines": {
|
|
20
22
|
"node": ">=12"
|
|
21
23
|
},
|
|
22
24
|
"license": "MIT",
|
|
23
25
|
"dependencies": {
|
|
24
|
-
"
|
|
25
|
-
"raw-body": "^2.4.1"
|
|
26
|
+
"raw-body": "2.4.2"
|
|
26
27
|
},
|
|
27
28
|
"devDependencies": {
|
|
28
|
-
"@midwayjs/core": "^3.0.
|
|
29
|
-
"@midwayjs/decorator": "^3.0.
|
|
30
|
-
"@midwayjs/
|
|
31
|
-
"@midwayjs/faas": "^3.0.
|
|
32
|
-
"@midwayjs/
|
|
33
|
-
"@midwayjs/
|
|
34
|
-
"@midwayjs/
|
|
35
|
-
"@midwayjs/
|
|
36
|
-
}
|
|
29
|
+
"@midwayjs/core": "^3.0.2",
|
|
30
|
+
"@midwayjs/decorator": "^3.0.2",
|
|
31
|
+
"@midwayjs/express": "^3.0.2",
|
|
32
|
+
"@midwayjs/faas": "^3.0.2",
|
|
33
|
+
"@midwayjs/koa": "^3.0.3",
|
|
34
|
+
"@midwayjs/mock": "^3.0.2",
|
|
35
|
+
"@midwayjs/serverless-app": "^3.0.2",
|
|
36
|
+
"@midwayjs/web": "^3.0.2"
|
|
37
|
+
},
|
|
38
|
+
"gitHead": "43a5971b284aa918d22d191236c5664b011f8d87"
|
|
37
39
|
}
|
package/CHANGELOG.md
DELETED
|
File without changes
|