diff --git a/package.json b/package.json index e5e9a8a..992c5d9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@adminjs/upload", - "version": "2.0.2", + "version": "2.0.2-dev3", "main": "index.js", "types": "types/index.d.ts", "private": false, @@ -25,7 +25,7 @@ }, "optionalDependencies": { "@google-cloud/storage": "^5.3.0", - "aws-sdk": "^2.728.0" + "aws-sdk": "^2.1138.0" }, "devDependencies": { "@commitlint/cli": "^8.3.5", @@ -39,7 +39,7 @@ "@typescript-eslint/eslint-plugin": "^3.7.0", "@typescript-eslint/parser": "^3.7.0", "adminjs": "^5.0.0", - "aws-sdk": "^2.728.0", + "aws-sdk": "^2.1138.0", "chai": "^4.2.0", "eslint": "^7.5.0", "eslint-config-airbnb": "^18.2.0", diff --git a/src/features/upload-file/providers/aws-provider.ts b/src/features/upload-file/providers/aws-provider.ts index c1faf80..785bfd6 100644 --- a/src/features/upload-file/providers/aws-provider.ts +++ b/src/features/upload-file/providers/aws-provider.ts @@ -1,6 +1,6 @@ import fs from 'fs' // eslint-disable-next-line import/no-extraneous-dependencies -import { S3 } from 'aws-sdk' +import { S3, Endpoint } from 'aws-sdk' import { UploadedFile } from 'adminjs' import { ERROR_MESSAGES, DAY_IN_MINUTES } from '../constants' @@ -29,6 +29,12 @@ export type AWSOptions = { * S3 Bucket where files will be stored */ bucket: string; + /** + * The endpoint URI to send requests to. + * The default endpoint is built from the configured region. + * Note that `bucket` should not appear in `endpoint`. + */ + endpoint?: string | Endpoint; /** * indicates how long links should be available after page load (in minutes). * Default to 24h. If set to 0 adapter will mark uploaded files as PUBLIC ACL. @@ -36,11 +42,16 @@ export type AWSOptions = { expires?: number; } +/** + * Generic S3 Provider for S3-compatible Object Storage Services, like Tencent Cloud COS. + */ export class AWSProvider extends BaseProvider { private s3: S3 public expires: number + public endpoint?: Endpoint + constructor(options: AWSOptions) { super(options.bucket) @@ -52,8 +63,14 @@ export class AWSProvider extends BaseProvider { } catch (error) { throw new Error(ERROR_MESSAGES.NO_AWS_SDK) } - this.expires = options.expires ?? DAY_IN_MINUTES - this.s3 = new AWS_S3(options) + const newOptions = options + if (typeof newOptions.endpoint === 'string') { + // convert into Endpoint object + newOptions.endpoint = new Endpoint(newOptions.endpoint) + } + this.expires = newOptions.expires ?? DAY_IN_MINUTES + this.endpoint = newOptions.endpoint + this.s3 = new AWS_S3(newOptions) } public async upload(file: UploadedFile, key: string): Promise { @@ -82,7 +99,16 @@ export class AWSProvider extends BaseProvider { Expires: this.expires, }) } - // https://bucket.s3.amazonaws.com/key - return `https://${bucket}.s3.amazonaws.com/${key}` + + let keyedPath: string + + if (this.endpoint) { + // NOTE: protocal contains a trailing ':' ! + keyedPath = `${this.endpoint.protocol}//${bucket}.${this.endpoint.host}/${key}` + } else { + // https://bucket.s3.amazonaws.com/key + keyedPath = `https://${bucket}.s3.amazonaws.com/${key}` + } + return keyedPath } } diff --git a/yarn.lock b/yarn.lock index 9bdd053..2b8c99f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2250,15 +2250,15 @@ at-least-node@^1.0.0: resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== -aws-sdk@^2.728.0: - version "2.746.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.746.0.tgz#19f2b8d5d628774030ae184b9e59a67bb9de1f63" - integrity sha512-TMa/jxS2AHuZqAYNyv0X+Ltjt2NebjraT7xdL6NqKUiu0U61j0uav+gr2zw9lkz5q+KeTeYo7pg+S9LXVawHXw== +aws-sdk@^2.1138.0: + version "2.1138.0" + resolved "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1138.0.tgz#5975e028807a327e0900075de6a054fdd939a1f0" + integrity sha512-81Bs7qVf1/NrZBDCVIPpynODNN8fvXLdbsK024VITKFjts6DpvWjWPCsRYvEtaksF6uypMx5D02nTYJ8RiXq9w== dependencies: buffer "4.9.2" events "1.1.1" ieee754 "1.1.13" - jmespath "0.15.0" + jmespath "0.16.0" querystring "0.2.0" sax "1.2.1" url "0.10.3" @@ -5081,10 +5081,10 @@ jest-worker@^26.0.0: merge-stream "^2.0.0" supports-color "^7.0.0" -jmespath@0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" - integrity sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc= +jmespath@0.16.0: + version "0.16.0" + resolved "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz#b15b0a85dfd4d930d43e69ed605943c802785076" + integrity sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw== "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0"