@nocobase/plugin-file-manager 1.7.0-beta.9 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/index.d.ts +13 -0
- package/dist/client/index.js +1 -1
- package/dist/client/schemas/storageTypes/ali-oss.d.ts +8 -0
- package/dist/client/schemas/storageTypes/index.d.ts +8 -0
- package/dist/common/collections/attachments.d.ts +37 -0
- package/dist/common/collections/attachments.js +97 -0
- package/dist/common/collections/storages.d.ts +79 -0
- package/dist/common/collections/storages.js +98 -0
- package/dist/common/constants.d.ts +9 -0
- package/dist/common/constants.js +36 -0
- package/dist/externalVersion.js +9 -8
- package/dist/locale/de-DE.json +1 -1
- package/dist/locale/en-US.json +25 -6
- package/dist/locale/it-IT.json +1 -1
- package/dist/locale/ja-JP.json +1 -1
- package/dist/locale/nl-NL.json +27 -9
- package/dist/locale/zh-CN.json +4 -2
- package/dist/node_modules/@aws-sdk/client-s3/dist-cjs/index.js +834 -834
- package/dist/node_modules/@aws-sdk/client-s3/package.json +1 -1
- package/dist/node_modules/mime-match/package.json +1 -1
- package/dist/node_modules/mkdirp/package.json +1 -1
- package/dist/node_modules/multer-aliyun-oss/index.js +3 -3
- package/dist/node_modules/multer-aliyun-oss/package.json +1 -1
- package/dist/node_modules/multer-cos/index.js +5 -5
- package/dist/node_modules/multer-cos/package.json +1 -1
- package/dist/node_modules/multer-s3/index.js +837 -837
- package/dist/node_modules/multer-s3/package.json +1 -1
- package/dist/node_modules/url-join/package.json +1 -1
- package/dist/server/actions/attachments.d.ts +0 -1
- package/dist/server/actions/attachments.js +21 -41
- package/dist/server/actions/storages.js +4 -1
- package/dist/server/collections/attachments.d.ts +2 -2
- package/dist/server/collections/attachments.js +12 -67
- package/dist/server/collections/storages.d.ts +2 -2
- package/dist/server/collections/storages.js +12 -64
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +3 -0
- package/dist/server/server.d.ts +19 -3
- package/dist/server/server.js +70 -53
- package/dist/server/storages/ali-oss.js +1 -1
- package/dist/server/storages/index.d.ts +17 -5
- package/dist/server/storages/index.js +41 -3
- package/dist/server/storages/local.d.ts +6 -0
- package/dist/server/storages/local.js +13 -2
- package/dist/server/utils.d.ts +1 -1
- package/dist/server/utils.js +8 -4
- package/package.json +6 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"multer-s3","version":"3.0.1","description":"Streaming multer storage engine for AWS S3","main":"index.js","scripts":{"test":"standard && mocha test/basic.js"},"engines":{"node":">= 12.0.0"},"repository":{"type":"git","url":"git+https://github.com/badunk/multer-s3.git"},"keywords":["multer","s3","amazon","aws"],"author":"badunk","license":"MIT","bugs":{"url":"https://github.com/badunk/multer-s3/issues"},"homepage":"https://github.com/badunk/multer-s3#readme","dependencies":{"@aws-sdk/lib-storage":"^3.46.0","file-type":"^3.3.0","html-comment-regex":"^1.1.2","run-parallel":"^1.1.6"},"peerDependencies":{"@aws-sdk/client-s3":"^3.0.0"},"devDependencies":{"express":"^4.13.1","form-data":"^1.0.0-rc3","mocha":"^2.2.5","multer":"^1.1.0","on-finished":"^2.3.0","standard":"^5.4.1","xtend":"^4.0.1"},"_lastModified":"2025-
|
|
1
|
+
{"name":"multer-s3","version":"3.0.1","description":"Streaming multer storage engine for AWS S3","main":"index.js","scripts":{"test":"standard && mocha test/basic.js"},"engines":{"node":">= 12.0.0"},"repository":{"type":"git","url":"git+https://github.com/badunk/multer-s3.git"},"keywords":["multer","s3","amazon","aws"],"author":"badunk","license":"MIT","bugs":{"url":"https://github.com/badunk/multer-s3/issues"},"homepage":"https://github.com/badunk/multer-s3#readme","dependencies":{"@aws-sdk/lib-storage":"^3.46.0","file-type":"^3.3.0","html-comment-regex":"^1.1.2","run-parallel":"^1.1.6"},"peerDependencies":{"@aws-sdk/client-s3":"^3.0.0"},"devDependencies":{"express":"^4.13.1","form-data":"^1.0.0-rc3","mocha":"^2.2.5","multer":"^1.1.0","on-finished":"^2.3.0","standard":"^5.4.1","xtend":"^4.0.1"},"_lastModified":"2025-06-03T16:31:36.572Z"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"url-join","version":"4.0.1","description":"Join urls and normalize as in path.join.","main":"lib/url-join.js","scripts":{"test":"mocha --require should"},"repository":{"type":"git","url":"git://github.com/jfromaniello/url-join.git"},"keywords":["url","join"],"author":"José F. Romaniello <jfromaniello@gmail.com> (http://joseoncode.com)","license":"MIT","devDependencies":{"conventional-changelog":"^1.1.10","mocha":"^3.2.0","should":"~1.2.1"},"_lastModified":"2025-
|
|
1
|
+
{"name":"url-join","version":"4.0.1","description":"Join urls and normalize as in path.join.","main":"lib/url-join.js","scripts":{"test":"mocha --require should"},"repository":{"type":"git","url":"git://github.com/jfromaniello/url-join.git"},"keywords":["url","join"],"author":"José F. Romaniello <jfromaniello@gmail.com> (http://joseoncode.com)","license":"MIT","devDependencies":{"conventional-changelog":"^1.1.10","mocha":"^3.2.0","should":"~1.2.1"},"_lastModified":"2025-06-03T16:31:29.289Z"}
|
|
@@ -7,5 +7,4 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
import { Context, Next } from '@nocobase/actions';
|
|
10
|
-
export declare function getFileData(ctx: Context): Promise<any>;
|
|
11
10
|
export declare function createMiddleware(ctx: Context, next: Next): Promise<any>;
|
|
@@ -36,12 +36,10 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
36
36
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
37
37
|
var attachments_exports = {};
|
|
38
38
|
__export(attachments_exports, {
|
|
39
|
-
createMiddleware: () => createMiddleware
|
|
40
|
-
getFileData: () => getFileData
|
|
39
|
+
createMiddleware: () => createMiddleware
|
|
41
40
|
});
|
|
42
41
|
module.exports = __toCommonJS(attachments_exports);
|
|
43
42
|
var import_utils = require("@nocobase/utils");
|
|
44
|
-
var import_path = __toESM(require("path"));
|
|
45
43
|
var import__ = __toESM(require(".."));
|
|
46
44
|
var import_constants = require("../../constants");
|
|
47
45
|
var Rules = __toESM(require("../rules"));
|
|
@@ -53,37 +51,6 @@ function getFileFilter(storage) {
|
|
|
53
51
|
cb(null, result);
|
|
54
52
|
};
|
|
55
53
|
}
|
|
56
|
-
async function getFileData(ctx) {
|
|
57
|
-
var _a;
|
|
58
|
-
const { [import_constants.FILE_FIELD_NAME]: file, storage } = ctx;
|
|
59
|
-
if (!file) {
|
|
60
|
-
return ctx.throw(400, "file validation failed");
|
|
61
|
-
}
|
|
62
|
-
const plugin = ctx.app.pm.get(import__.default);
|
|
63
|
-
const StorageType = plugin.storageTypes.get(storage.type);
|
|
64
|
-
const { [StorageType.filenameKey || "filename"]: name } = file;
|
|
65
|
-
const filename = import_path.default.basename(name);
|
|
66
|
-
const extname = import_path.default.extname(filename);
|
|
67
|
-
const path = (storage.path || "").replace(/^\/|\/$/g, "");
|
|
68
|
-
let storageInstance = plugin.storagesCache.get(storage.id);
|
|
69
|
-
if (!storageInstance) {
|
|
70
|
-
await plugin.loadStorages();
|
|
71
|
-
storageInstance = plugin.storagesCache.get(storage.id);
|
|
72
|
-
}
|
|
73
|
-
const data = {
|
|
74
|
-
title: Buffer.from(file.originalname, "latin1").toString("utf8").replace(extname, ""),
|
|
75
|
-
filename,
|
|
76
|
-
extname,
|
|
77
|
-
// TODO(feature): 暂时两者相同,后面 storage.path 模版化以后,这里只是 file 实际的 path
|
|
78
|
-
path,
|
|
79
|
-
size: file.size,
|
|
80
|
-
mimetype: file.mimetype,
|
|
81
|
-
meta: ctx.request.body,
|
|
82
|
-
storageId: storage.id,
|
|
83
|
-
...(_a = StorageType == null ? void 0 : StorageType["getFileData"]) == null ? void 0 : _a.call(StorageType, file)
|
|
84
|
-
};
|
|
85
|
-
return data;
|
|
86
|
-
}
|
|
87
54
|
async function multipart(ctx, next) {
|
|
88
55
|
const { storage } = ctx;
|
|
89
56
|
if (!storage) {
|
|
@@ -116,7 +83,11 @@ async function multipart(ctx, next) {
|
|
|
116
83
|
ctx.logger.error(err);
|
|
117
84
|
return ctx.throw(500, err);
|
|
118
85
|
}
|
|
119
|
-
const
|
|
86
|
+
const { [import_constants.FILE_FIELD_NAME]: file } = ctx;
|
|
87
|
+
if (!file) {
|
|
88
|
+
return ctx.throw(400, "file validation failed");
|
|
89
|
+
}
|
|
90
|
+
const values = storageInstance.getFileData(file, ctx.request.body);
|
|
120
91
|
ctx.action.mergeParams({
|
|
121
92
|
values
|
|
122
93
|
});
|
|
@@ -130,19 +101,28 @@ async function createMiddleware(ctx, next) {
|
|
|
130
101
|
if (((_a = collection == null ? void 0 : collection.options) == null ? void 0 : _a.template) !== "file" || !["upload", "create"].includes(actionName)) {
|
|
131
102
|
return next();
|
|
132
103
|
}
|
|
133
|
-
const storageName = (
|
|
134
|
-
const StorageRepo = ctx.db.getRepository("storages");
|
|
135
|
-
const storage = await StorageRepo.findOne({ filter: storageName ? { name: storageName } : { default: true } });
|
|
104
|
+
const storageName = resourceName === "attachments" ? (_c = (_b = ctx.db.getFieldByPath(attachmentField)) == null ? void 0 : _b.options) == null ? void 0 : _c.storage : collection.options.storage;
|
|
136
105
|
const plugin = ctx.app.pm.get(import__.default);
|
|
137
|
-
|
|
106
|
+
const storage = Array.from(plugin.storagesCache.values()).find(
|
|
107
|
+
(storage2) => storageName ? storage2.name === storageName : storage2.default
|
|
108
|
+
);
|
|
109
|
+
if (!storage) {
|
|
110
|
+
ctx.logger.error(`[file-manager] no storage found`);
|
|
111
|
+
return ctx.throw(500);
|
|
112
|
+
}
|
|
113
|
+
ctx.storage = storage;
|
|
138
114
|
if (ctx == null ? void 0 : ctx.request.is("multipart/*")) {
|
|
139
115
|
await multipart(ctx, next);
|
|
140
116
|
} else {
|
|
117
|
+
ctx.action.mergeParams({
|
|
118
|
+
values: {
|
|
119
|
+
storage: { id: storage.id }
|
|
120
|
+
}
|
|
121
|
+
});
|
|
141
122
|
await next();
|
|
142
123
|
}
|
|
143
124
|
}
|
|
144
125
|
// Annotate the CommonJS export names for ESM import in node:
|
|
145
126
|
0 && (module.exports = {
|
|
146
|
-
createMiddleware
|
|
147
|
-
getFileData
|
|
127
|
+
createMiddleware
|
|
148
128
|
});
|
|
@@ -41,6 +41,7 @@ __export(storages_exports, {
|
|
|
41
41
|
module.exports = __toCommonJS(storages_exports);
|
|
42
42
|
var import__ = __toESM(require(".."));
|
|
43
43
|
async function getBasicInfo(context, next) {
|
|
44
|
+
var _a, _b;
|
|
44
45
|
const { storagesCache } = context.app.pm.get(import__.default);
|
|
45
46
|
let result;
|
|
46
47
|
const { filterByTk } = context.action.params;
|
|
@@ -58,7 +59,9 @@ async function getBasicInfo(context, next) {
|
|
|
58
59
|
title: result.title,
|
|
59
60
|
name: result.name,
|
|
60
61
|
type: result.type,
|
|
61
|
-
rules: result.rules
|
|
62
|
+
rules: result.rules,
|
|
63
|
+
baseUrl: (_a = result.options) == null ? void 0 : _a.baseUrl,
|
|
64
|
+
public: (_b = result.options) == null ? void 0 : _b.public
|
|
62
65
|
};
|
|
63
66
|
next();
|
|
64
67
|
}
|
|
@@ -6,5 +6,5 @@
|
|
|
6
6
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
|
-
|
|
10
|
-
export default
|
|
9
|
+
import collection from '../../common/collections/attachments';
|
|
10
|
+
export default collection;
|
|
@@ -7,9 +7,11 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
var __create = Object.create;
|
|
10
11
|
var __defProp = Object.defineProperty;
|
|
11
12
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
13
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
14
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
13
15
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
16
|
var __export = (target, all) => {
|
|
15
17
|
for (var name in all)
|
|
@@ -23,76 +25,19 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
23
25
|
}
|
|
24
26
|
return to;
|
|
25
27
|
};
|
|
28
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
29
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
30
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
31
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
32
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
33
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
34
|
+
mod
|
|
35
|
+
));
|
|
26
36
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
37
|
var attachments_exports = {};
|
|
28
38
|
__export(attachments_exports, {
|
|
29
39
|
default: () => attachments_default
|
|
30
40
|
});
|
|
31
41
|
module.exports = __toCommonJS(attachments_exports);
|
|
32
|
-
var
|
|
33
|
-
var attachments_default =
|
|
34
|
-
dumpRules: {
|
|
35
|
-
group: "user"
|
|
36
|
-
},
|
|
37
|
-
migrationRules: ["schema-only", "overwrite"],
|
|
38
|
-
asStrategyResource: true,
|
|
39
|
-
shared: true,
|
|
40
|
-
name: "attachments",
|
|
41
|
-
createdBy: true,
|
|
42
|
-
updatedBy: true,
|
|
43
|
-
template: "file",
|
|
44
|
-
fields: [
|
|
45
|
-
{
|
|
46
|
-
comment: "\u7528\u6237\u6587\u4EF6\u540D\uFF08\u4E0D\u542B\u6269\u5C55\u540D\uFF09",
|
|
47
|
-
type: "string",
|
|
48
|
-
name: "title"
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
comment: "\u7CFB\u7EDF\u6587\u4EF6\u540D\uFF08\u542B\u6269\u5C55\u540D\uFF09",
|
|
52
|
-
type: "string",
|
|
53
|
-
name: "filename"
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
comment: "\u6269\u5C55\u540D\uFF08\u542B\u201C.\u201D\uFF09",
|
|
57
|
-
type: "string",
|
|
58
|
-
name: "extname"
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
comment: "\u6587\u4EF6\u4F53\u79EF\uFF08\u5B57\u8282\uFF09",
|
|
62
|
-
type: "integer",
|
|
63
|
-
name: "size"
|
|
64
|
-
},
|
|
65
|
-
// TODO: 使用暂不明确,以后再考虑
|
|
66
|
-
// {
|
|
67
|
-
// comment: '文件类型(mimetype 前半段,通常用于预览)',
|
|
68
|
-
// type: 'string',
|
|
69
|
-
// name: 'type',
|
|
70
|
-
// },
|
|
71
|
-
{
|
|
72
|
-
type: "string",
|
|
73
|
-
name: "mimetype"
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
comment: "\u5B58\u50A8\u5F15\u64CE",
|
|
77
|
-
type: "belongsTo",
|
|
78
|
-
name: "storage"
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
comment: "\u76F8\u5BF9\u8DEF\u5F84\uFF08\u542B\u201C/\u201D\u524D\u7F00\uFF09",
|
|
82
|
-
type: "text",
|
|
83
|
-
name: "path"
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
comment: "\u5176\u4ED6\u6587\u4EF6\u4FE1\u606F\uFF08\u5982\u56FE\u7247\u7684\u5BBD\u9AD8\uFF09",
|
|
87
|
-
type: "jsonb",
|
|
88
|
-
name: "meta",
|
|
89
|
-
defaultValue: {}
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
comment: "\u7F51\u7EDC\u8BBF\u95EE\u5730\u5740",
|
|
93
|
-
type: "text",
|
|
94
|
-
name: "url"
|
|
95
|
-
// formula: '{{ storage.baseUrl }}{{ path }}/{{ filename }}'
|
|
96
|
-
}
|
|
97
|
-
]
|
|
98
|
-
});
|
|
42
|
+
var import_attachments = __toESM(require("../../common/collections/attachments"));
|
|
43
|
+
var attachments_default = import_attachments.default;
|
|
@@ -6,5 +6,5 @@
|
|
|
6
6
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
|
-
|
|
10
|
-
export default
|
|
9
|
+
import collection from '../../common/collections/storages';
|
|
10
|
+
export default collection;
|
|
@@ -7,9 +7,11 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
var __create = Object.create;
|
|
10
11
|
var __defProp = Object.defineProperty;
|
|
11
12
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
13
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
14
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
13
15
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
16
|
var __export = (target, all) => {
|
|
15
17
|
for (var name in all)
|
|
@@ -23,73 +25,19 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
23
25
|
}
|
|
24
26
|
return to;
|
|
25
27
|
};
|
|
28
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
29
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
30
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
31
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
32
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
33
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
34
|
+
mod
|
|
35
|
+
));
|
|
26
36
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
37
|
var storages_exports = {};
|
|
28
38
|
__export(storages_exports, {
|
|
29
39
|
default: () => storages_default
|
|
30
40
|
});
|
|
31
41
|
module.exports = __toCommonJS(storages_exports);
|
|
32
|
-
var
|
|
33
|
-
var storages_default =
|
|
34
|
-
dumpRules: "required",
|
|
35
|
-
migrationRules: ["overwrite", "schema-only"],
|
|
36
|
-
name: "storages",
|
|
37
|
-
shared: true,
|
|
38
|
-
fields: [
|
|
39
|
-
{
|
|
40
|
-
title: "\u5B58\u50A8\u5F15\u64CE\u540D\u79F0",
|
|
41
|
-
comment: "\u5B58\u50A8\u5F15\u64CE\u540D\u79F0",
|
|
42
|
-
type: "string",
|
|
43
|
-
name: "title",
|
|
44
|
-
translation: true
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
title: "\u82F1\u6587\u6807\u8BC6",
|
|
48
|
-
// comment: '英文标识,用于代码层面配置',
|
|
49
|
-
type: "uid",
|
|
50
|
-
name: "name",
|
|
51
|
-
unique: true
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
comment: "\u7C7B\u578B\u6807\u8BC6\uFF0C\u5982 local/ali-oss \u7B49",
|
|
55
|
-
type: "string",
|
|
56
|
-
name: "type"
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
comment: "\u914D\u7F6E\u9879",
|
|
60
|
-
type: "jsonb",
|
|
61
|
-
name: "options",
|
|
62
|
-
defaultValue: {}
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
comment: "\u6587\u4EF6\u89C4\u5219",
|
|
66
|
-
type: "jsonb",
|
|
67
|
-
name: "rules",
|
|
68
|
-
defaultValue: {}
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
comment: "\u5B58\u50A8\u76F8\u5BF9\u8DEF\u5F84\u6A21\u677F",
|
|
72
|
-
type: "text",
|
|
73
|
-
name: "path",
|
|
74
|
-
defaultValue: ""
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
comment: "\u8BBF\u95EE\u5730\u5740\u524D\u7F00",
|
|
78
|
-
type: "string",
|
|
79
|
-
name: "baseUrl",
|
|
80
|
-
defaultValue: ""
|
|
81
|
-
},
|
|
82
|
-
// TODO(feature): 需要使用一个实现了可设置默认值的字段
|
|
83
|
-
{
|
|
84
|
-
comment: "\u9ED8\u8BA4\u5F15\u64CE",
|
|
85
|
-
type: "radio",
|
|
86
|
-
name: "default",
|
|
87
|
-
defaultValue: false
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
type: "boolean",
|
|
91
|
-
name: "paranoid",
|
|
92
|
-
defaultValue: false
|
|
93
|
-
}
|
|
94
|
-
]
|
|
95
|
-
});
|
|
42
|
+
var import_storages = __toESM(require("../../common/collections/storages"));
|
|
43
|
+
var storages_default = import_storages.default;
|
package/dist/server/index.d.ts
CHANGED
|
@@ -9,5 +9,6 @@
|
|
|
9
9
|
import { StorageEngine } from 'multer';
|
|
10
10
|
export * from '../constants';
|
|
11
11
|
export { AttachmentModel, default, PluginFileManagerServer, StorageModel } from './server';
|
|
12
|
+
export { cloudFilenameGetter } from './utils';
|
|
12
13
|
export { StorageType } from './storages';
|
|
13
14
|
export { StorageEngine };
|
package/dist/server/index.js
CHANGED
|
@@ -42,12 +42,14 @@ __export(server_exports, {
|
|
|
42
42
|
StorageEngine: () => import_multer.StorageEngine,
|
|
43
43
|
StorageModel: () => import_server.StorageModel,
|
|
44
44
|
StorageType: () => import_storages.StorageType,
|
|
45
|
+
cloudFilenameGetter: () => import_utils.cloudFilenameGetter,
|
|
45
46
|
default: () => import_server.default
|
|
46
47
|
});
|
|
47
48
|
module.exports = __toCommonJS(server_exports);
|
|
48
49
|
var import_multer = require("multer");
|
|
49
50
|
__reExport(server_exports, require("../constants"), module.exports);
|
|
50
51
|
var import_server = __toESM(require("./server"));
|
|
52
|
+
var import_utils = require("./utils");
|
|
51
53
|
var import_storages = require("./storages");
|
|
52
54
|
// Annotate the CommonJS export names for ESM import in node:
|
|
53
55
|
0 && (module.exports = {
|
|
@@ -56,5 +58,6 @@ var import_storages = require("./storages");
|
|
|
56
58
|
StorageEngine,
|
|
57
59
|
StorageModel,
|
|
58
60
|
StorageType,
|
|
61
|
+
cloudFilenameGetter,
|
|
59
62
|
...require("../constants")
|
|
60
63
|
});
|
package/dist/server/server.d.ts
CHANGED
|
@@ -6,9 +6,11 @@
|
|
|
6
6
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
|
+
/// <reference types="node" />
|
|
10
|
+
import { Model, Transactionable } from '@nocobase/database';
|
|
9
11
|
import { Plugin } from '@nocobase/server';
|
|
10
12
|
import { Registry } from '@nocobase/utils';
|
|
11
|
-
import {
|
|
13
|
+
import { Readable } from 'stream';
|
|
12
14
|
import { AttachmentModel, StorageClassType, StorageModel } from './storages';
|
|
13
15
|
export type * from './storages';
|
|
14
16
|
export type FileRecordOptions = {
|
|
@@ -29,7 +31,16 @@ export declare class PluginFileManagerServer extends Plugin {
|
|
|
29
31
|
registerStorageType(type: string, Type: StorageClassType): void;
|
|
30
32
|
createFileRecord(options: FileRecordOptions): Promise<any>;
|
|
31
33
|
parseStorage(instance: any): any;
|
|
32
|
-
uploadFile(options: UploadFileOptions): Promise<
|
|
34
|
+
uploadFile(options: UploadFileOptions): Promise<{
|
|
35
|
+
title: string;
|
|
36
|
+
filename: string;
|
|
37
|
+
extname: string;
|
|
38
|
+
path: string;
|
|
39
|
+
size: any;
|
|
40
|
+
mimetype: any;
|
|
41
|
+
meta: {};
|
|
42
|
+
storageId: number;
|
|
43
|
+
}>;
|
|
33
44
|
loadStorages(options?: {
|
|
34
45
|
transaction: any;
|
|
35
46
|
}): Promise<void>;
|
|
@@ -37,6 +48,11 @@ export declare class PluginFileManagerServer extends Plugin {
|
|
|
37
48
|
handleSyncMessage(message: any): Promise<void>;
|
|
38
49
|
beforeLoad(): Promise<void>;
|
|
39
50
|
load(): Promise<void>;
|
|
40
|
-
getFileURL(file: AttachmentModel, preview?: boolean): Promise<
|
|
51
|
+
getFileURL(file: AttachmentModel, preview?: boolean): Promise<any>;
|
|
52
|
+
isPublicAccessStorage(storageName: any): Promise<boolean>;
|
|
53
|
+
getFileStream(file: AttachmentModel): Promise<{
|
|
54
|
+
stream: Readable;
|
|
55
|
+
contentType?: string;
|
|
56
|
+
}>;
|
|
41
57
|
}
|
|
42
58
|
export default PluginFileManagerServer;
|
package/dist/server/server.js
CHANGED
|
@@ -40,14 +40,14 @@ __export(server_exports, {
|
|
|
40
40
|
default: () => server_default
|
|
41
41
|
});
|
|
42
42
|
module.exports = __toCommonJS(server_exports);
|
|
43
|
-
var
|
|
44
|
-
var import_utils = require("@nocobase/utils");
|
|
43
|
+
var import_fs = __toESM(require("fs"));
|
|
45
44
|
var import_path = require("path");
|
|
45
|
+
var import_mime_match = __toESM(require("mime-match"));
|
|
46
46
|
var import_database = require("@nocobase/database");
|
|
47
|
-
var
|
|
47
|
+
var import_server = require("@nocobase/server");
|
|
48
|
+
var import_utils = require("@nocobase/utils");
|
|
48
49
|
var import_constants = require("../constants");
|
|
49
50
|
var import_actions = __toESM(require("./actions"));
|
|
50
|
-
var import_attachments = require("./actions/attachments");
|
|
51
51
|
var import_attachment_interface = require("./interfaces/attachment-interface");
|
|
52
52
|
var import_ali_oss = __toESM(require("./storages/ali-oss"));
|
|
53
53
|
var import_local = __toESM(require("./storages/local"));
|
|
@@ -111,29 +111,24 @@ class PluginFileManagerServer extends import_server.Plugin {
|
|
|
111
111
|
}
|
|
112
112
|
async uploadFile(options) {
|
|
113
113
|
const { storageName, filePath, documentRoot } = options;
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
default: true
|
|
121
|
-
}
|
|
122
|
-
});
|
|
123
|
-
const fileStream = import_fs.default.createReadStream(filePath);
|
|
124
|
-
if (!storageInstance) {
|
|
114
|
+
if (!this.storagesCache.size) {
|
|
115
|
+
await this.loadStorages();
|
|
116
|
+
}
|
|
117
|
+
const storages = Array.from(this.storagesCache.values());
|
|
118
|
+
const storage = storages.find((item) => item.name === storageName) || storages.find((item) => item.default);
|
|
119
|
+
if (!storage) {
|
|
125
120
|
throw new Error("[file-manager] no linked or default storage provided");
|
|
126
121
|
}
|
|
127
|
-
|
|
122
|
+
const fileStream = import_fs.default.createReadStream(filePath);
|
|
128
123
|
if (documentRoot) {
|
|
129
|
-
|
|
124
|
+
storage.options["documentRoot"] = documentRoot;
|
|
130
125
|
}
|
|
131
|
-
const
|
|
132
|
-
const
|
|
133
|
-
if (!
|
|
134
|
-
throw new Error(`[file-manager] storage type "${
|
|
126
|
+
const StorageType = this.storageTypes.get(storage.type);
|
|
127
|
+
const storageInstance = new StorageType(storage);
|
|
128
|
+
if (!storageInstance) {
|
|
129
|
+
throw new Error(`[file-manager] storage type "${storage.type}" is not defined`);
|
|
135
130
|
}
|
|
136
|
-
const engine =
|
|
131
|
+
const engine = storageInstance.make();
|
|
137
132
|
const file = {
|
|
138
133
|
originalname: (0, import_path.basename)(filePath),
|
|
139
134
|
path: filePath,
|
|
@@ -148,7 +143,7 @@ class PluginFileManagerServer extends import_server.Plugin {
|
|
|
148
143
|
resolve(info);
|
|
149
144
|
});
|
|
150
145
|
});
|
|
151
|
-
return
|
|
146
|
+
return storageInstance.getFileData(file, {});
|
|
152
147
|
}
|
|
153
148
|
async loadStorages(options) {
|
|
154
149
|
const repository = this.db.getRepository("storages");
|
|
@@ -181,17 +176,8 @@ class PluginFileManagerServer extends import_server.Plugin {
|
|
|
181
176
|
}
|
|
182
177
|
}
|
|
183
178
|
async handleSyncMessage(message) {
|
|
184
|
-
if (message.type === "
|
|
185
|
-
|
|
186
|
-
filterByTk: message.storageId
|
|
187
|
-
});
|
|
188
|
-
if (storage) {
|
|
189
|
-
this.storagesCache.set(storage.id, this.parseStorage(storage));
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
if (message.type === "storageRemove") {
|
|
193
|
-
const id = message.storageId;
|
|
194
|
-
this.storagesCache.delete(id);
|
|
179
|
+
if (message.type === "reloadStorages") {
|
|
180
|
+
await this.loadStorages();
|
|
195
181
|
}
|
|
196
182
|
}
|
|
197
183
|
async beforeLoad() {
|
|
@@ -226,17 +212,11 @@ class PluginFileManagerServer extends import_server.Plugin {
|
|
|
226
212
|
this.storageTypes.register(import_constants.STORAGE_TYPE_S3, import_s3.default);
|
|
227
213
|
this.storageTypes.register(import_constants.STORAGE_TYPE_TX_COS, import_tx_cos.default);
|
|
228
214
|
const Storage = this.db.getModel("storages");
|
|
229
|
-
Storage.afterSave((m, { transaction }) => {
|
|
230
|
-
this.
|
|
231
|
-
this.sendSyncMessage(
|
|
232
|
-
{
|
|
233
|
-
type: "storageChange",
|
|
234
|
-
storageId: m.id
|
|
235
|
-
},
|
|
236
|
-
{ transaction }
|
|
237
|
-
);
|
|
215
|
+
Storage.afterSave(async (m, { transaction }) => {
|
|
216
|
+
await this.loadStorages({ transaction });
|
|
217
|
+
this.sendSyncMessage({ type: "reloadStorages" }, { transaction });
|
|
238
218
|
});
|
|
239
|
-
Storage.afterDestroy((m, { transaction }) => {
|
|
219
|
+
Storage.afterDestroy(async (m, { transaction }) => {
|
|
240
220
|
var _a, _b;
|
|
241
221
|
for (const collection of this.db.collections.values()) {
|
|
242
222
|
if (((_a = collection == null ? void 0 : collection.options) == null ? void 0 : _a.template) === "file" && ((_b = collection == null ? void 0 : collection.options) == null ? void 0 : _b.storage) === m.name) {
|
|
@@ -247,14 +227,8 @@ class PluginFileManagerServer extends import_server.Plugin {
|
|
|
247
227
|
);
|
|
248
228
|
}
|
|
249
229
|
}
|
|
250
|
-
this.
|
|
251
|
-
this.sendSyncMessage(
|
|
252
|
-
{
|
|
253
|
-
type: "storageRemove",
|
|
254
|
-
storageId: m.id
|
|
255
|
-
},
|
|
256
|
-
{ transaction }
|
|
257
|
-
);
|
|
230
|
+
await this.loadStorages({ transaction });
|
|
231
|
+
this.sendSyncMessage({ type: "reloadStorages" }, { transaction });
|
|
258
232
|
});
|
|
259
233
|
this.app.acl.registerSnippet({
|
|
260
234
|
name: `pm.${this.name}.storages`,
|
|
@@ -311,7 +285,50 @@ class PluginFileManagerServer extends import_server.Plugin {
|
|
|
311
285
|
return (0, import_utils2.encodeURL)(file.url);
|
|
312
286
|
}
|
|
313
287
|
const storageType = this.storageTypes.get(storage.type);
|
|
314
|
-
return new storageType(storage).getFileURL(
|
|
288
|
+
return new storageType(storage).getFileURL(
|
|
289
|
+
file,
|
|
290
|
+
Boolean(file.mimetype && (0, import_mime_match.default)(file.mimetype, "image/*") && preview && storage.options.thumbnailRule)
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
async isPublicAccessStorage(storageName) {
|
|
294
|
+
var _a;
|
|
295
|
+
const storageRepository = this.db.getRepository("storages");
|
|
296
|
+
const storages = await storageRepository.findOne({
|
|
297
|
+
filter: { default: true }
|
|
298
|
+
});
|
|
299
|
+
let storage;
|
|
300
|
+
if (!storageName) {
|
|
301
|
+
storage = storages;
|
|
302
|
+
} else {
|
|
303
|
+
storage = await storageRepository.findOne({
|
|
304
|
+
filter: {
|
|
305
|
+
name: storageName
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
storage = this.parseStorage(storage);
|
|
310
|
+
if (["local", "ali-oss", "s3", "tx-cos"].includes(storage.type)) {
|
|
311
|
+
return true;
|
|
312
|
+
}
|
|
313
|
+
return !!((_a = storage.options) == null ? void 0 : _a.public);
|
|
314
|
+
}
|
|
315
|
+
async getFileStream(file) {
|
|
316
|
+
if (!file.storageId) {
|
|
317
|
+
throw new Error("File storageId not found");
|
|
318
|
+
}
|
|
319
|
+
const storage = this.storagesCache.get(file.storageId);
|
|
320
|
+
if (!storage) {
|
|
321
|
+
throw new Error("[file-manager] no linked or default storage provided");
|
|
322
|
+
}
|
|
323
|
+
const StorageType = this.storageTypes.get(storage.type);
|
|
324
|
+
if (!StorageType) {
|
|
325
|
+
throw new Error(`[file-manager] storage type "${storage.type}" is not defined`);
|
|
326
|
+
}
|
|
327
|
+
const storageInstance = new StorageType(storage);
|
|
328
|
+
if (!storageInstance) {
|
|
329
|
+
throw new Error(`[file-manager] storage type "${storage.type}" is not defined`);
|
|
330
|
+
}
|
|
331
|
+
return storageInstance.getFileStream(file);
|
|
315
332
|
}
|
|
316
333
|
}
|
|
317
334
|
var server_default = PluginFileManagerServer;
|
|
@@ -50,7 +50,7 @@ class ali_oss_default extends import__.StorageType {
|
|
|
50
50
|
make() {
|
|
51
51
|
const createAliOssStorage = require("multer-aliyun-oss");
|
|
52
52
|
return new createAliOssStorage({
|
|
53
|
-
config: this.storage.options,
|
|
53
|
+
config: { timeout: 6e5, ...this.storage.options },
|
|
54
54
|
filename: (0, import_utils.cloudFilenameGetter)(this.storage)
|
|
55
55
|
});
|
|
56
56
|
}
|
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
|
+
/// <reference types="node" />
|
|
9
10
|
import { StorageEngine } from 'multer';
|
|
11
|
+
import type { Readable } from 'stream';
|
|
10
12
|
export interface StorageModel {
|
|
11
13
|
id?: number;
|
|
12
14
|
title: string;
|
|
@@ -22,8 +24,9 @@ export interface StorageModel {
|
|
|
22
24
|
export interface AttachmentModel {
|
|
23
25
|
title: string;
|
|
24
26
|
filename: string;
|
|
27
|
+
mimetype?: string;
|
|
25
28
|
path: string;
|
|
26
|
-
url
|
|
29
|
+
url?: string;
|
|
27
30
|
storageId: number;
|
|
28
31
|
}
|
|
29
32
|
export declare abstract class StorageType {
|
|
@@ -34,12 +37,21 @@ export declare abstract class StorageType {
|
|
|
34
37
|
abstract make(): StorageEngine;
|
|
35
38
|
abstract delete(records: AttachmentModel[]): [number, AttachmentModel[]] | Promise<[number, AttachmentModel[]]>;
|
|
36
39
|
getFileKey(record: AttachmentModel): any;
|
|
37
|
-
getFileData
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
getFileData(file: any, meta?: {}): {
|
|
41
|
+
title: string;
|
|
42
|
+
filename: string;
|
|
43
|
+
extname: string;
|
|
44
|
+
path: string;
|
|
45
|
+
size: any;
|
|
46
|
+
mimetype: any;
|
|
47
|
+
meta: {};
|
|
48
|
+
storageId: number;
|
|
41
49
|
};
|
|
42
50
|
getFileURL(file: AttachmentModel, preview?: boolean): string | Promise<string>;
|
|
51
|
+
getFileStream(file: AttachmentModel): Promise<{
|
|
52
|
+
stream: Readable;
|
|
53
|
+
contentType?: string;
|
|
54
|
+
}>;
|
|
43
55
|
}
|
|
44
56
|
export type StorageClassType = {
|
|
45
57
|
new (storage: StorageModel): StorageType;
|