Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

effect-cloudflare-r2-layer

Package Overview
Dependencies
Maintainers
0
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

effect-cloudflare-r2-layer

An effect layer to interact with Cloudware R2 storage service

  • 1.0.29
  • latest
  • npm
  • Socket score

Version published
Maintainers
0
Created
Source

effect-cloudflare-r2-layer

An effect layer to interact with Cloudware R2 storage service.

        

⚡ Quick start

🔶 Install

npm i effect-cloudflare-r2-layer
# or
pnpm i effect-cloudflare-r2-layer
# or
bun i effect-cloudflare-r2-layer

🔶 Use the layer

import { FetchHttpClient } from '@effect/platform';
import { Effect, Layer, pipe } from 'effect';
import {
  CloudflareR2StorageLayerLive,
  FileStorageLayer,
} from 'effect-cloudflare-r2-layer';

const task = pipe(
  FileStorageLayer.readAsText('my-bucket', 'some-file.txt'),
  Effect.scoped,
  Effect.provide(
    Layer.mergeAll(CloudflareR2StorageLayerLive, FetchHttpClient.layer)
  )
);

/* task is of type

  Effect.Effect<
    string, 
    ConfigError | HttpClientError | FileStorageError, 
    never
  >
*/

⚡ Env variables

The layer requires the following env variables:

CLOUDFLARE_ACCOUNT_ID=""
R2_DOCUMENTS_ACCESS_KEY_ID=""
R2_DOCUMENTS_SECRET_ACCESS_KEY=""

⚡ API

functiondescription
createBucketCreate a bucket
bucketInfosGet bucket infos
uploadFileAdds a file to the specified bucket
getFileUrlGets a pre-signed url to fetch a ressource by its filename from the specified bucket.
readAsJsonFetches a file, expecting a content extending Record<string, unknown>.
readAsTextFetches a file as a string.
readAsRawBinaryFetches a file as raw binary (ArrayBuffer).

🔶 createBucket

type createBucket = (
  input: CreateBucketCommandInput
) => Effect.Effect<
  CreateBucketCommandOutput,
  FileStorageError | ConfigError.ConfigError,
  FileStorage
>;
🧿 Example
import { Effect, pipe } from 'effect';
import {
  CloudflareR2StorageLayerLive,
  FileStorageLayer,
} from 'effect-cloudflare-r2-layer';

const task = pipe(
  Effect.gen(function* () {
    const result = yield* FileStorageLayer.createBucket({
      Bucket: 'test',
      CreateBucketConfiguration: {
        Bucket: {
          Type: 'Directory',
          DataRedundancy: 'SingleAvailabilityZone',
        },
      },
    });

    // ...
  }),
  Effect.provide(CloudflareR2StorageLayerLive)
);

🔶 bucketInfos

type BucketInfosInput<TBucket extends string> = {
  Bucket: TBucket;
  ExpectedBucketOwner?: string;
};

type BucketInfosResult = {
  region?: string;
};

type bucketInfos = <TBucket extends string>(
  input: BucketInfosInput<TBucket>
) => Effect.Effect<
  BucketInfosResult,
  ConfigError | FileStorageError | BucketNotFoundError,
  FileStorage
>;
🧿 Example
import { Effect, pipe } from 'effect';
import {
  CloudflareR2StorageLayerLive,
  FileStorageLayer,
} from 'effect-cloudflare-r2-layer';

type Buckets = 'assets' | 'config';

const task = pipe(
  Effect.gen(function* () {
    const result = yield* FileStorageLayer.bucketInfos<Buckets>({
      Bucket: 'assets',
    });

    // ...
  }),
  Effect.provide(CloudflareR2StorageLayerLive)
);

🔶 uploadFile

Adds a file to the specified bucket.

interface UploadFileInput<TBucket extends string> {
  bucketName: TBucket;
  key: string;
  data: Buffer;
  contentType: string | undefined;
}

type uploadFile = <TBucket extends string>(
  input: UploadFileInput<TBucket>
) => Effect.Effect<
  PutObjectCommandOutput,
  FileStorageError | ConfigError.ConfigError,
  FileStorage
>;
🧿 Example
import { Effect, pipe } from 'effect';
import {
  CloudflareR2StorageLayerLive,
  FileStorageLayer,
} from 'effect-cloudflare-r2-layer';
import { readFile } from 'fs-extra';

type Buckets = 'assets' | 'config';
const fileName = 'yolo.jpg';
const filePath = './assets/yolo.jpg';

const task = pipe(
  Effect.gen(function* () {
    const fileData = yield* Effect.tryPromise({
      try: () => readFile(filePath),
      catch: (e) => new FsError({ cause: e  }),
    });

    yield* FileStorageLayer.uploadFile<Buckets>({
      bucketName: 'assets',
      documentKey: fileName,
      data: fileData,
      contentType: 'image/jpeg',
    });

    // ...
  }),
  Effect.provide(CloudflareR2StorageLayerLive);
);

