doomistorage 1.0.10 → 2.0.1
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/.claude/settings.local.json +7 -0
- package/CLAUDE.md +53 -0
- package/package.json +27 -9
- package/rollup.config.js +36 -0
- package/src/azureblob.ts +83 -0
- package/src/cosfile.ts +45 -13
- package/src/declare.ts +5 -3
- package/src/file.ts +22 -140
- package/src/filehelper.ts +21 -6
- package/src/localfile.ts +26 -24
- package/src/uploader.ts +3 -3
- package/tsconfig-tsc.json +31 -0
- package/tsconfig.json +18 -30
- package/dist/cosfile.d.ts +0 -34
- package/dist/cosfile.js +0 -131
- package/dist/declare.d.ts +0 -16
- package/dist/declare.js +0 -2
- package/dist/file.d.ts +0 -55
- package/dist/file.js +0 -116
- package/dist/filehelper.d.ts +0 -91
- package/dist/filehelper.js +0 -185
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -18
- package/dist/localfile.d.ts +0 -30
- package/dist/localfile.js +0 -92
- package/dist/uploader.d.ts +0 -2
- package/dist/uploader.js +0 -65
package/src/filehelper.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CosFile } from "./cosfile";
|
|
2
|
+
import { AzureBlob } from "./azureblob";
|
|
2
3
|
import { FileConfig, FileResult } from "./declare";
|
|
3
4
|
import { FileBase } from "./file";
|
|
4
5
|
import { LocalFile } from "./localfile";
|
|
@@ -12,13 +13,12 @@ let config:any;
|
|
|
12
13
|
*/
|
|
13
14
|
function getConfigurationSetting(settingName?:string,isSection:boolean=true):any{
|
|
14
15
|
if (!config){
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
const configfilename = process.env["CONFIGFILE"] || 'configuration.json'
|
|
17
|
+
const configfile = path.join(process.cwd(), configfilename);
|
|
17
18
|
if (!fs.existsSync(configfile)) return null;
|
|
18
19
|
config = require(configfile);
|
|
19
20
|
}
|
|
20
21
|
if (!config) return null;
|
|
21
|
-
//const config = require(configfile)[settingName || 'tencentCOS'];
|
|
22
22
|
return isSection ? config[settingName || 'tencentCOS'] : (config.appsetting[settingName ||'destination']??'tencentcos') ;
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
@@ -27,6 +27,7 @@ function getConfigurationSetting(settingName?:string,isSection:boolean=true):any
|
|
|
27
27
|
export const FileProviderEnum = {
|
|
28
28
|
LOCAL: 'local',
|
|
29
29
|
TENCENTCOS: 'tencentcos',
|
|
30
|
+
Azure:'azure'
|
|
30
31
|
} as const;
|
|
31
32
|
export type FileProviderEnum = typeof FileProviderEnum[keyof typeof FileProviderEnum];
|
|
32
33
|
/**
|
|
@@ -45,6 +46,12 @@ export function FileHelper(provider?: FileProviderEnum, apiOption?: any): FileUt
|
|
|
45
46
|
}
|
|
46
47
|
filehandler = new CosFile(apiOption);
|
|
47
48
|
break;
|
|
49
|
+
case FileProviderEnum.Azure:
|
|
50
|
+
if (!apiOption || typeof (apiOption) == 'string') {
|
|
51
|
+
apiOption = getConfigurationSetting('azurestorge')
|
|
52
|
+
}
|
|
53
|
+
filehandler = new AzureBlob(apiOption);
|
|
54
|
+
break;
|
|
48
55
|
default: filehandler = new LocalFile();
|
|
49
56
|
}
|
|
50
57
|
return new FileUtility(filehandler)
|
|
@@ -54,11 +61,18 @@ export function FileHelper(provider?: FileProviderEnum, apiOption?: any): FileUt
|
|
|
54
61
|
/**
|
|
55
62
|
* 文件帮助工具
|
|
56
63
|
*/
|
|
57
|
-
class FileUtility {
|
|
64
|
+
export class FileUtility {
|
|
58
65
|
private fileHandler: FileBase;
|
|
59
66
|
constructor(handler: FileBase) {
|
|
60
67
|
this.fileHandler = handler;
|
|
61
68
|
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* 获取文件存储的临时token
|
|
72
|
+
*/
|
|
73
|
+
async getTemporaryToken(expiresSeconds: number=0, permission?: string):Promise<any>{
|
|
74
|
+
return await this.fileHandler.getTemporaryToken(expiresSeconds, permission);
|
|
75
|
+
}
|
|
62
76
|
/**
|
|
63
77
|
* 读取文件并保存至目标路径
|
|
64
78
|
* @param file 文件对象
|
|
@@ -76,6 +90,7 @@ class FileUtility {
|
|
|
76
90
|
return await this.fileHandler.saveFileStream(file, fileName, saveOption, userInfo);
|
|
77
91
|
}
|
|
78
92
|
|
|
93
|
+
|
|
79
94
|
/**
|
|
80
95
|
* 保存字符流到对应的存储设备
|
|
81
96
|
* @param bufferData
|
|
@@ -108,7 +123,7 @@ class FileUtility {
|
|
|
108
123
|
* @returns
|
|
109
124
|
*/
|
|
110
125
|
async BatchDownloadImage(urlArray: string[], saveOption: FileConfig, userInfo: any = {}): Promise<FileResult[]> {
|
|
111
|
-
|
|
126
|
+
const promiseArr = [];
|
|
112
127
|
for (const url of urlArray) {
|
|
113
128
|
promiseArr.push(this.DownloadFile(url, null, saveOption, userInfo))
|
|
114
129
|
}
|
|
@@ -125,7 +140,7 @@ class FileUtility {
|
|
|
125
140
|
*/
|
|
126
141
|
async DownloadFile(fileUrl: string, savefileName: string | null, savesetting: FileConfig, userInfo: any = {}, allowWebPFormat = false): Promise<FileResult> {
|
|
127
142
|
if (!allowWebPFormat && fileUrl.indexOf('&tp=webp') >= 0) fileUrl = fileUrl.replace('&tp=webp', '');
|
|
128
|
-
|
|
143
|
+
const fileName = savefileName ? savefileName : path.basename(fileUrl);
|
|
129
144
|
try {
|
|
130
145
|
const downloadResult = await axios.get(fileUrl, { responseType: 'arraybuffer' });
|
|
131
146
|
if (downloadResult.data) {
|
package/src/localfile.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { FileBase } from "./file";
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import path from 'path';
|
|
4
|
+
import { pipeline } from 'stream/promises';
|
|
4
5
|
import { FileConfig, FileResult } from "./declare";
|
|
5
6
|
export class LocalFile extends FileBase {
|
|
7
|
+
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
10
|
* 直接保存字符串
|
|
@@ -12,18 +14,20 @@ export class LocalFile extends FileBase {
|
|
|
12
14
|
* @param userInfo
|
|
13
15
|
*/
|
|
14
16
|
async saveString2File(data: string | Buffer, fileName: string, saveOption: FileConfig, userInfo: any = {}): Promise<FileResult> {
|
|
15
|
-
|
|
17
|
+
const baseFileName = this.getSaveFileName(saveOption, fileName, userInfo);
|
|
16
18
|
if (!baseFileName) return { successed: false };
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
const fullFileName = path.resolve(saveOption.basefolder || '', baseFileName);
|
|
20
|
+
const _saveDir = path.dirname(fullFileName);
|
|
19
21
|
///创建本地文件夹
|
|
20
22
|
if (!this.mkdirsSync(_saveDir)) return { successed: false };
|
|
21
23
|
return new Promise(resolve => {
|
|
22
|
-
fs.writeFile(fullFileName, data, (error) =>
|
|
23
|
-
return resolve({ successed: error == null, filePath: fullFileName })
|
|
24
|
-
})
|
|
24
|
+
fs.writeFile(fullFileName, data as any, (error:any) => resolve({ successed: !error , filePath: fullFileName, error }) )
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
|
+
|
|
28
|
+
async getTemporaryToken(expiresSeconds?: number, permission?: string): Promise<string> {
|
|
29
|
+
return 'localtoken'
|
|
30
|
+
}
|
|
27
31
|
/**
|
|
28
32
|
* 读取文件对象并保存至本地存储
|
|
29
33
|
* @param file
|
|
@@ -33,35 +37,33 @@ export class LocalFile extends FileBase {
|
|
|
33
37
|
* @returns
|
|
34
38
|
*/
|
|
35
39
|
async saveFileStream(file: any, fileName: any, saveOption: FileConfig, userInfo: any): Promise<FileResult> {
|
|
36
|
-
|
|
40
|
+
const baseFileName = this.getSaveFileName(saveOption, fileName, userInfo);
|
|
37
41
|
if (!baseFileName) return { successed: false };
|
|
38
|
-
|
|
39
|
-
|
|
42
|
+
const fullFileName = path.resolve(saveOption.basefolder || '', baseFileName);
|
|
43
|
+
const _saveDir = path.dirname(fullFileName);
|
|
40
44
|
///创建本地文件夹
|
|
41
45
|
if (!this.mkdirsSync(_saveDir)) return { successed: false };
|
|
42
|
-
|
|
43
|
-
|
|
46
|
+
try {
|
|
47
|
+
await pipeline(file, fs.createWriteStream(fullFileName));
|
|
48
|
+
return { successed: true, filePath: fullFileName };
|
|
49
|
+
} catch (error: any) {
|
|
50
|
+
return { successed: false, filePath: fullFileName, error };
|
|
51
|
+
}
|
|
44
52
|
}
|
|
45
53
|
/**
|
|
46
54
|
* 删除指定文件
|
|
47
55
|
* @param filepath
|
|
48
56
|
*/
|
|
49
57
|
async deleteFile(filepath: string | string[]): Promise<{ successed: boolean, error?: any }> {
|
|
50
|
-
|
|
58
|
+
try {
|
|
51
59
|
if (Array.isArray(filepath)) {
|
|
52
|
-
|
|
53
|
-
fs.unlink(f, (err: any) => {
|
|
54
|
-
if (err) console.log('delete file error', err)
|
|
55
|
-
})
|
|
56
|
-
}
|
|
60
|
+
await Promise.all(filepath.map(f => fs.promises.unlink(f)));
|
|
57
61
|
} else {
|
|
58
|
-
fs.unlink(filepath
|
|
59
|
-
if (err) console.log('delete file error', err)
|
|
60
|
-
})
|
|
62
|
+
await fs.promises.unlink(filepath);
|
|
61
63
|
}
|
|
62
|
-
return
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
return { successed: true };
|
|
65
|
+
} catch (error) {
|
|
66
|
+
return { successed: false, error };
|
|
67
|
+
}
|
|
66
68
|
}
|
|
67
69
|
}
|
package/src/uploader.ts
CHANGED
|
@@ -37,15 +37,15 @@ class LocalUploader{
|
|
|
37
37
|
req.shortpath = destinationFolder;
|
|
38
38
|
////如果目录不存在,则创建目录
|
|
39
39
|
destinationFolder = path.join(this.uploadconfig.dest, destinationFolder);
|
|
40
|
-
if (
|
|
41
|
-
cb(
|
|
40
|
+
if (fs.existsSync(destinationFolder) || this.fileUtilily.mkdirsSync(path.resolve(destinationFolder))) return cb(null, destinationFolder);
|
|
41
|
+
cb('如果目录不存在,创建失败', destinationFolder)
|
|
42
42
|
},
|
|
43
43
|
//给上传文件重命名,获取添加后缀名
|
|
44
44
|
filename: (req: any, file: any, cb: any) => {
|
|
45
45
|
let saveOption = req.fileconfig; //this.config.mapping[filetype];
|
|
46
46
|
if (!saveOption) {
|
|
47
47
|
req.fileerror = { successed: false, errmsg: "filetype not configurated in upload setting" };
|
|
48
|
-
cb("filetype not configurated in upload setting", null);
|
|
48
|
+
return cb("filetype not configurated in upload setting", null);
|
|
49
49
|
}
|
|
50
50
|
let finalFile = this.fileUtilily.getSaveOnlyFileName(saveOption, file.originalname);
|
|
51
51
|
req.shortpath = path.join(req.shortpath, finalFile);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"files": [
|
|
3
|
+
"src/index.ts"
|
|
4
|
+
],
|
|
5
|
+
"compilerOptions": {
|
|
6
|
+
"target": "es2015",
|
|
7
|
+
"module": "commonjs",
|
|
8
|
+
"declaration": true,
|
|
9
|
+
"outDir": "./dist",
|
|
10
|
+
"noEmit": false,
|
|
11
|
+
"strict": true,
|
|
12
|
+
"noImplicitAny": true,
|
|
13
|
+
"strictNullChecks": true,
|
|
14
|
+
"strictFunctionTypes": true,
|
|
15
|
+
"strictBindCallApply": true,
|
|
16
|
+
"strictPropertyInitialization": true,
|
|
17
|
+
"noImplicitThis": true,
|
|
18
|
+
"alwaysStrict": true,
|
|
19
|
+
"noUnusedLocals": true,
|
|
20
|
+
"noUnusedParameters": true,
|
|
21
|
+
"noImplicitReturns": true,
|
|
22
|
+
"noFallthroughCasesInSwitch": true,
|
|
23
|
+
"noUncheckedIndexedAccess": true,
|
|
24
|
+
"noImplicitOverride": true,
|
|
25
|
+
"moduleResolution": "node",
|
|
26
|
+
"noPropertyAccessFromIndexSignature": true,
|
|
27
|
+
"esModuleInterop": true,
|
|
28
|
+
"forceConsistentCasingInFileNames": true,
|
|
29
|
+
"skipLibCheck": true
|
|
30
|
+
}
|
|
31
|
+
}
|
package/tsconfig.json
CHANGED
|
@@ -1,31 +1,19 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
"noUnusedParameters": true,
|
|
21
|
-
"noImplicitReturns": true,
|
|
22
|
-
"noFallthroughCasesInSwitch": true,
|
|
23
|
-
"noUncheckedIndexedAccess": true,
|
|
24
|
-
"noImplicitOverride": true,
|
|
25
|
-
"moduleResolution": "node",
|
|
26
|
-
"noPropertyAccessFromIndexSignature": true,
|
|
27
|
-
"esModuleInterop": true,
|
|
28
|
-
"forceConsistentCasingInFileNames": true,
|
|
29
|
-
"skipLibCheck": true
|
|
30
|
-
}
|
|
31
|
-
}
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
|
|
4
|
+
"module": "ESNext" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
|
|
5
|
+
"declaration": true /* Generates corresponding '.d.ts' file. */,
|
|
6
|
+
"declarationMap": true /* Generates a sourcemap for each corresponding '.d.ts' file. */,
|
|
7
|
+
"sourceMap": true /* Generates corresponding '.map' file. */,
|
|
8
|
+
"outDir": "dist" /* Redirect output structure to the directory. */,
|
|
9
|
+
"declarationDir": "./dist/types",
|
|
10
|
+
"noEmit": false,
|
|
11
|
+
"emitDeclarationOnly": false,
|
|
12
|
+
"strict": true /* Enable all strict type-checking options. */,
|
|
13
|
+
"moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
|
|
14
|
+
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
|
|
15
|
+
"skipLibCheck": true /* Skip type checking of declaration files. */,
|
|
16
|
+
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
|
|
17
|
+
},
|
|
18
|
+
"include": ["src"]
|
|
19
|
+
}
|
package/dist/cosfile.d.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import { FileConfig, FileResult } from "./declare";
|
|
3
|
-
import { FileBase } from "./file";
|
|
4
|
-
export declare class CosFile extends FileBase {
|
|
5
|
-
private bucket;
|
|
6
|
-
private cos;
|
|
7
|
-
private region;
|
|
8
|
-
constructor(config: any);
|
|
9
|
-
/**
|
|
10
|
-
*
|
|
11
|
-
* @param data
|
|
12
|
-
* @param fileName
|
|
13
|
-
* @param saveOption
|
|
14
|
-
* @param userInfo
|
|
15
|
-
*/
|
|
16
|
-
saveString2File(data: string | Buffer, fileName: string, saveOption: FileConfig, userInfo?: any): Promise<FileResult>;
|
|
17
|
-
/**
|
|
18
|
-
*
|
|
19
|
-
* @param file
|
|
20
|
-
* @param fileName
|
|
21
|
-
* @param saveOption
|
|
22
|
-
* @param userInfo
|
|
23
|
-
* @returns
|
|
24
|
-
*/
|
|
25
|
-
saveFileStream(file: any, fileName: any, saveOption: FileConfig, userInfo: any): Promise<FileResult>;
|
|
26
|
-
/**
|
|
27
|
-
* 删除指定位置的文件
|
|
28
|
-
* @param filepath
|
|
29
|
-
*/
|
|
30
|
-
deleteFile(filepath: string | string[]): Promise<{
|
|
31
|
-
successed: boolean;
|
|
32
|
-
error?: any;
|
|
33
|
-
}>;
|
|
34
|
-
}
|
package/dist/cosfile.js
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.CosFile = void 0;
|
|
16
|
-
const file_1 = require("./file");
|
|
17
|
-
const cos_nodejs_sdk_v5_1 = __importDefault(require("cos-nodejs-sdk-v5"));
|
|
18
|
-
class CosFile extends file_1.FileBase {
|
|
19
|
-
constructor(config) {
|
|
20
|
-
super();
|
|
21
|
-
this.cos = new cos_nodejs_sdk_v5_1.default({
|
|
22
|
-
SecretId: config.SecretId,
|
|
23
|
-
SecretKey: config.SecretKey
|
|
24
|
-
});
|
|
25
|
-
this.bucket = config.bucket;
|
|
26
|
-
this.region = config.region;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
*
|
|
30
|
-
* @param data
|
|
31
|
-
* @param fileName
|
|
32
|
-
* @param saveOption
|
|
33
|
-
* @param userInfo
|
|
34
|
-
*/
|
|
35
|
-
saveString2File(data, fileName, saveOption, userInfo = {}) {
|
|
36
|
-
if (!data)
|
|
37
|
-
data = '';
|
|
38
|
-
let destinationFileName = this.getSaveFileName(saveOption, fileName, userInfo);
|
|
39
|
-
const streamBuffer = data instanceof Buffer ? data : Buffer.from(data, "utf-8");
|
|
40
|
-
const fileParam = {
|
|
41
|
-
Bucket: this.bucket,
|
|
42
|
-
Region: this.region,
|
|
43
|
-
Key: destinationFileName,
|
|
44
|
-
Body: streamBuffer,
|
|
45
|
-
ContentLength: streamBuffer.byteLength
|
|
46
|
-
};
|
|
47
|
-
return new Promise((success) => {
|
|
48
|
-
this.cos.putObject(fileParam, (err) => {
|
|
49
|
-
return success({ successed: err == null, filePath: destinationFileName });
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
*
|
|
55
|
-
* @param file
|
|
56
|
-
* @param fileName
|
|
57
|
-
* @param saveOption
|
|
58
|
-
* @param userInfo
|
|
59
|
-
* @returns
|
|
60
|
-
*/
|
|
61
|
-
saveFileStream(file, fileName, saveOption, userInfo) {
|
|
62
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
63
|
-
const destinationFileName = this.getSaveFileName(saveOption, fileName, userInfo);
|
|
64
|
-
return new Promise((resolve) => {
|
|
65
|
-
if (saveOption.reRead) {
|
|
66
|
-
let dataArr = [], //存储读取的结果集合
|
|
67
|
-
len = 0;
|
|
68
|
-
file.on('data', (chunk) => {
|
|
69
|
-
dataArr.push(chunk);
|
|
70
|
-
len += chunk.length;
|
|
71
|
-
});
|
|
72
|
-
file.on('end', () => {
|
|
73
|
-
const fileParam = {
|
|
74
|
-
Bucket: this.bucket,
|
|
75
|
-
Region: this.region,
|
|
76
|
-
Key: destinationFileName,
|
|
77
|
-
Body: Buffer.concat(dataArr, len),
|
|
78
|
-
ContentLength: len // file.byteCount || saveOption.contentLength
|
|
79
|
-
};
|
|
80
|
-
this.cos.putObject(fileParam, (err) => {
|
|
81
|
-
return resolve({ successed: err == null, filePath: destinationFileName });
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
const fileParam = {
|
|
87
|
-
Bucket: this.bucket,
|
|
88
|
-
Region: this.region,
|
|
89
|
-
// ContentDisposition: "form-data; name=\"file\"; filename=\"" + encodeURIComponent(destinationFileName) + "\"",
|
|
90
|
-
Key: destinationFileName,
|
|
91
|
-
Body: file,
|
|
92
|
-
ContentLength: file.byteCount || file.length
|
|
93
|
-
};
|
|
94
|
-
this.cos.putObject(fileParam, function (err) {
|
|
95
|
-
return resolve({ successed: err == null, filePath: destinationFileName });
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* 删除指定位置的文件
|
|
103
|
-
* @param filepath
|
|
104
|
-
*/
|
|
105
|
-
deleteFile(filepath) {
|
|
106
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
107
|
-
return new Promise(reslove => {
|
|
108
|
-
///如果是数组,则一次性删除多个文件
|
|
109
|
-
if (Array.isArray(filepath)) {
|
|
110
|
-
const params = {
|
|
111
|
-
Bucket: this.bucket,
|
|
112
|
-
Region: this.region,
|
|
113
|
-
Objects: filepath.map(item => { return { Key: item }; }),
|
|
114
|
-
};
|
|
115
|
-
return this.cos.deleteMultipleObject(params, (err) => {
|
|
116
|
-
return reslove({ successed: err == null, error: err });
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
const params = {
|
|
120
|
-
Bucket: this.bucket,
|
|
121
|
-
Region: this.region,
|
|
122
|
-
Key: filepath,
|
|
123
|
-
};
|
|
124
|
-
this.cos.deleteObject(params, (err) => {
|
|
125
|
-
return reslove({ successed: err == null, error: err });
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
exports.CosFile = CosFile;
|
package/dist/declare.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export interface FileConfig {
|
|
2
|
-
'subFolder': string;
|
|
3
|
-
'saveDir': string;
|
|
4
|
-
'fileName': string;
|
|
5
|
-
'reRead'?: boolean;
|
|
6
|
-
'basefolder'?: string;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* 文件的API
|
|
10
|
-
*/
|
|
11
|
-
export interface FileResult {
|
|
12
|
-
'successed': boolean;
|
|
13
|
-
'error'?: string;
|
|
14
|
-
'errcode'?: number;
|
|
15
|
-
'filePath'?: string;
|
|
16
|
-
}
|
package/dist/declare.js
DELETED
package/dist/file.d.ts
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import { FileConfig, FileResult } from './declare';
|
|
3
|
-
export declare abstract class FileBase {
|
|
4
|
-
/**
|
|
5
|
-
* 根据DoomiSoft框架生成的唯一文件名,用户上传后的文件存储后名称,防止重复
|
|
6
|
-
* @param {*} saveOption
|
|
7
|
-
* @param {*} fileName
|
|
8
|
-
* @param {*} userInfo
|
|
9
|
-
*/
|
|
10
|
-
getSaveFileName(saveOption: FileConfig, fileName: string, userInfo?: any): string;
|
|
11
|
-
/**
|
|
12
|
-
* 获取文件需要保存的目录
|
|
13
|
-
* @param {*} saveOption
|
|
14
|
-
* @param {*} userInfo
|
|
15
|
-
*/
|
|
16
|
-
getSaveFolder(saveOption: FileConfig, userInfo?: any): string;
|
|
17
|
-
/**
|
|
18
|
-
* 获取上传的文件仅包含文件名
|
|
19
|
-
* @param {*} saveOption
|
|
20
|
-
* @param {*} fileName
|
|
21
|
-
* @param {*} userInfo
|
|
22
|
-
*/
|
|
23
|
-
getSaveOnlyFileName(saveOption: FileConfig, fileName: string, userInfo?: any): string;
|
|
24
|
-
/**
|
|
25
|
-
* 保存文件流
|
|
26
|
-
* @param fileName
|
|
27
|
-
* @param file
|
|
28
|
-
* @param saveOption
|
|
29
|
-
* @param userInfo
|
|
30
|
-
*/
|
|
31
|
-
abstract saveFileStream(file: any, fileName: string, saveOption: FileConfig, userInfo: any): Promise<FileResult>;
|
|
32
|
-
/**
|
|
33
|
-
* 直接保存字符
|
|
34
|
-
* @param data
|
|
35
|
-
* @param fileName
|
|
36
|
-
* @param saveOption
|
|
37
|
-
* @param userInfo
|
|
38
|
-
*/
|
|
39
|
-
abstract saveString2File(data: string | Buffer, fileName: string, saveOption: FileConfig, userInfo: any): Promise<FileResult>;
|
|
40
|
-
/**
|
|
41
|
-
* 删除指定位置的文件
|
|
42
|
-
* @param filepath
|
|
43
|
-
*/
|
|
44
|
-
abstract deleteFile(filepath: string | string[]): Promise<{
|
|
45
|
-
successed: boolean;
|
|
46
|
-
error?: any;
|
|
47
|
-
}>;
|
|
48
|
-
/**
|
|
49
|
-
* 创建多级目录
|
|
50
|
-
* @param dirpath
|
|
51
|
-
* @param mode
|
|
52
|
-
* @returns
|
|
53
|
-
*/
|
|
54
|
-
mkdirsSync(dirpath: string, mode?: any): boolean;
|
|
55
|
-
}
|
package/dist/file.js
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
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
|
-
exports.FileBase = void 0;
|
|
7
|
-
const fs_1 = __importDefault(require("fs"));
|
|
8
|
-
const path_1 = __importDefault(require("path"));
|
|
9
|
-
const moment_1 = __importDefault(require("moment"));
|
|
10
|
-
const uuid_1 = require("uuid");
|
|
11
|
-
class FileBase {
|
|
12
|
-
/**
|
|
13
|
-
* 根据DoomiSoft框架生成的唯一文件名,用户上传后的文件存储后名称,防止重复
|
|
14
|
-
* @param {*} saveOption
|
|
15
|
-
* @param {*} fileName
|
|
16
|
-
* @param {*} userInfo
|
|
17
|
-
*/
|
|
18
|
-
getSaveFileName(saveOption, fileName, userInfo = {}) {
|
|
19
|
-
let saveFolder = this.getSaveFolder(saveOption, userInfo);
|
|
20
|
-
// console.log('getSaveFileName', fileName)
|
|
21
|
-
let _fileName = this.getSaveOnlyFileName(saveOption, fileName, userInfo);
|
|
22
|
-
return path_1.default.join(saveFolder, _fileName);
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* 获取文件需要保存的目录
|
|
26
|
-
* @param {*} saveOption
|
|
27
|
-
* @param {*} userInfo
|
|
28
|
-
*/
|
|
29
|
-
getSaveFolder(saveOption, userInfo = {}) {
|
|
30
|
-
var _a;
|
|
31
|
-
let subFolder = '';
|
|
32
|
-
///分目录存储
|
|
33
|
-
switch ((saveOption.subFolder || '').toLowerCase()) {
|
|
34
|
-
///按日建造一个目录
|
|
35
|
-
case 'onebydate':
|
|
36
|
-
subFolder = (0, moment_1.default)().format('YYYYMMDD');
|
|
37
|
-
break;
|
|
38
|
-
///按日建造多级目录
|
|
39
|
-
case 'mutilbydate':
|
|
40
|
-
subFolder = (0, moment_1.default)().year() + path_1.default.sep + (0, moment_1.default)().month() + path_1.default.sep + (0, moment_1.default)().day();
|
|
41
|
-
break;
|
|
42
|
-
///用自己的id(当前登录的id)建造目录
|
|
43
|
-
case 'identity':
|
|
44
|
-
subFolder = (_a = userInfo.id) !== null && _a !== void 0 ? _a : (0, uuid_1.v4)();
|
|
45
|
-
break;
|
|
46
|
-
}
|
|
47
|
-
let saveFolder = path_1.default.join(saveOption.saveDir, subFolder + '');
|
|
48
|
-
if (userInfo && userInfo.subfolder)
|
|
49
|
-
saveFolder = path_1.default.join(saveFolder, userInfo.subfolder);
|
|
50
|
-
///如果包含当前调用用户的信息,则替换整个路径中的@@关键字
|
|
51
|
-
if (userInfo) {
|
|
52
|
-
const matched = saveFolder.match(/@.*?@/g);
|
|
53
|
-
if (matched && matched.length > 0)
|
|
54
|
-
matched.forEach(ele => {
|
|
55
|
-
const matchValue = ele.substring(1, ele.length - 1);
|
|
56
|
-
if (matchValue.indexOf(' ') >= 0 || matchValue.indexOf(':') >= 0 || matchValue.indexOf('=') >= 0)
|
|
57
|
-
return;
|
|
58
|
-
let keyName = ele.substring(1, ele.length - 1);
|
|
59
|
-
const keyValue = userInfo[keyName] || '';
|
|
60
|
-
saveFolder = saveFolder.replace(ele, keyValue);
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
return saveFolder;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* 获取上传的文件仅包含文件名
|
|
67
|
-
* @param {*} saveOption
|
|
68
|
-
* @param {*} fileName
|
|
69
|
-
* @param {*} userInfo
|
|
70
|
-
*/
|
|
71
|
-
getSaveOnlyFileName(saveOption, fileName, userInfo = {}) {
|
|
72
|
-
var _a;
|
|
73
|
-
let _fileName = '';
|
|
74
|
-
switch ((saveOption.fileName || 'keep').toLowerCase()) {
|
|
75
|
-
///保持和原有文件一致的文件名
|
|
76
|
-
case "keep":
|
|
77
|
-
_fileName = fileName;
|
|
78
|
-
break;
|
|
79
|
-
///随机命名,但后缀必须一致
|
|
80
|
-
case "random":
|
|
81
|
-
_fileName = (0, uuid_1.v4)() + path_1.default.extname(fileName);
|
|
82
|
-
break;
|
|
83
|
-
///使用当前账号的id命名
|
|
84
|
-
case "identity":
|
|
85
|
-
_fileName = ((_a = userInfo.id) !== null && _a !== void 0 ? _a : (0, uuid_1.v4)()) + path_1.default.extname(fileName);
|
|
86
|
-
break;
|
|
87
|
-
}
|
|
88
|
-
return _fileName;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* 创建多级目录
|
|
92
|
-
* @param dirpath
|
|
93
|
-
* @param mode
|
|
94
|
-
* @returns
|
|
95
|
-
*/
|
|
96
|
-
mkdirsSync(dirpath, mode = null) {
|
|
97
|
-
if (!fs_1.default.existsSync(dirpath)) {
|
|
98
|
-
let pathtmp = '', splitPath = dirpath.split(path_1.default.sep);
|
|
99
|
-
for (const dirname of splitPath) {
|
|
100
|
-
if (dirname.length == 0) {
|
|
101
|
-
pathtmp = path_1.default.sep;
|
|
102
|
-
continue;
|
|
103
|
-
}
|
|
104
|
-
if (pathtmp)
|
|
105
|
-
pathtmp = path_1.default.join(pathtmp, dirname);
|
|
106
|
-
else
|
|
107
|
-
pathtmp = dirname;
|
|
108
|
-
if (!fs_1.default.existsSync(pathtmp)) {
|
|
109
|
-
fs_1.default.mkdirSync(pathtmp, mode);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
return true;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
exports.FileBase = FileBase;
|