Skip to content

Instantly share code, notes, and snippets.

@josdotdev
Forked from AndrewIngram/R2_storage.ts
Created April 30, 2023 18:55
Show Gist options
  • Select an option

  • Save josdotdev/a4583f5d2788e569a7d4c12e497d80df to your computer and use it in GitHub Desktop.

Select an option

Save josdotdev/a4583f5d2788e569a7d4c12e497d80df to your computer and use it in GitHub Desktop.

Revisions

  1. @AndrewIngram AndrewIngram revised this gist Feb 22, 2023. 1 changed file with 4 additions and 5 deletions.
    9 changes: 4 additions & 5 deletions R2_storage.ts
    Original file line number Diff line number Diff line change
    @@ -1,10 +1,10 @@
    import { AwsClient } from "aws4fetch";
    import { deflate } from "pako";

    const R2_ACCOUNT_ID = "SOMETHING
    const R2_ACCESS_KEY_ID = "SOMETHING
    const R2_SECRET_ACCESS_KEY ="SOMETHING
    const R2_BUCKET = "SOMETHING
    const R2_ACCOUNT_ID = "SOMETHING"
    const R2_ACCESS_KEY_ID = "SOMETHING"
    const R2_SECRET_ACCESS_KEY ="SOMETHING"
    const R2_BUCKET = "SOMETHING"
    const R2_URL = `https://${R2_BUCKET}.${R2_ACCOUNT_ID}.r2.cloudflarestorage.com`;


    @@ -84,7 +84,6 @@ export default class FileStorage {

    let body;

    // Might need to do some manipulation depending on the type of the data
    if (typeof data === "string") {
    const enc = new TextEncoder();
    body = deflate(enc.encode(data));
  2. @AndrewIngram AndrewIngram renamed this gist Feb 22, 2023. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  3. @AndrewIngram AndrewIngram renamed this gist Feb 22, 2023. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  4. @AndrewIngram AndrewIngram created this gist Feb 22, 2023.
    105 changes: 105 additions & 0 deletions 01_basic.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,105 @@
    import { AwsClient } from "aws4fetch";
    import { deflate } from "pako";

    const R2_ACCOUNT_ID = "SOMETHING
    const R2_ACCESS_KEY_ID = "SOMETHING
    const R2_SECRET_ACCESS_KEY ="SOMETHING
    const R2_BUCKET = "SOMETHING
    const R2_URL = `https://${R2_BUCKET}.${R2_ACCOUNT_ID}.r2.cloudflarestorage.com`;


    const getR2Client = () => {
    return new AwsClient({
    accessKeyId: R2_ACCESS_KEY_ID,
    secretAccessKey: R2_SECRET_ACCESS_KEY,
    });
    });

    export default class FileStorage {
    static head(key: string) {
    return getR2Client().fetch(`${R2_URL}/${key}`, {
    method: "HEAD",
    });
    }

    static async exists(key: string): Promise<boolean> {
    const response = await this.head(key);
    return response.status !== 404;
    }

    static list() {
    return getR2Client().fetch(`${R2_URL}`, {
    method: "GET",
    });
    }


    static async get(key: string) {
    const url = new URL(R2_URL);

    // preserve the original path
    url.pathname = key;

    // Specify a custom expiry for the presigned URL, in seconds
    // 3600 is almost certainly overkill
    url.searchParams.set("X-Amz-Expires", "3600");

    const signed = await getR2Client().sign(
    new Request(url, {
    method: "GET",
    headers: {
    "Accept-Encoding": "deflate",
    },
    }),
    {
    aws: { signQuery: true },
    },
    );

    return fetch(signed.url, {
    method: "GET",
    headers: {
    "Accept-Encoding": "deflate",
    },
    });
    }

    static async put(key: string, data: Buffer | Uint8Array | string) {
    const url = new URL(R2_URL);
    url.pathname = key;

    // Specify a custom expiry for the presigned URL, in seconds
    // 3600 is almost certainly overkill
    url.searchParams.set("X-Amz-Expires", "3600");

    const signed = await getR2Client().sign(
    new Request(url, {
    method: "PUT",
    headers: {},
    }),
    {
    aws: { signQuery: true },
    },
    );

    let body;

    // Might need to do some manipulation depending on the type of the data
    if (typeof data === "string") {
    const enc = new TextEncoder();
    body = deflate(enc.encode(data));
    } else if (data instanceof Uint8Array) {
    body = deflate(data);
    } else {
    body = data;
    }

    return fetch(signed.url, {
    method: "PUT",
    body,
    headers: {
    "Content-Encoding": "deflate",
    },
    });
    }
    }