diff --git a/src/drivers/s3.ts b/src/drivers/s3.ts index 30798b11..22efd6ce 100644 --- a/src/drivers/s3.ts +++ b/src/drivers/s3.ts @@ -74,7 +74,7 @@ export default defineDriver((options: S3DriverOptions) => { const baseURL = `${options.endpoint.replace(/\/$/, "")}/${options.bucket || ""}`; - const url = (key: string = "") => `${baseURL}/${normalizeKey(key)}`; + const url = (key: string = "") => `${baseURL}/${normalizeKey(key, "/")}`; const awsFetch = async (url: string, opts?: RequestInit) => { const request = await getAwsClient().sign(url, opts); diff --git a/src/drivers/utils/index.ts b/src/drivers/utils/index.ts index 6bba218c..16e584a3 100644 --- a/src/drivers/utils/index.ts +++ b/src/drivers/utils/index.ts @@ -11,11 +11,14 @@ export function defineDriver( return factory; } -export function normalizeKey(key: string | undefined): string { +export function normalizeKey( + key: string | undefined, + sep: ":" | "/" = ":" +): string { if (!key) { return ""; } - return key.replace(/[/\\]/g, ":").replace(/^:|:$/g, ""); + return key.replace(/[:/\\]/g, sep).replace(/^[:/\\]|[:/\\]$/g, ""); } export function joinKeys(...keys: string[]) { diff --git a/test/drivers/s3.test.ts b/test/drivers/s3.test.ts index e836c174..e507a9df 100644 --- a/test/drivers/s3.test.ts +++ b/test/drivers/s3.test.ts @@ -1,6 +1,7 @@ -import { describe } from "vitest"; +import { describe, it, expect } from "vitest"; import s3Driver from "../../src/drivers/s3"; import { testDriver } from "./utils"; +import { AwsClient } from "aws4fetch"; const accessKeyId = process.env.VITE_S3_ACCESS_KEY_ID; const secretAccessKey = process.env.VITE_S3_SECRET_ACCESS_KEY; @@ -20,5 +21,25 @@ describe.skipIf( endpoint: endpoint!, region: region!, }), + additionalTests(ctx) { + it("can access directly with / separator", async () => { + await ctx.storage.set("foo/bar:baz", "ok"); + expect(await ctx.storage.get("foo/bar:baz")).toBe("ok"); + + const client = new AwsClient({ + accessKeyId: accessKeyId!, + secretAccessKey: secretAccessKey!, + region, + }); + const response = await client.fetch( + `${endpoint}/${bucket}/foo/bar/baz`, + { + method: "GET", + } + ); + expect(response.status).toBe(200); + expect(await response.text()).toBe("ok"); + }); + }, }); });