diff --git a/packages/backend-core/src/objectStore/buckets/tests/app.spec.ts b/packages/backend-core/src/objectStore/buckets/tests/app.spec.ts index d188d774bb..e36b36d39d 100644 --- a/packages/backend-core/src/objectStore/buckets/tests/app.spec.ts +++ b/packages/backend-core/src/objectStore/buckets/tests/app.spec.ts @@ -93,6 +93,22 @@ describe("app", () => { testEnv.multiTenant() }) + it("gets url with embedded minio", async () => { + testEnv.withMinio() + const url = await getAppFileUrl() + expect(url).toBe( + "/files/signed/prod-budi-app-assets/app_123/attachments/image.jpeg" + ) + }) + + it("gets url with custom S3", async () => { + testEnv.withS3() + const url = await getAppFileUrl() + expect(url).toBe( + "http://s3.example.com/prod-budi-app-assets/app_123/attachments/image.jpeg" + ) + }) + it("gets url with cloudfront + s3", async () => { testEnv.withCloudfront() const url = await getAppFileUrl() @@ -108,6 +124,26 @@ describe("app", () => { testEnv.multiTenant() }) + it("gets url with embedded minio", async () => { + testEnv.withMinio() + await testEnv.withTenant(async () => { + const url = await getAppFileUrl() + expect(url).toBe( + "/files/signed/prod-budi-app-assets/app_123/attachments/image.jpeg" + ) + }) + }) + + it("gets url with custom S3", async () => { + testEnv.withS3() + await testEnv.withTenant(async () => { + const url = await getAppFileUrl() + expect(url).toBe( + "http://s3.example.com/prod-budi-app-assets/app_123/attachments/image.jpeg" + ) + }) + }) + it("gets url with cloudfront + s3", async () => { testEnv.withCloudfront() await testEnv.withTenant(async () => { diff --git a/packages/backend-core/src/objectStore/buckets/tests/global.spec.ts b/packages/backend-core/src/objectStore/buckets/tests/global.spec.ts index 9d5ec07c7a..c98d98e016 100644 --- a/packages/backend-core/src/objectStore/buckets/tests/global.spec.ts +++ b/packages/backend-core/src/objectStore/buckets/tests/global.spec.ts @@ -12,6 +12,18 @@ describe("global", () => { testEnv.singleTenant() }) + it("gets url with embedded minio", async () => { + testEnv.withMinio() + const url = await getGlobalFileUrl() + expect(url).toBe("/files/signed/global/settings/logoUrl") + }) + + it("gets url with custom S3", async () => { + testEnv.withS3() + const url = await getGlobalFileUrl() + expect(url).toBe("http://s3.example.com/global/settings/logoUrl") + }) + it("gets url with cloudfront + s3", async () => { testEnv.withCloudfront() const url = await getGlobalFileUrl() @@ -27,6 +39,24 @@ describe("global", () => { testEnv.multiTenant() }) + it("gets url with embedded minio", async () => { + testEnv.withMinio() + await testEnv.withTenant(async tenantId => { + const url = await getGlobalFileUrl() + expect(url).toBe(`/files/signed/global/${tenantId}/settings/logoUrl`) + }) + }) + + it("gets url with custom S3", async () => { + testEnv.withS3() + await testEnv.withTenant(async tenantId => { + const url = await getGlobalFileUrl() + expect(url).toBe( + `http://s3.example.com/global/${tenantId}/settings/logoUrl` + ) + }) + }) + it("gets url with cloudfront + s3", async () => { testEnv.withCloudfront() await testEnv.withTenant(async tenantId => { diff --git a/packages/backend-core/src/objectStore/objectStore.ts b/packages/backend-core/src/objectStore/objectStore.ts index adc974a131..4f07abe7e2 100644 --- a/packages/backend-core/src/objectStore/objectStore.ts +++ b/packages/backend-core/src/objectStore/objectStore.ts @@ -23,6 +23,7 @@ import { v4 } from "uuid" import { APP_PREFIX, APP_DEV_PREFIX } from "../db" import fsp from "fs/promises" import { ReadableStream } from "stream/web" +import { NodeJsRuntimeStreamingBlobPayloadOutputTypes } from "@smithy/types" const streamPipeline = promisify(stream.pipeline) // use this as a temporary store of buckets that are being created @@ -194,17 +195,17 @@ export async function upload({ } let contentType = type - if (!contentType) { - contentType = extension - ? CONTENT_TYPE_MAP[extension.toLowerCase()] - : CONTENT_TYPE_MAP.txt - } + const finalContentType = contentType + ? contentType + : extension + ? CONTENT_TYPE_MAP[extension.toLowerCase()] + : CONTENT_TYPE_MAP.txt const config: PutObjectCommandInput = { // windows file paths need to be converted to forward slashes for s3 Bucket: sanitizeBucket(bucketName), Key: sanitizeKey(filename), Body: fileBytes as stream.Readable | Buffer, - ContentType: contentType!, + ContentType: finalContentType, } if (metadata && typeof metadata === "object") { // remove any nullish keys from the metadata object, as these may be considered invalid @@ -310,11 +311,13 @@ export async function retrieve( if (!response.Body) { throw new Error("Unable to retrieve object") } + const nodeResponse = + response.Body as NodeJsRuntimeStreamingBlobPayloadOutputTypes // currently these are all strings if (STRING_CONTENT_TYPES.includes(response.ContentType)) { - return response.Body.toString() + return nodeResponse.toString() } else { - return response.Body as stream.Readable + return nodeResponse } }