import { Injectable } from '@nestjs/common';
import { GetObjectCommand,S3Client } from '@aws-sdk/client-s3';
import ExcelJS from 'exceljs';
import { parse } from 'csv-parse/sync';
@Injectable()
export class ImportFileReaderService {
private readonly bucket=process.env.OBJECT_STORAGE_BUCKET ?? 'gastro-os';
private readonly s3=new S3Client({
region:process.env.OBJECT_STORAGE_REGION ?? 'local',
endpoint:process.env.OBJECT_STORAGE_ENDPOINT,
forcePathStyle:true,
credentials:{
accessKeyId:process.env.OBJECT_STORAGE_ACCESS_KEY ?? 'minio',
secretAccessKey:process.env.OBJECT_STORAGE_SECRET_KEY ?? 'change-me',
},
});
async read(input:{storageKey:string;mimeType:string}) {
const object=await this.s3.send(new GetObjectCommand({Bucket:this.bucket,Key:input.storageKey}));
const bytes=Buffer.from(await object.Body!.transformToByteArray());
if(bytes.length>25*1024*1024) throw new Error('imports.file_too_large');
if(input.mimeType==='text/csv') {
return parse(bytes.toString('utf8'),{
columns:true,skip_empty_lines:true,trim:true,relax_column_count:false,
}) as Record<string,string>[];
}
if(input.mimeType==='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
const workbook=new ExcelJS.Workbook();
await workbook.xlsx.load(bytes as any);
const sheet=workbook.worksheets[0];
if(!sheet) return [];
const headerRow=sheet.getRow(1);
const headers=headerRow.values as any[];
const out:Record<string,string>[]=[];
sheet.eachRow((row:any,rowNumber:number)=>{
if(rowNumber===1) return;
const obj:Record<string,string>={};
for(let i=1;i<headers.length;i++) {
const h=headers[i];
if(!h) continue;
const cell=row.getCell(i).value;
obj[String(h).trim()]=cell==null?'':String(typeof cell==='object' && 'text' in (cell as any) ? (cell as any).text : cell).trim();
}
if(Object.values(obj).some((x)=>x!=='')) out.push(obj);
});
return out;
}
throw new Error('imports.unsupported_mime');
}
}
