@nocobase/plugin-file-manager 0.9.1-alpha.1 → 0.9.2-alpha.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/lib/client/FileStorage.js +3 -49
- package/lib/client/FileStorageShortcut.js +5 -35
- package/lib/client/StorageOptions.js +10 -24
- package/lib/client/hooks/index.d.ts +1 -0
- package/lib/client/hooks/index.js +16 -0
- package/lib/client/hooks/useUploadFiles.d.ts +8 -0
- package/lib/client/hooks/useUploadFiles.js +78 -0
- package/lib/client/index.js +40 -16
- package/lib/client/initializers/UploadActionInitializer.d.ts +1 -0
- package/lib/client/initializers/UploadActionInitializer.js +67 -0
- package/lib/client/initializers/index.d.ts +1 -0
- package/lib/client/initializers/index.js +16 -0
- package/lib/client/locale/index.d.ts +2 -0
- package/lib/client/locale/index.js +29 -0
- package/lib/client/locale/zh-CN.d.ts +10 -0
- package/lib/client/locale/zh-CN.js +17 -0
- package/lib/client/schemas/storage.js +4 -13
- package/lib/client/templates/file.d.ts +2 -0
- package/lib/client/templates/file.js +164 -0
- package/lib/client/templates/index.d.ts +1 -0
- package/lib/client/templates/index.js +16 -0
- package/lib/index.js +0 -2
- package/lib/server/actions/upload.d.ts +2 -1
- package/lib/server/actions/upload.js +91 -125
- package/lib/server/collections/attachments.js +5 -4
- package/lib/server/collections/storages.js +3 -2
- package/lib/server/index.js +0 -4
- package/lib/server/rules/index.js +0 -2
- package/lib/server/rules/mimetype.js +0 -5
- package/lib/server/server.js +13 -38
- package/lib/server/storages/ali-oss.js +0 -6
- package/lib/server/storages/index.js +0 -8
- package/lib/server/storages/local.js +12 -66
- package/lib/server/storages/s3.js +10 -26
- package/lib/server/storages/tx-cos.js +0 -7
- package/lib/server/utils.js +0 -11
- package/package.json +7 -6
|
@@ -4,33 +4,25 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.storageSchema = void 0;
|
|
7
|
-
|
|
8
7
|
function _shared() {
|
|
9
8
|
const data = require("@formily/shared");
|
|
10
|
-
|
|
11
9
|
_shared = function _shared() {
|
|
12
10
|
return data;
|
|
13
11
|
};
|
|
14
|
-
|
|
15
12
|
return data;
|
|
16
13
|
}
|
|
17
|
-
|
|
18
14
|
function _client() {
|
|
19
15
|
const data = require("@nocobase/client");
|
|
20
|
-
|
|
21
16
|
_client = function _client() {
|
|
22
17
|
return data;
|
|
23
18
|
};
|
|
24
|
-
|
|
25
19
|
return data;
|
|
26
20
|
}
|
|
27
|
-
|
|
28
21
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
29
|
-
|
|
30
22
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
31
|
-
|
|
32
|
-
function
|
|
33
|
-
|
|
23
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
24
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
25
|
+
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
34
26
|
const collection = {
|
|
35
27
|
name: 'storages',
|
|
36
28
|
fields: [{
|
|
@@ -108,7 +100,7 @@ const collection = {
|
|
|
108
100
|
const storageSchema = {
|
|
109
101
|
type: 'object',
|
|
110
102
|
properties: {
|
|
111
|
-
|
|
103
|
+
[(0, _shared().uid)()]: {
|
|
112
104
|
type: 'void',
|
|
113
105
|
'x-decorator': 'ResourceActionProvider',
|
|
114
106
|
'x-decorator-props': {
|
|
@@ -173,7 +165,6 @@ const storageSchema = {
|
|
|
173
165
|
refreshDeps: [ctx.visible]
|
|
174
166
|
}));
|
|
175
167
|
}
|
|
176
|
-
|
|
177
168
|
},
|
|
178
169
|
title: '{{t("Add storage")}}',
|
|
179
170
|
properties: {
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.file = void 0;
|
|
7
|
+
function _client() {
|
|
8
|
+
const data = require("@nocobase/client");
|
|
9
|
+
_client = function _client() {
|
|
10
|
+
return data;
|
|
11
|
+
};
|
|
12
|
+
return data;
|
|
13
|
+
}
|
|
14
|
+
var _locale = require("../locale");
|
|
15
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
16
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
17
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
18
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
19
|
+
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
20
|
+
const file = {
|
|
21
|
+
name: 'file',
|
|
22
|
+
title: `{{t("File collection", { ns: "${_locale.NAMESPACE}" })}}`,
|
|
23
|
+
order: 3,
|
|
24
|
+
color: 'blue',
|
|
25
|
+
default: {
|
|
26
|
+
createdBy: true,
|
|
27
|
+
updatedBy: true,
|
|
28
|
+
fields: [{
|
|
29
|
+
interface: 'input',
|
|
30
|
+
type: 'string',
|
|
31
|
+
name: 'title',
|
|
32
|
+
deletable: false,
|
|
33
|
+
uiSchema: {
|
|
34
|
+
type: 'string',
|
|
35
|
+
title: `{{t("Title")}}`,
|
|
36
|
+
'x-component': 'Input'
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
// '系统文件名(含扩展名)',
|
|
40
|
+
{
|
|
41
|
+
interface: 'input',
|
|
42
|
+
type: 'string',
|
|
43
|
+
name: 'filename',
|
|
44
|
+
deletable: false,
|
|
45
|
+
uiSchema: {
|
|
46
|
+
type: 'string',
|
|
47
|
+
title: `{{t("File name", { ns: "${_locale.NAMESPACE}" })}}`,
|
|
48
|
+
'x-component': 'Input',
|
|
49
|
+
'x-read-pretty': true
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
// '扩展名(含“.”)',
|
|
53
|
+
{
|
|
54
|
+
interface: 'input',
|
|
55
|
+
type: 'string',
|
|
56
|
+
name: 'extname',
|
|
57
|
+
deletable: false,
|
|
58
|
+
uiSchema: {
|
|
59
|
+
type: 'string',
|
|
60
|
+
title: `{{t("Extension name", { ns: "${_locale.NAMESPACE}" })}}`,
|
|
61
|
+
'x-component': 'Input',
|
|
62
|
+
'x-read-pretty': true
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
// '文件体积(字节)',
|
|
66
|
+
{
|
|
67
|
+
interface: 'integer',
|
|
68
|
+
type: 'integer',
|
|
69
|
+
name: 'size',
|
|
70
|
+
deletable: false,
|
|
71
|
+
uiSchema: {
|
|
72
|
+
type: 'number',
|
|
73
|
+
title: `{{t("Size", { ns: "${_locale.NAMESPACE}" })}}`,
|
|
74
|
+
'x-component': 'InputNumber',
|
|
75
|
+
'x-read-pretty': true,
|
|
76
|
+
'x-component-props': {
|
|
77
|
+
stringMode: true,
|
|
78
|
+
step: '0'
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}, {
|
|
82
|
+
interface: 'input',
|
|
83
|
+
type: 'string',
|
|
84
|
+
name: 'mimetype',
|
|
85
|
+
deletable: false,
|
|
86
|
+
uiSchema: {
|
|
87
|
+
type: 'string',
|
|
88
|
+
title: `{{t("Mime type", { ns: "${_locale.NAMESPACE}" })}}`,
|
|
89
|
+
'x-component': 'Input',
|
|
90
|
+
'x-read-pretty': true
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
// '相对路径(含“/”前缀)',
|
|
94
|
+
{
|
|
95
|
+
interface: 'input',
|
|
96
|
+
type: 'string',
|
|
97
|
+
name: 'path',
|
|
98
|
+
deletable: false,
|
|
99
|
+
uiSchema: {
|
|
100
|
+
type: 'string',
|
|
101
|
+
title: `{{t("Path")}}`,
|
|
102
|
+
'x-component': 'Input',
|
|
103
|
+
'x-read-pretty': true
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
// 文件的可访问地址
|
|
107
|
+
{
|
|
108
|
+
interface: 'input',
|
|
109
|
+
type: 'string',
|
|
110
|
+
name: 'url',
|
|
111
|
+
deletable: false,
|
|
112
|
+
uiSchema: {
|
|
113
|
+
type: 'string',
|
|
114
|
+
title: `{{t("URL")}}`,
|
|
115
|
+
'x-component': 'Input.URL',
|
|
116
|
+
'x-read-pretty': true
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
// 用于预览
|
|
120
|
+
{
|
|
121
|
+
interface: 'url',
|
|
122
|
+
type: 'string',
|
|
123
|
+
name: 'preview',
|
|
124
|
+
field: 'url',
|
|
125
|
+
deletable: false,
|
|
126
|
+
uiSchema: {
|
|
127
|
+
type: 'string',
|
|
128
|
+
title: `{{t("Preview")}}`,
|
|
129
|
+
'x-component': 'Preview',
|
|
130
|
+
'x-read-pretty': true
|
|
131
|
+
}
|
|
132
|
+
}, {
|
|
133
|
+
comment: '存储引擎',
|
|
134
|
+
type: 'belongsTo',
|
|
135
|
+
name: 'storage',
|
|
136
|
+
target: 'storages',
|
|
137
|
+
foreignKey: 'storageId',
|
|
138
|
+
deletable: false
|
|
139
|
+
},
|
|
140
|
+
// '其他文件信息(如图片的宽高)',
|
|
141
|
+
{
|
|
142
|
+
type: 'jsonb',
|
|
143
|
+
name: 'meta',
|
|
144
|
+
deletable: false,
|
|
145
|
+
defaultValue: {}
|
|
146
|
+
}]
|
|
147
|
+
},
|
|
148
|
+
configurableProperties: _objectSpread(_objectSpread(_objectSpread({}, (0, _client().getConfigurableProperties)('title', 'name')), {}, {
|
|
149
|
+
inherits: _objectSpread(_objectSpread({}, (0, _client().getConfigurableProperties)('inherits').inherits), {}, {
|
|
150
|
+
'x-reactions': ['{{useAsyncDataSource(loadCollections)}}']
|
|
151
|
+
})
|
|
152
|
+
}, (0, _client().getConfigurableProperties)('category')), {}, {
|
|
153
|
+
storage: {
|
|
154
|
+
title: `{{t("File storage", { ns: "${_locale.NAMESPACE}" })}}`,
|
|
155
|
+
type: 'hasOne',
|
|
156
|
+
name: 'storage',
|
|
157
|
+
required: true,
|
|
158
|
+
'x-decorator': 'FormItem',
|
|
159
|
+
'x-component': 'Select',
|
|
160
|
+
'x-reactions': ['{{useAsyncDataSource(loadStorages)}}']
|
|
161
|
+
}
|
|
162
|
+
})
|
|
163
|
+
};
|
|
164
|
+
exports.file = file;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './file';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
var _file = require("./file");
|
|
7
|
+
Object.keys(_file).forEach(function (key) {
|
|
8
|
+
if (key === "default" || key === "__esModule") return;
|
|
9
|
+
if (key in exports && exports[key] === _file[key]) return;
|
|
10
|
+
Object.defineProperty(exports, key, {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: function get() {
|
|
13
|
+
return _file[key];
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
});
|
package/lib/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { Context, Next } from '@nocobase/actions';
|
|
2
2
|
export declare function middleware(ctx: Context, next: Next): Promise<any>;
|
|
3
|
-
export declare function
|
|
3
|
+
export declare function createAction(ctx: Context, next: Next): Promise<any>;
|
|
4
|
+
export declare function uploadAction(ctx: Context, next: Next): Promise<never>;
|
|
@@ -3,154 +3,110 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.createAction = createAction;
|
|
7
7
|
exports.middleware = middleware;
|
|
8
|
-
|
|
8
|
+
exports.uploadAction = uploadAction;
|
|
9
9
|
function _multer() {
|
|
10
10
|
const data = _interopRequireDefault(require("@koa/multer"));
|
|
11
|
-
|
|
12
11
|
_multer = function _multer() {
|
|
13
12
|
return data;
|
|
14
13
|
};
|
|
15
|
-
|
|
16
|
-
return data;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function _database() {
|
|
20
|
-
const data = require("@nocobase/database");
|
|
21
|
-
|
|
22
|
-
_database = function _database() {
|
|
23
|
-
return data;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
14
|
return data;
|
|
27
15
|
}
|
|
28
|
-
|
|
29
16
|
function _path() {
|
|
30
17
|
const data = _interopRequireDefault(require("path"));
|
|
31
|
-
|
|
32
18
|
_path = function _path() {
|
|
33
19
|
return data;
|
|
34
20
|
};
|
|
35
|
-
|
|
36
21
|
return data;
|
|
37
22
|
}
|
|
38
|
-
|
|
39
23
|
var _constants = require("../constants");
|
|
40
|
-
|
|
41
24
|
var Rules = _interopRequireWildcard(require("../rules"));
|
|
42
|
-
|
|
43
25
|
var _storages = require("../storages");
|
|
44
|
-
|
|
45
26
|
const _excluded = ["size"];
|
|
46
|
-
|
|
47
27
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
48
|
-
|
|
49
28
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
50
|
-
|
|
51
29
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
52
|
-
|
|
53
30
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
54
|
-
|
|
55
31
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
56
|
-
|
|
57
|
-
function
|
|
58
|
-
|
|
32
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
33
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
34
|
+
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
59
35
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
60
|
-
|
|
61
36
|
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
62
|
-
|
|
63
37
|
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
64
|
-
|
|
65
38
|
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
66
|
-
|
|
67
39
|
function getRules(ctx) {
|
|
68
40
|
const resourceField = ctx.resourceField;
|
|
69
|
-
|
|
70
41
|
if (!resourceField) {
|
|
71
42
|
return ctx.storage.rules;
|
|
72
43
|
}
|
|
73
|
-
|
|
74
44
|
const _ref = resourceField.options.attachment || {},
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
45
|
+
_ref$rules = _ref.rules,
|
|
46
|
+
rules = _ref$rules === void 0 ? {} : _ref$rules;
|
|
78
47
|
return Object.assign({}, ctx.storage.rules, rules);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
48
|
+
}
|
|
49
|
+
// TODO(optimize): 需要优化错误处理,计算失败后需要抛出对应错误,以便程序处理
|
|
82
50
|
function getFileFilter(ctx) {
|
|
83
51
|
return (req, file, cb) => {
|
|
84
52
|
// size 交给 limits 处理
|
|
85
53
|
const _getRules = getRules(ctx),
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
54
|
+
size = _getRules.size,
|
|
55
|
+
rules = _objectWithoutProperties(_getRules, _excluded);
|
|
89
56
|
const ruleKeys = Object.keys(rules);
|
|
90
57
|
const result = !ruleKeys.length || !ruleKeys.some(key => typeof Rules[key] !== 'function' || !Rules[key](file, rules[key], ctx));
|
|
91
58
|
cb(null, result);
|
|
92
59
|
};
|
|
93
60
|
}
|
|
94
|
-
|
|
61
|
+
const isUploadAction = ctx => {
|
|
62
|
+
var _collection$options;
|
|
63
|
+
const _ctx$action = ctx.action,
|
|
64
|
+
resourceName = _ctx$action.resourceName,
|
|
65
|
+
actionName = _ctx$action.actionName;
|
|
66
|
+
if (actionName === 'upload' && resourceName === 'attachments') {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
const collection = ctx.db.getCollection(resourceName);
|
|
70
|
+
if ((collection === null || collection === void 0 ? void 0 : (_collection$options = collection.options) === null || _collection$options === void 0 ? void 0 : _collection$options.template) === 'file' && ['upload', 'create'].includes(actionName)) {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
95
74
|
function middleware(_x, _x2) {
|
|
96
75
|
return _middleware.apply(this, arguments);
|
|
97
76
|
}
|
|
98
|
-
|
|
99
77
|
function _middleware() {
|
|
100
78
|
_middleware = _asyncToGenerator(function* (ctx, next) {
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
associatedName = _ctx$action$params.associatedName;
|
|
105
|
-
|
|
106
|
-
if (actionName !== 'upload') {
|
|
79
|
+
const resourceName = ctx.action.resourceName;
|
|
80
|
+
const collection = ctx.db.getCollection(resourceName);
|
|
81
|
+
if (!isUploadAction(ctx)) {
|
|
107
82
|
return next();
|
|
108
|
-
}
|
|
109
|
-
// 1. 存储引擎选择依赖于字段定义
|
|
110
|
-
// 2. 字段定义中需包含引擎的外键值
|
|
111
|
-
// 3. 无字段时按 storages 表的默认项
|
|
112
|
-
// 4. 插件初始化后应提示用户添加至少一个存储引擎并设为默认
|
|
113
|
-
|
|
114
|
-
|
|
83
|
+
}
|
|
115
84
|
const Storage = ctx.db.getCollection('storages');
|
|
116
85
|
let storage;
|
|
117
|
-
|
|
118
|
-
if (resourceName === 'attachments') {
|
|
119
|
-
// 如果没有包含关联,则直接按默认文件上传至默认存储引擎
|
|
86
|
+
if (collection.options.storage) {
|
|
120
87
|
storage = yield Storage.repository.findOne({
|
|
121
88
|
filter: {
|
|
122
|
-
|
|
89
|
+
name: collection.options.storage
|
|
123
90
|
}
|
|
124
91
|
});
|
|
125
|
-
} else
|
|
126
|
-
const AssociatedCollection = ctx.db.getCollection(associatedName);
|
|
127
|
-
const resourceField = AssociatedCollection.getField(resourceName);
|
|
128
|
-
ctx.resourceField = resourceField;
|
|
129
|
-
const _resourceField$option = resourceField.options.attachment,
|
|
130
|
-
attachment = _resourceField$option === void 0 ? {} : _resourceField$option;
|
|
92
|
+
} else {
|
|
131
93
|
storage = yield Storage.repository.findOne({
|
|
132
|
-
filter:
|
|
133
|
-
name: attachment.storage
|
|
134
|
-
} : {
|
|
94
|
+
filter: {
|
|
135
95
|
default: true
|
|
136
96
|
}
|
|
137
97
|
});
|
|
138
98
|
}
|
|
139
|
-
|
|
140
99
|
if (!storage) {
|
|
141
100
|
console.error('[file-manager] no default or linked storage provided');
|
|
142
101
|
return ctx.throw(500);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
|
|
102
|
+
}
|
|
103
|
+
// 传递已取得的存储引擎,避免重查
|
|
146
104
|
ctx.storage = storage;
|
|
147
105
|
const storageConfig = (0, _storages.getStorageConfig)(storage.type);
|
|
148
|
-
|
|
149
106
|
if (!storageConfig) {
|
|
150
107
|
console.error(`[file-manager] storage type "${storage.type}" is not defined`);
|
|
151
108
|
return ctx.throw(500);
|
|
152
109
|
}
|
|
153
|
-
|
|
154
110
|
const multerOptions = {
|
|
155
111
|
fileFilter: getFileFilter(ctx),
|
|
156
112
|
limits: {
|
|
@@ -165,29 +121,62 @@ function _middleware() {
|
|
|
165
121
|
});
|
|
166
122
|
return _middleware.apply(this, arguments);
|
|
167
123
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
return _action.apply(this, arguments);
|
|
124
|
+
function createAction(_x3, _x4) {
|
|
125
|
+
return _createAction.apply(this, arguments);
|
|
171
126
|
}
|
|
172
|
-
|
|
173
|
-
function
|
|
174
|
-
|
|
127
|
+
function _createAction() {
|
|
128
|
+
_createAction = _asyncToGenerator(function* (ctx, next) {
|
|
129
|
+
if (!isUploadAction(ctx)) {
|
|
130
|
+
return next();
|
|
131
|
+
}
|
|
175
132
|
const file = ctx[_constants.FILE_FIELD_NAME],
|
|
176
|
-
|
|
177
|
-
|
|
133
|
+
storage = ctx.storage;
|
|
178
134
|
if (!file) {
|
|
179
135
|
return ctx.throw(400, 'file validation failed');
|
|
180
136
|
}
|
|
181
|
-
|
|
182
137
|
const storageConfig = (0, _storages.getStorageConfig)(storage.type);
|
|
183
|
-
const name = file[storageConfig.filenameKey || 'filename'];
|
|
184
|
-
|
|
138
|
+
const name = file[storageConfig.filenameKey || 'filename'];
|
|
139
|
+
// make compatible filename across cloud service (with path)
|
|
140
|
+
const filename = _path().default.basename(name);
|
|
141
|
+
const extname = _path().default.extname(filename);
|
|
142
|
+
const urlPath = storage.path ? storage.path.replace(/^([^\/])/, '/$1') : '';
|
|
143
|
+
const values = _objectSpread({
|
|
144
|
+
title: file.originalname.replace(extname, ''),
|
|
145
|
+
filename,
|
|
146
|
+
extname,
|
|
147
|
+
// TODO(feature): 暂时两者相同,后面 storage.path 模版化以后,这里只是 file 实际的 path
|
|
148
|
+
path: storage.path,
|
|
149
|
+
size: file.size,
|
|
150
|
+
// 直接缓存起来
|
|
151
|
+
url: `${storage.baseUrl}${urlPath}/${filename}`,
|
|
152
|
+
mimetype: file.mimetype,
|
|
153
|
+
storageId: storage.id,
|
|
154
|
+
// @ts-ignore
|
|
155
|
+
meta: ctx.request.body
|
|
156
|
+
}, storageConfig.getFileData ? storageConfig.getFileData(file) : {});
|
|
157
|
+
ctx.action.mergeParams({
|
|
158
|
+
values
|
|
159
|
+
});
|
|
160
|
+
yield next();
|
|
161
|
+
});
|
|
162
|
+
return _createAction.apply(this, arguments);
|
|
163
|
+
}
|
|
164
|
+
function uploadAction(_x5, _x6) {
|
|
165
|
+
return _uploadAction.apply(this, arguments);
|
|
166
|
+
}
|
|
167
|
+
function _uploadAction() {
|
|
168
|
+
_uploadAction = _asyncToGenerator(function* (ctx, next) {
|
|
169
|
+
const file = ctx[_constants.FILE_FIELD_NAME],
|
|
170
|
+
storage = ctx.storage;
|
|
171
|
+
if (!file) {
|
|
172
|
+
return ctx.throw(400, 'file validation failed');
|
|
173
|
+
}
|
|
174
|
+
const storageConfig = (0, _storages.getStorageConfig)(storage.type);
|
|
175
|
+
const name = file[storageConfig.filenameKey || 'filename'];
|
|
176
|
+
// make compatible filename across cloud service (with path)
|
|
185
177
|
const filename = _path().default.basename(name);
|
|
186
|
-
|
|
187
178
|
const extname = _path().default.extname(filename);
|
|
188
|
-
|
|
189
179
|
const urlPath = storage.path ? storage.path.replace(/^([^\/])/, '/$1') : '';
|
|
190
|
-
|
|
191
180
|
const data = _objectSpread({
|
|
192
181
|
title: file.originalname.replace(extname, ''),
|
|
193
182
|
filename,
|
|
@@ -198,49 +187,26 @@ function _action() {
|
|
|
198
187
|
// 直接缓存起来
|
|
199
188
|
url: `${storage.baseUrl}${urlPath}/${filename}`,
|
|
200
189
|
mimetype: file.mimetype,
|
|
190
|
+
storageId: storage.id,
|
|
201
191
|
// @ts-ignore
|
|
202
192
|
meta: ctx.request.body
|
|
203
193
|
}, storageConfig.getFileData ? storageConfig.getFileData(file) : {});
|
|
204
|
-
|
|
205
|
-
const attachment = yield ctx.db.sequelize.transaction( /*#__PURE__*/function () {
|
|
194
|
+
const fileData = yield ctx.db.sequelize.transaction( /*#__PURE__*/function () {
|
|
206
195
|
var _ref2 = _asyncToGenerator(function* (transaction) {
|
|
207
|
-
|
|
208
|
-
const
|
|
209
|
-
|
|
196
|
+
const resourceName = ctx.action.resourceName;
|
|
197
|
+
const repository = ctx.db.getRepository(resourceName);
|
|
198
|
+
const result = yield repository.create({
|
|
199
|
+
values: _objectSpread({}, data),
|
|
210
200
|
transaction
|
|
211
201
|
});
|
|
212
|
-
const _ctx$action$params2 = ctx.action.params,
|
|
213
|
-
associatedName = _ctx$action$params2.associatedName,
|
|
214
|
-
associatedIndex = _ctx$action$params2.associatedIndex,
|
|
215
|
-
resourceName = _ctx$action$params2.resourceName;
|
|
216
|
-
const AssociatedCollection = ctx.db.getCollection(associatedName);
|
|
217
|
-
|
|
218
|
-
if (AssociatedCollection && associatedIndex && resourceName) {
|
|
219
|
-
const Repo = AssociatedCollection.repository.relation(resourceName).of(associatedIndex);
|
|
220
|
-
const Attachment = ctx.db.getCollection('attachments').model;
|
|
221
|
-
const opts = {
|
|
222
|
-
tk: result[Attachment.primaryKeyAttribute],
|
|
223
|
-
transaction
|
|
224
|
-
};
|
|
225
|
-
|
|
226
|
-
if (Repo instanceof _database().BelongsToManyRepository) {
|
|
227
|
-
yield Repo.add(opts);
|
|
228
|
-
} else if (Repo instanceof _database().BelongsToRepository) {
|
|
229
|
-
yield Repo.set(opts);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
202
|
return result;
|
|
234
203
|
});
|
|
235
|
-
|
|
236
|
-
return function (_x5) {
|
|
204
|
+
return function (_x7) {
|
|
237
205
|
return _ref2.apply(this, arguments);
|
|
238
206
|
};
|
|
239
|
-
}());
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
ctx.body = attachment;
|
|
207
|
+
}());
|
|
208
|
+
ctx.body = fileData;
|
|
243
209
|
yield next();
|
|
244
210
|
});
|
|
245
|
-
return
|
|
211
|
+
return _uploadAction.apply(this, arguments);
|
|
246
212
|
}
|
|
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _default = {
|
|
8
|
-
namespace: 'file-manager',
|
|
8
|
+
namespace: 'file-manager.attachmentRecords',
|
|
9
9
|
duplicator: 'optional',
|
|
10
10
|
name: 'attachments',
|
|
11
11
|
title: '文件管理器',
|
|
@@ -27,7 +27,8 @@ var _default = {
|
|
|
27
27
|
comment: '文件体积(字节)',
|
|
28
28
|
type: 'integer',
|
|
29
29
|
name: 'size'
|
|
30
|
-
},
|
|
30
|
+
},
|
|
31
|
+
// TODO: 使用暂不明确,以后再考虑
|
|
31
32
|
// {
|
|
32
33
|
// comment: '文件类型(mimetype 前半段,通常用于预览)',
|
|
33
34
|
// type: 'string',
|
|
@@ -52,8 +53,8 @@ var _default = {
|
|
|
52
53
|
}, {
|
|
53
54
|
comment: '网络访问地址',
|
|
54
55
|
type: 'string',
|
|
55
|
-
name: 'url'
|
|
56
|
-
|
|
56
|
+
name: 'url'
|
|
57
|
+
// formula: '{{ storage.baseUrl }}{{ path }}/{{ filename }}'
|
|
57
58
|
}]
|
|
58
59
|
};
|
|
59
60
|
exports.default = _default;
|
|
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _default = {
|
|
8
|
-
namespace: 'file-manager',
|
|
8
|
+
namespace: 'file-manager.storageSetting',
|
|
9
9
|
duplicator: 'optional',
|
|
10
10
|
name: 'storages',
|
|
11
11
|
title: '存储引擎',
|
|
@@ -44,7 +44,8 @@ var _default = {
|
|
|
44
44
|
type: 'string',
|
|
45
45
|
name: 'baseUrl',
|
|
46
46
|
defaultValue: ''
|
|
47
|
-
},
|
|
47
|
+
},
|
|
48
|
+
// TODO(feature): 需要使用一个实现了可设置默认值的字段
|
|
48
49
|
{
|
|
49
50
|
comment: '默认引擎',
|
|
50
51
|
type: 'radio',
|
package/lib/server/index.js
CHANGED
|
@@ -10,9 +10,7 @@ Object.defineProperty(exports, "default", {
|
|
|
10
10
|
return _server.default;
|
|
11
11
|
}
|
|
12
12
|
});
|
|
13
|
-
|
|
14
13
|
var _constants = require("./constants");
|
|
15
|
-
|
|
16
14
|
Object.keys(_constants).forEach(function (key) {
|
|
17
15
|
if (key === "default" || key === "__esModule") return;
|
|
18
16
|
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
@@ -24,7 +22,5 @@ Object.keys(_constants).forEach(function (key) {
|
|
|
24
22
|
}
|
|
25
23
|
});
|
|
26
24
|
});
|
|
27
|
-
|
|
28
25
|
var _server = _interopRequireDefault(require("./server"));
|
|
29
|
-
|
|
30
26
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|