|
import { S3 } from "aws-sdk"; |
|
import Crypto from "node:crypto"; |
|
|
|
export const TestData1KB = [ |
|
"7798762c1ae1b9e17546e572870ba5c7214f10cb0d4aa8170fe290036138dea5a993ae3de8b1d3ae28de337ead0bc9b89da", |
|
"2a6f3b66d33f238b41e53c6e7b93d0ac66f959d3f42fba9c71a7f9597c6c4e7dffa28ad0bd86e0be28386c1e6db7eeb7ac9", |
|
"720e6c398919ede3aaadff485991a38c62f169ec2bec7e7833ec0233f043d773a16cd369b5772a9501d6e0d9aa30f644c74", |
|
"149e8c7c216e3a879ee995b1b611b57bcd3badb56f29b090925384a74bb3d997c6cad0d1530a50f93fdf1dfd7c6d8fca168", |
|
"637d9210a0c132e95c078888317b60d187f98b7bb4e2c150337966a4cfb949d06f0fa3d58b150cc27f5c8a6ef53824722d8", |
|
"29c877c7870df3fdad1092d5737464f3aab0101c910b4c4ae01f230be1611836c69ae385bfc2e07bb14f8b350dd0019956a", |
|
"6530bc2fc9365d4ca9a10878ba6d9271078c4a3b93a8a03ee169f0a9480d679b333c6d80fd46e8dd849ab5cf521df924f09", |
|
"8c6cd75509c640eb1af6b648d5e15c5efcc4f61a0233899392166ac748043b9fad77a595390b055d95e58be6943bba761e1", |
|
"7bfe04ef07163877c179365b11cfde8b9c748bded7007d357205fd9383da45ea5e178745539ed35839a0dd51f7d3496877c", |
|
"c8e1e3987cc13775efe4945484b8d8231f3f9527176325418e4a93e4e04fcbdfe8d879cb2575948820a08f792985e2cbbe9", |
|
"212ffd062577d9aa829ab88", |
|
"", |
|
].join("\n"); |
|
if (TestData1KB.length !== 1024) throw new Error("TestData1KB is not 1KB."); |
|
export const TestData5MB = Array.from({ length: 5 * 1024 }) |
|
.map(() => TestData1KB) |
|
.join(""); |
|
export const getSHA256 = (data: string): string => Crypto.createHash("sha256").update(data, "utf8").digest("base64"); |
|
|
|
// ----- S3 ----- |
|
|
|
const TestBucket = "mryhryki-test"; |
|
const s3 = new S3({ apiVersion: "2006-03-01" }); |
|
export const listObjects = () => s3.listObjectsV2({ Bucket: TestBucket, Prefix: "" }).promise(); |
|
|
|
export const putObjectWithChecksum = (key: string, data: string, checksum: string) => { |
|
return s3 |
|
.putObject({ |
|
Bucket: TestBucket, |
|
Key: key, |
|
Body: data, |
|
ContentType: "text/plain; charset=utf-8", |
|
ChecksumAlgorithm: "SHA256", |
|
ChecksumSHA256: checksum, |
|
}) |
|
.promise(); |
|
}; |
|
|
|
export const createMultipartUpload = async (key: string): Promise<{ UploadId: string }> => { |
|
const { UploadId } = await s3 |
|
.createMultipartUpload({ |
|
Bucket: TestBucket, |
|
Key: key, |
|
ChecksumAlgorithm: "SHA256", |
|
}) |
|
.promise(); |
|
if (UploadId == null) throw new Error("UploadId is null"); |
|
return { UploadId }; |
|
}; |
|
|
|
export const uploadMultipart = async ( |
|
key: string, |
|
data: string, |
|
partNumber: number, |
|
checksum: string, |
|
uploadId: string |
|
): Promise<{ ETag: string; partNumber: number }> => { |
|
const { ETag } = await s3 |
|
.uploadPart({ |
|
Bucket: TestBucket, |
|
Key: key, |
|
Body: data, |
|
PartNumber: partNumber, |
|
ChecksumAlgorithm: "SHA256", |
|
ChecksumSHA256: checksum, |
|
UploadId: uploadId, |
|
}) |
|
.promise(); |
|
if (ETag == null) { |
|
throw new Error("ETag null"); |
|
} |
|
return { ETag, partNumber }; |
|
}; |
|
|
|
export const completeMultipartUpload = (key: string, UploadId: string, Parts: S3.Types.CompletedPart[]) => { |
|
return s3 |
|
.completeMultipartUpload({ |
|
Bucket: TestBucket, |
|
Key: key, |
|
MultipartUpload: { Parts }, |
|
UploadId, |
|
}) |
|
.promise(); |
|
}; |
|
|
|
export const cleanupBucket = async () => { |
|
const objects = await listObjects(); |
|
await Promise.all( |
|
(objects.Contents ?? []).map(async ({ Key }) => { |
|
if (Key == null) return; |
|
console.log("Delete object: %s", Key); |
|
await s3.deleteObject({ Bucket: TestBucket, Key }); |
|
}) |
|
); |
|
const multiparts = await s3.listMultipartUploads({ Bucket: TestBucket }).promise(); |
|
await Promise.all( |
|
(multiparts.Uploads ?? []).map(async ({ Key, UploadId }) => { |
|
if (Key == null || UploadId == null) return; |
|
console.debug("Delete Multipart Upload:", Key, UploadId); |
|
await s3.abortMultipartUpload({ Bucket: TestBucket, Key, UploadId }).promise(); |
|
}) |
|
); |
|
}; |