29 lines
1.1 KiB
TypeScript
29 lines
1.1 KiB
TypeScript
import { Controller, Get, Header, NotFoundException, Param, StreamableFile } from '@nestjs/common';
|
|||
|
|
import { createReadStream } from 'node:fs';
|
||
|
|
import { Public } from '../auth/guards';
|
||
|
|
import { mimeForUpload, resolveStoredUpload } from './upload-path';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Public file serving at GET /api/uploads/:filename.
|
||
|
|
*
|
||
|
|
* ProductImage.url is stored as `/uploads/<file>`, which nginx proxies. Shoppers
|
||
|
|
* and operators also hit `/api/uploads/<file>` (user-app axios base is `/api`,
|
||
|
|
* and the API Dokploy domain sits behind the same prefix). useStaticAssets only
|
||
|
|
* mounts `/uploads/`, so those requests 404'd with Nest's "Cannot GET /api/uploads/...".
|
||
|
|
*/
|
||
|
|
@Public()
|
||
|
|
@Controller('uploads')
|
||
|
|
export class PublicUploadsController {
|
||
|
|
@Get(':filename')
|
||
|
|
@Header('Cache-Control', 'public, max-age=86400')
|
||
|
|
stream(@Param('filename') filename: string): StreamableFile {
|
||
|
|
const file = resolveStoredUpload(filename);
|
||
|
|
if (!file) throw new NotFoundException('فایل یافت نشد');
|
||
|
|
|
||
|
|
return new StreamableFile(createReadStream(file), {
|
||
|
|
type: mimeForUpload(file) ?? 'application/octet-stream',
|
||
|
|
disposition: 'inline',
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|