@nocobase/plugin-file-manager 0.5.0-alpha.34 → 0.5.0-alpha.35
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/actions/upload.d.ts.map +1 -1
- package/lib/actions/upload.js +27 -20
- package/lib/actions/upload.js.map +1 -1
- package/lib/constants.d.ts +1 -0
- package/lib/constants.d.ts.map +1 -1
- package/lib/constants.js +2 -1
- package/lib/constants.js.map +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +39 -0
- package/lib/index.js.map +1 -1
- package/lib/server.d.ts.map +1 -1
- package/lib/server.js +20 -22
- package/lib/server.js.map +1 -1
- package/lib/storages/ali-oss.d.ts +15 -8
- package/lib/storages/ali-oss.d.ts.map +1 -1
- package/lib/storages/ali-oss.js +23 -45
- package/lib/storages/ali-oss.js.map +1 -1
- package/lib/storages/index.d.ts +8 -2
- package/lib/storages/index.d.ts.map +1 -1
- package/lib/storages/index.js +11 -1
- package/lib/storages/index.js.map +1 -1
- package/lib/storages/local.d.ts +11 -3
- package/lib/storages/local.d.ts.map +1 -1
- package/lib/storages/local.js +123 -63
- package/lib/storages/local.js.map +1 -1
- package/lib/storages/s3.d.ts +17 -0
- package/lib/storages/s3.d.ts.map +1 -0
- package/lib/storages/s3.js +90 -0
- package/lib/storages/s3.js.map +1 -0
- package/lib/utils.d.ts +1 -0
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +13 -1
- package/lib/utils.js.map +1 -1
- package/package.json +6 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["actions/upload.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AA2BlD,wBAAsB,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,gBAkDxD;AAED,wBAAsB,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,
|
|
1
|
+
{"version":3,"sources":["actions/upload.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AA2BlD,wBAAsB,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,gBAkDxD;AAED,wBAAsB,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,kBAkDpD","file":"upload.d.ts","sourcesContent":["import path from 'path';\nimport multer from '@koa/multer';\nimport { Context, Next } from '@nocobase/actions';\nimport { getStorageConfig } from '../storages';\nimport * as Rules from '../rules';\nimport { FILE_FIELD_NAME, LIMIT_FILES, LIMIT_MAX_FILE_SIZE } from '../constants';\n\nfunction getRules(ctx: Context) {\n const { resourceField } = ctx.action.params;\n if (!resourceField) {\n return ctx.storage.rules;\n }\n const { rules = {} } = resourceField.getOptions().attachment || {};\n return Object.assign({}, ctx.storage.rules, rules);\n}\n\n// TODO(optimize): 需要优化错误处理,计算失败后需要抛出对应错误,以便程序处理\nfunction getFileFilter(ctx: Context) {\n return (req, file, cb) => {\n // size 交给 limits 处理\n const { size, ...rules } = getRules(ctx);\n const ruleKeys = Object.keys(rules);\n const result = !ruleKeys.length || !ruleKeys\n .some(key => typeof Rules[key] !== 'function'\n || !Rules[key](file, rules[key], ctx));\n cb(null, result);\n }\n}\n\nexport async function middleware(ctx: Context, next: Next) {\n const { resourceName, actionName, resourceField } = ctx.action.params;\n if (actionName !== 'upload') {\n return next();\n }\n\n // NOTE:\n // 1. 存储引擎选择依赖于字段定义\n // 2. 字段定义中需包含引擎的外键值\n // 3. 无字段时按 storages 表的默认项\n // 4. 插件初始化后应提示用户添加至少一个存储引擎并设为默认\n\n const StorageModel = ctx.db.getModel('storages');\n let storage;\n\n if (resourceName === 'attachments') {\n // 如果没有包含关联,则直接按默认文件上传至默认存储引擎\n storage = await StorageModel.findOne({ where: { default: true } });\n } else {\n const { attachment = {} } = resourceField.getOptions();\n storage = await StorageModel.findOne({\n where: attachment.storage\n ? { name: attachment.storage }\n : { default: true }\n });\n }\n\n if (!storage) {\n console.error('[file-manager] no default or linked storage provided');\n return ctx.throw(500);\n }\n // 传递已取得的存储引擎,避免重查\n ctx.storage = storage;\n\n const storageConfig = getStorageConfig(storage.type);\n if (!storageConfig) {\n console.error(`[file-manager] storage type \"${storage.type}\" is not defined`);\n return ctx.throw(500);\n }\n const multerOptions = {\n fileFilter: getFileFilter(ctx),\n limits: {\n fileSize: Math.min(getRules(ctx).size || LIMIT_MAX_FILE_SIZE, LIMIT_MAX_FILE_SIZE),\n // 每次只允许提交一个文件\n files: LIMIT_FILES\n },\n storage: storageConfig.make(storage),\n };\n const upload = multer(multerOptions).single(FILE_FIELD_NAME);\n return upload(ctx, next);\n};\n\nexport async function action(ctx: Context, next: Next) {\n const { [FILE_FIELD_NAME]: file, storage } = ctx;\n if (!file) {\n return ctx.throw(400, 'file validation failed');\n }\n\n const storageConfig = getStorageConfig(storage.type);\n const { [storageConfig.filenameKey || 'filename']: name } = file;\n // make compatible filename across cloud service (with path)\n const filename = path.basename(name);\n const extname = path.extname(filename);\n const urlPath = storage.path\n ? storage.path.replace(/^([^\\/])/, '/$1')\n : '';\n\n const data = {\n title: file.originalname.replace(extname, ''),\n filename,\n extname,\n // TODO(feature): 暂时两者相同,后面 storage.path 模版化以后,这里只是 file 实际的 path\n path: storage.path,\n size: file.size,\n // 直接缓存起来\n url: `${storage.baseUrl}${urlPath}/${filename}`,\n mimetype: file.mimetype,\n // @ts-ignore\n meta: ctx.request.body,\n ...(storageConfig.getFileData ? storageConfig.getFileData(file) : {})\n };\n \n const attachment = await ctx.db.sequelize.transaction(async transaction => {\n // TODO(optimize): 应使用关联 accessors 获取\n const result = await storage.createAttachment(data, { transaction });\n \n const { associatedName, associatedIndex, resourceField } = ctx.action.params;\n if (associatedIndex && resourceField) {\n const Attachment = ctx.db.getModel('attachments');\n const SourceModel = ctx.db.getModel(associatedName);\n const source = await SourceModel.findByPk(associatedIndex, { transaction });\n await source[resourceField.getAccessors().set](result[Attachment.primaryKeyAttribute], { transaction });\n }\n\n return result;\n });\n\n // 将存储引擎的信息附在已创建的记录里,节省一次查询\n // attachment.setDataValue('storage', storage);\n ctx.body = attachment;\n\n await next();\n};\n"]}
|
package/lib/actions/upload.js
CHANGED
|
@@ -102,7 +102,7 @@ const path_1 = __importDefault(require("path"));
|
|
|
102
102
|
|
|
103
103
|
const multer_1 = __importDefault(require("@koa/multer"));
|
|
104
104
|
|
|
105
|
-
const storages_1 =
|
|
105
|
+
const storages_1 = require("../storages");
|
|
106
106
|
|
|
107
107
|
const Rules = __importStar(require("../rules"));
|
|
108
108
|
|
|
@@ -155,10 +155,13 @@ function middleware(ctx, next) {
|
|
|
155
155
|
}
|
|
156
156
|
});
|
|
157
157
|
} else {
|
|
158
|
-
const
|
|
158
|
+
const _resourceField$getOpt = resourceField.getOptions(),
|
|
159
|
+
_resourceField$getOpt2 = _resourceField$getOpt.attachment,
|
|
160
|
+
attachment = _resourceField$getOpt2 === void 0 ? {} : _resourceField$getOpt2;
|
|
161
|
+
|
|
159
162
|
storage = yield StorageModel.findOne({
|
|
160
|
-
where:
|
|
161
|
-
|
|
163
|
+
where: attachment.storage ? {
|
|
164
|
+
name: attachment.storage
|
|
162
165
|
} : {
|
|
163
166
|
default: true
|
|
164
167
|
}
|
|
@@ -171,9 +174,9 @@ function middleware(ctx, next) {
|
|
|
171
174
|
}
|
|
172
175
|
|
|
173
176
|
ctx.storage = storage;
|
|
174
|
-
const
|
|
177
|
+
const storageConfig = (0, storages_1.getStorageConfig)(storage.type);
|
|
175
178
|
|
|
176
|
-
if (!
|
|
179
|
+
if (!storageConfig) {
|
|
177
180
|
console.error(`[file-manager] storage type "${storage.type}" is not defined`);
|
|
178
181
|
return ctx.throw(500);
|
|
179
182
|
}
|
|
@@ -184,10 +187,10 @@ function middleware(ctx, next) {
|
|
|
184
187
|
fileSize: Math.min(getRules(ctx).size || constants_1.LIMIT_MAX_FILE_SIZE, constants_1.LIMIT_MAX_FILE_SIZE),
|
|
185
188
|
files: constants_1.LIMIT_FILES
|
|
186
189
|
},
|
|
187
|
-
storage:
|
|
190
|
+
storage: storageConfig.make(storage)
|
|
188
191
|
};
|
|
189
|
-
const upload = (0, multer_1.default)(multerOptions);
|
|
190
|
-
return upload
|
|
192
|
+
const upload = (0, multer_1.default)(multerOptions).single(constants_1.FILE_FIELD_NAME);
|
|
193
|
+
return upload(ctx, next);
|
|
191
194
|
});
|
|
192
195
|
}
|
|
193
196
|
|
|
@@ -203,30 +206,34 @@ function action(ctx, next) {
|
|
|
203
206
|
return ctx.throw(400, 'file validation failed');
|
|
204
207
|
}
|
|
205
208
|
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
const
|
|
211
|
-
const data = {
|
|
209
|
+
const storageConfig = (0, storages_1.getStorageConfig)(storage.type);
|
|
210
|
+
const name = file[storageConfig.filenameKey || 'filename'];
|
|
211
|
+
const filename = path_1.default.basename(name);
|
|
212
|
+
const extname = path_1.default.extname(filename);
|
|
213
|
+
const urlPath = storage.path ? storage.path.replace(/^([^\/])/, '/$1') : '';
|
|
214
|
+
const data = Object.assign({
|
|
212
215
|
title: file.originalname.replace(extname, ''),
|
|
213
|
-
filename
|
|
216
|
+
filename,
|
|
214
217
|
extname,
|
|
215
218
|
path: storage.path,
|
|
216
219
|
size: file.size,
|
|
217
|
-
url: `${storage.baseUrl}${
|
|
220
|
+
url: `${storage.baseUrl}${urlPath}/${filename}`,
|
|
218
221
|
mimetype: file.mimetype,
|
|
219
222
|
meta: ctx.request.body
|
|
220
|
-
};
|
|
223
|
+
}, storageConfig.getFileData ? storageConfig.getFileData(file) : {});
|
|
221
224
|
const attachment = yield ctx.db.sequelize.transaction(transaction => __awaiter(this, void 0, void 0, function* () {
|
|
222
225
|
const result = yield storage.createAttachment(data, {
|
|
223
226
|
transaction
|
|
224
227
|
});
|
|
228
|
+
const _ctx$action$params2 = ctx.action.params,
|
|
229
|
+
associatedName = _ctx$action$params2.associatedName,
|
|
230
|
+
associatedIndex = _ctx$action$params2.associatedIndex,
|
|
231
|
+
resourceField = _ctx$action$params2.resourceField;
|
|
225
232
|
|
|
226
|
-
if (
|
|
233
|
+
if (associatedIndex && resourceField) {
|
|
227
234
|
const Attachment = ctx.db.getModel('attachments');
|
|
228
235
|
const SourceModel = ctx.db.getModel(associatedName);
|
|
229
|
-
const source = yield SourceModel.findByPk(
|
|
236
|
+
const source = yield SourceModel.findByPk(associatedIndex, {
|
|
230
237
|
transaction
|
|
231
238
|
});
|
|
232
239
|
yield source[resourceField.getAccessors().set](result[Attachment.primaryKeyAttribute], {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["actions/upload.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,gDAAwB;AACxB,yDAAiC;AAEjC,
|
|
1
|
+
{"version":3,"sources":["actions/upload.ts"],"names":[],"mappings":"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","file":"upload.js","sourcesContent":["import path from 'path';\nimport multer from '@koa/multer';\nimport { Context, Next } from '@nocobase/actions';\nimport { getStorageConfig } from '../storages';\nimport * as Rules from '../rules';\nimport { FILE_FIELD_NAME, LIMIT_FILES, LIMIT_MAX_FILE_SIZE } from '../constants';\n\nfunction getRules(ctx: Context) {\n const { resourceField } = ctx.action.params;\n if (!resourceField) {\n return ctx.storage.rules;\n }\n const { rules = {} } = resourceField.getOptions().attachment || {};\n return Object.assign({}, ctx.storage.rules, rules);\n}\n\n// TODO(optimize): 需要优化错误处理,计算失败后需要抛出对应错误,以便程序处理\nfunction getFileFilter(ctx: Context) {\n return (req, file, cb) => {\n // size 交给 limits 处理\n const { size, ...rules } = getRules(ctx);\n const ruleKeys = Object.keys(rules);\n const result = !ruleKeys.length || !ruleKeys\n .some(key => typeof Rules[key] !== 'function'\n || !Rules[key](file, rules[key], ctx));\n cb(null, result);\n }\n}\n\nexport async function middleware(ctx: Context, next: Next) {\n const { resourceName, actionName, resourceField } = ctx.action.params;\n if (actionName !== 'upload') {\n return next();\n }\n\n // NOTE:\n // 1. 存储引擎选择依赖于字段定义\n // 2. 字段定义中需包含引擎的外键值\n // 3. 无字段时按 storages 表的默认项\n // 4. 插件初始化后应提示用户添加至少一个存储引擎并设为默认\n\n const StorageModel = ctx.db.getModel('storages');\n let storage;\n\n if (resourceName === 'attachments') {\n // 如果没有包含关联,则直接按默认文件上传至默认存储引擎\n storage = await StorageModel.findOne({ where: { default: true } });\n } else {\n const { attachment = {} } = resourceField.getOptions();\n storage = await StorageModel.findOne({\n where: attachment.storage\n ? { name: attachment.storage }\n : { default: true }\n });\n }\n\n if (!storage) {\n console.error('[file-manager] no default or linked storage provided');\n return ctx.throw(500);\n }\n // 传递已取得的存储引擎,避免重查\n ctx.storage = storage;\n\n const storageConfig = getStorageConfig(storage.type);\n if (!storageConfig) {\n console.error(`[file-manager] storage type \"${storage.type}\" is not defined`);\n return ctx.throw(500);\n }\n const multerOptions = {\n fileFilter: getFileFilter(ctx),\n limits: {\n fileSize: Math.min(getRules(ctx).size || LIMIT_MAX_FILE_SIZE, LIMIT_MAX_FILE_SIZE),\n // 每次只允许提交一个文件\n files: LIMIT_FILES\n },\n storage: storageConfig.make(storage),\n };\n const upload = multer(multerOptions).single(FILE_FIELD_NAME);\n return upload(ctx, next);\n};\n\nexport async function action(ctx: Context, next: Next) {\n const { [FILE_FIELD_NAME]: file, storage } = ctx;\n if (!file) {\n return ctx.throw(400, 'file validation failed');\n }\n\n const storageConfig = getStorageConfig(storage.type);\n const { [storageConfig.filenameKey || 'filename']: name } = file;\n // make compatible filename across cloud service (with path)\n const filename = path.basename(name);\n const extname = path.extname(filename);\n const urlPath = storage.path\n ? storage.path.replace(/^([^\\/])/, '/$1')\n : '';\n\n const data = {\n title: file.originalname.replace(extname, ''),\n filename,\n extname,\n // TODO(feature): 暂时两者相同,后面 storage.path 模版化以后,这里只是 file 实际的 path\n path: storage.path,\n size: file.size,\n // 直接缓存起来\n url: `${storage.baseUrl}${urlPath}/${filename}`,\n mimetype: file.mimetype,\n // @ts-ignore\n meta: ctx.request.body,\n ...(storageConfig.getFileData ? storageConfig.getFileData(file) : {})\n };\n \n const attachment = await ctx.db.sequelize.transaction(async transaction => {\n // TODO(optimize): 应使用关联 accessors 获取\n const result = await storage.createAttachment(data, { transaction });\n \n const { associatedName, associatedIndex, resourceField } = ctx.action.params;\n if (associatedIndex && resourceField) {\n const Attachment = ctx.db.getModel('attachments');\n const SourceModel = ctx.db.getModel(associatedName);\n const source = await SourceModel.findByPk(associatedIndex, { transaction });\n await source[resourceField.getAccessors().set](result[Attachment.primaryKeyAttribute], { transaction });\n }\n\n return result;\n });\n\n // 将存储引擎的信息附在已创建的记录里,节省一次查询\n // attachment.setDataValue('storage', storage);\n ctx.body = attachment;\n\n await next();\n};\n"]}
|
package/lib/constants.d.ts
CHANGED
package/lib/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,SAAS,CAAC;AACtC,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,mBAAmB,QAAqB,CAAC;AAEtD,eAAO,MAAM,kBAAkB,UAAU,CAAC;AAC1C,eAAO,MAAM,oBAAoB,YAAY,CAAC","file":"constants.d.ts","sourcesContent":["export const FILE_FIELD_NAME = 'file';\nexport const LIMIT_FILES = 1;\nexport const LIMIT_MAX_FILE_SIZE = 1024 * 1024 * 1024;\n\nexport const STORAGE_TYPE_LOCAL = 'local';\nexport const STORAGE_TYPE_ALI_OSS = 'ali-oss';\n"]}
|
|
1
|
+
{"version":3,"sources":["constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,SAAS,CAAC;AACtC,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,mBAAmB,QAAqB,CAAC;AAEtD,eAAO,MAAM,kBAAkB,UAAU,CAAC;AAC1C,eAAO,MAAM,oBAAoB,YAAY,CAAC;AAC9C,eAAO,MAAM,eAAe,OAAO,CAAC","file":"constants.d.ts","sourcesContent":["export const FILE_FIELD_NAME = 'file';\nexport const LIMIT_FILES = 1;\nexport const LIMIT_MAX_FILE_SIZE = 1024 * 1024 * 1024;\n\nexport const STORAGE_TYPE_LOCAL = 'local';\nexport const STORAGE_TYPE_ALI_OSS = 'ali-oss';\nexport const STORAGE_TYPE_S3 = 's3';\n"]}
|
package/lib/constants.js
CHANGED
|
@@ -15,10 +15,11 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
15
15
|
Object.defineProperty(exports, "__esModule", {
|
|
16
16
|
value: true
|
|
17
17
|
});
|
|
18
|
-
exports.STORAGE_TYPE_ALI_OSS = exports.STORAGE_TYPE_LOCAL = exports.LIMIT_MAX_FILE_SIZE = exports.LIMIT_FILES = exports.FILE_FIELD_NAME = void 0;
|
|
18
|
+
exports.STORAGE_TYPE_S3 = exports.STORAGE_TYPE_ALI_OSS = exports.STORAGE_TYPE_LOCAL = exports.LIMIT_MAX_FILE_SIZE = exports.LIMIT_FILES = exports.FILE_FIELD_NAME = void 0;
|
|
19
19
|
exports.FILE_FIELD_NAME = 'file';
|
|
20
20
|
exports.LIMIT_FILES = 1;
|
|
21
21
|
exports.LIMIT_MAX_FILE_SIZE = 1024 * 1024 * 1024;
|
|
22
22
|
exports.STORAGE_TYPE_LOCAL = 'local';
|
|
23
23
|
exports.STORAGE_TYPE_ALI_OSS = 'ali-oss';
|
|
24
|
+
exports.STORAGE_TYPE_S3 = 's3';
|
|
24
25
|
//# sourceMappingURL=constants.js.map
|
package/lib/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,eAAe,GAAG,MAAM,CAAC;AACzB,QAAA,WAAW,GAAG,CAAC,CAAC;AAChB,QAAA,mBAAmB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEzC,QAAA,kBAAkB,GAAG,OAAO,CAAC;AAC7B,QAAA,oBAAoB,GAAG,SAAS,CAAC","file":"constants.js","sourcesContent":["export const FILE_FIELD_NAME = 'file';\nexport const LIMIT_FILES = 1;\nexport const LIMIT_MAX_FILE_SIZE = 1024 * 1024 * 1024;\n\nexport const STORAGE_TYPE_LOCAL = 'local';\nexport const STORAGE_TYPE_ALI_OSS = 'ali-oss';\n"]}
|
|
1
|
+
{"version":3,"sources":["constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,eAAe,GAAG,MAAM,CAAC;AACzB,QAAA,WAAW,GAAG,CAAC,CAAC;AAChB,QAAA,mBAAmB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEzC,QAAA,kBAAkB,GAAG,OAAO,CAAC;AAC7B,QAAA,oBAAoB,GAAG,SAAS,CAAC;AACjC,QAAA,eAAe,GAAG,IAAI,CAAC","file":"constants.js","sourcesContent":["export const FILE_FIELD_NAME = 'file';\nexport const LIMIT_FILES = 1;\nexport const LIMIT_MAX_FILE_SIZE = 1024 * 1024 * 1024;\n\nexport const STORAGE_TYPE_LOCAL = 'local';\nexport const STORAGE_TYPE_ALI_OSS = 'ali-oss';\nexport const STORAGE_TYPE_S3 = 's3';\n"]}
|
package/lib/index.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
export * from './constants';
|
|
2
|
+
export { default } from './server';
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["index.ts"],"names":[],"mappings":"","file":"index.d.ts","sourcesContent":[""]}
|
|
1
|
+
{"version":3,"sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC","file":"index.d.ts","sourcesContent":["export * from './constants';\nexport { default } from './server';\n"]}
|
package/lib/index.js
CHANGED
|
@@ -11,4 +11,43 @@ function _react() {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
14
|
+
|
|
15
|
+
var __createBinding = void 0 && (void 0).__createBinding || (Object.create ? function (o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
Object.defineProperty(o, k2, {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
get: function get() {
|
|
20
|
+
return m[k];
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
} : function (o, m, k, k2) {
|
|
24
|
+
if (k2 === undefined) k2 = k;
|
|
25
|
+
o[k2] = m[k];
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
var __exportStar = void 0 && (void 0).__exportStar || function (m, exports) {
|
|
29
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
var __importDefault = void 0 && (void 0).__importDefault || function (mod) {
|
|
33
|
+
return mod && mod.__esModule ? mod : {
|
|
34
|
+
"default": mod
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
Object.defineProperty(exports, "__esModule", {
|
|
39
|
+
value: true
|
|
40
|
+
});
|
|
41
|
+
exports.default = void 0;
|
|
42
|
+
|
|
43
|
+
__exportStar(require("./constants"), exports);
|
|
44
|
+
|
|
45
|
+
var server_1 = require("./server");
|
|
46
|
+
|
|
47
|
+
Object.defineProperty(exports, "default", {
|
|
48
|
+
enumerable: true,
|
|
49
|
+
get: function get() {
|
|
50
|
+
return __importDefault(server_1).default;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
14
53
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["index.ts"],"names":[],"mappings":"","file":"index.js","sourcesContent":[""]}
|
|
1
|
+
{"version":3,"sources":["index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B;AAC5B,mCAAmC;AAA1B,kHAAA,OAAO,OAAA","file":"index.js","sourcesContent":["export * from './constants';\nexport { default } from './server';\n"]}
|
package/lib/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["server.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,
|
|
1
|
+
{"version":3,"sources":["server.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;;AASjD,wBAkCmB","file":"server.d.ts","sourcesContent":["import path from 'path';\nimport Database from '@nocobase/database';\nimport Resourcer from '@nocobase/resourcer';\nimport { PluginOptions } from '@nocobase/server';\n\nimport {\n action as uploadAction,\n middleware as uploadMiddleware,\n} from './actions/upload';\nimport { getStorageConfig } from './storages';\nimport { STORAGE_TYPE_LOCAL } from './constants';\n\nexport default {\n name: 'file-manager',\n async load() {\n const database: Database = this.app.db;\n const resourcer: Resourcer = this.app.resourcer;\n \n database.import({\n directory: path.resolve(__dirname, 'collections'),\n });\n \n // 暂时中间件只能通过 use 加进来\n resourcer.use(uploadMiddleware);\n resourcer.registerActionHandler('upload', uploadAction);\n\n const { DEFAULT_STORAGE_TYPE } = process.env;\n\n if (process.env.NOCOBASE_ENV !== 'production') {\n this.app.on('beforeStart', async () => {\n await getStorageConfig(STORAGE_TYPE_LOCAL).middleware(this.app);\n });\n }\n\n this.app.on('db.init', async () => {\n const defaultStorageConfig = getStorageConfig(DEFAULT_STORAGE_TYPE);\n if (defaultStorageConfig) {\n const StorageModel = database.getModel('storages');\n await StorageModel.create({\n ...defaultStorageConfig.defaults(),\n type: DEFAULT_STORAGE_TYPE,\n default: true\n });\n }\n });\n },\n} as PluginOptions;\n"]}
|
package/lib/server.js
CHANGED
|
@@ -58,7 +58,9 @@ const path_1 = __importDefault(require("path"));
|
|
|
58
58
|
|
|
59
59
|
const upload_1 = require("./actions/upload");
|
|
60
60
|
|
|
61
|
-
const
|
|
61
|
+
const storages_1 = require("./storages");
|
|
62
|
+
|
|
63
|
+
const constants_1 = require("./constants");
|
|
62
64
|
|
|
63
65
|
exports.default = {
|
|
64
66
|
name: 'file-manager',
|
|
@@ -72,28 +74,24 @@ exports.default = {
|
|
|
72
74
|
});
|
|
73
75
|
resourcer.use(upload_1.middleware);
|
|
74
76
|
resourcer.registerActionHandler('upload', upload_1.action);
|
|
75
|
-
|
|
76
|
-
|
|
77
|
+
const DEFAULT_STORAGE_TYPE = process.env.DEFAULT_STORAGE_TYPE;
|
|
78
|
+
|
|
79
|
+
if (process.env.NOCOBASE_ENV !== 'production') {
|
|
80
|
+
this.app.on('beforeStart', () => __awaiter(this, void 0, void 0, function* () {
|
|
81
|
+
yield (0, storages_1.getStorageConfig)(constants_1.STORAGE_TYPE_LOCAL).middleware(this.app);
|
|
82
|
+
}));
|
|
83
|
+
}
|
|
84
|
+
|
|
77
85
|
this.app.on('db.init', () => __awaiter(this, void 0, void 0, function* () {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
type: 'ali-oss',
|
|
88
|
-
baseUrl: process.env.ALI_OSS_STORAGE_BASE_URL,
|
|
89
|
-
options: {
|
|
90
|
-
region: process.env.ALI_OSS_REGION,
|
|
91
|
-
accessKeyId: process.env.ALI_OSS_ACCESS_KEY_ID,
|
|
92
|
-
accessKeySecret: process.env.ALI_OSS_ACCESS_KEY_SECRET,
|
|
93
|
-
bucket: process.env.ALI_OSS_BUCKET
|
|
94
|
-
},
|
|
95
|
-
default: process.env.STORAGE_TYPE === 'ali-oss'
|
|
96
|
-
});
|
|
86
|
+
const defaultStorageConfig = (0, storages_1.getStorageConfig)(DEFAULT_STORAGE_TYPE);
|
|
87
|
+
|
|
88
|
+
if (defaultStorageConfig) {
|
|
89
|
+
const StorageModel = database.getModel('storages');
|
|
90
|
+
yield StorageModel.create(Object.assign(Object.assign({}, defaultStorageConfig.defaults()), {
|
|
91
|
+
type: DEFAULT_STORAGE_TYPE,
|
|
92
|
+
default: true
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
97
95
|
}));
|
|
98
96
|
});
|
|
99
97
|
}
|
package/lib/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["server.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,gDAAwB;AAKxB,6CAG0B;AAC1B,
|
|
1
|
+
{"version":3,"sources":["server.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,gDAAwB;AAKxB,6CAG0B;AAC1B,yCAA8C;AAC9C,2CAAiD;AAEjD,kBAAe;IACb,IAAI,EAAE,cAAc;IACd,IAAI;;YACR,MAAM,QAAQ,GAAa,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACvC,MAAM,SAAS,GAAc,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC;YAEhD,QAAQ,CAAC,MAAM,CAAC;gBACd,SAAS,EAAE,cAAI,CAAC,OAAO,CAAC,SAAS,EAAE,aAAa,CAAC;aAClD,CAAC,CAAC;YAGH,SAAS,CAAC,GAAG,CAAC,mBAAgB,CAAC,CAAC;YAChC,SAAS,CAAC,qBAAqB,CAAC,QAAQ,EAAE,eAAY,CAAC,CAAC;YAExD,MAAM,EAAE,oBAAoB,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;YAE7C,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,YAAY,EAAE;gBAC7C,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,aAAa,EAAE,GAAS,EAAE;oBACpC,MAAM,IAAA,2BAAgB,EAAC,8BAAkB,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAClE,CAAC,CAAA,CAAC,CAAC;aACJ;YAED,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,GAAS,EAAE;gBAChC,MAAM,oBAAoB,GAAG,IAAA,2BAAgB,EAAC,oBAAoB,CAAC,CAAC;gBACpE,IAAI,oBAAoB,EAAE;oBACxB,MAAM,YAAY,GAAG,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;oBACnD,MAAM,YAAY,CAAC,MAAM,iCACpB,oBAAoB,CAAC,QAAQ,EAAE,KAClC,IAAI,EAAE,oBAAoB,EAC1B,OAAO,EAAE,IAAI,IACb,CAAC;iBACJ;YACH,CAAC,CAAA,CAAC,CAAC;QACL,CAAC;KAAA;CACe,CAAC","file":"server.js","sourcesContent":["import path from 'path';\nimport Database from '@nocobase/database';\nimport Resourcer from '@nocobase/resourcer';\nimport { PluginOptions } from '@nocobase/server';\n\nimport {\n action as uploadAction,\n middleware as uploadMiddleware,\n} from './actions/upload';\nimport { getStorageConfig } from './storages';\nimport { STORAGE_TYPE_LOCAL } from './constants';\n\nexport default {\n name: 'file-manager',\n async load() {\n const database: Database = this.app.db;\n const resourcer: Resourcer = this.app.resourcer;\n \n database.import({\n directory: path.resolve(__dirname, 'collections'),\n });\n \n // 暂时中间件只能通过 use 加进来\n resourcer.use(uploadMiddleware);\n resourcer.registerActionHandler('upload', uploadAction);\n\n const { DEFAULT_STORAGE_TYPE } = process.env;\n\n if (process.env.NOCOBASE_ENV !== 'production') {\n this.app.on('beforeStart', async () => {\n await getStorageConfig(STORAGE_TYPE_LOCAL).middleware(this.app);\n });\n }\n\n this.app.on('db.init', async () => {\n const defaultStorageConfig = getStorageConfig(DEFAULT_STORAGE_TYPE);\n if (defaultStorageConfig) {\n const StorageModel = database.getModel('storages');\n await StorageModel.create({\n ...defaultStorageConfig.defaults(),\n type: DEFAULT_STORAGE_TYPE,\n default: true\n });\n }\n });\n },\n} as PluginOptions;\n"]}
|
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
declare const _default: {
|
|
2
|
+
make(storage: any): any;
|
|
3
|
+
defaults(): {
|
|
4
|
+
title: string;
|
|
5
|
+
type: string;
|
|
6
|
+
name: string;
|
|
7
|
+
baseUrl: string;
|
|
8
|
+
options: {
|
|
9
|
+
region: string;
|
|
10
|
+
accessKeyId: string;
|
|
11
|
+
accessKeySecret: string;
|
|
12
|
+
bucket: string;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
};
|
|
9
16
|
export default _default;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["storages/ali-oss.ts"],"names":[],"mappings":"AAGA,
|
|
1
|
+
{"version":3,"sources":["storages/ali-oss.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAGA,wBAsBC","file":"ali-oss.d.ts","sourcesContent":["import { STORAGE_TYPE_ALI_OSS } from '../constants';\nimport { cloudFilenameGetter } from '../utils';\n\nexport default {\n make(storage) {\n const createAliOssStorage = require('multer-aliyun-oss');\n return new createAliOssStorage({\n config: storage.options,\n filename: cloudFilenameGetter(storage)\n });\n },\n defaults() {\n return {\n title: '阿里云对象存储',\n type: STORAGE_TYPE_ALI_OSS,\n name: 'ali-oss-1',\n baseUrl: process.env.ALI_OSS_STORAGE_BASE_URL,\n options: {\n region: process.env.ALI_OSS_REGION,\n accessKeyId: process.env.ALI_OSS_ACCESS_KEY_ID,\n accessKeySecret: process.env.ALI_OSS_ACCESS_KEY_SECRET,\n bucket: process.env.ALI_OSS_BUCKET,\n }\n }\n }\n}\n"]}
|
package/lib/storages/ali-oss.js
CHANGED
|
@@ -12,60 +12,38 @@ function _react() {
|
|
|
12
12
|
|
|
13
13
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
14
14
|
|
|
15
|
-
var __importDefault = void 0 && (void 0).__importDefault || function (mod) {
|
|
16
|
-
return mod && mod.__esModule ? mod : {
|
|
17
|
-
"default": mod
|
|
18
|
-
};
|
|
19
|
-
};
|
|
20
|
-
|
|
21
15
|
Object.defineProperty(exports, "__esModule", {
|
|
22
16
|
value: true
|
|
23
17
|
});
|
|
24
|
-
exports.AliOssStorage = void 0;
|
|
25
18
|
|
|
26
|
-
const
|
|
19
|
+
const constants_1 = require("../constants");
|
|
27
20
|
|
|
28
21
|
const utils_1 = require("../utils");
|
|
29
22
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
this.getFilename = opts.filename || utils_1.getFilename;
|
|
34
|
-
}
|
|
23
|
+
exports.default = {
|
|
24
|
+
make(storage) {
|
|
25
|
+
const createAliOssStorage = require('multer-aliyun-oss');
|
|
35
26
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
return cb({
|
|
40
|
-
message: 'oss client undefined'
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
this.getFilename(req, file, (err, filename) => {
|
|
45
|
-
if (err) return cb(err);
|
|
46
|
-
this.client.putStream(filename, file.stream).then(result => cb(null, {
|
|
47
|
-
filename: result.name,
|
|
48
|
-
url: result.url
|
|
49
|
-
})).catch(cb);
|
|
27
|
+
return new createAliOssStorage({
|
|
28
|
+
config: storage.options,
|
|
29
|
+
filename: (0, utils_1.cloudFilenameGetter)(storage)
|
|
50
30
|
});
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
defaults() {
|
|
34
|
+
return {
|
|
35
|
+
title: '阿里云对象存储',
|
|
36
|
+
type: constants_1.STORAGE_TYPE_ALI_OSS,
|
|
37
|
+
name: 'ali-oss-1',
|
|
38
|
+
baseUrl: process.env.ALI_OSS_STORAGE_BASE_URL,
|
|
39
|
+
options: {
|
|
40
|
+
region: process.env.ALI_OSS_REGION,
|
|
41
|
+
accessKeyId: process.env.ALI_OSS_ACCESS_KEY_ID,
|
|
42
|
+
accessKeySecret: process.env.ALI_OSS_ACCESS_KEY_SECRET,
|
|
43
|
+
bucket: process.env.ALI_OSS_BUCKET
|
|
44
|
+
}
|
|
45
|
+
};
|
|
51
46
|
}
|
|
52
47
|
|
|
53
|
-
|
|
54
|
-
if (!this.client) {
|
|
55
|
-
console.error('oss client undefined');
|
|
56
|
-
return cb({
|
|
57
|
-
message: 'oss client undefined'
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
this.client.delete(file.filename).then(result => cb(null, result)).catch(cb);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
exports.AliOssStorage = AliOssStorage;
|
|
67
|
-
|
|
68
|
-
exports.default = storage => new AliOssStorage({
|
|
69
|
-
config: storage.options
|
|
70
|
-
});
|
|
48
|
+
};
|
|
71
49
|
//# sourceMappingURL=ali-oss.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["storages/ali-oss.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["storages/ali-oss.ts"],"names":[],"mappings":";;AAAA,4CAAoD;AACpD,oCAA+C;AAE/C,kBAAe;IACb,IAAI,CAAC,OAAO;QACV,MAAM,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;QACzD,OAAO,IAAI,mBAAmB,CAAC;YAC7B,MAAM,EAAE,OAAO,CAAC,OAAO;YACvB,QAAQ,EAAE,IAAA,2BAAmB,EAAC,OAAO,CAAC;SACvC,CAAC,CAAC;IACL,CAAC;IACD,QAAQ;QACN,OAAO;YACL,KAAK,EAAE,SAAS;YAChB,IAAI,EAAE,gCAAoB;YAC1B,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,wBAAwB;YAC7C,OAAO,EAAE;gBACP,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc;gBAClC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB;gBAC9C,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,yBAAyB;gBACtD,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc;aACnC;SACF,CAAA;IACH,CAAC;CACF,CAAA","file":"ali-oss.js","sourcesContent":["import { STORAGE_TYPE_ALI_OSS } from '../constants';\nimport { cloudFilenameGetter } from '../utils';\n\nexport default {\n make(storage) {\n const createAliOssStorage = require('multer-aliyun-oss');\n return new createAliOssStorage({\n config: storage.options,\n filename: cloudFilenameGetter(storage)\n });\n },\n defaults() {\n return {\n title: '阿里云对象存储',\n type: STORAGE_TYPE_ALI_OSS,\n name: 'ali-oss-1',\n baseUrl: process.env.ALI_OSS_STORAGE_BASE_URL,\n options: {\n region: process.env.ALI_OSS_REGION,\n accessKeyId: process.env.ALI_OSS_ACCESS_KEY_ID,\n accessKeySecret: process.env.ALI_OSS_ACCESS_KEY_SECRET,\n bucket: process.env.ALI_OSS_BUCKET,\n }\n }\n }\n}\n"]}
|
package/lib/storages/index.d.ts
CHANGED
|
@@ -1,2 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export interface IStorage {
|
|
2
|
+
filenameKey?: string;
|
|
3
|
+
middleware?: Function;
|
|
4
|
+
getFileData?: Function;
|
|
5
|
+
make: Function;
|
|
6
|
+
defaults: Function;
|
|
7
|
+
}
|
|
8
|
+
export declare function getStorageConfig(key: string): IStorage;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["storages/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["storages/index.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,QAAQ;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,QAAQ,CAAC;IACtB,WAAW,CAAC,EAAE,QAAQ,CAAC;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAQD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAEtD","file":"index.d.ts","sourcesContent":["import local from './local';\nimport oss from './ali-oss';\nimport s3 from './s3';\n\nimport {\n STORAGE_TYPE_LOCAL,\n STORAGE_TYPE_ALI_OSS,\n STORAGE_TYPE_S3\n} from '../constants';\n\nexport interface IStorage {\n filenameKey?: string;\n middleware?: Function;\n getFileData?: Function;\n make: Function;\n defaults: Function;\n}\n\nconst map = new Map<string, IStorage>();\nmap.set(STORAGE_TYPE_LOCAL, local);\nmap.set(STORAGE_TYPE_ALI_OSS, oss);\nmap.set(STORAGE_TYPE_S3, s3);\n\n\nexport function getStorageConfig(key: string): IStorage {\n return map.get(key);\n};\n"]}
|
package/lib/storages/index.js
CHANGED
|
@@ -21,15 +21,25 @@ var __importDefault = void 0 && (void 0).__importDefault || function (mod) {
|
|
|
21
21
|
Object.defineProperty(exports, "__esModule", {
|
|
22
22
|
value: true
|
|
23
23
|
});
|
|
24
|
+
exports.getStorageConfig = void 0;
|
|
24
25
|
|
|
25
26
|
const local_1 = __importDefault(require("./local"));
|
|
26
27
|
|
|
27
28
|
const ali_oss_1 = __importDefault(require("./ali-oss"));
|
|
28
29
|
|
|
30
|
+
const s3_1 = __importDefault(require("./s3"));
|
|
31
|
+
|
|
29
32
|
const constants_1 = require("../constants");
|
|
30
33
|
|
|
31
34
|
const map = new Map();
|
|
32
35
|
map.set(constants_1.STORAGE_TYPE_LOCAL, local_1.default);
|
|
33
36
|
map.set(constants_1.STORAGE_TYPE_ALI_OSS, ali_oss_1.default);
|
|
34
|
-
|
|
37
|
+
map.set(constants_1.STORAGE_TYPE_S3, s3_1.default);
|
|
38
|
+
|
|
39
|
+
function getStorageConfig(key) {
|
|
40
|
+
return map.get(key);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
exports.getStorageConfig = getStorageConfig;
|
|
44
|
+
;
|
|
35
45
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["storages/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["storages/index.ts"],"names":[],"mappings":";;;;;;AAAA,oDAA4B;AAC5B,wDAA4B;AAC5B,8CAAsB;AAEtB,4CAIsB;AAUtB,MAAM,GAAG,GAAG,IAAI,GAAG,EAAoB,CAAC;AACxC,GAAG,CAAC,GAAG,CAAC,8BAAkB,EAAE,eAAK,CAAC,CAAC;AACnC,GAAG,CAAC,GAAG,CAAC,gCAAoB,EAAE,iBAAG,CAAC,CAAC;AACnC,GAAG,CAAC,GAAG,CAAC,2BAAe,EAAE,YAAE,CAAC,CAAC;AAG7B,SAAgB,gBAAgB,CAAC,GAAW;IAC1C,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACtB,CAAC;AAFD,4CAEC;AAAA,CAAC","file":"index.js","sourcesContent":["import local from './local';\nimport oss from './ali-oss';\nimport s3 from './s3';\n\nimport {\n STORAGE_TYPE_LOCAL,\n STORAGE_TYPE_ALI_OSS,\n STORAGE_TYPE_S3\n} from '../constants';\n\nexport interface IStorage {\n filenameKey?: string;\n middleware?: Function;\n getFileData?: Function;\n make: Function;\n defaults: Function;\n}\n\nconst map = new Map<string, IStorage>();\nmap.set(STORAGE_TYPE_LOCAL, local);\nmap.set(STORAGE_TYPE_ALI_OSS, oss);\nmap.set(STORAGE_TYPE_S3, s3);\n\n\nexport function getStorageConfig(key: string): IStorage {\n return map.get(key);\n};\n"]}
|
package/lib/storages/local.d.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import multer from 'multer';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
declare function middleware(app: any, options?: any): Promise<void>;
|
|
3
|
+
declare const _default: {
|
|
4
|
+
middleware: typeof middleware;
|
|
5
|
+
make(storage: any): multer.StorageEngine;
|
|
6
|
+
defaults(): {
|
|
7
|
+
title: string;
|
|
8
|
+
type: string;
|
|
9
|
+
name: string;
|
|
10
|
+
baseUrl: string;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
5
13
|
export default _default;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["storages/local.ts"],"names":[],"mappings":"AAGA,OAAO,MAAM,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"sources":["storages/local.ts"],"names":[],"mappings":"AAGA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAoD5B,iBAAe,UAAU,CAAC,GAAG,KAAA,EAAE,OAAO,CAAC,KAAA,iBAmDtC;;;;;;;;;;;AAED,wBAmBE","file":"local.d.ts","sourcesContent":["import path from 'path';\nimport { URL } from 'url';\nimport mkdirp from 'mkdirp';\nimport multer from 'multer';\nimport serve from 'koa-static';\nimport { STORAGE_TYPE_LOCAL } from '../constants';\nimport { getFilename } from '../utils';\n\n// use koa-mount match logic\nfunction match(basePath: string, pathname: string): boolean {\n if (!pathname.startsWith(basePath)) {\n return false;\n }\n\n const newPath = pathname.replace(basePath, '') || '/';\n if (basePath.slice(-1) === '/') {\n return true;\n }\n\n return newPath[0] === '/';\n}\n\nasync function update(app, storages) {\n const StorageModel = app.db.getModel('storages');\n\n const items = await StorageModel.findAll({\n where: {\n type: STORAGE_TYPE_LOCAL,\n }\n });\n\n const primaryKey = StorageModel.primaryKeyAttribute;\n\n storages.clear();\n for (const storage of items) {\n storages.set(storage[primaryKey], storage);\n }\n}\n\nfunction createLocalServerUpdateHook(app, storages) {\n return async function (row) {\n if (row.get('type') === STORAGE_TYPE_LOCAL) {\n await update(app, storages);\n }\n }\n}\n\nfunction getDocumentRoot(storage): string {\n const { documentRoot = 'uploads' } = storage.options || {};\n // TODO(feature): 后面考虑以字符串模板的方式使用,可注入 req/action 相关变量,以便于区分文件夹\n return path.resolve(path.isAbsolute(documentRoot)\n ? documentRoot\n : path.join(process.cwd(), documentRoot));\n}\n\nasync function middleware(app, options?) {\n const LOCALHOST = `http://localhost:${process.env.API_PORT}`;\n\n const StorageModel = app.db.getModel('storages');\n const storages = new Map<string, any>();\n\n const localServerUpdateHook = createLocalServerUpdateHook(app, storages);\n StorageModel.addHook('afterCreate', localServerUpdateHook);\n StorageModel.addHook('afterUpdate', localServerUpdateHook);\n StorageModel.addHook('afterDestroy', localServerUpdateHook);\n\n await update(app, storages);\n\n app.use(async function (ctx, next) {\n for (const storage of storages.values()) {\n const baseUrl = storage.get('baseUrl');\n\n let url;\n try {\n url = new URL(baseUrl);\n } catch (e) {\n url = {\n pathname: baseUrl\n };\n }\n\n // 以下情况才认为当前进程所应该提供静态服务\n // 否则都忽略,交给其他 server 来提供(如 nginx/cdn 等)\n if (url.origin && url.origin !== LOCALHOST) {\n continue;\n }\n\n const basePath = url.pathname.startsWith('/') ? url.pathname : `/${url.pathname}`;\n if (!match(basePath, ctx.path)) {\n continue;\n }\n\n return serve(getDocumentRoot(storage), {\n // for handle files after any api handlers\n defer: true\n })(ctx, async () => {\n if (ctx.path.startsWith(basePath)) {\n ctx.path = ctx.path.replace(basePath, '');\n }\n // console.log('file request:', `${basePath}${ctx.path}`);\n await next();\n });\n }\n\n await next();\n });\n}\n\nexport default {\n middleware,\n make(storage) {\n return multer.diskStorage({\n destination: function (req, file, cb) {\n const destPath = path.join(getDocumentRoot(storage), storage.path);\n mkdirp(destPath, (err: Error | null) => cb(err, destPath));\n },\n filename: getFilename\n });\n },\n defaults() {\n return {\n title: '本地存储',\n type: STORAGE_TYPE_LOCAL,\n name: `local`,\n baseUrl: process.env.LOCAL_STORAGE_BASE_URL || `http://localhost:${process.env.API_PORT}/uploads`\n };\n }\n};\n"]}
|
package/lib/storages/local.js
CHANGED
|
@@ -59,7 +59,6 @@ var __importDefault = void 0 && (void 0).__importDefault || function (mod) {
|
|
|
59
59
|
Object.defineProperty(exports, "__esModule", {
|
|
60
60
|
value: true
|
|
61
61
|
});
|
|
62
|
-
exports.middleware = exports.getDocumentRoot = void 0;
|
|
63
62
|
|
|
64
63
|
const path_1 = __importDefault(require("path"));
|
|
65
64
|
|
|
@@ -71,90 +70,151 @@ const multer_1 = __importDefault(require("multer"));
|
|
|
71
70
|
|
|
72
71
|
const koa_static_1 = __importDefault(require("koa-static"));
|
|
73
72
|
|
|
74
|
-
const koa_mount_1 = __importDefault(require("koa-mount"));
|
|
75
|
-
|
|
76
73
|
const constants_1 = require("../constants");
|
|
77
74
|
|
|
78
75
|
const utils_1 = require("../utils");
|
|
79
76
|
|
|
80
|
-
function
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
77
|
+
function match(basePath, pathname) {
|
|
78
|
+
if (!pathname.startsWith(basePath)) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
84
81
|
|
|
85
|
-
|
|
82
|
+
const newPath = pathname.replace(basePath, '') || '/';
|
|
83
|
+
|
|
84
|
+
if (basePath.slice(-1) === '/') {
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return newPath[0] === '/';
|
|
86
89
|
}
|
|
87
90
|
|
|
88
|
-
|
|
91
|
+
function update(app, storages) {
|
|
92
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
93
|
+
const StorageModel = app.db.getModel('storages');
|
|
94
|
+
const items = yield StorageModel.findAll({
|
|
95
|
+
where: {
|
|
96
|
+
type: constants_1.STORAGE_TYPE_LOCAL
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
const primaryKey = StorageModel.primaryKeyAttribute;
|
|
100
|
+
storages.clear();
|
|
101
|
+
|
|
102
|
+
var _iterator = _createForOfIteratorHelper(items),
|
|
103
|
+
_step;
|
|
89
104
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
105
|
+
try {
|
|
106
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
107
|
+
const storage = _step.value;
|
|
108
|
+
storages.set(storage[primaryKey], storage);
|
|
109
|
+
}
|
|
110
|
+
} catch (err) {
|
|
111
|
+
_iterator.e(err);
|
|
112
|
+
} finally {
|
|
113
|
+
_iterator.f();
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
94
117
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
return app.use(function (ctx, next) {
|
|
118
|
+
function createLocalServerUpdateHook(app, storages) {
|
|
119
|
+
return function (row) {
|
|
98
120
|
return __awaiter(this, void 0, void 0, function* () {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
var _iterator = _createForOfIteratorHelper(items),
|
|
107
|
-
_step;
|
|
121
|
+
if (row.get('type') === constants_1.STORAGE_TYPE_LOCAL) {
|
|
122
|
+
yield update(app, storages);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
};
|
|
126
|
+
}
|
|
108
127
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
128
|
+
function getDocumentRoot(storage) {
|
|
129
|
+
const _ref = storage.options || {},
|
|
130
|
+
_ref$documentRoot = _ref.documentRoot,
|
|
131
|
+
documentRoot = _ref$documentRoot === void 0 ? 'uploads' : _ref$documentRoot;
|
|
112
132
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}
|
|
133
|
+
return path_1.default.resolve(path_1.default.isAbsolute(documentRoot) ? documentRoot : path_1.default.join(process.cwd(), documentRoot));
|
|
134
|
+
}
|
|
116
135
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
136
|
+
function middleware(app, options) {
|
|
137
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
138
|
+
const LOCALHOST = `http://localhost:${process.env.API_PORT}`;
|
|
139
|
+
const StorageModel = app.db.getModel('storages');
|
|
140
|
+
const storages = new Map();
|
|
141
|
+
const localServerUpdateHook = createLocalServerUpdateHook(app, storages);
|
|
142
|
+
StorageModel.addHook('afterCreate', localServerUpdateHook);
|
|
143
|
+
StorageModel.addHook('afterUpdate', localServerUpdateHook);
|
|
144
|
+
StorageModel.addHook('afterDestroy', localServerUpdateHook);
|
|
145
|
+
yield update(app, storages);
|
|
146
|
+
app.use(function (ctx, next) {
|
|
147
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
148
|
+
var _iterator2 = _createForOfIteratorHelper(storages.values()),
|
|
149
|
+
_step2;
|
|
150
|
+
|
|
151
|
+
try {
|
|
152
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
153
|
+
const storage = _step2.value;
|
|
154
|
+
const baseUrl = storage.get('baseUrl');
|
|
155
|
+
let url;
|
|
156
|
+
|
|
157
|
+
try {
|
|
158
|
+
url = new url_1.URL(baseUrl);
|
|
159
|
+
} catch (e) {
|
|
160
|
+
url = {
|
|
161
|
+
pathname: baseUrl
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (url.origin && url.origin !== LOCALHOST) {
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
130
168
|
|
|
131
|
-
if (process.env.LOCAL_STORAGE_USE_STATIC_SERVER) {
|
|
132
169
|
const basePath = url.pathname.startsWith('/') ? url.pathname : `/${url.pathname}`;
|
|
133
|
-
app.use((0, koa_mount_1.default)(basePath, (0, koa_static_1.default)(getDocumentRoot(storage))));
|
|
134
|
-
}
|
|
135
170
|
|
|
136
|
-
|
|
171
|
+
if (!match(basePath, ctx.path)) {
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return (0, koa_static_1.default)(getDocumentRoot(storage), {
|
|
176
|
+
defer: true
|
|
177
|
+
})(ctx, () => __awaiter(this, void 0, void 0, function* () {
|
|
178
|
+
if (ctx.path.startsWith(basePath)) {
|
|
179
|
+
ctx.path = ctx.path.replace(basePath, '');
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
yield next();
|
|
183
|
+
}));
|
|
184
|
+
}
|
|
185
|
+
} catch (err) {
|
|
186
|
+
_iterator2.e(err);
|
|
187
|
+
} finally {
|
|
188
|
+
_iterator2.f();
|
|
137
189
|
}
|
|
138
|
-
} catch (err) {
|
|
139
|
-
_iterator.e(err);
|
|
140
|
-
} finally {
|
|
141
|
-
_iterator.f();
|
|
142
|
-
}
|
|
143
190
|
|
|
144
|
-
|
|
191
|
+
yield next();
|
|
192
|
+
});
|
|
145
193
|
});
|
|
146
194
|
});
|
|
147
195
|
}
|
|
148
196
|
|
|
149
|
-
exports.
|
|
197
|
+
exports.default = {
|
|
198
|
+
middleware,
|
|
150
199
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
200
|
+
make(storage) {
|
|
201
|
+
return multer_1.default.diskStorage({
|
|
202
|
+
destination: function destination(req, file, cb) {
|
|
203
|
+
const destPath = path_1.default.join(getDocumentRoot(storage), storage.path);
|
|
204
|
+
(0, mkdirp_1.default)(destPath, err => cb(err, destPath));
|
|
205
|
+
},
|
|
206
|
+
filename: utils_1.getFilename
|
|
207
|
+
});
|
|
157
208
|
},
|
|
158
|
-
|
|
159
|
-
|
|
209
|
+
|
|
210
|
+
defaults() {
|
|
211
|
+
return {
|
|
212
|
+
title: '本地存储',
|
|
213
|
+
type: constants_1.STORAGE_TYPE_LOCAL,
|
|
214
|
+
name: `local`,
|
|
215
|
+
baseUrl: process.env.LOCAL_STORAGE_BASE_URL || `http://localhost:${process.env.API_PORT}/uploads`
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
};
|
|
160
220
|
//# sourceMappingURL=local.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["storages/local.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["storages/local.ts"],"names":[],"mappings":"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","file":"local.js","sourcesContent":["import path from 'path';\nimport { URL } from 'url';\nimport mkdirp from 'mkdirp';\nimport multer from 'multer';\nimport serve from 'koa-static';\nimport { STORAGE_TYPE_LOCAL } from '../constants';\nimport { getFilename } from '../utils';\n\n// use koa-mount match logic\nfunction match(basePath: string, pathname: string): boolean {\n if (!pathname.startsWith(basePath)) {\n return false;\n }\n\n const newPath = pathname.replace(basePath, '') || '/';\n if (basePath.slice(-1) === '/') {\n return true;\n }\n\n return newPath[0] === '/';\n}\n\nasync function update(app, storages) {\n const StorageModel = app.db.getModel('storages');\n\n const items = await StorageModel.findAll({\n where: {\n type: STORAGE_TYPE_LOCAL,\n }\n });\n\n const primaryKey = StorageModel.primaryKeyAttribute;\n\n storages.clear();\n for (const storage of items) {\n storages.set(storage[primaryKey], storage);\n }\n}\n\nfunction createLocalServerUpdateHook(app, storages) {\n return async function (row) {\n if (row.get('type') === STORAGE_TYPE_LOCAL) {\n await update(app, storages);\n }\n }\n}\n\nfunction getDocumentRoot(storage): string {\n const { documentRoot = 'uploads' } = storage.options || {};\n // TODO(feature): 后面考虑以字符串模板的方式使用,可注入 req/action 相关变量,以便于区分文件夹\n return path.resolve(path.isAbsolute(documentRoot)\n ? documentRoot\n : path.join(process.cwd(), documentRoot));\n}\n\nasync function middleware(app, options?) {\n const LOCALHOST = `http://localhost:${process.env.API_PORT}`;\n\n const StorageModel = app.db.getModel('storages');\n const storages = new Map<string, any>();\n\n const localServerUpdateHook = createLocalServerUpdateHook(app, storages);\n StorageModel.addHook('afterCreate', localServerUpdateHook);\n StorageModel.addHook('afterUpdate', localServerUpdateHook);\n StorageModel.addHook('afterDestroy', localServerUpdateHook);\n\n await update(app, storages);\n\n app.use(async function (ctx, next) {\n for (const storage of storages.values()) {\n const baseUrl = storage.get('baseUrl');\n\n let url;\n try {\n url = new URL(baseUrl);\n } catch (e) {\n url = {\n pathname: baseUrl\n };\n }\n\n // 以下情况才认为当前进程所应该提供静态服务\n // 否则都忽略,交给其他 server 来提供(如 nginx/cdn 等)\n if (url.origin && url.origin !== LOCALHOST) {\n continue;\n }\n\n const basePath = url.pathname.startsWith('/') ? url.pathname : `/${url.pathname}`;\n if (!match(basePath, ctx.path)) {\n continue;\n }\n\n return serve(getDocumentRoot(storage), {\n // for handle files after any api handlers\n defer: true\n })(ctx, async () => {\n if (ctx.path.startsWith(basePath)) {\n ctx.path = ctx.path.replace(basePath, '');\n }\n // console.log('file request:', `${basePath}${ctx.path}`);\n await next();\n });\n }\n\n await next();\n });\n}\n\nexport default {\n middleware,\n make(storage) {\n return multer.diskStorage({\n destination: function (req, file, cb) {\n const destPath = path.join(getDocumentRoot(storage), storage.path);\n mkdirp(destPath, (err: Error | null) => cb(err, destPath));\n },\n filename: getFilename\n });\n },\n defaults() {\n return {\n title: '本地存储',\n type: STORAGE_TYPE_LOCAL,\n name: `local`,\n baseUrl: process.env.LOCAL_STORAGE_BASE_URL || `http://localhost:${process.env.API_PORT}/uploads`\n };\n }\n};\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
filenameKey: string;
|
|
3
|
+
make(storage: any): any;
|
|
4
|
+
defaults(): {
|
|
5
|
+
title: string;
|
|
6
|
+
name: string;
|
|
7
|
+
type: string;
|
|
8
|
+
baseUrl: string;
|
|
9
|
+
options: {
|
|
10
|
+
region: string;
|
|
11
|
+
accessKeyId: string;
|
|
12
|
+
secretAccessKey: string;
|
|
13
|
+
bucket: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
export default _default;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["storages/s3.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAGA,wBAiDC","file":"s3.d.ts","sourcesContent":["import { STORAGE_TYPE_S3 } from '../constants';\nimport { cloudFilenameGetter } from '../utils';\n\nexport default {\n filenameKey: 'key',\n make(storage) {\n const S3Client = require('aws-sdk/clients/s3');\n const multerS3 = require('multer-s3');\n const {\n accessKeyId,\n secretAccessKey,\n bucket,\n acl = 'public-read',\n ...options\n } = storage.options;\n const s3 = new S3Client({\n ...options,\n credentials: {\n accessKeyId,\n secretAccessKey\n }\n });\n\n return multerS3({\n s3,\n bucket,\n acl,\n contentType(req, file, cb) {\n if (file.mimetype) {\n cb(null, file.mimetype);\n return;\n }\n \n multerS3.AUTO_CONTENT_TYPE(req, file, cb);\n },\n key: cloudFilenameGetter(storage)\n });\n },\n defaults() {\n return {\n title: 'AWS S3',\n name: 'aws-s3',\n type: STORAGE_TYPE_S3,\n baseUrl: process.env.AWS_S3_STORAGE_BASE_URL,\n options: {\n region: process.env.AWS_S3_REGION,\n accessKeyId: process.env.AWS_ACCESS_KEY_ID,\n secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,\n bucket: process.env.AWS_S3_BUCKET,\n }\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
function _react() {
|
|
4
|
+
const data = _interopRequireDefault(require("react"));
|
|
5
|
+
|
|
6
|
+
_react = function _react() {
|
|
7
|
+
return data;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
return data;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
14
|
+
|
|
15
|
+
var __rest = void 0 && (void 0).__rest || function (s, e) {
|
|
16
|
+
var t = {};
|
|
17
|
+
|
|
18
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
|
|
19
|
+
|
|
20
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
21
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
|
|
22
|
+
}
|
|
23
|
+
return t;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
Object.defineProperty(exports, "__esModule", {
|
|
27
|
+
value: true
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const constants_1 = require("../constants");
|
|
31
|
+
|
|
32
|
+
const utils_1 = require("../utils");
|
|
33
|
+
|
|
34
|
+
exports.default = {
|
|
35
|
+
filenameKey: 'key',
|
|
36
|
+
|
|
37
|
+
make(storage) {
|
|
38
|
+
const S3Client = require('aws-sdk/clients/s3');
|
|
39
|
+
|
|
40
|
+
const multerS3 = require('multer-s3');
|
|
41
|
+
|
|
42
|
+
const _a = storage.options,
|
|
43
|
+
accessKeyId = _a.accessKeyId,
|
|
44
|
+
secretAccessKey = _a.secretAccessKey,
|
|
45
|
+
bucket = _a.bucket,
|
|
46
|
+
_a$acl = _a.acl,
|
|
47
|
+
acl = _a$acl === void 0 ? 'public-read' : _a$acl,
|
|
48
|
+
options = __rest(_a, ["accessKeyId", "secretAccessKey", "bucket", "acl"]);
|
|
49
|
+
|
|
50
|
+
const s3 = new S3Client(Object.assign(Object.assign({}, options), {
|
|
51
|
+
credentials: {
|
|
52
|
+
accessKeyId,
|
|
53
|
+
secretAccessKey
|
|
54
|
+
}
|
|
55
|
+
}));
|
|
56
|
+
return multerS3({
|
|
57
|
+
s3,
|
|
58
|
+
bucket,
|
|
59
|
+
acl,
|
|
60
|
+
|
|
61
|
+
contentType(req, file, cb) {
|
|
62
|
+
if (file.mimetype) {
|
|
63
|
+
cb(null, file.mimetype);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
multerS3.AUTO_CONTENT_TYPE(req, file, cb);
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
key: (0, utils_1.cloudFilenameGetter)(storage)
|
|
71
|
+
});
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
defaults() {
|
|
75
|
+
return {
|
|
76
|
+
title: 'AWS S3',
|
|
77
|
+
name: 'aws-s3',
|
|
78
|
+
type: constants_1.STORAGE_TYPE_S3,
|
|
79
|
+
baseUrl: process.env.AWS_S3_STORAGE_BASE_URL,
|
|
80
|
+
options: {
|
|
81
|
+
region: process.env.AWS_S3_REGION,
|
|
82
|
+
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
|
83
|
+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
|
|
84
|
+
bucket: process.env.AWS_S3_BUCKET
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
};
|
|
90
|
+
//# sourceMappingURL=s3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["storages/s3.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,4CAA+C;AAC/C,oCAA+C;AAE/C,kBAAe;IACb,WAAW,EAAE,KAAK;IAClB,IAAI,CAAC,OAAO;QACV,MAAM,QAAQ,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;QACtC,MAAM,KAMF,OAAO,CAAC,OAAO,EANb,EACJ,WAAW,EACX,eAAe,EACf,MAAM,EACN,GAAG,GAAG,aAAa,OAEF,EADd,OAAO,cALN,mDAML,CAAkB,CAAC;QACpB,MAAM,EAAE,GAAG,IAAI,QAAQ,iCAClB,OAAO,KACV,WAAW,EAAE;gBACX,WAAW;gBACX,eAAe;aAChB,IACD,CAAC;QAEH,OAAO,QAAQ,CAAC;YACd,EAAE;YACF,MAAM;YACN,GAAG;YACH,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;gBACvB,IAAI,IAAI,CAAC,QAAQ,EAAE;oBACjB,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;oBACxB,OAAO;iBACR;gBAED,QAAQ,CAAC,iBAAiB,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;YAC5C,CAAC;YACD,GAAG,EAAE,IAAA,2BAAmB,EAAC,OAAO,CAAC;SAClC,CAAC,CAAC;IACL,CAAC;IACD,QAAQ;QACN,OAAO;YACL,KAAK,EAAE,QAAQ;YACf,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,2BAAe;YACrB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,uBAAuB;YAC5C,OAAO,EAAE;gBACP,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa;gBACjC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB;gBAC1C,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB;gBAClD,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa;aAClC;SACF,CAAA;IACH,CAAC;CACF,CAAA","file":"s3.js","sourcesContent":["import { STORAGE_TYPE_S3 } from '../constants';\nimport { cloudFilenameGetter } from '../utils';\n\nexport default {\n filenameKey: 'key',\n make(storage) {\n const S3Client = require('aws-sdk/clients/s3');\n const multerS3 = require('multer-s3');\n const {\n accessKeyId,\n secretAccessKey,\n bucket,\n acl = 'public-read',\n ...options\n } = storage.options;\n const s3 = new S3Client({\n ...options,\n credentials: {\n accessKeyId,\n secretAccessKey\n }\n });\n\n return multerS3({\n s3,\n bucket,\n acl,\n contentType(req, file, cb) {\n if (file.mimetype) {\n cb(null, file.mimetype);\n return;\n }\n \n multerS3.AUTO_CONTENT_TYPE(req, file, cb);\n },\n key: cloudFilenameGetter(storage)\n });\n },\n defaults() {\n return {\n title: 'AWS S3',\n name: 'aws-s3',\n type: STORAGE_TYPE_S3,\n baseUrl: process.env.AWS_S3_STORAGE_BASE_URL,\n options: {\n region: process.env.AWS_S3_REGION,\n accessKeyId: process.env.AWS_ACCESS_KEY_ID,\n secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,\n bucket: process.env.AWS_S3_BUCKET,\n }\n }\n }\n}\n"]}
|
package/lib/utils.d.ts
CHANGED
package/lib/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["utils.ts"],"names":[],"mappings":"AAGA,wBAAgB,WAAW,CAAC,GAAG,KAAA,EAAE,IAAI,KAAA,EAAE,EAAE,KAAA,QAIxC","file":"utils.d.ts","sourcesContent":["import crypto from 'crypto';\nimport path from 'path';\n\nexport function getFilename(req, file, cb) {\n crypto.pseudoRandomBytes(16, function (err, raw) {\n cb(err, err ? undefined : `${raw.toString('hex')}${path.extname(file.originalname)}`)\n })\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["utils.ts"],"names":[],"mappings":"AAGA,wBAAgB,WAAW,CAAC,GAAG,KAAA,EAAE,IAAI,KAAA,EAAE,EAAE,KAAA,QAIxC;AAED,eAAO,MAAM,mBAAmB,0DAO/B,CAAA","file":"utils.d.ts","sourcesContent":["import crypto from 'crypto';\nimport path from 'path';\n\nexport function getFilename(req, file, cb) {\n crypto.pseudoRandomBytes(16, function (err, raw) {\n cb(err, err ? undefined : `${raw.toString('hex')}${path.extname(file.originalname)}`)\n });\n}\n\nexport const cloudFilenameGetter = storage => (req, file, cb) => {\n getFilename(req, file, (err, filename) => {\n if (err) {\n return cb(err);\n }\n cb(null, `${storage.path ? `${storage.path}/` : ''}${filename}`);\n });\n}\n"]}
|
package/lib/utils.js
CHANGED
|
@@ -21,7 +21,7 @@ var __importDefault = void 0 && (void 0).__importDefault || function (mod) {
|
|
|
21
21
|
Object.defineProperty(exports, "__esModule", {
|
|
22
22
|
value: true
|
|
23
23
|
});
|
|
24
|
-
exports.getFilename = void 0;
|
|
24
|
+
exports.cloudFilenameGetter = exports.getFilename = void 0;
|
|
25
25
|
|
|
26
26
|
const crypto_1 = __importDefault(require("crypto"));
|
|
27
27
|
|
|
@@ -34,4 +34,16 @@ function getFilename(req, file, cb) {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
exports.getFilename = getFilename;
|
|
37
|
+
|
|
38
|
+
const cloudFilenameGetter = storage => (req, file, cb) => {
|
|
39
|
+
getFilename(req, file, (err, filename) => {
|
|
40
|
+
if (err) {
|
|
41
|
+
return cb(err);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
cb(null, `${storage.path ? `${storage.path}/` : ''}${filename}`);
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
exports.cloudFilenameGetter = cloudFilenameGetter;
|
|
37
49
|
//# sourceMappingURL=utils.js.map
|
package/lib/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["utils.ts"],"names":[],"mappings":";;;;;;AAAA,oDAA4B;AAC5B,gDAAwB;AAExB,SAAgB,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;IACvC,gBAAM,CAAC,iBAAiB,CAAC,EAAE,EAAE,UAAU,GAAG,EAAE,GAAG;QAC7C,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,cAAI,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAA;IACvF,CAAC,CAAC,
|
|
1
|
+
{"version":3,"sources":["utils.ts"],"names":[],"mappings":";;;;;;AAAA,oDAA4B;AAC5B,gDAAwB;AAExB,SAAgB,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;IACvC,gBAAM,CAAC,iBAAiB,CAAC,EAAE,EAAE,UAAU,GAAG,EAAE,GAAG;QAC7C,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,cAAI,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAA;IACvF,CAAC,CAAC,CAAC;AACL,CAAC;AAJD,kCAIC;AAEM,MAAM,mBAAmB,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE;IAC9D,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE;QACvC,IAAI,GAAG,EAAE;YACP,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC;SAChB;QACD,EAAE,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,QAAQ,EAAE,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC,CAAA;AAPY,QAAA,mBAAmB,uBAO/B","file":"utils.js","sourcesContent":["import crypto from 'crypto';\nimport path from 'path';\n\nexport function getFilename(req, file, cb) {\n crypto.pseudoRandomBytes(16, function (err, raw) {\n cb(err, err ? undefined : `${raw.toString('hex')}${path.extname(file.originalname)}`)\n });\n}\n\nexport const cloudFilenameGetter = storage => (req, file, cb) => {\n getFilename(req, file, (err, filename) => {\n if (err) {\n return cb(err);\n }\n cb(null, `${storage.path ? `${storage.path}/` : ''}${filename}`);\n });\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/plugin-file-manager",
|
|
3
|
-
"version": "0.5.0-alpha.
|
|
3
|
+
"version": "0.5.0-alpha.35",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"@koa/multer": "^3.0.0",
|
|
8
|
-
"
|
|
9
|
-
"ali-oss": "^6.12.0",
|
|
10
|
-
"koa-mount": "^4.0.0",
|
|
8
|
+
"aws-sdk": "^2.2.32",
|
|
11
9
|
"koa-static": "^5.0.0",
|
|
12
10
|
"mime-match": "^1.0.2",
|
|
13
|
-
"multer": "^1.4.2"
|
|
11
|
+
"multer": "^1.4.2",
|
|
12
|
+
"multer-aliyun-oss": "1.1.1",
|
|
13
|
+
"multer-s3": "^2.10.0"
|
|
14
14
|
},
|
|
15
15
|
"devDependencies": {
|
|
16
|
-
"@nocobase/test": "^0.5.0-alpha.34",
|
|
17
16
|
"@types/multer": "^1.4.5"
|
|
18
17
|
},
|
|
19
|
-
"gitHead": "
|
|
18
|
+
"gitHead": "2b81a6af327ee784a6943aff6e028fde3298dec9"
|
|
20
19
|
}
|