Initial Mento CRM: portal OTP, reports, SMS, and deploy for crm.montzar.ir.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
import { Injectable, OnModuleInit } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { createReadStream, promises as fs } from 'fs';
|
||||
import * as path from 'path';
|
||||
import type { Readable } from 'stream';
|
||||
|
||||
@Injectable()
|
||||
export class LocalFileStorage implements OnModuleInit {
|
||||
private readonly root: string;
|
||||
|
||||
constructor(private readonly config: ConfigService) {
|
||||
this.root =
|
||||
this.config.get<string>('UPLOAD_DIR')?.trim() ||
|
||||
path.join(process.cwd(), 'uploads');
|
||||
}
|
||||
|
||||
async onModuleInit() {
|
||||
await fs.mkdir(this.root, { recursive: true });
|
||||
}
|
||||
|
||||
absolutePath(storageKey: string): string {
|
||||
const resolved = path.resolve(this.root, storageKey);
|
||||
if (!resolved.startsWith(path.resolve(this.root))) {
|
||||
throw new Error('Invalid storage key');
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
|
||||
async save(storageKey: string, buffer: Buffer): Promise<void> {
|
||||
const abs = this.absolutePath(storageKey);
|
||||
await fs.mkdir(path.dirname(abs), { recursive: true });
|
||||
await fs.writeFile(abs, buffer);
|
||||
}
|
||||
|
||||
async remove(storageKey: string): Promise<void> {
|
||||
const abs = this.absolutePath(storageKey);
|
||||
try {
|
||||
await fs.unlink(abs);
|
||||
} catch (err) {
|
||||
const code = (err as NodeJS.ErrnoException).code;
|
||||
if (code !== 'ENOENT') throw err;
|
||||
}
|
||||
}
|
||||
|
||||
openReadStream(storageKey: string): Readable {
|
||||
return createReadStream(this.absolutePath(storageKey));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { Global, Module } from '@nestjs/common';
|
||||
import { LocalFileStorage } from './local-file.storage';
|
||||
|
||||
@Global()
|
||||
@Module({
|
||||
providers: [LocalFileStorage],
|
||||
exports: [LocalFileStorage],
|
||||
})
|
||||
export class StorageModule {}
|
||||
Reference in New Issue
Block a user