Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation for File Data Processing #22

Merged
merged 9 commits into from
Oct 20, 2022
Prev Previous commit
Next Next commit
feat: Added Storage service to @impler/shared
  • Loading branch information
chavda-bhavik committed Oct 19, 2022
commit de3e0eaeae1e3d3538fdfa26485e7b401e900b73
1 change: 1 addition & 0 deletions libs/shared/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"typescript": "^4.8.3"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.185.0",
"rimraf": "^3.0.2"
},
"lint-staged": {
Expand Down
6 changes: 6 additions & 0 deletions libs/shared/src/errors/file-not-exist.error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export class FileNotExistError extends Error {
constructor() {
super('File not found for the key provided');
this.name = 'NonExistingFileError';
}
}
1 change: 1 addition & 0 deletions libs/shared/src/errors/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './file-not-exist.error';
2 changes: 2 additions & 0 deletions libs/shared/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export * from './utils/helpers';
export * from './types';
export * from './errors';
export * from './services';
1 change: 1 addition & 0 deletions libs/shared/src/services/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './storage.service';
79 changes: 79 additions & 0 deletions libs/shared/src/services/storage.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { Readable } from 'stream';
import {
S3Client,
PutObjectCommand,
PutObjectCommandOutput,
GetObjectCommand,
DeleteObjectCommand,
} from '@aws-sdk/client-s3';
import { FileNotExistError } from '../errors/file-not-exist.error';

export interface IFilePath {
path: string;
name: string;
}

export abstract class StorageService {
abstract uploadFile(
key: string,
file: Buffer | string,
contentType: string,
isPublic?: boolean
): Promise<PutObjectCommandOutput>;
abstract getFileContent(key: string, encoding?: BufferEncoding): Promise<string>;
abstract deleteFile(key: string): Promise<void>;
}

async function streamToString(stream: Readable, encoding: BufferEncoding): Promise<string> {
return await new Promise((resolve, reject) => {
const chunks: Uint8Array[] = [];
stream.on('data', (chunk) => chunks.push(chunk));
stream.on('error', reject);
stream.on('end', () => resolve(Buffer.concat(chunks).toString(encoding)));
});
}

export class S3StorageService implements StorageService {
private s3 = new S3Client({
region: process.env.S3_REGION,
endpoint: process.env.S3_LOCAL_STACK || undefined,
forcePathStyle: true,
});

async uploadFile(key: string, file: Buffer, contentType: string, isPublic = false): Promise<PutObjectCommandOutput> {
const command = new PutObjectCommand({
Bucket: process.env.S3_BUCKET_NAME,
Key: key,
Body: file,
ACL: isPublic ? 'public-read' : 'private',
ContentType: contentType,
});

return await this.s3.send(command);
}

async getFileContent(key: string, encoding = 'utf8' as BufferEncoding): Promise<string> {
try {
const command = new GetObjectCommand({
Bucket: process.env.S3_BUCKET_NAME,
Key: key,
});
const data = await this.s3.send(command);

return await streamToString(data.Body as Readable, encoding);
} catch (error) {
if (error.code === 404 || error.message === 'The specified key does not exist.') {
throw new FileNotExistError();
}
throw error;
}
}

async deleteFile(key: string): Promise<void> {
const command = new DeleteObjectCommand({
Bucket: process.env.S3_BUCKET_NAME,
Key: key,
});
await this.s3.send(command);
}
}
18 changes: 17 additions & 1 deletion libs/shared/src/types/upload/upload.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,23 @@ export enum QueuesEnum {
'PROCESS_FILE' = 'PROCESS_FILE',
}

export type ProcessFileData = { uploadId: string };
export type ProcessFileCachedData = {
page: number;
callbackUrl: string;
chunkSize: number;
code: string; // template code
extra?: string;
isInvalidRecords: boolean;
processInvalidRecords: boolean;
_templateId: string;
validDataFilePath: string;
invalidDataFilePath: string;
};

export type ProcessFileData = {
uploadId: string;
cache?: ProcessFileCachedData;
};
export type PublishToQueueData = ProcessFileData;

export interface IFileInformation {
Expand Down