@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.
Files changed (37) hide show
  1. package/lib/client/FileStorage.js +3 -49
  2. package/lib/client/FileStorageShortcut.js +5 -35
  3. package/lib/client/StorageOptions.js +10 -24
  4. package/lib/client/hooks/index.d.ts +1 -0
  5. package/lib/client/hooks/index.js +16 -0
  6. package/lib/client/hooks/useUploadFiles.d.ts +8 -0
  7. package/lib/client/hooks/useUploadFiles.js +78 -0
  8. package/lib/client/index.js +40 -16
  9. package/lib/client/initializers/UploadActionInitializer.d.ts +1 -0
  10. package/lib/client/initializers/UploadActionInitializer.js +67 -0
  11. package/lib/client/initializers/index.d.ts +1 -0
  12. package/lib/client/initializers/index.js +16 -0
  13. package/lib/client/locale/index.d.ts +2 -0
  14. package/lib/client/locale/index.js +29 -0
  15. package/lib/client/locale/zh-CN.d.ts +10 -0
  16. package/lib/client/locale/zh-CN.js +17 -0
  17. package/lib/client/schemas/storage.js +4 -13
  18. package/lib/client/templates/file.d.ts +2 -0
  19. package/lib/client/templates/file.js +164 -0
  20. package/lib/client/templates/index.d.ts +1 -0
  21. package/lib/client/templates/index.js +16 -0
  22. package/lib/index.js +0 -2
  23. package/lib/server/actions/upload.d.ts +2 -1
  24. package/lib/server/actions/upload.js +91 -125
  25. package/lib/server/collections/attachments.js +5 -4
  26. package/lib/server/collections/storages.js +3 -2
  27. package/lib/server/index.js +0 -4
  28. package/lib/server/rules/index.js +0 -2
  29. package/lib/server/rules/mimetype.js +0 -5
  30. package/lib/server/server.js +13 -38
  31. package/lib/server/storages/ali-oss.js +0 -6
  32. package/lib/server/storages/index.js +0 -8
  33. package/lib/server/storages/local.js +12 -66
  34. package/lib/server/storages/s3.js +10 -26
  35. package/lib/server/storages/tx-cos.js +0 -7
  36. package/lib/server/utils.js +0 -11
  37. 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 _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
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
- block1: {
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,2 @@
1
+ import { CollectionOptions } from '@nocobase/database';
2
+ export declare const file: CollectionOptions;
@@ -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
@@ -9,7 +9,5 @@ Object.defineProperty(exports, "default", {
9
9
  return _server.default;
10
10
  }
11
11
  });
12
-
13
12
  var _server = _interopRequireDefault(require("./server"));
14
-
15
13
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -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 action(ctx: Context, next: Next): Promise<never>;
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.action = action;
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 _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
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
- _ref$rules = _ref.rules,
76
- rules = _ref$rules === void 0 ? {} : _ref$rules;
77
-
45
+ _ref$rules = _ref.rules,
46
+ rules = _ref$rules === void 0 ? {} : _ref$rules;
78
47
  return Object.assign({}, ctx.storage.rules, rules);
79
- } // TODO(optimize): 需要优化错误处理,计算失败后需要抛出对应错误,以便程序处理
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
- size = _getRules.size,
87
- rules = _objectWithoutProperties(_getRules, _excluded);
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 _ctx$action$params = ctx.action.params,
102
- resourceName = _ctx$action$params.resourceName,
103
- actionName = _ctx$action$params.actionName,
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
- } // NOTE:
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
- default: true
89
+ name: collection.options.storage
123
90
  }
124
91
  });
125
- } else if (associatedName) {
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: attachment.storage ? {
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
- function action(_x3, _x4) {
170
- return _action.apply(this, arguments);
124
+ function createAction(_x3, _x4) {
125
+ return _createAction.apply(this, arguments);
171
126
  }
172
-
173
- function _action() {
174
- _action = _asyncToGenerator(function* (ctx, next) {
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
- storage = ctx.storage;
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']; // make compatible filename across cloud service (with path)
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
- // TODO(optimize): 应使用关联 accessors 获取
208
- const result = yield storage.createAttachment(data, {
209
- context: ctx,
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
- // attachment.setDataValue('storage', storage);
241
-
242
- ctx.body = attachment;
207
+ }());
208
+ ctx.body = fileData;
243
209
  yield next();
244
210
  });
245
- return _action.apply(this, arguments);
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
- }, // TODO: 使用暂不明确,以后再考虑
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' // formula: '{{ storage.baseUrl }}{{ path }}/{{ filename }}'
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
- }, // TODO(feature): 需要使用一个实现了可设置默认值的字段
47
+ },
48
+ // TODO(feature): 需要使用一个实现了可设置默认值的字段
48
49
  {
49
50
  comment: '默认引擎',
50
51
  type: 'radio',
@@ -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 }; }
@@ -9,7 +9,5 @@ Object.defineProperty(exports, "mimetype", {
9
9
  return _mimetype.default;
10
10
  }
11
11
  });
12
-
13
12
  var _mimetype = _interopRequireDefault(require("./mimetype"));
14
-
15
13
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }