qstd 0.3.54 → 0.3.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,16 +1,21 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type DeleteObjectCommandOutput, type GetObjectCommandOutput, type HeadObjectCommandOutput } from "@aws-sdk/client-s3";
|
|
2
2
|
import { type PresignedPost } from "@aws-sdk/s3-presigned-post";
|
|
3
3
|
import * as _t from "./types";
|
|
4
4
|
export declare const create: (props?: _t.CreateProps) => _t.Client;
|
|
5
5
|
/**
|
|
6
|
-
* signed
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* Create a signed URL for S3 operations.
|
|
7
|
+
*
|
|
8
|
+
* Supports three actions:
|
|
9
|
+
* - `get`: Returns a signed URL string for downloading
|
|
10
|
+
* - `post`: Returns a PresignedPost for single-part uploads (< 5MB)
|
|
11
|
+
* - `multipart`: Returns uploadId + signed URLs for multi-part uploads (> 5MB)
|
|
12
|
+
*
|
|
13
|
+
* NOTE: Ensure lambda has permissions to create signed URLs
|
|
14
|
+
* or the URL will give access denied.
|
|
11
15
|
*/
|
|
12
16
|
export declare function createSignedUrl(s3: _t.Client, props: _t.SignedUrlGetProps): Promise<string>;
|
|
13
17
|
export declare function createSignedUrl(s3: _t.Client, props: _t.SignedUrlPostProps): Promise<PresignedPost>;
|
|
18
|
+
export declare function createSignedUrl(s3: _t.Client, props: _t.SignedUrlMultipartProps): Promise<_t.PrepareMultipartUploadResult>;
|
|
14
19
|
/**
|
|
15
20
|
* upload a file directly to s3 bucket
|
|
16
21
|
* @param s3
|
|
@@ -25,19 +30,18 @@ export type FileProps = {
|
|
|
25
30
|
export declare const getFile: (s3: _t.Client, props: FileProps) => Promise<GetObjectCommandOutput>;
|
|
26
31
|
export declare const deleteFile: (s3: _t.Client, props: FileProps) => Promise<DeleteObjectCommandOutput>;
|
|
27
32
|
export declare const getFileMetadata: (s3: _t.Client, props: FileProps) => Promise<HeadObjectCommandOutput>;
|
|
28
|
-
/**
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}): Promise<boolean>;
|
|
33
|
+
/**
|
|
34
|
+
* Create a new S3 bucket
|
|
35
|
+
*/
|
|
36
|
+
export declare const createBucket: (s3: _t.Client, bucketName: string) => Promise<import("@aws-sdk/client-s3").CreateBucketCommandOutput>;
|
|
37
|
+
/**
|
|
38
|
+
* Delete an S3 bucket
|
|
39
|
+
*/
|
|
40
|
+
export declare const deleteBucket: (s3: _t.Client, bucketName: string) => Promise<import("@aws-sdk/client-s3").DeleteBucketCommandOutput>;
|
|
41
|
+
/**
|
|
42
|
+
* Check if an S3 bucket exists
|
|
43
|
+
*/
|
|
44
|
+
export declare const bucketExists: (s3: _t.Client, bucketName: string) => Promise<boolean>;
|
|
41
45
|
/**
|
|
42
46
|
* Copy and delete original files from src bucket to target bucket.
|
|
43
47
|
* @param s3
|
|
@@ -45,6 +49,42 @@ export declare function bucketHandle(s3: _t.Client, props: {
|
|
|
45
49
|
* @returns
|
|
46
50
|
*/
|
|
47
51
|
export declare const migrateBucketContents: (s3: _t.Client, buckets: _t.BucketTransferOpts) => Promise<DeleteObjectCommandOutput[] | undefined>;
|
|
52
|
+
/**
|
|
53
|
+
* Prepare a multipart upload by initiating it and generating signed URLs
|
|
54
|
+
* for each part. Use this for files larger than 5MB.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* const { uploadId, signedUrls, key } = await S3.prepareMultipartUpload(s3, {
|
|
59
|
+
* key: "videos/my-video.mp4",
|
|
60
|
+
* contentType: "video/mp4",
|
|
61
|
+
* numOfParts: 10,
|
|
62
|
+
* expiresInSecs: 3600,
|
|
63
|
+
* });
|
|
64
|
+
*
|
|
65
|
+
* // Client uploads each part to its corresponding signed URL
|
|
66
|
+
* // Then call finalizeMultipartUpload to complete
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export declare const prepareMultipartUpload: (s3: _t.Client, props: _t.PrepareMultipartUploadProps) => Promise<{
|
|
70
|
+
uploadId: string;
|
|
71
|
+
signedUrls: string[];
|
|
72
|
+
key: string;
|
|
73
|
+
}>;
|
|
74
|
+
/**
|
|
75
|
+
* Finalize a multipart upload after all parts have been uploaded.
|
|
76
|
+
* This internally lists all uploaded parts and completes the upload.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```ts
|
|
80
|
+
* // After client has uploaded all parts to their signed URLs
|
|
81
|
+
* await S3.finalizeMultipartUpload(s3, {
|
|
82
|
+
* key: "videos/my-video.mp4",
|
|
83
|
+
* uploadId: "abc123...",
|
|
84
|
+
* });
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export declare const finalizeMultipartUpload: (s3: _t.Client, props: _t.FinalizeMultipartUploadProps) => Promise<import("@aws-sdk/client-s3").CompleteMultipartUploadCommandOutput>;
|
|
48
88
|
/**
|
|
49
89
|
* Parse and decode S3 records from an SQS message body.
|
|
50
90
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domain.d.ts","sourceRoot":"","sources":["../../../../src/server/aws/s3/domain.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"domain.d.ts","sourceRoot":"","sources":["../../../../src/server/aws/s3/domain.ts"],"names":[],"mappings":"AAAA,OAAO,EAgBL,KAAK,yBAAyB,EAC9B,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAE7B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,4BAA4B,CAAC;AAGpC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9B,eAAO,MAAM,MAAM,GAAI,QAAO,EAAE,CAAC,WAAgB,KAAG,EAAE,CAAC,MAKtD,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,EAAE,EAAE,EAAE,CAAC,MAAM,EACb,KAAK,EAAE,EAAE,CAAC,iBAAiB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAAC;AACnB,wBAAgB,eAAe,CAC7B,EAAE,EAAE,EAAE,CAAC,MAAM,EACb,KAAK,EAAE,EAAE,CAAC,kBAAkB,GAC3B,OAAO,CAAC,aAAa,CAAC,CAAC;AAC1B,wBAAgB,eAAe,CAC7B,EAAE,EAAE,EAAE,CAAC,MAAM,EACb,KAAK,EAAE,EAAE,CAAC,uBAAuB,GAChC,OAAO,CAAC,EAAE,CAAC,4BAA4B,CAAC,CAAC;AAoD5C;;;;;GAKG;AACH,eAAO,MAAM,UAAU,GAAI,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,WAAW,iEAU9D,CAAC;AAMF,MAAM,MAAM,SAAS,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D,eAAO,MAAM,OAAO,GAClB,IAAI,EAAE,CAAC,MAAM,EACb,OAAO,SAAS,KACf,OAAO,CAAC,sBAAsB,CAWhC,CAAC;AAEF,eAAO,MAAM,UAAU,GACrB,IAAI,EAAE,CAAC,MAAM,EACb,OAAO,SAAS,KACf,OAAO,CAAC,yBAAyB,CAWnC,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,IAAI,EAAE,CAAC,MAAM,EACb,OAAO,SAAS,KACf,OAAO,CAAC,uBAAuB,CAWjC,CAAC;AAMF;;GAEG;AACH,eAAO,MAAM,YAAY,GAAI,IAAI,EAAE,CAAC,MAAM,EAAE,YAAY,MAAM,oEAG7D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,GAAI,IAAI,EAAE,CAAC,MAAM,EAAE,YAAY,MAAM,oEAG7D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,GAAU,IAAI,EAAE,CAAC,MAAM,EAAE,YAAY,MAAM,qBAgBnE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAChC,IAAI,EAAE,CAAC,MAAM,EACb,SAAS,EAAE,CAAC,kBAAkB,qDAkB/B,CAAC;AAMF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,sBAAsB,GACjC,IAAI,EAAE,CAAC,MAAM,EACb,OAAO,EAAE,CAAC,2BAA2B;;;;EAiCtC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,uBAAuB,GAClC,IAAI,EAAE,CAAC,MAAM,EACb,OAAO,EAAE,CAAC,4BAA4B,+EAiCvC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,KAAG,EAAE,CAAC,SAAS,EAAE,GAAG,IAgB9D,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { S3Client } from "@aws-sdk/client-s3";
|
|
2
|
-
import type { CompletedPart,
|
|
2
|
+
import type { CompletedPart, UploadPartRequest, PutObjectCommandInput } from "@aws-sdk/client-s3";
|
|
3
3
|
import type { PresignedPostOptions } from "@aws-sdk/s3-presigned-post";
|
|
4
4
|
import type { S3Event } from "aws-lambda";
|
|
5
5
|
export type NotificationEvent = S3Event;
|
|
@@ -44,7 +44,15 @@ export type SignedUrlGetProps = {
|
|
|
44
44
|
export type SignedUrlPostProps = SignedPostOpts & {
|
|
45
45
|
action: "post";
|
|
46
46
|
};
|
|
47
|
-
export type
|
|
47
|
+
export type SignedUrlMultipartProps = {
|
|
48
|
+
action: "multipart";
|
|
49
|
+
key: string;
|
|
50
|
+
contentType?: string;
|
|
51
|
+
numOfParts: number;
|
|
52
|
+
expiresInSecs?: number;
|
|
53
|
+
bucketName?: string;
|
|
54
|
+
};
|
|
55
|
+
export type SignedUrlProps = SignedUrlGetProps | SignedUrlPostProps | SignedUrlMultipartProps;
|
|
48
56
|
export type SignedUrlOpts = {
|
|
49
57
|
key: string;
|
|
50
58
|
expires: number;
|
|
@@ -79,6 +87,23 @@ export type MultiPartProps = {
|
|
|
79
87
|
uploadId: string;
|
|
80
88
|
key: string;
|
|
81
89
|
};
|
|
90
|
+
export type PrepareMultipartUploadProps = {
|
|
91
|
+
expiresInSecs?: number;
|
|
92
|
+
contentType?: string;
|
|
93
|
+
bucketName?: string;
|
|
94
|
+
numOfParts: number;
|
|
95
|
+
key: string;
|
|
96
|
+
};
|
|
97
|
+
export type PrepareMultipartUploadResult = {
|
|
98
|
+
signedUrls: string[];
|
|
99
|
+
uploadId: string;
|
|
100
|
+
key: string;
|
|
101
|
+
};
|
|
102
|
+
export type FinalizeMultipartUploadProps = {
|
|
103
|
+
bucketName?: string;
|
|
104
|
+
uploadId: string;
|
|
105
|
+
key: string;
|
|
106
|
+
};
|
|
82
107
|
export type UploadPartProps = {
|
|
83
108
|
key: string;
|
|
84
109
|
partNum: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/server/aws/s3/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,EACV,aAAa,EACb,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/server/aws/s3/types.ts"],"names":[],"mappings":"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"}
|
package/dist/server/index.cjs
CHANGED
|
@@ -1994,13 +1994,17 @@ var send2 = (ses, email) => {
|
|
|
1994
1994
|
// src/server/aws/s3/index.ts
|
|
1995
1995
|
var s3_exports = {};
|
|
1996
1996
|
__export(s3_exports, {
|
|
1997
|
-
|
|
1997
|
+
bucketExists: () => bucketExists,
|
|
1998
1998
|
create: () => create6,
|
|
1999
|
+
createBucket: () => createBucket,
|
|
1999
2000
|
createSignedUrl: () => createSignedUrl,
|
|
2001
|
+
deleteBucket: () => deleteBucket,
|
|
2000
2002
|
deleteFile: () => deleteFile,
|
|
2003
|
+
finalizeMultipartUpload: () => finalizeMultipartUpload,
|
|
2001
2004
|
getFile: () => getFile,
|
|
2002
2005
|
getFileMetadata: () => getFileMetadata,
|
|
2003
2006
|
migrateBucketContents: () => migrateBucketContents,
|
|
2007
|
+
prepareMultipartUpload: () => prepareMultipartUpload,
|
|
2004
2008
|
recordsFromSqs: () => recordsFromSqs,
|
|
2005
2009
|
uploadFile: () => uploadFile
|
|
2006
2010
|
});
|
|
@@ -2053,6 +2057,14 @@ function createSignedUrl(s3, props) {
|
|
|
2053
2057
|
params.Conditions.push(["starts-with", "$key", props.startsWith]);
|
|
2054
2058
|
}
|
|
2055
2059
|
return s3PresignedPost.createPresignedPost(s3.client, params);
|
|
2060
|
+
} else if (props.action === "multipart") {
|
|
2061
|
+
return prepareMultipartUpload(s3, {
|
|
2062
|
+
expiresInSecs: props.expiresInSecs,
|
|
2063
|
+
contentType: props.contentType,
|
|
2064
|
+
numOfParts: props.numOfParts,
|
|
2065
|
+
bucketName: props.bucketName,
|
|
2066
|
+
key: props.key
|
|
2067
|
+
});
|
|
2056
2068
|
} else {
|
|
2057
2069
|
throw new Error(
|
|
2058
2070
|
// @ts-expect-error - runtime check for invalid action
|
|
@@ -2107,31 +2119,28 @@ var getFileMetadata = async (s3, props) => {
|
|
|
2107
2119
|
throw err;
|
|
2108
2120
|
}
|
|
2109
2121
|
};
|
|
2110
|
-
|
|
2111
|
-
const
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
}
|
|
2128
|
-
console.log(err);
|
|
2129
|
-
throw err;
|
|
2122
|
+
var createBucket = (s3, bucketName) => {
|
|
2123
|
+
const command = new clientS3.CreateBucketCommand({ Bucket: bucketName });
|
|
2124
|
+
return s3.client.send(command);
|
|
2125
|
+
};
|
|
2126
|
+
var deleteBucket = (s3, bucketName) => {
|
|
2127
|
+
const command = new clientS3.DeleteBucketCommand({ Bucket: bucketName });
|
|
2128
|
+
return s3.client.send(command);
|
|
2129
|
+
};
|
|
2130
|
+
var bucketExists = async (s3, bucketName) => {
|
|
2131
|
+
try {
|
|
2132
|
+
const command = new clientS3.HeadBucketCommand({ Bucket: bucketName });
|
|
2133
|
+
await s3.client.send(command);
|
|
2134
|
+
return true;
|
|
2135
|
+
} catch (err) {
|
|
2136
|
+
const awsError = err;
|
|
2137
|
+
if (awsError.$metadata?.httpStatusCode === 404 || awsError.$metadata?.httpStatusCode === 400) {
|
|
2138
|
+
return false;
|
|
2130
2139
|
}
|
|
2131
|
-
|
|
2132
|
-
throw
|
|
2140
|
+
console.log(err);
|
|
2141
|
+
throw err;
|
|
2133
2142
|
}
|
|
2134
|
-
}
|
|
2143
|
+
};
|
|
2135
2144
|
var migrateBucketContents = async (s3, buckets) => {
|
|
2136
2145
|
const command = new clientS3.ListObjectsV2Command({ Bucket: buckets.from });
|
|
2137
2146
|
const srcFiles = await s3.client.send(command);
|
|
@@ -2147,6 +2156,60 @@ var migrateBucketContents = async (s3, buckets) => {
|
|
|
2147
2156
|
});
|
|
2148
2157
|
return Promise.all(s3Promises);
|
|
2149
2158
|
};
|
|
2159
|
+
var prepareMultipartUpload = async (s3, props) => {
|
|
2160
|
+
const Bucket = getBucketNameOrThrow(props.bucketName, s3.bucketName);
|
|
2161
|
+
const { key, contentType, numOfParts, expiresInSecs = 3600 } = props;
|
|
2162
|
+
const createCommand = new clientS3.CreateMultipartUploadCommand({
|
|
2163
|
+
ContentType: contentType,
|
|
2164
|
+
Key: key,
|
|
2165
|
+
Bucket
|
|
2166
|
+
});
|
|
2167
|
+
const { UploadId } = await s3.client.send(createCommand);
|
|
2168
|
+
if (!UploadId) {
|
|
2169
|
+
throw new Error("[s3] [prepareMultipartUpload] failed to get UploadId");
|
|
2170
|
+
}
|
|
2171
|
+
const signedUrls = [];
|
|
2172
|
+
for (let partNumber = 1; partNumber <= numOfParts; partNumber++) {
|
|
2173
|
+
const uploadPartCommand = new clientS3.UploadPartCommand({
|
|
2174
|
+
PartNumber: partNumber,
|
|
2175
|
+
Key: key,
|
|
2176
|
+
UploadId,
|
|
2177
|
+
Bucket
|
|
2178
|
+
});
|
|
2179
|
+
const url = await s3RequestPresigner.getSignedUrl(s3.client, uploadPartCommand, {
|
|
2180
|
+
expiresIn: expiresInSecs
|
|
2181
|
+
});
|
|
2182
|
+
signedUrls.push(url);
|
|
2183
|
+
}
|
|
2184
|
+
return { uploadId: UploadId, signedUrls, key };
|
|
2185
|
+
};
|
|
2186
|
+
var finalizeMultipartUpload = async (s3, props) => {
|
|
2187
|
+
const Bucket = getBucketNameOrThrow(props.bucketName, s3.bucketName);
|
|
2188
|
+
const { key, uploadId } = props;
|
|
2189
|
+
const listCommand = new clientS3.ListPartsCommand({
|
|
2190
|
+
UploadId: uploadId,
|
|
2191
|
+
Key: key,
|
|
2192
|
+
Bucket
|
|
2193
|
+
});
|
|
2194
|
+
const { Parts } = await s3.client.send(listCommand);
|
|
2195
|
+
if (!Parts || Parts.length === 0) {
|
|
2196
|
+
throw new Error(
|
|
2197
|
+
"[s3] [finalizeMultipartUpload] no parts found - ensure all parts were uploaded"
|
|
2198
|
+
);
|
|
2199
|
+
}
|
|
2200
|
+
const completeCommand = new clientS3.CompleteMultipartUploadCommand({
|
|
2201
|
+
Bucket,
|
|
2202
|
+
Key: key,
|
|
2203
|
+
UploadId: uploadId,
|
|
2204
|
+
MultipartUpload: {
|
|
2205
|
+
Parts: Parts.map((part) => ({
|
|
2206
|
+
PartNumber: part.PartNumber,
|
|
2207
|
+
ETag: part.ETag
|
|
2208
|
+
}))
|
|
2209
|
+
}
|
|
2210
|
+
});
|
|
2211
|
+
return s3.client.send(completeCommand);
|
|
2212
|
+
};
|
|
2150
2213
|
var recordsFromSqs = (body) => {
|
|
2151
2214
|
try {
|
|
2152
2215
|
const event = JSON.parse(body);
|
package/dist/server/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import signale from 'signale';
|
|
|
8
8
|
import { SNSClient, PublishCommand } from '@aws-sdk/client-sns';
|
|
9
9
|
import { SQSClient, SendMessageCommand } from '@aws-sdk/client-sqs';
|
|
10
10
|
import { SESClient, SendEmailCommand } from '@aws-sdk/client-ses';
|
|
11
|
-
import { S3Client, GetObjectCommand, PutObjectCommand, DeleteObjectCommand, HeadObjectCommand, CreateBucketCommand, DeleteBucketCommand, HeadBucketCommand, ListObjectsV2Command, CopyObjectCommand } from '@aws-sdk/client-s3';
|
|
11
|
+
import { S3Client, GetObjectCommand, PutObjectCommand, DeleteObjectCommand, HeadObjectCommand, CreateBucketCommand, DeleteBucketCommand, HeadBucketCommand, ListObjectsV2Command, CopyObjectCommand, CreateMultipartUploadCommand, UploadPartCommand, ListPartsCommand, CompleteMultipartUploadCommand } from '@aws-sdk/client-s3';
|
|
12
12
|
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
|
13
13
|
import { createPresignedPost } from '@aws-sdk/s3-presigned-post';
|
|
14
14
|
|
|
@@ -1986,13 +1986,17 @@ var send2 = (ses, email) => {
|
|
|
1986
1986
|
// src/server/aws/s3/index.ts
|
|
1987
1987
|
var s3_exports = {};
|
|
1988
1988
|
__export(s3_exports, {
|
|
1989
|
-
|
|
1989
|
+
bucketExists: () => bucketExists,
|
|
1990
1990
|
create: () => create6,
|
|
1991
|
+
createBucket: () => createBucket,
|
|
1991
1992
|
createSignedUrl: () => createSignedUrl,
|
|
1993
|
+
deleteBucket: () => deleteBucket,
|
|
1992
1994
|
deleteFile: () => deleteFile,
|
|
1995
|
+
finalizeMultipartUpload: () => finalizeMultipartUpload,
|
|
1993
1996
|
getFile: () => getFile,
|
|
1994
1997
|
getFileMetadata: () => getFileMetadata,
|
|
1995
1998
|
migrateBucketContents: () => migrateBucketContents,
|
|
1999
|
+
prepareMultipartUpload: () => prepareMultipartUpload,
|
|
1996
2000
|
recordsFromSqs: () => recordsFromSqs,
|
|
1997
2001
|
uploadFile: () => uploadFile
|
|
1998
2002
|
});
|
|
@@ -2045,6 +2049,14 @@ function createSignedUrl(s3, props) {
|
|
|
2045
2049
|
params.Conditions.push(["starts-with", "$key", props.startsWith]);
|
|
2046
2050
|
}
|
|
2047
2051
|
return createPresignedPost(s3.client, params);
|
|
2052
|
+
} else if (props.action === "multipart") {
|
|
2053
|
+
return prepareMultipartUpload(s3, {
|
|
2054
|
+
expiresInSecs: props.expiresInSecs,
|
|
2055
|
+
contentType: props.contentType,
|
|
2056
|
+
numOfParts: props.numOfParts,
|
|
2057
|
+
bucketName: props.bucketName,
|
|
2058
|
+
key: props.key
|
|
2059
|
+
});
|
|
2048
2060
|
} else {
|
|
2049
2061
|
throw new Error(
|
|
2050
2062
|
// @ts-expect-error - runtime check for invalid action
|
|
@@ -2099,31 +2111,28 @@ var getFileMetadata = async (s3, props) => {
|
|
|
2099
2111
|
throw err;
|
|
2100
2112
|
}
|
|
2101
2113
|
};
|
|
2102
|
-
|
|
2103
|
-
const
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
}
|
|
2120
|
-
console.log(err);
|
|
2121
|
-
throw err;
|
|
2114
|
+
var createBucket = (s3, bucketName) => {
|
|
2115
|
+
const command = new CreateBucketCommand({ Bucket: bucketName });
|
|
2116
|
+
return s3.client.send(command);
|
|
2117
|
+
};
|
|
2118
|
+
var deleteBucket = (s3, bucketName) => {
|
|
2119
|
+
const command = new DeleteBucketCommand({ Bucket: bucketName });
|
|
2120
|
+
return s3.client.send(command);
|
|
2121
|
+
};
|
|
2122
|
+
var bucketExists = async (s3, bucketName) => {
|
|
2123
|
+
try {
|
|
2124
|
+
const command = new HeadBucketCommand({ Bucket: bucketName });
|
|
2125
|
+
await s3.client.send(command);
|
|
2126
|
+
return true;
|
|
2127
|
+
} catch (err) {
|
|
2128
|
+
const awsError = err;
|
|
2129
|
+
if (awsError.$metadata?.httpStatusCode === 404 || awsError.$metadata?.httpStatusCode === 400) {
|
|
2130
|
+
return false;
|
|
2122
2131
|
}
|
|
2123
|
-
|
|
2124
|
-
throw
|
|
2132
|
+
console.log(err);
|
|
2133
|
+
throw err;
|
|
2125
2134
|
}
|
|
2126
|
-
}
|
|
2135
|
+
};
|
|
2127
2136
|
var migrateBucketContents = async (s3, buckets) => {
|
|
2128
2137
|
const command = new ListObjectsV2Command({ Bucket: buckets.from });
|
|
2129
2138
|
const srcFiles = await s3.client.send(command);
|
|
@@ -2139,6 +2148,60 @@ var migrateBucketContents = async (s3, buckets) => {
|
|
|
2139
2148
|
});
|
|
2140
2149
|
return Promise.all(s3Promises);
|
|
2141
2150
|
};
|
|
2151
|
+
var prepareMultipartUpload = async (s3, props) => {
|
|
2152
|
+
const Bucket = getBucketNameOrThrow(props.bucketName, s3.bucketName);
|
|
2153
|
+
const { key, contentType, numOfParts, expiresInSecs = 3600 } = props;
|
|
2154
|
+
const createCommand = new CreateMultipartUploadCommand({
|
|
2155
|
+
ContentType: contentType,
|
|
2156
|
+
Key: key,
|
|
2157
|
+
Bucket
|
|
2158
|
+
});
|
|
2159
|
+
const { UploadId } = await s3.client.send(createCommand);
|
|
2160
|
+
if (!UploadId) {
|
|
2161
|
+
throw new Error("[s3] [prepareMultipartUpload] failed to get UploadId");
|
|
2162
|
+
}
|
|
2163
|
+
const signedUrls = [];
|
|
2164
|
+
for (let partNumber = 1; partNumber <= numOfParts; partNumber++) {
|
|
2165
|
+
const uploadPartCommand = new UploadPartCommand({
|
|
2166
|
+
PartNumber: partNumber,
|
|
2167
|
+
Key: key,
|
|
2168
|
+
UploadId,
|
|
2169
|
+
Bucket
|
|
2170
|
+
});
|
|
2171
|
+
const url = await getSignedUrl(s3.client, uploadPartCommand, {
|
|
2172
|
+
expiresIn: expiresInSecs
|
|
2173
|
+
});
|
|
2174
|
+
signedUrls.push(url);
|
|
2175
|
+
}
|
|
2176
|
+
return { uploadId: UploadId, signedUrls, key };
|
|
2177
|
+
};
|
|
2178
|
+
var finalizeMultipartUpload = async (s3, props) => {
|
|
2179
|
+
const Bucket = getBucketNameOrThrow(props.bucketName, s3.bucketName);
|
|
2180
|
+
const { key, uploadId } = props;
|
|
2181
|
+
const listCommand = new ListPartsCommand({
|
|
2182
|
+
UploadId: uploadId,
|
|
2183
|
+
Key: key,
|
|
2184
|
+
Bucket
|
|
2185
|
+
});
|
|
2186
|
+
const { Parts } = await s3.client.send(listCommand);
|
|
2187
|
+
if (!Parts || Parts.length === 0) {
|
|
2188
|
+
throw new Error(
|
|
2189
|
+
"[s3] [finalizeMultipartUpload] no parts found - ensure all parts were uploaded"
|
|
2190
|
+
);
|
|
2191
|
+
}
|
|
2192
|
+
const completeCommand = new CompleteMultipartUploadCommand({
|
|
2193
|
+
Bucket,
|
|
2194
|
+
Key: key,
|
|
2195
|
+
UploadId: uploadId,
|
|
2196
|
+
MultipartUpload: {
|
|
2197
|
+
Parts: Parts.map((part) => ({
|
|
2198
|
+
PartNumber: part.PartNumber,
|
|
2199
|
+
ETag: part.ETag
|
|
2200
|
+
}))
|
|
2201
|
+
}
|
|
2202
|
+
});
|
|
2203
|
+
return s3.client.send(completeCommand);
|
|
2204
|
+
};
|
|
2142
2205
|
var recordsFromSqs = (body) => {
|
|
2143
2206
|
try {
|
|
2144
2207
|
const event = JSON.parse(body);
|