qstd 0.3.55 → 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.
|
@@ -3,14 +3,19 @@ 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
|
|
@@ -44,6 +49,42 @@ export declare const bucketExists: (s3: _t.Client, bucketName: string) => Promis
|
|
|
44
49
|
* @returns
|
|
45
50
|
*/
|
|
46
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>;
|
|
47
88
|
/**
|
|
48
89
|
* Parse and decode S3 records from an SQS message body.
|
|
49
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":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,EACV,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAEvE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC;AAExC,2DAA2D;AAC3D,MAAM,MAAM,SAAS,GAAG;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IACnB,MAAM,EAAE,QAAQ,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhE,MAAM,MAAM,kBAAkB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9D,MAAM,MAAM,cAAc,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,KAAK,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,cAAc,GAAG;IAChD,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,WAAW,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,cAAc,GACtB,iBAAiB,GACjB,kBAAkB,GAClB,uBAAuB,CAAC;AAE5B,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,qBAAqB,CAAC,MAAM,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,UAAU,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAMF,MAAM,MAAM,2BAA2B,GAAG;IACxC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,oBAAoB,CAAC"}
|
package/dist/server/index.cjs
CHANGED
|
@@ -2000,9 +2000,11 @@ __export(s3_exports, {
|
|
|
2000
2000
|
createSignedUrl: () => createSignedUrl,
|
|
2001
2001
|
deleteBucket: () => deleteBucket,
|
|
2002
2002
|
deleteFile: () => deleteFile,
|
|
2003
|
+
finalizeMultipartUpload: () => finalizeMultipartUpload,
|
|
2003
2004
|
getFile: () => getFile,
|
|
2004
2005
|
getFileMetadata: () => getFileMetadata,
|
|
2005
2006
|
migrateBucketContents: () => migrateBucketContents,
|
|
2007
|
+
prepareMultipartUpload: () => prepareMultipartUpload,
|
|
2006
2008
|
recordsFromSqs: () => recordsFromSqs,
|
|
2007
2009
|
uploadFile: () => uploadFile
|
|
2008
2010
|
});
|
|
@@ -2055,6 +2057,14 @@ function createSignedUrl(s3, props) {
|
|
|
2055
2057
|
params.Conditions.push(["starts-with", "$key", props.startsWith]);
|
|
2056
2058
|
}
|
|
2057
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
|
+
});
|
|
2058
2068
|
} else {
|
|
2059
2069
|
throw new Error(
|
|
2060
2070
|
// @ts-expect-error - runtime check for invalid action
|
|
@@ -2146,6 +2156,60 @@ var migrateBucketContents = async (s3, buckets) => {
|
|
|
2146
2156
|
});
|
|
2147
2157
|
return Promise.all(s3Promises);
|
|
2148
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
|
+
};
|
|
2149
2213
|
var recordsFromSqs = (body) => {
|
|
2150
2214
|
try {
|
|
2151
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
|
|
|
@@ -1992,9 +1992,11 @@ __export(s3_exports, {
|
|
|
1992
1992
|
createSignedUrl: () => createSignedUrl,
|
|
1993
1993
|
deleteBucket: () => deleteBucket,
|
|
1994
1994
|
deleteFile: () => deleteFile,
|
|
1995
|
+
finalizeMultipartUpload: () => finalizeMultipartUpload,
|
|
1995
1996
|
getFile: () => getFile,
|
|
1996
1997
|
getFileMetadata: () => getFileMetadata,
|
|
1997
1998
|
migrateBucketContents: () => migrateBucketContents,
|
|
1999
|
+
prepareMultipartUpload: () => prepareMultipartUpload,
|
|
1998
2000
|
recordsFromSqs: () => recordsFromSqs,
|
|
1999
2001
|
uploadFile: () => uploadFile
|
|
2000
2002
|
});
|
|
@@ -2047,6 +2049,14 @@ function createSignedUrl(s3, props) {
|
|
|
2047
2049
|
params.Conditions.push(["starts-with", "$key", props.startsWith]);
|
|
2048
2050
|
}
|
|
2049
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
|
+
});
|
|
2050
2060
|
} else {
|
|
2051
2061
|
throw new Error(
|
|
2052
2062
|
// @ts-expect-error - runtime check for invalid action
|
|
@@ -2138,6 +2148,60 @@ var migrateBucketContents = async (s3, buckets) => {
|
|
|
2138
2148
|
});
|
|
2139
2149
|
return Promise.all(s3Promises);
|
|
2140
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
|
+
};
|
|
2141
2205
|
var recordsFromSqs = (body) => {
|
|
2142
2206
|
try {
|
|
2143
2207
|
const event = JSON.parse(body);
|