fix(file-manager): create file record with custom storage and values

This commit is contained in:
chenos 2024-08-20 10:11:48 +08:00
parent f17b7c6413
commit 51c6c6dcfa
2 changed files with 84 additions and 12 deletions

View File

@ -51,10 +51,10 @@ describe('action', () => {
describe('create / upload', () => {
describe('default storage', () => {
it('createFileRecord', async () => {
it('should be create file record', async () => {
const Plugin = app.pm.get(PluginFileManagerServer) as PluginFileManagerServer;
const model = await Plugin.createFileRecord({
collection: 'attachments',
collectionName: 'attachments',
filePath: path.resolve(__dirname, './files/text.txt'),
});
const matcher = {
@ -68,6 +68,55 @@ describe('action', () => {
expect(model.toJSON()).toMatchObject(matcher);
});
it('should be local2 storage', async () => {
const storage = await StorageRepo.create({
values: {
name: 'local2',
type: STORAGE_TYPE_LOCAL,
baseUrl: DEFAULT_LOCAL_BASE_URL,
rules: {
size: 1024,
},
paranoid: true,
},
});
const Plugin = app.pm.get(PluginFileManagerServer) as PluginFileManagerServer;
const model = await Plugin.createFileRecord({
collectionName: 'attachments',
storageName: 'local2',
filePath: path.resolve(__dirname, './files/text.txt'),
});
const matcher = {
title: 'text',
extname: '.txt',
path: '',
// size: 13,
meta: {},
storageId: storage.id,
};
expect(model.toJSON()).toMatchObject(matcher);
});
it.only('should be custom values', async () => {
const Plugin = app.pm.get(PluginFileManagerServer) as PluginFileManagerServer;
const model = await Plugin.createFileRecord({
collectionName: 'attachments',
filePath: path.resolve(__dirname, './files/text.txt'),
values: {
size: 22,
},
});
const matcher = {
title: 'text',
extname: '.txt',
path: '',
size: 22,
meta: {},
storageId: 1,
};
expect(model.toJSON()).toMatchObject(matcher);
});
it('upload file should be ok', async () => {
const { body } = await agent.resource('attachments').create({
[FILE_FIELD_NAME]: path.resolve(__dirname, './files/text.txt'),

View File

@ -30,8 +30,10 @@ export type * from './storages';
const DEFAULT_STORAGE_TYPE = STORAGE_TYPE_LOCAL;
export type FileRecordOptions = {
collection: string;
collectionName: string;
filePath: string;
storageName?: string;
values?: any;
} & Transactionable;
export default class PluginFileManagerServer extends Plugin {
@ -39,24 +41,45 @@ export default class PluginFileManagerServer extends Plugin {
storagesCache = new Map<number, StorageModel>();
async createFileRecord(options: FileRecordOptions) {
const { collection, filePath, transaction } = options;
const { values, storageName, collectionName, filePath, transaction } = options;
const collection = this.db.getCollection(collectionName);
if (!collection) {
throw new Error(`collection does not exist`);
}
const storageRepository = this.db.getRepository('storages');
const collectionRepository = this.db.getRepository(collection);
const storage = await storageRepository.findOne();
const collectionRepository = this.db.getRepository(collectionName);
const name = storageName || collection.options.storage;
let storageInstance;
if (name) {
storageInstance = await storageRepository.findOne({
filter: {
name,
},
});
}
if (!storageInstance) {
storageInstance = await storageRepository.findOne({
filter: {
default: true,
},
});
}
const fileStream = fs.createReadStream(filePath);
if (!storage) {
if (!storageInstance) {
throw new Error('[file-manager] no linked or default storage provided');
}
const storageConfig = this.storageTypes.get(storage.type);
const storageConfig = this.storageTypes.get(storageInstance.type);
if (!storageConfig) {
throw new Error(`[file-manager] storage type "${storage.type}" is not defined`);
throw new Error(`[file-manager] storage type "${storageInstance.type}" is not defined`);
}
const engine = storageConfig.make(storage);
const engine = storageConfig.make(storageInstance);
const file = {
originalname: basename(filePath),
@ -74,8 +97,8 @@ export default class PluginFileManagerServer extends Plugin {
});
});
const values = getFileData({ app: this.app, file, storage, request: { body: {} } } as any);
return await collectionRepository.create({ values, transaction });
const data = getFileData({ app: this.app, file, storage: storageInstance, request: { body: {} } } as any);
return await collectionRepository.create({ values: { ...data, ...values }, transaction });
}
async loadStorages(options?: { transaction: any }) {