@geekmidas/storage 2.0.1 → 2.0.2
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.
- package/CHANGELOG.md +6 -0
- package/dist/{AmazonStorageClient-BzoByQDt.d.cts → AmazonStorageClient-BHpWawGD.d.mts} +3 -2
- package/dist/AmazonStorageClient-BHpWawGD.d.mts.map +1 -0
- package/dist/{AmazonStorageClient-Z61MeFBa.d.mts → AmazonStorageClient-BNoY2PL6.d.cts} +3 -2
- package/dist/AmazonStorageClient-BNoY2PL6.d.cts.map +1 -0
- package/dist/{AmazonStorageClient-C63eEnlC.cjs → AmazonStorageClient-BvoZepKJ.cjs} +11 -11
- package/dist/AmazonStorageClient-BvoZepKJ.cjs.map +1 -0
- package/dist/{AmazonStorageClient-CKdLCAKb.mjs → AmazonStorageClient-Dz-KCJ_4.mjs} +11 -11
- package/dist/AmazonStorageClient-Dz-KCJ_4.mjs.map +1 -0
- package/dist/AmazonStorageClient.cjs +1 -1
- package/dist/AmazonStorageClient.d.cts +2 -2
- package/dist/AmazonStorageClient.d.mts +2 -2
- package/dist/AmazonStorageClient.mjs +1 -1
- package/dist/StorageClient-4ADnTPnJ.mjs.map +1 -1
- package/dist/StorageClient-BDRVrMJj.cjs.map +1 -1
- package/dist/{StorageClient-CF0gnATD.d.mts → StorageClient-COs9SOsU.d.cts} +12 -1
- package/dist/{StorageClient-BQBlgTzu.d.cts.map → StorageClient-COs9SOsU.d.cts.map} +1 -1
- package/dist/{StorageClient-BQBlgTzu.d.cts → StorageClient-DH4tP-Mf.d.mts} +12 -1
- package/dist/{StorageClient-CF0gnATD.d.mts.map → StorageClient-DH4tP-Mf.d.mts.map} +1 -1
- package/dist/StorageClient.d.cts +1 -1
- package/dist/StorageClient.d.mts +1 -1
- package/dist/aws.cjs +1 -1
- package/dist/aws.d.cts +2 -2
- package/dist/aws.d.mts +2 -2
- package/dist/aws.mjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/package.json +1 -1
- package/src/AmazonStorageClient.ts +17 -15
- package/src/StorageClient.ts +11 -0
- package/src/__tests__/AmazonStorageClient.spec.ts +70 -0
- package/src/__tests__/StorageClient.spec.ts +9 -0
- package/dist/AmazonStorageClient-BzoByQDt.d.cts.map +0 -1
- package/dist/AmazonStorageClient-C63eEnlC.cjs.map +0 -1
- package/dist/AmazonStorageClient-CKdLCAKb.mjs.map +0 -1
- package/dist/AmazonStorageClient-Z61MeFBa.d.mts.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @geekmidas/storage
|
|
2
2
|
|
|
3
|
+
## 2.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- ✨ [`f843d08`](https://github.com/geekmidas/toolbox/commit/f843d08e512d5d5410fb93376a8b9b127434ff39) Thanks [@geekmidas](https://github.com/geekmidas)! - Add response type and content dispotion
|
|
8
|
+
|
|
3
9
|
## 2.0.1
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DocumentVersion, File, GetUploadParams, GetUploadResponse, StorageClient, StorageProvider } from "./StorageClient-
|
|
1
|
+
import { DocumentVersion, File, GetUploadParams, GetUploadResponse, StorageClient, StorageProvider } from "./StorageClient-DH4tP-Mf.mjs";
|
|
2
2
|
import { S3Client } from "@aws-sdk/client-s3";
|
|
3
3
|
import { Cache } from "@geekmidas/cache";
|
|
4
4
|
|
|
@@ -11,6 +11,7 @@ declare class AmazonStorageClient implements StorageClient {
|
|
|
11
11
|
readonly provider = StorageProvider.AWSS3;
|
|
12
12
|
static create(options: AmazonStorageClientCreateOptions): AmazonStorageClient;
|
|
13
13
|
constructor(client: S3Client, bucket: string, acl?: AmazonCannedAccessControlList, cache?: Cache);
|
|
14
|
+
private createGetObjectCommand;
|
|
14
15
|
getVersionDownloadURL(file: File, versionId: string): Promise<string>;
|
|
15
16
|
getVersions(key: string): Promise<DocumentVersion[]>;
|
|
16
17
|
getDownloadURL(file: File, expiresIn?: number): Promise<string>;
|
|
@@ -41,4 +42,4 @@ interface AmazonStorageClientCreateOptions {
|
|
|
41
42
|
}
|
|
42
43
|
//#endregion
|
|
43
44
|
export { AmazonCannedAccessControlList, AmazonStorageClient };
|
|
44
|
-
//# sourceMappingURL=AmazonStorageClient-
|
|
45
|
+
//# sourceMappingURL=AmazonStorageClient-BHpWawGD.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AmazonStorageClient-BHpWawGD.d.mts","names":[],"sources":["../src/AmazonStorageClient.ts"],"sourcesContent":[],"mappings":";;;;;cAoBa,mBAAA,YAA+B;;EAA/B,iBAAA,MAAoB;EAAA,iBAAA,GAAA;EAAA,SAkCd,KAAA,CAAA,EAAA,KAAA;EAAK,SAjCN,QAAA,GAAA,eAAA,CAAA,KAAA;EAAA,OAGP,MAAA,CAAA,OAAA,EAAA,gCAAA,CAAA,EACP,mBADO;EAAgC,WACvC,CAAA,MAAA,EA0BuB,QA1BvB,EAAA,MAAA,EAAA,MAAA,EAAA,GAAA,CAAA,EA4BkB,6BA5BlB,EAAA,KAAA,CAAA,EA6Be,KA7Bf;EAAmB,QA0BI,sBAAA;EAAQ,qBAEb,CAAA,IAAA,EAyBO,IAzBP,EAAA,SAAA,EAAA,MAAA,CAAA,EAyBiC,OAzBjC,CAAA,MAAA,CAAA;EAAkD,WACrD,CAAA,GAAA,EAAA,MAAA,CAAA,EA6Bc,OA7Bd,CA6BsB,eA7BtB,EAAA,CAAA;EAAK,cAwBK,CAAA,IAAA,EAmBD,IAnBC,EAAA,SAAA,CAAA,EAAA,MAAA,CAAA,EAmB2B,OAnB3B,CAAA,MAAA,CAAA;EAAI,YAAsB,CAAA,MAAA,EAuC7C,eAvC6C,EAAA,SAAA,CAAA,EAAA,MAAA,CAAA,EAyCnD,OAzCmD,CAAA,MAAA,CAAA;EAAO,SAKrB,CAAA,MAAA,EAgD/B,eAhD+B,EAAA,SAAA,CAAA,EAAA,MAAA,CAAA,EAkDrC,OAlDqC,CAkD7B,iBAlD6B,CAAA;EAAe,MAAvB,CAAA,GAAA,EAAA,MAAA,EAAA,IAAA,EAAA,MAAA,GA4EhB,MA5EgB,EAAA,WAAA,EAAA,MAAA,CAAA,EA8E7B,OA9E6B,CAAA,IAAA,CAAA;EAAO,MAcZ,CAAA,GAAA,EAAA,MAAA,CAAA,EA+EA,OA/EA,CAAA,IAAA,CAAA;;AAoBlB,aAqEE,6BAAA;EArEa,iBAErB,GAAA,oBAAA;EAAO,OAYD,GAAA,SAAA;EAAe,UAEb,GAAA,aAAA;EAAiB,eAAzB,GAAA,mBAAA;EAAO,WA0BM,GAAA,eAAA;EAAM,eAEnB,GAAA,mBAAA;EAAO,sBAeiB,GAAA,2BAAA;EAAO,gBA5JS,GAAA,oBAAA;AAAa;AAsKzD,UAWU,gCAAA,CAX+B;EAW/B,MAAA,EAAA,MAAA;EAAgC,MAAA,CAAA,EAAA,MAAA;EAAA,GAGnC,CAAA,EAAA,6BAAA;EAA6B,WAK3B,CAAA,EAAA,MAAA;EAAK,eAAA,CAAA,EAAA,MAAA;;;UAAL"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DocumentVersion, File, GetUploadParams, GetUploadResponse, StorageClient, StorageProvider } from "./StorageClient-
|
|
1
|
+
import { DocumentVersion, File, GetUploadParams, GetUploadResponse, StorageClient, StorageProvider } from "./StorageClient-COs9SOsU.cjs";
|
|
2
2
|
import { S3Client } from "@aws-sdk/client-s3";
|
|
3
3
|
import { Cache } from "@geekmidas/cache";
|
|
4
4
|
|
|
@@ -11,6 +11,7 @@ declare class AmazonStorageClient implements StorageClient {
|
|
|
11
11
|
readonly provider = StorageProvider.AWSS3;
|
|
12
12
|
static create(options: AmazonStorageClientCreateOptions): AmazonStorageClient;
|
|
13
13
|
constructor(client: S3Client, bucket: string, acl?: AmazonCannedAccessControlList, cache?: Cache);
|
|
14
|
+
private createGetObjectCommand;
|
|
14
15
|
getVersionDownloadURL(file: File, versionId: string): Promise<string>;
|
|
15
16
|
getVersions(key: string): Promise<DocumentVersion[]>;
|
|
16
17
|
getDownloadURL(file: File, expiresIn?: number): Promise<string>;
|
|
@@ -41,4 +42,4 @@ interface AmazonStorageClientCreateOptions {
|
|
|
41
42
|
}
|
|
42
43
|
//#endregion
|
|
43
44
|
export { AmazonCannedAccessControlList, AmazonStorageClient };
|
|
44
|
-
//# sourceMappingURL=AmazonStorageClient-
|
|
45
|
+
//# sourceMappingURL=AmazonStorageClient-BNoY2PL6.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AmazonStorageClient-BNoY2PL6.d.cts","names":[],"sources":["../src/AmazonStorageClient.ts"],"sourcesContent":[],"mappings":";;;;;cAoBa,mBAAA,YAA+B;;EAA/B,iBAAA,MAAoB;EAAA,iBAAA,GAAA;EAAA,SAkCd,KAAA,CAAA,EAAA,KAAA;EAAK,SAjCN,QAAA,GAAA,eAAA,CAAA,KAAA;EAAA,OAGP,MAAA,CAAA,OAAA,EAAA,gCAAA,CAAA,EACP,mBADO;EAAgC,WACvC,CAAA,MAAA,EA0BuB,QA1BvB,EAAA,MAAA,EAAA,MAAA,EAAA,GAAA,CAAA,EA4BkB,6BA5BlB,EAAA,KAAA,CAAA,EA6Be,KA7Bf;EAAmB,QA0BI,sBAAA;EAAQ,qBAEb,CAAA,IAAA,EAyBO,IAzBP,EAAA,SAAA,EAAA,MAAA,CAAA,EAyBiC,OAzBjC,CAAA,MAAA,CAAA;EAAkD,WACrD,CAAA,GAAA,EAAA,MAAA,CAAA,EA6Bc,OA7Bd,CA6BsB,eA7BtB,EAAA,CAAA;EAAK,cAwBK,CAAA,IAAA,EAmBD,IAnBC,EAAA,SAAA,CAAA,EAAA,MAAA,CAAA,EAmB2B,OAnB3B,CAAA,MAAA,CAAA;EAAI,YAAsB,CAAA,MAAA,EAuC7C,eAvC6C,EAAA,SAAA,CAAA,EAAA,MAAA,CAAA,EAyCnD,OAzCmD,CAAA,MAAA,CAAA;EAAO,SAKrB,CAAA,MAAA,EAgD/B,eAhD+B,EAAA,SAAA,CAAA,EAAA,MAAA,CAAA,EAkDrC,OAlDqC,CAkD7B,iBAlD6B,CAAA;EAAe,MAAvB,CAAA,GAAA,EAAA,MAAA,EAAA,IAAA,EAAA,MAAA,GA4EhB,MA5EgB,EAAA,WAAA,EAAA,MAAA,CAAA,EA8E7B,OA9E6B,CAAA,IAAA,CAAA;EAAO,MAcZ,CAAA,GAAA,EAAA,MAAA,CAAA,EA+EA,OA/EA,CAAA,IAAA,CAAA;;AAoBlB,aAqEE,6BAAA;EArEa,iBAErB,GAAA,oBAAA;EAAO,OAYD,GAAA,SAAA;EAAe,UAEb,GAAA,aAAA;EAAiB,eAAzB,GAAA,mBAAA;EAAO,WA0BM,GAAA,eAAA;EAAM,eAEnB,GAAA,mBAAA;EAAO,sBAeiB,GAAA,2BAAA;EAAO,gBA5JS,GAAA,oBAAA;AAAa;AAsKzD,UAWU,gCAAA,CAX+B;EAW/B,MAAA,EAAA,MAAA;EAAgC,MAAA,CAAA,EAAA,MAAA;EAAA,GAGnC,CAAA,EAAA,6BAAA;EAA6B,WAK3B,CAAA,EAAA,MAAA;EAAK,eAAA,CAAA,EAAA,MAAA;;;UAAL"}
|
|
@@ -50,14 +50,19 @@ var AmazonStorageClient = class AmazonStorageClient {
|
|
|
50
50
|
this.acl = acl;
|
|
51
51
|
this.cache = cache;
|
|
52
52
|
}
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
const
|
|
53
|
+
createGetObjectCommand(file, overrides) {
|
|
54
|
+
const disposition = file.disposition ?? (file.name ? "attachment" : void 0);
|
|
55
|
+
const ResponseContentDisposition = disposition ? file.name ? `${disposition}; filename=${encodeURIComponent(file.name)}` : disposition : void 0;
|
|
56
|
+
return new __aws_sdk_client_s3.GetObjectCommand({
|
|
56
57
|
Bucket: this.bucket,
|
|
57
58
|
Key: file.path,
|
|
58
59
|
ResponseContentDisposition,
|
|
59
|
-
|
|
60
|
+
ResponseContentType: file.responseContentType,
|
|
61
|
+
...overrides
|
|
60
62
|
});
|
|
63
|
+
}
|
|
64
|
+
getVersionDownloadURL(file, versionId) {
|
|
65
|
+
const command = this.createGetObjectCommand(file, { VersionId: versionId });
|
|
61
66
|
return (0, __aws_sdk_s3_request_presigner.getSignedUrl)(this.client, command, { expiresIn: 60 * 60 * 24 });
|
|
62
67
|
}
|
|
63
68
|
async getVersions(key) {
|
|
@@ -75,12 +80,7 @@ var AmazonStorageClient = class AmazonStorageClient {
|
|
|
75
80
|
const cacheKey = `download-url:${file.path}`;
|
|
76
81
|
const cachedURL = await this.cache?.get(cacheKey);
|
|
77
82
|
if (cachedURL) return cachedURL;
|
|
78
|
-
const
|
|
79
|
-
const command = new __aws_sdk_client_s3.GetObjectCommand({
|
|
80
|
-
Bucket: this.bucket,
|
|
81
|
-
Key: file.path,
|
|
82
|
-
ResponseContentDisposition
|
|
83
|
-
});
|
|
83
|
+
const command = this.createGetObjectCommand(file);
|
|
84
84
|
const url = await (0, __aws_sdk_s3_request_presigner.getSignedUrl)(this.client, command, { expiresIn });
|
|
85
85
|
const cacheExpiration = Math.max(expiresIn - 60, 0);
|
|
86
86
|
if (cacheExpiration) await this.cache?.set(cacheKey, url, cacheExpiration);
|
|
@@ -158,4 +158,4 @@ Object.defineProperty(exports, 'AmazonStorageClient', {
|
|
|
158
158
|
return AmazonStorageClient;
|
|
159
159
|
}
|
|
160
160
|
});
|
|
161
|
-
//# sourceMappingURL=AmazonStorageClient-
|
|
161
|
+
//# sourceMappingURL=AmazonStorageClient-BvoZepKJ.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AmazonStorageClient-BvoZepKJ.cjs","names":["StorageProvider","options: AmazonStorageClientCreateOptions","S3Client","client: S3Client","bucket: string","cache?: Cache","file: File","overrides?: { VersionId?: string }","GetObjectCommand","versionId: string","key: string","ListObjectVersionsCommand","params: GetUploadParams","PutObjectCommand","data: string | Buffer","contentType: string","DeleteObjectCommand"],"sources":["../src/AmazonStorageClient.ts"],"sourcesContent":["import {\n\tDeleteObjectCommand,\n\tGetObjectCommand,\n\tListObjectVersionsCommand,\n\tPutObjectCommand,\n\tS3Client,\n} from '@aws-sdk/client-s3';\nimport { createPresignedPost } from '@aws-sdk/s3-presigned-post';\nimport { getSignedUrl } from '@aws-sdk/s3-request-presigner';\n\nimport type { Cache } from '@geekmidas/cache';\nimport {\n\ttype DocumentVersion,\n\ttype File,\n\ttype GetUploadParams,\n\ttype GetUploadResponse,\n\ttype StorageClient,\n\tStorageProvider,\n} from './StorageClient';\n\nexport class AmazonStorageClient implements StorageClient {\n\treadonly provider = StorageProvider.AWSS3;\n\n\tstatic create(\n\t\toptions: AmazonStorageClientCreateOptions,\n\t): AmazonStorageClient {\n\t\tconst {\n\t\t\tbucket,\n\t\t\tregion,\n\t\t\taccessKeyId,\n\t\t\tacl,\n\t\t\tendpoint,\n\t\t\tsecretAccessKey,\n\t\t\tforcePathStyle = false,\n\t\t\tcache,\n\t\t} = options;\n\t\tconst hasCredentials = accessKeyId && secretAccessKey;\n\t\tconst credentials = hasCredentials\n\t\t\t? { accessKeyId, secretAccessKey }\n\t\t\t: undefined;\n\n\t\tconst client = new S3Client({\n\t\t\tregion,\n\t\t\tcredentials,\n\t\t\tendpoint,\n\t\t\tforcePathStyle,\n\t\t});\n\n\t\treturn new AmazonStorageClient(client, bucket, acl, cache);\n\t}\n\tconstructor(\n\t\tprivate readonly client: S3Client,\n\t\tprivate readonly bucket: string,\n\t\tprivate readonly acl = AmazonCannedAccessControlList.AuthenticatedRead,\n\t\treadonly cache?: Cache,\n\t) {}\n\n\tprivate createGetObjectCommand(\n\t\tfile: File,\n\t\toverrides?: { VersionId?: string },\n\t): GetObjectCommand {\n\t\tconst disposition =\n\t\t\tfile.disposition ?? (file.name ? 'attachment' : undefined);\n\t\tconst ResponseContentDisposition = disposition\n\t\t\t? file.name\n\t\t\t\t? `${disposition}; filename=${encodeURIComponent(file.name)}`\n\t\t\t\t: disposition\n\t\t\t: undefined;\n\n\t\treturn new GetObjectCommand({\n\t\t\tBucket: this.bucket,\n\t\t\tKey: file.path,\n\t\t\tResponseContentDisposition,\n\t\t\tResponseContentType: file.responseContentType,\n\t\t\t...overrides,\n\t\t});\n\t}\n\n\tgetVersionDownloadURL(file: File, versionId: string): Promise<string> {\n\t\tconst command = this.createGetObjectCommand(file, { VersionId: versionId });\n\t\treturn getSignedUrl(this.client, command, { expiresIn: 60 * 60 * 24 });\n\t}\n\n\tasync getVersions(key: string): Promise<DocumentVersion[]> {\n\t\tconst command = new ListObjectVersionsCommand({\n\t\t\tBucket: this.bucket,\n\t\t\tPrefix: key,\n\t\t});\n\n\t\tconst { Versions = [] } = await this.client.send(command);\n\n\t\treturn Versions.map((version) => ({\n\t\t\tid: version.VersionId || '',\n\t\t\tcreatedAt: version.LastModified || new Date(),\n\t\t}));\n\t}\n\n\tasync getDownloadURL(file: File, expiresIn = 60 * 60): Promise<string> {\n\t\tconst cacheKey = `download-url:${file.path}`;\n\t\tconst cachedURL = await this.cache?.get<string>(cacheKey);\n\n\t\tif (cachedURL) {\n\t\t\treturn cachedURL;\n\t\t}\n\n\t\tconst command = this.createGetObjectCommand(file);\n\t\tconst url = await getSignedUrl(this.client, command, { expiresIn });\n\t\tconst cacheExpiration = Math.max(expiresIn - 60, 0);\n\n\t\tif (cacheExpiration) {\n\t\t\tawait this.cache?.set(cacheKey, url, cacheExpiration);\n\t\t}\n\n\t\treturn url;\n\t}\n\n\tasync getUploadURL(\n\t\tparams: GetUploadParams,\n\t\texpiresIn = 60 * 60,\n\t): Promise<string> {\n\t\tconst command = new PutObjectCommand({\n\t\t\tBucket: this.bucket,\n\t\t\tKey: params.path,\n\t\t\tContentType: params.contentType,\n\t\t\tContentLength: params.contentLength,\n\t\t});\n\n\t\treturn getSignedUrl(this.client, command, { expiresIn });\n\t}\n\n\tasync getUpload(\n\t\tparams: GetUploadParams,\n\t\texpiresIn = 5,\n\t): Promise<GetUploadResponse> {\n\t\tconst { path } = params;\n\t\tconst { fields: values, url } = await createPresignedPost(this.client, {\n\t\t\tExpires: expiresIn * 60,\n\t\t\tBucket: this.bucket,\n\t\t\tFields: {\n\t\t\t\tacl: this.acl,\n\t\t\t},\n\t\t\tConditions: [\n\t\t\t\t// content length restrictions: 0-1MB]\n\t\t\t\t// ['content-length-range', 0, contentLength],\n\t\t\t\t// specify content-type to be more generic- images only\n\t\t\t\t// ['starts-with', '$Content-Type', 'image/'],\n\t\t\t\t// ['starts-with', '$Content-Type', contentType],\n\t\t\t],\n\t\t\tKey: path,\n\t\t});\n\n\t\tconst keys = Object.keys(values);\n\t\tconst fields = keys.map((key) => ({ key, value: values[key] || '' }));\n\n\t\treturn { url, fields };\n\t}\n\n\tasync upload(\n\t\tkey: string,\n\t\tdata: string | Buffer,\n\t\tcontentType: string,\n\t): Promise<void> {\n\t\tconst Body = typeof data === 'string' ? Buffer.from(data, 'base64') : data;\n\n\t\tconst params = {\n\t\t\tBucket: this.bucket,\n\t\t\tKey: key,\n\t\t\tBody,\n\t\t\tContentType: contentType,\n\t\t};\n\n\t\tconst command = new PutObjectCommand(params);\n\n\t\tawait this.client.send(command);\n\t}\n\n\tasync delete(key: string): Promise<void> {\n\t\tconst command = new DeleteObjectCommand({\n\t\t\tBucket: this.bucket,\n\t\t\tKey: key,\n\t\t});\n\n\t\tawait this.client.send(command);\n\t}\n}\n\nexport enum AmazonCannedAccessControlList {\n\tAuthenticatedRead = 'authenticated-read',\n\tPrivate = 'private',\n\tPublicRead = 'public-read',\n\tPublicReadWrite = 'public-read-write',\n\tAwsExecRead = 'aws-exec-read',\n\tBucketOwnerRead = 'bucket-owner-read',\n\tBucketOwnerFullControl = 'bucket-owner-full-control',\n\tLogDeliveryWrite = 'log-delivery-write',\n}\n\ninterface AmazonStorageClientCreateOptions {\n\tbucket: string;\n\tregion?: string;\n\tacl?: AmazonCannedAccessControlList;\n\taccessKeyId?: string;\n\tsecretAccessKey?: string;\n\tendpoint?: string;\n\tforcePathStyle?: boolean;\n\tcache?: Cache;\n}\n"],"mappings":"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"}
|
|
@@ -27,14 +27,19 @@ var AmazonStorageClient = class AmazonStorageClient {
|
|
|
27
27
|
this.acl = acl;
|
|
28
28
|
this.cache = cache;
|
|
29
29
|
}
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
const
|
|
30
|
+
createGetObjectCommand(file, overrides) {
|
|
31
|
+
const disposition = file.disposition ?? (file.name ? "attachment" : void 0);
|
|
32
|
+
const ResponseContentDisposition = disposition ? file.name ? `${disposition}; filename=${encodeURIComponent(file.name)}` : disposition : void 0;
|
|
33
|
+
return new GetObjectCommand({
|
|
33
34
|
Bucket: this.bucket,
|
|
34
35
|
Key: file.path,
|
|
35
36
|
ResponseContentDisposition,
|
|
36
|
-
|
|
37
|
+
ResponseContentType: file.responseContentType,
|
|
38
|
+
...overrides
|
|
37
39
|
});
|
|
40
|
+
}
|
|
41
|
+
getVersionDownloadURL(file, versionId) {
|
|
42
|
+
const command = this.createGetObjectCommand(file, { VersionId: versionId });
|
|
38
43
|
return getSignedUrl(this.client, command, { expiresIn: 60 * 60 * 24 });
|
|
39
44
|
}
|
|
40
45
|
async getVersions(key) {
|
|
@@ -52,12 +57,7 @@ var AmazonStorageClient = class AmazonStorageClient {
|
|
|
52
57
|
const cacheKey = `download-url:${file.path}`;
|
|
53
58
|
const cachedURL = await this.cache?.get(cacheKey);
|
|
54
59
|
if (cachedURL) return cachedURL;
|
|
55
|
-
const
|
|
56
|
-
const command = new GetObjectCommand({
|
|
57
|
-
Bucket: this.bucket,
|
|
58
|
-
Key: file.path,
|
|
59
|
-
ResponseContentDisposition
|
|
60
|
-
});
|
|
60
|
+
const command = this.createGetObjectCommand(file);
|
|
61
61
|
const url = await getSignedUrl(this.client, command, { expiresIn });
|
|
62
62
|
const cacheExpiration = Math.max(expiresIn - 60, 0);
|
|
63
63
|
if (cacheExpiration) await this.cache?.set(cacheKey, url, cacheExpiration);
|
|
@@ -124,4 +124,4 @@ let AmazonCannedAccessControlList = /* @__PURE__ */ function(AmazonCannedAccessC
|
|
|
124
124
|
|
|
125
125
|
//#endregion
|
|
126
126
|
export { AmazonCannedAccessControlList, AmazonStorageClient };
|
|
127
|
-
//# sourceMappingURL=AmazonStorageClient-
|
|
127
|
+
//# sourceMappingURL=AmazonStorageClient-Dz-KCJ_4.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AmazonStorageClient-Dz-KCJ_4.mjs","names":["options: AmazonStorageClientCreateOptions","client: S3Client","bucket: string","cache?: Cache","file: File","overrides?: { VersionId?: string }","versionId: string","key: string","params: GetUploadParams","data: string | Buffer","contentType: string"],"sources":["../src/AmazonStorageClient.ts"],"sourcesContent":["import {\n\tDeleteObjectCommand,\n\tGetObjectCommand,\n\tListObjectVersionsCommand,\n\tPutObjectCommand,\n\tS3Client,\n} from '@aws-sdk/client-s3';\nimport { createPresignedPost } from '@aws-sdk/s3-presigned-post';\nimport { getSignedUrl } from '@aws-sdk/s3-request-presigner';\n\nimport type { Cache } from '@geekmidas/cache';\nimport {\n\ttype DocumentVersion,\n\ttype File,\n\ttype GetUploadParams,\n\ttype GetUploadResponse,\n\ttype StorageClient,\n\tStorageProvider,\n} from './StorageClient';\n\nexport class AmazonStorageClient implements StorageClient {\n\treadonly provider = StorageProvider.AWSS3;\n\n\tstatic create(\n\t\toptions: AmazonStorageClientCreateOptions,\n\t): AmazonStorageClient {\n\t\tconst {\n\t\t\tbucket,\n\t\t\tregion,\n\t\t\taccessKeyId,\n\t\t\tacl,\n\t\t\tendpoint,\n\t\t\tsecretAccessKey,\n\t\t\tforcePathStyle = false,\n\t\t\tcache,\n\t\t} = options;\n\t\tconst hasCredentials = accessKeyId && secretAccessKey;\n\t\tconst credentials = hasCredentials\n\t\t\t? { accessKeyId, secretAccessKey }\n\t\t\t: undefined;\n\n\t\tconst client = new S3Client({\n\t\t\tregion,\n\t\t\tcredentials,\n\t\t\tendpoint,\n\t\t\tforcePathStyle,\n\t\t});\n\n\t\treturn new AmazonStorageClient(client, bucket, acl, cache);\n\t}\n\tconstructor(\n\t\tprivate readonly client: S3Client,\n\t\tprivate readonly bucket: string,\n\t\tprivate readonly acl = AmazonCannedAccessControlList.AuthenticatedRead,\n\t\treadonly cache?: Cache,\n\t) {}\n\n\tprivate createGetObjectCommand(\n\t\tfile: File,\n\t\toverrides?: { VersionId?: string },\n\t): GetObjectCommand {\n\t\tconst disposition =\n\t\t\tfile.disposition ?? (file.name ? 'attachment' : undefined);\n\t\tconst ResponseContentDisposition = disposition\n\t\t\t? file.name\n\t\t\t\t? `${disposition}; filename=${encodeURIComponent(file.name)}`\n\t\t\t\t: disposition\n\t\t\t: undefined;\n\n\t\treturn new GetObjectCommand({\n\t\t\tBucket: this.bucket,\n\t\t\tKey: file.path,\n\t\t\tResponseContentDisposition,\n\t\t\tResponseContentType: file.responseContentType,\n\t\t\t...overrides,\n\t\t});\n\t}\n\n\tgetVersionDownloadURL(file: File, versionId: string): Promise<string> {\n\t\tconst command = this.createGetObjectCommand(file, { VersionId: versionId });\n\t\treturn getSignedUrl(this.client, command, { expiresIn: 60 * 60 * 24 });\n\t}\n\n\tasync getVersions(key: string): Promise<DocumentVersion[]> {\n\t\tconst command = new ListObjectVersionsCommand({\n\t\t\tBucket: this.bucket,\n\t\t\tPrefix: key,\n\t\t});\n\n\t\tconst { Versions = [] } = await this.client.send(command);\n\n\t\treturn Versions.map((version) => ({\n\t\t\tid: version.VersionId || '',\n\t\t\tcreatedAt: version.LastModified || new Date(),\n\t\t}));\n\t}\n\n\tasync getDownloadURL(file: File, expiresIn = 60 * 60): Promise<string> {\n\t\tconst cacheKey = `download-url:${file.path}`;\n\t\tconst cachedURL = await this.cache?.get<string>(cacheKey);\n\n\t\tif (cachedURL) {\n\t\t\treturn cachedURL;\n\t\t}\n\n\t\tconst command = this.createGetObjectCommand(file);\n\t\tconst url = await getSignedUrl(this.client, command, { expiresIn });\n\t\tconst cacheExpiration = Math.max(expiresIn - 60, 0);\n\n\t\tif (cacheExpiration) {\n\t\t\tawait this.cache?.set(cacheKey, url, cacheExpiration);\n\t\t}\n\n\t\treturn url;\n\t}\n\n\tasync getUploadURL(\n\t\tparams: GetUploadParams,\n\t\texpiresIn = 60 * 60,\n\t): Promise<string> {\n\t\tconst command = new PutObjectCommand({\n\t\t\tBucket: this.bucket,\n\t\t\tKey: params.path,\n\t\t\tContentType: params.contentType,\n\t\t\tContentLength: params.contentLength,\n\t\t});\n\n\t\treturn getSignedUrl(this.client, command, { expiresIn });\n\t}\n\n\tasync getUpload(\n\t\tparams: GetUploadParams,\n\t\texpiresIn = 5,\n\t): Promise<GetUploadResponse> {\n\t\tconst { path } = params;\n\t\tconst { fields: values, url } = await createPresignedPost(this.client, {\n\t\t\tExpires: expiresIn * 60,\n\t\t\tBucket: this.bucket,\n\t\t\tFields: {\n\t\t\t\tacl: this.acl,\n\t\t\t},\n\t\t\tConditions: [\n\t\t\t\t// content length restrictions: 0-1MB]\n\t\t\t\t// ['content-length-range', 0, contentLength],\n\t\t\t\t// specify content-type to be more generic- images only\n\t\t\t\t// ['starts-with', '$Content-Type', 'image/'],\n\t\t\t\t// ['starts-with', '$Content-Type', contentType],\n\t\t\t],\n\t\t\tKey: path,\n\t\t});\n\n\t\tconst keys = Object.keys(values);\n\t\tconst fields = keys.map((key) => ({ key, value: values[key] || '' }));\n\n\t\treturn { url, fields };\n\t}\n\n\tasync upload(\n\t\tkey: string,\n\t\tdata: string | Buffer,\n\t\tcontentType: string,\n\t): Promise<void> {\n\t\tconst Body = typeof data === 'string' ? Buffer.from(data, 'base64') : data;\n\n\t\tconst params = {\n\t\t\tBucket: this.bucket,\n\t\t\tKey: key,\n\t\t\tBody,\n\t\t\tContentType: contentType,\n\t\t};\n\n\t\tconst command = new PutObjectCommand(params);\n\n\t\tawait this.client.send(command);\n\t}\n\n\tasync delete(key: string): Promise<void> {\n\t\tconst command = new DeleteObjectCommand({\n\t\t\tBucket: this.bucket,\n\t\t\tKey: key,\n\t\t});\n\n\t\tawait this.client.send(command);\n\t}\n}\n\nexport enum AmazonCannedAccessControlList {\n\tAuthenticatedRead = 'authenticated-read',\n\tPrivate = 'private',\n\tPublicRead = 'public-read',\n\tPublicReadWrite = 'public-read-write',\n\tAwsExecRead = 'aws-exec-read',\n\tBucketOwnerRead = 'bucket-owner-read',\n\tBucketOwnerFullControl = 'bucket-owner-full-control',\n\tLogDeliveryWrite = 'log-delivery-write',\n}\n\ninterface AmazonStorageClientCreateOptions {\n\tbucket: string;\n\tregion?: string;\n\tacl?: AmazonCannedAccessControlList;\n\taccessKeyId?: string;\n\tsecretAccessKey?: string;\n\tendpoint?: string;\n\tforcePathStyle?: boolean;\n\tcache?: Cache;\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_AmazonStorageClient = require('./AmazonStorageClient-
|
|
1
|
+
const require_AmazonStorageClient = require('./AmazonStorageClient-BvoZepKJ.cjs');
|
|
2
2
|
require('./StorageClient-BDRVrMJj.cjs');
|
|
3
3
|
|
|
4
4
|
exports.AmazonCannedAccessControlList = require_AmazonStorageClient.AmazonCannedAccessControlList;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import "./StorageClient-
|
|
2
|
-
import { AmazonCannedAccessControlList, AmazonStorageClient } from "./AmazonStorageClient-
|
|
1
|
+
import "./StorageClient-COs9SOsU.cjs";
|
|
2
|
+
import { AmazonCannedAccessControlList, AmazonStorageClient } from "./AmazonStorageClient-BNoY2PL6.cjs";
|
|
3
3
|
export { AmazonCannedAccessControlList, AmazonStorageClient };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import "./StorageClient-
|
|
2
|
-
import { AmazonCannedAccessControlList, AmazonStorageClient } from "./AmazonStorageClient-
|
|
1
|
+
import "./StorageClient-DH4tP-Mf.mjs";
|
|
2
|
+
import { AmazonCannedAccessControlList, AmazonStorageClient } from "./AmazonStorageClient-BHpWawGD.mjs";
|
|
3
3
|
export { AmazonCannedAccessControlList, AmazonStorageClient };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import "./StorageClient-4ADnTPnJ.mjs";
|
|
2
|
-
import { AmazonCannedAccessControlList, AmazonStorageClient } from "./AmazonStorageClient-
|
|
2
|
+
import { AmazonCannedAccessControlList, AmazonStorageClient } from "./AmazonStorageClient-Dz-KCJ_4.mjs";
|
|
3
3
|
|
|
4
4
|
export { AmazonCannedAccessControlList, AmazonStorageClient };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StorageClient-4ADnTPnJ.mjs","names":[],"sources":["../src/StorageClient.ts"],"sourcesContent":["import type { Cache } from '@geekmidas/cache';\nexport interface DocumentVersion {\n\tid: string;\n\tcreatedAt: Date;\n}\n\nexport enum StorageProvider {\n\tAWSS3 = 'geekimdas.toolbox.storage.aws.s3',\n\tGCP = 'geekimdas.toolbox.storage.gcp',\n\tAZURE = 'geekimdas.toolbox.storage.azure',\n}\n\nexport interface StorageClient {\n\treadonly provider: StorageProvider;\n\treadonly cache?: Cache;\n\t/**\n\t * Get a URL to upload a file to.\n\t *\n\t * @param params - The parameters to get the upload URL for.\n\t * @param expiresIn - The number of minutes the URL should be valid for.\n\t * Defaults to 60 * 60 (1 hour).\n\t * @returns A promise that resolves to the upload URL.\n\t */\n\tgetUploadURL(params: GetUploadParams, expiresIn?: number): Promise<string>;\n\n\t/**\n\t * Get a URL to download a file from.\n\t *\n\t * @param file - The file to get the download URL for.\n\t * @param expiresIn - The number of seconds the URL should be valid for.\n\t * Defaults to 60 * 60 (1 hour).\n\t * @returns A promise that resolves to the download URL.\n\t */\n\tgetDownloadURL(file: File, expiresIn?: number): Promise<string>;\n\t/**\n\t * Get the versions for a key.\n\t *\n\t * @param key - The key to get the versions for.\n\t */\n\tgetVersions(key: string): Promise<DocumentVersion[]>;\n\n\t/**\n\t * Get a URL to download a version of a file from.\n\t *\n\t * @param file - The file to get the download URL for.\n\t * @param versionId - The version ID to get the download URL for.\n\t */\n\tgetVersionDownloadURL(file: File, versionId: string): Promise<string>;\n\t/**\n\t *\n\t * @param key - The key to upload the file to.\n\t * @param data - The data to upload.\n\t * @param contentType - The content type of the data.\n\t */\n\tupload(\n\t\tkey: string,\n\t\tdata: string | Buffer,\n\t\tcontentType: string,\n\t): Promise<void>;\n\t/**\n\t * Get a URL to upload a file to.\n\t *\n\t * @param params - The parameters to get the upload URL for.\n\t * @param expiresIn - The number of minutes the URL should be valid for.\n\t */\n\tgetUpload(\n\t\tparams: GetUploadParams,\n\t\texpiresIn?: number,\n\t): Promise<GetUploadResponse>;\n\t/**\n\t * Delete a file from storage.\n\t *\n\t * @param key - The key (path) of the file to delete.\n\t */\n\tdelete(key: string): Promise<void>;\n}\n\nexport interface GetUploadParams {\n\tpath: string;\n\tcontentType: string;\n\tcontentLength: number;\n}\n\nexport type UploadField = {\n\tkey: string;\n\tvalue: string;\n};\n\nexport type GetUploadResponse = {\n\turl: string;\n\tfields: UploadField[];\n};\n\nexport interface File {\n\tname?: string;\n\tpath: string;\n}\n"],"mappings":";AAMA,IAAY,8DAAL;AACN;AACA;AACA;;AACA"}
|
|
1
|
+
{"version":3,"file":"StorageClient-4ADnTPnJ.mjs","names":[],"sources":["../src/StorageClient.ts"],"sourcesContent":["import type { Cache } from '@geekmidas/cache';\nexport interface DocumentVersion {\n\tid: string;\n\tcreatedAt: Date;\n}\n\nexport enum StorageProvider {\n\tAWSS3 = 'geekimdas.toolbox.storage.aws.s3',\n\tGCP = 'geekimdas.toolbox.storage.gcp',\n\tAZURE = 'geekimdas.toolbox.storage.azure',\n}\n\nexport interface StorageClient {\n\treadonly provider: StorageProvider;\n\treadonly cache?: Cache;\n\t/**\n\t * Get a URL to upload a file to.\n\t *\n\t * @param params - The parameters to get the upload URL for.\n\t * @param expiresIn - The number of minutes the URL should be valid for.\n\t * Defaults to 60 * 60 (1 hour).\n\t * @returns A promise that resolves to the upload URL.\n\t */\n\tgetUploadURL(params: GetUploadParams, expiresIn?: number): Promise<string>;\n\n\t/**\n\t * Get a URL to download a file from.\n\t *\n\t * @param file - The file to get the download URL for.\n\t * @param expiresIn - The number of seconds the URL should be valid for.\n\t * Defaults to 60 * 60 (1 hour).\n\t * @returns A promise that resolves to the download URL.\n\t */\n\tgetDownloadURL(file: File, expiresIn?: number): Promise<string>;\n\t/**\n\t * Get the versions for a key.\n\t *\n\t * @param key - The key to get the versions for.\n\t */\n\tgetVersions(key: string): Promise<DocumentVersion[]>;\n\n\t/**\n\t * Get a URL to download a version of a file from.\n\t *\n\t * @param file - The file to get the download URL for.\n\t * @param versionId - The version ID to get the download URL for.\n\t */\n\tgetVersionDownloadURL(file: File, versionId: string): Promise<string>;\n\t/**\n\t *\n\t * @param key - The key to upload the file to.\n\t * @param data - The data to upload.\n\t * @param contentType - The content type of the data.\n\t */\n\tupload(\n\t\tkey: string,\n\t\tdata: string | Buffer,\n\t\tcontentType: string,\n\t): Promise<void>;\n\t/**\n\t * Get a URL to upload a file to.\n\t *\n\t * @param params - The parameters to get the upload URL for.\n\t * @param expiresIn - The number of minutes the URL should be valid for.\n\t */\n\tgetUpload(\n\t\tparams: GetUploadParams,\n\t\texpiresIn?: number,\n\t): Promise<GetUploadResponse>;\n\t/**\n\t * Delete a file from storage.\n\t *\n\t * @param key - The key (path) of the file to delete.\n\t */\n\tdelete(key: string): Promise<void>;\n}\n\nexport interface GetUploadParams {\n\tpath: string;\n\tcontentType: string;\n\tcontentLength: number;\n}\n\nexport type UploadField = {\n\tkey: string;\n\tvalue: string;\n};\n\nexport type GetUploadResponse = {\n\turl: string;\n\tfields: UploadField[];\n};\n\nexport interface File {\n\tname?: string;\n\tpath: string;\n\t/**\n\t * Override the Content-Type of the response.\n\t * Useful when the stored object's content type differs from what the browser should receive.\n\t */\n\tresponseContentType?: string;\n\t/**\n\t * Control how the browser handles the file.\n\t * - `'attachment'` — prompts download (default when `name` is set)\n\t * - `'inline'` — displays in the browser\n\t */\n\tdisposition?: 'inline' | 'attachment';\n}\n"],"mappings":";AAMA,IAAY,8DAAL;AACN;AACA;AACA;;AACA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StorageClient-BDRVrMJj.cjs","names":[],"sources":["../src/StorageClient.ts"],"sourcesContent":["import type { Cache } from '@geekmidas/cache';\nexport interface DocumentVersion {\n\tid: string;\n\tcreatedAt: Date;\n}\n\nexport enum StorageProvider {\n\tAWSS3 = 'geekimdas.toolbox.storage.aws.s3',\n\tGCP = 'geekimdas.toolbox.storage.gcp',\n\tAZURE = 'geekimdas.toolbox.storage.azure',\n}\n\nexport interface StorageClient {\n\treadonly provider: StorageProvider;\n\treadonly cache?: Cache;\n\t/**\n\t * Get a URL to upload a file to.\n\t *\n\t * @param params - The parameters to get the upload URL for.\n\t * @param expiresIn - The number of minutes the URL should be valid for.\n\t * Defaults to 60 * 60 (1 hour).\n\t * @returns A promise that resolves to the upload URL.\n\t */\n\tgetUploadURL(params: GetUploadParams, expiresIn?: number): Promise<string>;\n\n\t/**\n\t * Get a URL to download a file from.\n\t *\n\t * @param file - The file to get the download URL for.\n\t * @param expiresIn - The number of seconds the URL should be valid for.\n\t * Defaults to 60 * 60 (1 hour).\n\t * @returns A promise that resolves to the download URL.\n\t */\n\tgetDownloadURL(file: File, expiresIn?: number): Promise<string>;\n\t/**\n\t * Get the versions for a key.\n\t *\n\t * @param key - The key to get the versions for.\n\t */\n\tgetVersions(key: string): Promise<DocumentVersion[]>;\n\n\t/**\n\t * Get a URL to download a version of a file from.\n\t *\n\t * @param file - The file to get the download URL for.\n\t * @param versionId - The version ID to get the download URL for.\n\t */\n\tgetVersionDownloadURL(file: File, versionId: string): Promise<string>;\n\t/**\n\t *\n\t * @param key - The key to upload the file to.\n\t * @param data - The data to upload.\n\t * @param contentType - The content type of the data.\n\t */\n\tupload(\n\t\tkey: string,\n\t\tdata: string | Buffer,\n\t\tcontentType: string,\n\t): Promise<void>;\n\t/**\n\t * Get a URL to upload a file to.\n\t *\n\t * @param params - The parameters to get the upload URL for.\n\t * @param expiresIn - The number of minutes the URL should be valid for.\n\t */\n\tgetUpload(\n\t\tparams: GetUploadParams,\n\t\texpiresIn?: number,\n\t): Promise<GetUploadResponse>;\n\t/**\n\t * Delete a file from storage.\n\t *\n\t * @param key - The key (path) of the file to delete.\n\t */\n\tdelete(key: string): Promise<void>;\n}\n\nexport interface GetUploadParams {\n\tpath: string;\n\tcontentType: string;\n\tcontentLength: number;\n}\n\nexport type UploadField = {\n\tkey: string;\n\tvalue: string;\n};\n\nexport type GetUploadResponse = {\n\turl: string;\n\tfields: UploadField[];\n};\n\nexport interface File {\n\tname?: string;\n\tpath: string;\n}\n"],"mappings":";;AAMA,IAAY,8DAAL;AACN;AACA;AACA;;AACA"}
|
|
1
|
+
{"version":3,"file":"StorageClient-BDRVrMJj.cjs","names":[],"sources":["../src/StorageClient.ts"],"sourcesContent":["import type { Cache } from '@geekmidas/cache';\nexport interface DocumentVersion {\n\tid: string;\n\tcreatedAt: Date;\n}\n\nexport enum StorageProvider {\n\tAWSS3 = 'geekimdas.toolbox.storage.aws.s3',\n\tGCP = 'geekimdas.toolbox.storage.gcp',\n\tAZURE = 'geekimdas.toolbox.storage.azure',\n}\n\nexport interface StorageClient {\n\treadonly provider: StorageProvider;\n\treadonly cache?: Cache;\n\t/**\n\t * Get a URL to upload a file to.\n\t *\n\t * @param params - The parameters to get the upload URL for.\n\t * @param expiresIn - The number of minutes the URL should be valid for.\n\t * Defaults to 60 * 60 (1 hour).\n\t * @returns A promise that resolves to the upload URL.\n\t */\n\tgetUploadURL(params: GetUploadParams, expiresIn?: number): Promise<string>;\n\n\t/**\n\t * Get a URL to download a file from.\n\t *\n\t * @param file - The file to get the download URL for.\n\t * @param expiresIn - The number of seconds the URL should be valid for.\n\t * Defaults to 60 * 60 (1 hour).\n\t * @returns A promise that resolves to the download URL.\n\t */\n\tgetDownloadURL(file: File, expiresIn?: number): Promise<string>;\n\t/**\n\t * Get the versions for a key.\n\t *\n\t * @param key - The key to get the versions for.\n\t */\n\tgetVersions(key: string): Promise<DocumentVersion[]>;\n\n\t/**\n\t * Get a URL to download a version of a file from.\n\t *\n\t * @param file - The file to get the download URL for.\n\t * @param versionId - The version ID to get the download URL for.\n\t */\n\tgetVersionDownloadURL(file: File, versionId: string): Promise<string>;\n\t/**\n\t *\n\t * @param key - The key to upload the file to.\n\t * @param data - The data to upload.\n\t * @param contentType - The content type of the data.\n\t */\n\tupload(\n\t\tkey: string,\n\t\tdata: string | Buffer,\n\t\tcontentType: string,\n\t): Promise<void>;\n\t/**\n\t * Get a URL to upload a file to.\n\t *\n\t * @param params - The parameters to get the upload URL for.\n\t * @param expiresIn - The number of minutes the URL should be valid for.\n\t */\n\tgetUpload(\n\t\tparams: GetUploadParams,\n\t\texpiresIn?: number,\n\t): Promise<GetUploadResponse>;\n\t/**\n\t * Delete a file from storage.\n\t *\n\t * @param key - The key (path) of the file to delete.\n\t */\n\tdelete(key: string): Promise<void>;\n}\n\nexport interface GetUploadParams {\n\tpath: string;\n\tcontentType: string;\n\tcontentLength: number;\n}\n\nexport type UploadField = {\n\tkey: string;\n\tvalue: string;\n};\n\nexport type GetUploadResponse = {\n\turl: string;\n\tfields: UploadField[];\n};\n\nexport interface File {\n\tname?: string;\n\tpath: string;\n\t/**\n\t * Override the Content-Type of the response.\n\t * Useful when the stored object's content type differs from what the browser should receive.\n\t */\n\tresponseContentType?: string;\n\t/**\n\t * Control how the browser handles the file.\n\t * - `'attachment'` — prompts download (default when `name` is set)\n\t * - `'inline'` — displays in the browser\n\t */\n\tdisposition?: 'inline' | 'attachment';\n}\n"],"mappings":";;AAMA,IAAY,8DAAL;AACN;AACA;AACA;;AACA"}
|
|
@@ -81,8 +81,19 @@ type GetUploadResponse = {
|
|
|
81
81
|
interface File {
|
|
82
82
|
name?: string;
|
|
83
83
|
path: string;
|
|
84
|
+
/**
|
|
85
|
+
* Override the Content-Type of the response.
|
|
86
|
+
* Useful when the stored object's content type differs from what the browser should receive.
|
|
87
|
+
*/
|
|
88
|
+
responseContentType?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Control how the browser handles the file.
|
|
91
|
+
* - `'attachment'` — prompts download (default when `name` is set)
|
|
92
|
+
* - `'inline'` — displays in the browser
|
|
93
|
+
*/
|
|
94
|
+
disposition?: 'inline' | 'attachment';
|
|
84
95
|
}
|
|
85
96
|
//# sourceMappingURL=StorageClient.d.ts.map
|
|
86
97
|
//#endregion
|
|
87
98
|
export { DocumentVersion, File, GetUploadParams, GetUploadResponse, StorageClient, StorageProvider, UploadField };
|
|
88
|
-
//# sourceMappingURL=StorageClient-
|
|
99
|
+
//# sourceMappingURL=StorageClient-COs9SOsU.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StorageClient-
|
|
1
|
+
{"version":3,"file":"StorageClient-COs9SOsU.d.cts","names":[],"sources":["../src/StorageClient.ts"],"sourcesContent":[],"mappings":";;;UACiB,eAAA;;EAAA,SAAA,EAEL,IAFK;AAKjB;AAMiB,aANL,eAAA;EAMkB,KAAA,GAAA,kCAAA;EAAA,GACV,GAAA,+BAAA;EAAe,KACjB,GAAA,iCAAA;;AAS0C,UAX3C,aAAA,CAW2C;EAAO,SAU7C,QAAA,EApBF,eAoBE;EAAI,SAAuB,KAAA,CAAA,EAnB/B,KAmB+B;EAAO;;;;;;;;EAmC3B,YAAzB,CAAA,MAAA,EA7CkB,eA6ClB,EAAA,SAAA,CAAA,EAAA,MAAA,CAAA,EA7CwD,OA6CxD,CAAA,MAAA,CAAA;EAAO;AAMkB;AAG7B;AAMA;AAKA;AAKA;;;uBA5DsB,2BAA2B;;;;;;4BAMtB,QAAQ;;;;;;;8BAQN,0BAA0B;;;;;;;qCAStC,8BAEb;;;;;;;oBAQM,sCAEN,QAAQ;;;;;;uBAMU;;UAGL,eAAA;;;;;KAML,WAAA;;;;KAKA,iBAAA;;UAEH;;UAGQ,IAAA"}
|
|
@@ -81,8 +81,19 @@ type GetUploadResponse = {
|
|
|
81
81
|
interface File {
|
|
82
82
|
name?: string;
|
|
83
83
|
path: string;
|
|
84
|
+
/**
|
|
85
|
+
* Override the Content-Type of the response.
|
|
86
|
+
* Useful when the stored object's content type differs from what the browser should receive.
|
|
87
|
+
*/
|
|
88
|
+
responseContentType?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Control how the browser handles the file.
|
|
91
|
+
* - `'attachment'` — prompts download (default when `name` is set)
|
|
92
|
+
* - `'inline'` — displays in the browser
|
|
93
|
+
*/
|
|
94
|
+
disposition?: 'inline' | 'attachment';
|
|
84
95
|
}
|
|
85
96
|
//# sourceMappingURL=StorageClient.d.ts.map
|
|
86
97
|
//#endregion
|
|
87
98
|
export { DocumentVersion, File, GetUploadParams, GetUploadResponse, StorageClient, StorageProvider, UploadField };
|
|
88
|
-
//# sourceMappingURL=StorageClient-
|
|
99
|
+
//# sourceMappingURL=StorageClient-DH4tP-Mf.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StorageClient-
|
|
1
|
+
{"version":3,"file":"StorageClient-DH4tP-Mf.d.mts","names":[],"sources":["../src/StorageClient.ts"],"sourcesContent":[],"mappings":";;;UACiB,eAAA;;EAAA,SAAA,EAEL,IAFK;AAKjB;AAMiB,aANL,eAAA;EAMkB,KAAA,GAAA,kCAAA;EAAA,GACV,GAAA,+BAAA;EAAe,KACjB,GAAA,iCAAA;;AAS0C,UAX3C,aAAA,CAW2C;EAAO,SAU7C,QAAA,EApBF,eAoBE;EAAI,SAAuB,KAAA,CAAA,EAnB/B,KAmB+B;EAAO;;;;;;;;EAmC3B,YAAzB,CAAA,MAAA,EA7CkB,eA6ClB,EAAA,SAAA,CAAA,EAAA,MAAA,CAAA,EA7CwD,OA6CxD,CAAA,MAAA,CAAA;EAAO;AAMkB;AAG7B;AAMA;AAKA;AAKA;;;uBA5DsB,2BAA2B;;;;;;4BAMtB,QAAQ;;;;;;;8BAQN,0BAA0B;;;;;;;qCAStC,8BAEb;;;;;;;oBAQM,sCAEN,QAAQ;;;;;;uBAMU;;UAGL,eAAA;;;;;KAML,WAAA;;;;KAKA,iBAAA;;UAEH;;UAGQ,IAAA"}
|
package/dist/StorageClient.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { DocumentVersion, File, GetUploadParams, GetUploadResponse, StorageClient, StorageProvider, UploadField } from "./StorageClient-
|
|
1
|
+
import { DocumentVersion, File, GetUploadParams, GetUploadResponse, StorageClient, StorageProvider, UploadField } from "./StorageClient-COs9SOsU.cjs";
|
|
2
2
|
export { DocumentVersion, File, GetUploadParams, GetUploadResponse, StorageClient, StorageProvider, UploadField };
|
package/dist/StorageClient.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { DocumentVersion, File, GetUploadParams, GetUploadResponse, StorageClient, StorageProvider, UploadField } from "./StorageClient-
|
|
1
|
+
import { DocumentVersion, File, GetUploadParams, GetUploadResponse, StorageClient, StorageProvider, UploadField } from "./StorageClient-DH4tP-Mf.mjs";
|
|
2
2
|
export { DocumentVersion, File, GetUploadParams, GetUploadResponse, StorageClient, StorageProvider, UploadField };
|
package/dist/aws.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_AmazonStorageClient = require('./AmazonStorageClient-
|
|
1
|
+
const require_AmazonStorageClient = require('./AmazonStorageClient-BvoZepKJ.cjs');
|
|
2
2
|
require('./StorageClient-BDRVrMJj.cjs');
|
|
3
3
|
|
|
4
4
|
exports.AmazonCannedAccessControlList = require_AmazonStorageClient.AmazonCannedAccessControlList;
|
package/dist/aws.d.cts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { DocumentVersion, File, GetUploadParams, GetUploadResponse, StorageClient } from "./StorageClient-
|
|
2
|
-
import { AmazonCannedAccessControlList, AmazonStorageClient } from "./AmazonStorageClient-
|
|
1
|
+
import { DocumentVersion, File, GetUploadParams, GetUploadResponse, StorageClient } from "./StorageClient-COs9SOsU.cjs";
|
|
2
|
+
import { AmazonCannedAccessControlList, AmazonStorageClient } from "./AmazonStorageClient-BNoY2PL6.cjs";
|
|
3
3
|
export { AmazonCannedAccessControlList, AmazonStorageClient, DocumentVersion, File, GetUploadParams, GetUploadResponse, StorageClient };
|
package/dist/aws.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { DocumentVersion, File, GetUploadParams, GetUploadResponse, StorageClient } from "./StorageClient-
|
|
2
|
-
import { AmazonCannedAccessControlList, AmazonStorageClient } from "./AmazonStorageClient-
|
|
1
|
+
import { DocumentVersion, File, GetUploadParams, GetUploadResponse, StorageClient } from "./StorageClient-DH4tP-Mf.mjs";
|
|
2
|
+
import { AmazonCannedAccessControlList, AmazonStorageClient } from "./AmazonStorageClient-BHpWawGD.mjs";
|
|
3
3
|
export { AmazonCannedAccessControlList, AmazonStorageClient, DocumentVersion, File, GetUploadParams, GetUploadResponse, StorageClient };
|
package/dist/aws.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import "./StorageClient-4ADnTPnJ.mjs";
|
|
2
|
-
import { AmazonCannedAccessControlList, AmazonStorageClient } from "./AmazonStorageClient-
|
|
2
|
+
import { AmazonCannedAccessControlList, AmazonStorageClient } from "./AmazonStorageClient-Dz-KCJ_4.mjs";
|
|
3
3
|
|
|
4
4
|
export { AmazonCannedAccessControlList, AmazonStorageClient };
|
package/dist/index.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { StorageClient } from "./StorageClient-
|
|
1
|
+
import { StorageClient } from "./StorageClient-COs9SOsU.cjs";
|
|
2
2
|
export { StorageClient };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { StorageClient } from "./StorageClient-
|
|
1
|
+
import { StorageClient } from "./StorageClient-DH4tP-Mf.mjs";
|
|
2
2
|
export { StorageClient };
|
package/package.json
CHANGED
|
@@ -55,18 +55,29 @@ export class AmazonStorageClient implements StorageClient {
|
|
|
55
55
|
readonly cache?: Cache,
|
|
56
56
|
) {}
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
private createGetObjectCommand(
|
|
59
|
+
file: File,
|
|
60
|
+
overrides?: { VersionId?: string },
|
|
61
|
+
): GetObjectCommand {
|
|
62
|
+
const disposition =
|
|
63
|
+
file.disposition ?? (file.name ? 'attachment' : undefined);
|
|
64
|
+
const ResponseContentDisposition = disposition
|
|
65
|
+
? file.name
|
|
66
|
+
? `${disposition}; filename=${encodeURIComponent(file.name)}`
|
|
67
|
+
: disposition
|
|
61
68
|
: undefined;
|
|
62
69
|
|
|
63
|
-
|
|
70
|
+
return new GetObjectCommand({
|
|
64
71
|
Bucket: this.bucket,
|
|
65
72
|
Key: file.path,
|
|
66
73
|
ResponseContentDisposition,
|
|
67
|
-
|
|
74
|
+
ResponseContentType: file.responseContentType,
|
|
75
|
+
...overrides,
|
|
68
76
|
});
|
|
77
|
+
}
|
|
69
78
|
|
|
79
|
+
getVersionDownloadURL(file: File, versionId: string): Promise<string> {
|
|
80
|
+
const command = this.createGetObjectCommand(file, { VersionId: versionId });
|
|
70
81
|
return getSignedUrl(this.client, command, { expiresIn: 60 * 60 * 24 });
|
|
71
82
|
}
|
|
72
83
|
|
|
@@ -92,16 +103,7 @@ export class AmazonStorageClient implements StorageClient {
|
|
|
92
103
|
return cachedURL;
|
|
93
104
|
}
|
|
94
105
|
|
|
95
|
-
const
|
|
96
|
-
? `attachment; filename=${encodeURIComponent(file.name)}`
|
|
97
|
-
: undefined;
|
|
98
|
-
|
|
99
|
-
const command = new GetObjectCommand({
|
|
100
|
-
Bucket: this.bucket,
|
|
101
|
-
Key: file.path,
|
|
102
|
-
ResponseContentDisposition,
|
|
103
|
-
});
|
|
104
|
-
|
|
106
|
+
const command = this.createGetObjectCommand(file);
|
|
105
107
|
const url = await getSignedUrl(this.client, command, { expiresIn });
|
|
106
108
|
const cacheExpiration = Math.max(expiresIn - 60, 0);
|
|
107
109
|
|
package/src/StorageClient.ts
CHANGED
|
@@ -94,4 +94,15 @@ export type GetUploadResponse = {
|
|
|
94
94
|
export interface File {
|
|
95
95
|
name?: string;
|
|
96
96
|
path: string;
|
|
97
|
+
/**
|
|
98
|
+
* Override the Content-Type of the response.
|
|
99
|
+
* Useful when the stored object's content type differs from what the browser should receive.
|
|
100
|
+
*/
|
|
101
|
+
responseContentType?: string;
|
|
102
|
+
/**
|
|
103
|
+
* Control how the browser handles the file.
|
|
104
|
+
* - `'attachment'` — prompts download (default when `name` is set)
|
|
105
|
+
* - `'inline'` — displays in the browser
|
|
106
|
+
*/
|
|
107
|
+
disposition?: 'inline' | 'attachment';
|
|
97
108
|
}
|
|
@@ -77,6 +77,60 @@ describe('AmazonStorageClient Integration Tests', () => {
|
|
|
77
77
|
);
|
|
78
78
|
});
|
|
79
79
|
|
|
80
|
+
it('should generate download URL with inline disposition', async () => {
|
|
81
|
+
const key = 'test-files/inline-file.txt';
|
|
82
|
+
await client.upload(key, testContent, testContentType);
|
|
83
|
+
|
|
84
|
+
const downloadUrl = await client.getDownloadURL({
|
|
85
|
+
path: key,
|
|
86
|
+
disposition: 'inline',
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
expect(downloadUrl).toContain('response-content-disposition=inline');
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('should generate download URL with inline disposition and filename', async () => {
|
|
93
|
+
const key = 'test-files/inline-named.txt';
|
|
94
|
+
await client.upload(key, testContent, testContentType);
|
|
95
|
+
|
|
96
|
+
const downloadUrl = await client.getDownloadURL({
|
|
97
|
+
path: key,
|
|
98
|
+
name: 'preview.txt',
|
|
99
|
+
disposition: 'inline',
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
expect(downloadUrl).toContain(
|
|
103
|
+
'response-content-disposition=inline%3B%20filename%3Dpreview.txt',
|
|
104
|
+
);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('should generate download URL with response content type override', async () => {
|
|
108
|
+
const key = 'test-files/content-type-override.bin';
|
|
109
|
+
await client.upload(key, testContent, 'application/octet-stream');
|
|
110
|
+
|
|
111
|
+
const downloadUrl = await client.getDownloadURL({
|
|
112
|
+
path: key,
|
|
113
|
+
responseContentType: 'application/pdf',
|
|
114
|
+
disposition: 'inline',
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
expect(downloadUrl).toContain('response-content-type=application%2Fpdf');
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('should default to attachment disposition when name is set', async () => {
|
|
121
|
+
const key = 'test-files/default-disposition.txt';
|
|
122
|
+
await client.upload(key, testContent, testContentType);
|
|
123
|
+
|
|
124
|
+
const downloadUrl = await client.getDownloadURL({
|
|
125
|
+
path: key,
|
|
126
|
+
name: 'download.txt',
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
expect(downloadUrl).toContain(
|
|
130
|
+
'response-content-disposition=attachment%3B%20filename%3Ddownload.txt',
|
|
131
|
+
);
|
|
132
|
+
});
|
|
133
|
+
|
|
80
134
|
it('should handle binary data upload', async () => {
|
|
81
135
|
const binaryKey = 'test-files/binary.bin';
|
|
82
136
|
const binaryData = Buffer.from([0x48, 0x65, 0x6c, 0x6c, 0x6f]); // "Hello" in bytes
|
|
@@ -514,6 +568,22 @@ describe('AmazonStorageClient Integration Tests', () => {
|
|
|
514
568
|
);
|
|
515
569
|
});
|
|
516
570
|
|
|
571
|
+
it('should generate version URL with inline disposition', async () => {
|
|
572
|
+
const versionKey = 'test-files/version-inline.txt';
|
|
573
|
+
const versionId = 'test-version-id';
|
|
574
|
+
|
|
575
|
+
await client.upload(versionKey, testContent, testContentType);
|
|
576
|
+
|
|
577
|
+
const downloadUrl = await client.getVersionDownloadURL(
|
|
578
|
+
{ path: versionKey, name: 'inline-file.txt', disposition: 'inline' },
|
|
579
|
+
versionId,
|
|
580
|
+
);
|
|
581
|
+
|
|
582
|
+
expect(downloadUrl).toContain(
|
|
583
|
+
'response-content-disposition=inline%3B%20filename%3Dinline-file.txt',
|
|
584
|
+
);
|
|
585
|
+
});
|
|
586
|
+
|
|
517
587
|
it('should generate version URL without filename', async () => {
|
|
518
588
|
const versionKey = 'test-files/version-no-name.txt';
|
|
519
589
|
const versionId = 'test-version-id';
|
|
@@ -44,6 +44,15 @@ describe('StorageClient', () => {
|
|
|
44
44
|
|
|
45
45
|
expect(fileWithName.path).toBe('test/path.txt');
|
|
46
46
|
expect(fileWithName.name).toBe('display-name.txt');
|
|
47
|
+
|
|
48
|
+
const fileWithDisposition: import('../StorageClient').File = {
|
|
49
|
+
path: 'test/path.txt',
|
|
50
|
+
disposition: 'inline',
|
|
51
|
+
responseContentType: 'application/pdf',
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
expect(fileWithDisposition.disposition).toBe('inline');
|
|
55
|
+
expect(fileWithDisposition.responseContentType).toBe('application/pdf');
|
|
47
56
|
});
|
|
48
57
|
|
|
49
58
|
it('should define GetUploadParams interface correctly', () => {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AmazonStorageClient-BzoByQDt.d.cts","names":[],"sources":["../src/AmazonStorageClient.ts"],"sourcesContent":[],"mappings":";;;;;cAoBa,mBAAA,YAA+B;;EAA/B,iBAAA,MAAoB;EAAA,iBAAA,GAAA;EAAA,SAkCd,KAAA,CAAA,EAAA,KAAA;EAAK,SAjCN,QAAA,GAAA,eAAA,CAAA,KAAA;EAAA,OAGP,MAAA,CAAA,OAAA,EAAA,gCAAA,CAAA,EACP,mBADO;EAAgC,WACvC,CAAA,MAAA,EA0BuB,QA1BvB,EAAA,MAAA,EAAA,MAAA,EAAA,GAAA,CAAA,EA4BkB,6BA5BlB,EAAA,KAAA,CAAA,EA6Be,KA7Bf;EAAmB,qBA0BI,CAAA,IAAA,EAME,IANF,EAAA,SAAA,EAAA,MAAA,CAAA,EAM4B,OAN5B,CAAA,MAAA,CAAA;EAAQ,WAEb,CAAA,GAAA,EAAA,MAAA,CAAA,EAmBW,OAnBX,CAmBmB,eAnBnB,EAAA,CAAA;EAAkD,cACrD,CAAA,IAAA,EAgCS,IAhCT,EAAA,SAAA,CAAA,EAAA,MAAA,CAAA,EAgCqC,OAhCrC,CAAA,MAAA,CAAA;EAAK,YAGK,CAAA,MAAA,EA0DnB,eA1DmB,EAAA,SAAA,CAAA,EAAA,MAAA,CAAA,EA4DzB,OA5DyB,CAAA,MAAA,CAAA;EAAI,SAAsB,CAAA,MAAA,EAwE7C,eAxE6C,EAAA,SAAA,CAAA,EAAA,MAAA,CAAA,EA0EnD,OA1EmD,CA0E3C,iBA1E2C,CAAA;EAAO,MAerB,CAAA,GAAA,EAAA,MAAA,EAAA,IAAA,EAAA,MAAA,GAqFxB,MArFwB,EAAA,WAAA,EAAA,MAAA,CAAA,EAuFrC,OAvFqC,CAAA,IAAA,CAAA;EAAe,MAAvB,CAAA,GAAA,EAAA,MAAA,CAAA,EAsGL,OAtGK,CAAA,IAAA,CAAA;;AAcuB,aAkG5C,6BAAA;EAlGmD,iBA6BrD,GAAA,oBAAA;EAAe,OAErB,GAAA,SAAA;EAAO,UAYD,GAAA,aAAA;EAAe,eAEb,GAAA,mBAAA;EAAiB,WAAzB,GAAA,eAAA;EAAO,eA0BM,GAAA,mBAAA;EAAM,sBAEnB,GAAA,2BAAA;EAAO,gBAeiB,GAAA,oBAAA;;AA1J6B,UA+K/C,gCAAA,CA/K+C;EAoK7C,MAAA,EAAA,MAAA;EAWF,MAAA,CAAA,EAAA,MAAA;EAAgC,GAAA,CAAA,EAGnC,6BAHmC;EAAA,WAGnC,CAAA,EAAA,MAAA;EAA6B,eAK3B,CAAA,EAAA,MAAA;EAAK,QAAA,CAAA,EAAA,MAAA;;UAAL"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AmazonStorageClient-C63eEnlC.cjs","names":["StorageProvider","options: AmazonStorageClientCreateOptions","S3Client","client: S3Client","bucket: string","cache?: Cache","file: File","versionId: string","GetObjectCommand","key: string","ListObjectVersionsCommand","params: GetUploadParams","PutObjectCommand","data: string | Buffer","contentType: string","DeleteObjectCommand"],"sources":["../src/AmazonStorageClient.ts"],"sourcesContent":["import {\n\tDeleteObjectCommand,\n\tGetObjectCommand,\n\tListObjectVersionsCommand,\n\tPutObjectCommand,\n\tS3Client,\n} from '@aws-sdk/client-s3';\nimport { createPresignedPost } from '@aws-sdk/s3-presigned-post';\nimport { getSignedUrl } from '@aws-sdk/s3-request-presigner';\n\nimport type { Cache } from '@geekmidas/cache';\nimport {\n\ttype DocumentVersion,\n\ttype File,\n\ttype GetUploadParams,\n\ttype GetUploadResponse,\n\ttype StorageClient,\n\tStorageProvider,\n} from './StorageClient';\n\nexport class AmazonStorageClient implements StorageClient {\n\treadonly provider = StorageProvider.AWSS3;\n\n\tstatic create(\n\t\toptions: AmazonStorageClientCreateOptions,\n\t): AmazonStorageClient {\n\t\tconst {\n\t\t\tbucket,\n\t\t\tregion,\n\t\t\taccessKeyId,\n\t\t\tacl,\n\t\t\tendpoint,\n\t\t\tsecretAccessKey,\n\t\t\tforcePathStyle = false,\n\t\t\tcache,\n\t\t} = options;\n\t\tconst hasCredentials = accessKeyId && secretAccessKey;\n\t\tconst credentials = hasCredentials\n\t\t\t? { accessKeyId, secretAccessKey }\n\t\t\t: undefined;\n\n\t\tconst client = new S3Client({\n\t\t\tregion,\n\t\t\tcredentials,\n\t\t\tendpoint,\n\t\t\tforcePathStyle,\n\t\t});\n\n\t\treturn new AmazonStorageClient(client, bucket, acl, cache);\n\t}\n\tconstructor(\n\t\tprivate readonly client: S3Client,\n\t\tprivate readonly bucket: string,\n\t\tprivate readonly acl = AmazonCannedAccessControlList.AuthenticatedRead,\n\t\treadonly cache?: Cache,\n\t) {}\n\n\tgetVersionDownloadURL(file: File, versionId: string): Promise<string> {\n\t\tconst ResponseContentDisposition = file.name\n\t\t\t? `attachment; filename=${encodeURIComponent(file.name)}`\n\t\t\t: undefined;\n\n\t\tconst command = new GetObjectCommand({\n\t\t\tBucket: this.bucket,\n\t\t\tKey: file.path,\n\t\t\tResponseContentDisposition,\n\t\t\tVersionId: versionId,\n\t\t});\n\n\t\treturn getSignedUrl(this.client, command, { expiresIn: 60 * 60 * 24 });\n\t}\n\n\tasync getVersions(key: string): Promise<DocumentVersion[]> {\n\t\tconst command = new ListObjectVersionsCommand({\n\t\t\tBucket: this.bucket,\n\t\t\tPrefix: key,\n\t\t});\n\n\t\tconst { Versions = [] } = await this.client.send(command);\n\n\t\treturn Versions.map((version) => ({\n\t\t\tid: version.VersionId || '',\n\t\t\tcreatedAt: version.LastModified || new Date(),\n\t\t}));\n\t}\n\n\tasync getDownloadURL(file: File, expiresIn = 60 * 60): Promise<string> {\n\t\tconst cacheKey = `download-url:${file.path}`;\n\t\tconst cachedURL = await this.cache?.get<string>(cacheKey);\n\n\t\tif (cachedURL) {\n\t\t\treturn cachedURL;\n\t\t}\n\n\t\tconst ResponseContentDisposition = file.name\n\t\t\t? `attachment; filename=${encodeURIComponent(file.name)}`\n\t\t\t: undefined;\n\n\t\tconst command = new GetObjectCommand({\n\t\t\tBucket: this.bucket,\n\t\t\tKey: file.path,\n\t\t\tResponseContentDisposition,\n\t\t});\n\n\t\tconst url = await getSignedUrl(this.client, command, { expiresIn });\n\t\tconst cacheExpiration = Math.max(expiresIn - 60, 0);\n\n\t\tif (cacheExpiration) {\n\t\t\tawait this.cache?.set(cacheKey, url, cacheExpiration);\n\t\t}\n\n\t\treturn url;\n\t}\n\n\tasync getUploadURL(\n\t\tparams: GetUploadParams,\n\t\texpiresIn = 60 * 60,\n\t): Promise<string> {\n\t\tconst command = new PutObjectCommand({\n\t\t\tBucket: this.bucket,\n\t\t\tKey: params.path,\n\t\t\tContentType: params.contentType,\n\t\t\tContentLength: params.contentLength,\n\t\t});\n\n\t\treturn getSignedUrl(this.client, command, { expiresIn });\n\t}\n\n\tasync getUpload(\n\t\tparams: GetUploadParams,\n\t\texpiresIn = 5,\n\t): Promise<GetUploadResponse> {\n\t\tconst { path } = params;\n\t\tconst { fields: values, url } = await createPresignedPost(this.client, {\n\t\t\tExpires: expiresIn * 60,\n\t\t\tBucket: this.bucket,\n\t\t\tFields: {\n\t\t\t\tacl: this.acl,\n\t\t\t},\n\t\t\tConditions: [\n\t\t\t\t// content length restrictions: 0-1MB]\n\t\t\t\t// ['content-length-range', 0, contentLength],\n\t\t\t\t// specify content-type to be more generic- images only\n\t\t\t\t// ['starts-with', '$Content-Type', 'image/'],\n\t\t\t\t// ['starts-with', '$Content-Type', contentType],\n\t\t\t],\n\t\t\tKey: path,\n\t\t});\n\n\t\tconst keys = Object.keys(values);\n\t\tconst fields = keys.map((key) => ({ key, value: values[key] || '' }));\n\n\t\treturn { url, fields };\n\t}\n\n\tasync upload(\n\t\tkey: string,\n\t\tdata: string | Buffer,\n\t\tcontentType: string,\n\t): Promise<void> {\n\t\tconst Body = typeof data === 'string' ? Buffer.from(data, 'base64') : data;\n\n\t\tconst params = {\n\t\t\tBucket: this.bucket,\n\t\t\tKey: key,\n\t\t\tBody,\n\t\t\tContentType: contentType,\n\t\t};\n\n\t\tconst command = new PutObjectCommand(params);\n\n\t\tawait this.client.send(command);\n\t}\n\n\tasync delete(key: string): Promise<void> {\n\t\tconst command = new DeleteObjectCommand({\n\t\t\tBucket: this.bucket,\n\t\t\tKey: key,\n\t\t});\n\n\t\tawait this.client.send(command);\n\t}\n}\n\nexport enum AmazonCannedAccessControlList {\n\tAuthenticatedRead = 'authenticated-read',\n\tPrivate = 'private',\n\tPublicRead = 'public-read',\n\tPublicReadWrite = 'public-read-write',\n\tAwsExecRead = 'aws-exec-read',\n\tBucketOwnerRead = 'bucket-owner-read',\n\tBucketOwnerFullControl = 'bucket-owner-full-control',\n\tLogDeliveryWrite = 'log-delivery-write',\n}\n\ninterface AmazonStorageClientCreateOptions {\n\tbucket: string;\n\tregion?: string;\n\tacl?: AmazonCannedAccessControlList;\n\taccessKeyId?: string;\n\tsecretAccessKey?: string;\n\tendpoint?: string;\n\tforcePathStyle?: boolean;\n\tcache?: Cache;\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AmazonStorageClient-CKdLCAKb.mjs","names":["options: AmazonStorageClientCreateOptions","client: S3Client","bucket: string","cache?: Cache","file: File","versionId: string","key: string","params: GetUploadParams","data: string | Buffer","contentType: string"],"sources":["../src/AmazonStorageClient.ts"],"sourcesContent":["import {\n\tDeleteObjectCommand,\n\tGetObjectCommand,\n\tListObjectVersionsCommand,\n\tPutObjectCommand,\n\tS3Client,\n} from '@aws-sdk/client-s3';\nimport { createPresignedPost } from '@aws-sdk/s3-presigned-post';\nimport { getSignedUrl } from '@aws-sdk/s3-request-presigner';\n\nimport type { Cache } from '@geekmidas/cache';\nimport {\n\ttype DocumentVersion,\n\ttype File,\n\ttype GetUploadParams,\n\ttype GetUploadResponse,\n\ttype StorageClient,\n\tStorageProvider,\n} from './StorageClient';\n\nexport class AmazonStorageClient implements StorageClient {\n\treadonly provider = StorageProvider.AWSS3;\n\n\tstatic create(\n\t\toptions: AmazonStorageClientCreateOptions,\n\t): AmazonStorageClient {\n\t\tconst {\n\t\t\tbucket,\n\t\t\tregion,\n\t\t\taccessKeyId,\n\t\t\tacl,\n\t\t\tendpoint,\n\t\t\tsecretAccessKey,\n\t\t\tforcePathStyle = false,\n\t\t\tcache,\n\t\t} = options;\n\t\tconst hasCredentials = accessKeyId && secretAccessKey;\n\t\tconst credentials = hasCredentials\n\t\t\t? { accessKeyId, secretAccessKey }\n\t\t\t: undefined;\n\n\t\tconst client = new S3Client({\n\t\t\tregion,\n\t\t\tcredentials,\n\t\t\tendpoint,\n\t\t\tforcePathStyle,\n\t\t});\n\n\t\treturn new AmazonStorageClient(client, bucket, acl, cache);\n\t}\n\tconstructor(\n\t\tprivate readonly client: S3Client,\n\t\tprivate readonly bucket: string,\n\t\tprivate readonly acl = AmazonCannedAccessControlList.AuthenticatedRead,\n\t\treadonly cache?: Cache,\n\t) {}\n\n\tgetVersionDownloadURL(file: File, versionId: string): Promise<string> {\n\t\tconst ResponseContentDisposition = file.name\n\t\t\t? `attachment; filename=${encodeURIComponent(file.name)}`\n\t\t\t: undefined;\n\n\t\tconst command = new GetObjectCommand({\n\t\t\tBucket: this.bucket,\n\t\t\tKey: file.path,\n\t\t\tResponseContentDisposition,\n\t\t\tVersionId: versionId,\n\t\t});\n\n\t\treturn getSignedUrl(this.client, command, { expiresIn: 60 * 60 * 24 });\n\t}\n\n\tasync getVersions(key: string): Promise<DocumentVersion[]> {\n\t\tconst command = new ListObjectVersionsCommand({\n\t\t\tBucket: this.bucket,\n\t\t\tPrefix: key,\n\t\t});\n\n\t\tconst { Versions = [] } = await this.client.send(command);\n\n\t\treturn Versions.map((version) => ({\n\t\t\tid: version.VersionId || '',\n\t\t\tcreatedAt: version.LastModified || new Date(),\n\t\t}));\n\t}\n\n\tasync getDownloadURL(file: File, expiresIn = 60 * 60): Promise<string> {\n\t\tconst cacheKey = `download-url:${file.path}`;\n\t\tconst cachedURL = await this.cache?.get<string>(cacheKey);\n\n\t\tif (cachedURL) {\n\t\t\treturn cachedURL;\n\t\t}\n\n\t\tconst ResponseContentDisposition = file.name\n\t\t\t? `attachment; filename=${encodeURIComponent(file.name)}`\n\t\t\t: undefined;\n\n\t\tconst command = new GetObjectCommand({\n\t\t\tBucket: this.bucket,\n\t\t\tKey: file.path,\n\t\t\tResponseContentDisposition,\n\t\t});\n\n\t\tconst url = await getSignedUrl(this.client, command, { expiresIn });\n\t\tconst cacheExpiration = Math.max(expiresIn - 60, 0);\n\n\t\tif (cacheExpiration) {\n\t\t\tawait this.cache?.set(cacheKey, url, cacheExpiration);\n\t\t}\n\n\t\treturn url;\n\t}\n\n\tasync getUploadURL(\n\t\tparams: GetUploadParams,\n\t\texpiresIn = 60 * 60,\n\t): Promise<string> {\n\t\tconst command = new PutObjectCommand({\n\t\t\tBucket: this.bucket,\n\t\t\tKey: params.path,\n\t\t\tContentType: params.contentType,\n\t\t\tContentLength: params.contentLength,\n\t\t});\n\n\t\treturn getSignedUrl(this.client, command, { expiresIn });\n\t}\n\n\tasync getUpload(\n\t\tparams: GetUploadParams,\n\t\texpiresIn = 5,\n\t): Promise<GetUploadResponse> {\n\t\tconst { path } = params;\n\t\tconst { fields: values, url } = await createPresignedPost(this.client, {\n\t\t\tExpires: expiresIn * 60,\n\t\t\tBucket: this.bucket,\n\t\t\tFields: {\n\t\t\t\tacl: this.acl,\n\t\t\t},\n\t\t\tConditions: [\n\t\t\t\t// content length restrictions: 0-1MB]\n\t\t\t\t// ['content-length-range', 0, contentLength],\n\t\t\t\t// specify content-type to be more generic- images only\n\t\t\t\t// ['starts-with', '$Content-Type', 'image/'],\n\t\t\t\t// ['starts-with', '$Content-Type', contentType],\n\t\t\t],\n\t\t\tKey: path,\n\t\t});\n\n\t\tconst keys = Object.keys(values);\n\t\tconst fields = keys.map((key) => ({ key, value: values[key] || '' }));\n\n\t\treturn { url, fields };\n\t}\n\n\tasync upload(\n\t\tkey: string,\n\t\tdata: string | Buffer,\n\t\tcontentType: string,\n\t): Promise<void> {\n\t\tconst Body = typeof data === 'string' ? Buffer.from(data, 'base64') : data;\n\n\t\tconst params = {\n\t\t\tBucket: this.bucket,\n\t\t\tKey: key,\n\t\t\tBody,\n\t\t\tContentType: contentType,\n\t\t};\n\n\t\tconst command = new PutObjectCommand(params);\n\n\t\tawait this.client.send(command);\n\t}\n\n\tasync delete(key: string): Promise<void> {\n\t\tconst command = new DeleteObjectCommand({\n\t\t\tBucket: this.bucket,\n\t\t\tKey: key,\n\t\t});\n\n\t\tawait this.client.send(command);\n\t}\n}\n\nexport enum AmazonCannedAccessControlList {\n\tAuthenticatedRead = 'authenticated-read',\n\tPrivate = 'private',\n\tPublicRead = 'public-read',\n\tPublicReadWrite = 'public-read-write',\n\tAwsExecRead = 'aws-exec-read',\n\tBucketOwnerRead = 'bucket-owner-read',\n\tBucketOwnerFullControl = 'bucket-owner-full-control',\n\tLogDeliveryWrite = 'log-delivery-write',\n}\n\ninterface AmazonStorageClientCreateOptions {\n\tbucket: string;\n\tregion?: string;\n\tacl?: AmazonCannedAccessControlList;\n\taccessKeyId?: string;\n\tsecretAccessKey?: string;\n\tendpoint?: string;\n\tforcePathStyle?: boolean;\n\tcache?: Cache;\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AmazonStorageClient-Z61MeFBa.d.mts","names":[],"sources":["../src/AmazonStorageClient.ts"],"sourcesContent":[],"mappings":";;;;;cAoBa,mBAAA,YAA+B;;EAA/B,iBAAA,MAAoB;EAAA,iBAAA,GAAA;EAAA,SAkCd,KAAA,CAAA,EAAA,KAAA;EAAK,SAjCN,QAAA,GAAA,eAAA,CAAA,KAAA;EAAA,OAGP,MAAA,CAAA,OAAA,EAAA,gCAAA,CAAA,EACP,mBADO;EAAgC,WACvC,CAAA,MAAA,EA0BuB,QA1BvB,EAAA,MAAA,EAAA,MAAA,EAAA,GAAA,CAAA,EA4BkB,6BA5BlB,EAAA,KAAA,CAAA,EA6Be,KA7Bf;EAAmB,qBA0BI,CAAA,IAAA,EAME,IANF,EAAA,SAAA,EAAA,MAAA,CAAA,EAM4B,OAN5B,CAAA,MAAA,CAAA;EAAQ,WAEb,CAAA,GAAA,EAAA,MAAA,CAAA,EAmBW,OAnBX,CAmBmB,eAnBnB,EAAA,CAAA;EAAkD,cACrD,CAAA,IAAA,EAgCS,IAhCT,EAAA,SAAA,CAAA,EAAA,MAAA,CAAA,EAgCqC,OAhCrC,CAAA,MAAA,CAAA;EAAK,YAGK,CAAA,MAAA,EA0DnB,eA1DmB,EAAA,SAAA,CAAA,EAAA,MAAA,CAAA,EA4DzB,OA5DyB,CAAA,MAAA,CAAA;EAAI,SAAsB,CAAA,MAAA,EAwE7C,eAxE6C,EAAA,SAAA,CAAA,EAAA,MAAA,CAAA,EA0EnD,OA1EmD,CA0E3C,iBA1E2C,CAAA;EAAO,MAerB,CAAA,GAAA,EAAA,MAAA,EAAA,IAAA,EAAA,MAAA,GAqFxB,MArFwB,EAAA,WAAA,EAAA,MAAA,CAAA,EAuFrC,OAvFqC,CAAA,IAAA,CAAA;EAAe,MAAvB,CAAA,GAAA,EAAA,MAAA,CAAA,EAsGL,OAtGK,CAAA,IAAA,CAAA;;AAcuB,aAkG5C,6BAAA;EAlGmD,iBA6BrD,GAAA,oBAAA;EAAe,OAErB,GAAA,SAAA;EAAO,UAYD,GAAA,aAAA;EAAe,eAEb,GAAA,mBAAA;EAAiB,WAAzB,GAAA,eAAA;EAAO,eA0BM,GAAA,mBAAA;EAAM,sBAEnB,GAAA,2BAAA;EAAO,gBAeiB,GAAA,oBAAA;;AA1J6B,UA+K/C,gCAAA,CA/K+C;EAoK7C,MAAA,EAAA,MAAA;EAWF,MAAA,CAAA,EAAA,MAAA;EAAgC,GAAA,CAAA,EAGnC,6BAHmC;EAAA,WAGnC,CAAA,EAAA,MAAA;EAA6B,eAK3B,CAAA,EAAA,MAAA;EAAK,QAAA,CAAA,EAAA,MAAA;;UAAL"}
|