s3Helper.ts
unknown
typescript
2 years ago
5.3 kB
6
Indexable
import {API, graphqlOperation} from 'aws-amplify'; import { endSimpleTrainConsistTrip, getPresignedPostUrl, } from '@graphql/queriesFn'; // Utils import { deleteGzipFile, readAndDecompressGzipFile, readGzipDirectory, } from '@Utils/fileHelper'; // Types import {File, S3PathKey} from '@Types'; // Apollo import apolloClient from '@ApolloClient/apolloClient'; /** * Requests an S3 pre-signed URL that can be used to upload files. * @param {string} s3PathKey - An enum value specifying the data type (e.g GPS, MODELS, etc.). * @returns {Promise<string>} - An S3 pre-signed URL. */ const getS3PreSignedUrl = async ({s3PathKey}: {s3PathKey: string}) => { try { const client = await apolloClient(); const response = await client.query({ query: getPresignedPostUrl({ s3_path_key: s3PathKey, }), }); console.log('response', response, s3PathKey); return response; } catch (error) { console.log('error', error); return error; } }; /** * This is an asynchronous function that ends a simple train consist trip by calling an API with the * necessary parameters. * @param - The function `endTrip` takes in an object with three properties as its parameter: */ const endTrip = async ( createdBy: string, endDateUtc: string, simpleTrainConsistId: string, ) => { try { const client = await apolloClient(); await client.mutate({ mutation: endSimpleTrainConsistTrip({ createdBy, endDateUtc, simpleTrainConsistId, }), }); } catch (error) { console.log(error); } }; /** * Uploads a single file to S3 using a pre-signed URL. * @param {string} url - The pre-signed URL used to upload the file. * @param {any} postRequestFields - Request headers * @param {File} file - An object containing information about the file to upload. It should have the following properties: * - file_name: The name of the file, including the extension. * - file_type: The MIME type of the file. * - file_uri: The URI of the file to upload. * @returns {Promise<void>} - A promise that resolves when the file has been successfully uploaded to S3. */ const uploadSingleFileToS3 = async ( url: string, postRequestFields: any, file: File, s3PathKey: S3PathKey, ) => { console.log(`Uploading ${file.name}...`); const fileContent = await readAndDecompressGzipFile(s3PathKey, file.name); const fileContentObject = JSON.parse(fileContent); endTrip( fileContentObject.created_at_utc, fileContentObject.end_trip_timestamp_utc, fileContentObject.simple_train_consist_id, ); const formData = new FormData(); // Add post request fields to body requests for (const [key, value] of Object.entries(postRequestFields)) { formData.append(key, value); } formData.append('file', { ...file, }); const response = await fetch(url, { method: 'POST', body: formData, headers: { 'Content-Type': `multipart/form-data`, }, }); return response; }; /** * Uploads an array of .gzip files read from native file system to S3 using pre-signed URLs. * @param {S3PathKey} s3PathKey - An enum value specifying the data type (e.g GPS, MODEL, etc.). */ export const uploadAllFilesToS3 = async (s3PathKey: S3PathKey) => { const files: File[] = await readGzipDirectory(s3PathKey); for (const file of files) { // 1. Request for a pre-signed url given railroad_id, timestamp and file format let preSignedUrl, postRequestFields; try { const fileMetaData = file.name.split(':'); // File name on S3 is just the Simple Train Consist const fileNameOnS3 = fileMetaData[5]; const preSignedUrlResponse: any = await getS3PreSignedUrl({ s3PathKey: `${s3PathKey}/railroad=${fileMetaData[0]}/year=${fileMetaData[1]}/month=${fileMetaData[2]}/day=${fileMetaData[3]}/${fileNameOnS3}`, }); const presignedPostUrl = preSignedUrlResponse?.data?.presigned_post_url; const {response_code, presigned_url, post_request_fields} = presignedPostUrl; const parsed_post_request_fields = JSON.parse(post_request_fields); if (response_code === 409) { console.error(`${file.name} already exists`); deleteGzipFile(s3PathKey, file.name); continue; } preSignedUrl = presigned_url; postRequestFields = parsed_post_request_fields; } catch (error) { console.error(`Error getting pre-signed URL for ${file.name}: ${error}`); continue; } // 2. Upload the file to S3 using the pre-signed URL try { const response = await uploadSingleFileToS3( preSignedUrl, postRequestFields, file, s3PathKey, ); if (response.status === 409) { console.log(`${file.name} already exists`); deleteGzipFile(s3PathKey, file.name); return; } if (response.status !== 200 && response.status !== 204) { console.log(`${file.name} uploaded failed!`); return; } console.log(`${file.name} uploaded successfully!`); // Delete gzip file after uploading successfully deleteGzipFile(s3PathKey, file.name); } catch (error) { console.error(`Error uploading ${file.name}: ${error}`); } } };
Editor is loading...