I wanna create an Interceptor of nestjs and on this level and want to do uploading file. I can't find a solution, how to resolve this code by Observable (https://github.com/fastify/fastify-multipart)
I'm using fromPromise but with this tool, I've more problems. Because I can resolve only once. I need for each file do validation and if validation returns resolve then run pump for writing.
const mp = req.multipart(handler, function (err) {
console.log('upload completed')
reply.code(200).send()
})
// handler wil run for each file
function handler (field, file, filename, encoding, mimetype) {
// to accumulate the file in memory! Be careful!
//
// file.pipe(concat(function (buf) {
// console.log('received', filename, 'size', buf.length)
// }))
//
// or
pump(file, fs.createWriteStream('a-destination'))
// be careful of permission issues on disk and not overwrite
// sensitive files that could cause security risks
}
I use this code, for my old case it's enough...
const obs1$ = fromPromise(new Promise((res, rej) => {
const mp = request.multipart((field, file, filename, encoding, mimetype) => {
const writeStream = fs.createWriteStream('path');
//here need run onValidation
pump(file, writeStream);
}, (err) => {
//doSuccess
(err) ? rej(err) : res();
});
}));
return obs1$.pipe(
catchError(error => {
throw new BadRequestException(error);
}),
switchMap(() => {
request.body = body;
return next.handle();
}), mergeAll());
but I've a new case (I need do validation before file will be save) and case is: next.hander() return Observable with some methods:
@Controller('test')
export class TestCtrl {
@Post('upload')
@UseInterceptors(new FileInterceptor())
uploadFile() {
return {
onValidate: (file: IFiles) => {
console.log(this.tst);
return Promise.resolve(true);
},
onSuccess: () => {
return Promise.resolve(true);
}
};
}
}
Tried something like that:
@Injectable()
export class FileInterceptor implements NestInterceptor {
intercept(context: any, next: CallHandler): Observable<any> {
const request = context.getRequest();
const body: Array<any> = [];
return next.handle().pipe(switchMap((methods: any) => {
const mp = request.multipart((field, file, filename, encoding, mimetype) => {
const writeStream = fs.createWriteStream('path');
body.push({
filename, file
});
methods.onValidation(file).then(() => {
pump(file, writeStream);
}).catch(() => {
writeStream.destroy();
});
}, () => {
//done
methods.onSuccess(body); // how to return this?
});
return null; // ???
}));
}
}