🔶 getFileUrl

Gets a pre-signed url to fetch a ressource by its filename from the specified bucket.

type getFileUrl = <TBucket extends string>(
  bucket: TBucket
  fileName: string,
) => Effect.Effect<
  string,
  FileStorageError | ConfigError.ConfigError,
  FileStorage
>;
🧿 Example
import { Effect, pipe } from 'effect';
import {
  CloudflareR2StorageLayerLive,
  FileStorageLayer,
} from 'effect-cloudflare-r2-layer';

type Buckets = 'assets' | 'config';
const filename = 'yolo.jpg';

const task = pipe(
  Effect.gen(function* () {
    const url = yield* FileStorageLayer.getFileUrl<Buckets>('assets', filename);

    // ...
  }),
  Effect.provide(CloudflareR2StorageLayerLive);
);

🔶 readAsJson

Fetches a file, expecting a content extending Record<string, unknown>.

type readAsJson = <
  TBucket extends string,
  TShape extends Record<string, unknown>
>(
  bucket: TBucket,
  fileName: string
) => Effect.Effect<
  TShape,
  HttpClientError | FileStorageError | ConfigError.ConfigError,
  FileStorage | Scope | HttpClient<HttpClientError, Scope>
>;
🧿 Example
import { FetchHttpClient } from '@effect/platform';
import { Effect, Layer, pipe } from 'effect';
import {
  CloudflareR2StorageLayerLive,
  FileStorageLayer,
} from 'effect-cloudflare-r2-layer';

type Buckets = 'assets' | 'config';

type JsonData = {
  cool: boolean;
  yolo: string;
};

const task = pipe(
  pipe(
    Effect.gen(function* () {
      const json = yield* FileStorageLayer.readAsJson<Buckets, JsonData>(
        'config',
        'app-config.json'
      );

      // json is of type JsonData ...
    }),
    Effect.scoped,
    Effect.provide(
      Layer.mergeAll(CloudflareR2StorageLayerLive, FetchHttpClient.layer)
    )
  )
);

🔶 readAsText

Fetches a file as a string.

readAsText: <TBucket extends string>(
  bucketName: TBucket,
  documentKey: string
) =>
  Effect.Effect<
    string,
    ConfigError | HttpClientError | FileStorageError,
    FileStorage | Scope | HttpClient<HttpClientError, Scope>
  >;
🧿 Example
import { FetchHttpClient } from '@effect/platform';
import { Effect, Layer, pipe } from 'effect';
import {
  CloudflareR2StorageLayerLive,
  FileStorageLayer,
} from 'effect-cloudflare-r2-layer';

type Buckets = 'assets' | 'config';

const task = pipe(
  pipe(
    Effect.gen(function* () {
      const text = yield* FileStorageLayer.readAsText<Buckets>(
        'assets',
        'content.txt'
      );

      // ...
    }),
    Effect.scoped,
    Effect.provide(
      Layer.mergeAll(CloudflareR2StorageLayerLive, FetchHttpClient.layer)
    )
  )
);

🔶 readAsRawBinary

Fetches a file as raw binary.

readAsRawBinary: <TBucket extends string>(
  bucketName: TBucket,
  documentKey: string
) =>
  Effect.Effect<
    ArrayBuffer,
    ConfigError | HttpClientError | FileStorageError,
    FileStorage | Scope | HttpClient<HttpClientError, Scope>
  >;
🧿 Example
import { FetchHttpClient } from '@effect/platform';
import { Effect, Layer, pipe } from 'effect';
import {
  CloudflareR2StorageLayerLive,
  FileStorageLayer,
} from 'effect-cloudflare-r2-layer';
import fs from 'fs-extra';
import { TaggedError } from 'effect/Data';

export class FsError extends TaggedError('FsError')<{
  cause?: unknown;
}> {}

type Buckets = 'assets' | 'config';

const task = pipe(
  pipe(
    Effect.gen(function* () {
      const buffer = yield* FileStorageLayer.readAsRawBinary<Buckets>(
        'assets',
        'yolo.jpg'
      );

      yield* Effect.tryPromise({
        try: () =>
          fs.writeFile('./file.jpg', Buffer.from(buffer), {
            encoding: 'utf-8',
          }),
        catch: (e) => new FsError({ cause: e }),
      });
    }),
    Effect.scoped,
    Effect.provide(
      Layer.mergeAll(CloudflareR2StorageLayerLive, FetchHttpClient.layer)
    )
  )
);

Keywords

FAQs

Package last updated on 03 Nov 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc