Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
3.1 kB · 104 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105import type { CloudflareOpContext } from "@distilled.cloud/cloudflare";import { Forbidden, Unauthorized } from "@distilled.cloud/cloudflare/Errors";import * as Effect from "effect/Effect";import { cloudflare } from "./cloudflare-sdk.ts";import { AccountDenied, ReauthorizationRequired, TemporarilyUnavailable,} from "./deployment-errors.ts";import { object } from "./deployment-values.ts";import { bodyBytes, withResponse } from "../server/http.ts";
export class CloudflareAccount { constructor( private readonly accessToken: string, readonly accountId: string, private readonly network: typeof fetch = fetch, ) {} sdk<A, E>(operation: Effect.Effect<A, E, CloudflareOpContext>) { return cloudflare(operation, this.accessToken, this.network).pipe( Effect.mapError((error) => error instanceof Unauthorized ? new ReauthorizationRequired() : error instanceof Forbidden ? new AccountDenied() : new TemporarilyUnavailable(), ), ); } response<A, E>( path: string, init: RequestInit, read: (response: Response) => Effect.Effect<A, E>, ) { const url = `https://api.cloudflare.com/client/v4/accounts/${this.accountId}/${path}`; const headers = new Headers(init.headers); headers.set("Authorization", `Bearer ${this.accessToken}`); return withResponse( this.network, url, { ...init, headers, }, 60_000, new TemporarilyUnavailable(), (response) => Effect.gen(function* () { if (response.status === 401) return yield* new ReauthorizationRequired(); if (response.status === 403) return yield* new AccountDenied(); return yield* read(response); }), ); } request( path: string, { method = "GET", body, allowNotFound = false, }: { method?: "GET" | "POST" | "PUT" | "PATCH"; body?: unknown; allowNotFound?: boolean; } = {}, ) { return this.response( path, { method, ...(body === undefined ? {} : { body: body instanceof FormData ? body : JSON.stringify(body), ...(body instanceof FormData ? {} : { headers: { "Content-Type": "application/json" } }), }), }, (response) => Effect.gen(function* () { if (response.status === 404 && allowNotFound) return null; const bytes = yield* bodyBytes( response, 2 * 1024 * 1024, new TemporarilyUnavailable(), ); const envelope: unknown = yield* Effect.try({ try: () => JSON.parse(new TextDecoder().decode(bytes)), catch: () => new TemporarilyUnavailable(), }); if ( !response.ok || !object(envelope) || envelope.success !== true || !("result" in envelope) ) return yield* new TemporarilyUnavailable(); return envelope.result; }), ); }}