1import type * as runtime from "@cloudflare/workers-types";
2import * as Effect from "effect/Effect";
3import * as Layer from "effect/Layer";
4import * as Redacted from "effect/Redacted";
5import { Worker, WorkerEnvironment } from "../Workers/Worker.ts";
6import type { Secret } from "./Secret.ts";
7import { ReadSecret, SecretError } from "./ReadSecret.ts";
8
9export const ReadSecretBinding = Layer.effect(
10 ReadSecret,
11 Effect.gen(function* () {
12 const env = yield* WorkerEnvironment;
13 const host = yield* Worker;
14
15 return Effect.fn(function* (secret: Secret) {
16 if (!globalThis.__ALCHEMY_RUNTIME__) {
17 yield* host.bind`${secret}`({
18 bindings: [
19 {
20 type: "secrets_store_secret",
21 name: secret.LogicalId,
22 secretName: secret.secretName,
23 storeId: secret.storeId,
24 },
25 ],
26 });
27 }
28 const raw = Effect.sync(
29 () =>
30 (env as Record<string, runtime.SecretsStoreSecret>)[secret.LogicalId],
31 );
32 const tryPromise = <T>(
33 fn: () => Promise<T>,
34 ): Effect.Effect<T, SecretError> =>
35 Effect.tryPromise({
36 try: fn,
37 catch: (error: any) =>
38 new SecretError({
39 message: error.message ?? "Unknown error",
40 cause: error,
41 }),
42 });
43
44 const getEffect = raw.pipe(
45 Effect.flatMap((raw) =>
46 tryPromise(() => raw.get().then(Redacted.make)),
47 ),
48 );
49
50 return Object.assign(getEffect, {
51 raw,
52 get: () => getEffect,
53 });
54 });
55 }),
56);