1import * as machines from "@distilled.cloud/fly-io/machines";
2import * as Effect from "effect/Effect";
3import * as Layer from "effect/Layer";
4import * as FetchHttpClient from "effect/http/FetchHttpClient";
5import { CredentialsFromAmbientOrEnv } from "./Credentials.ts";
6import { Encrypt, type EncryptRequest } from "./Encrypt.ts";
7import {
8 base64ToBytes,
9 bytesToBase64,
10 makeHttpSecretKeyBinding,
11} from "./SecretKeyHttp.ts";
12
13/**
14 * HTTP implementation of {@link Encrypt}. Provide it on the
15 * {@link Service} or Action Effect.
16 *
17 *
18 * ### Provide the layer
19 * **Example:** On a Service
20 * ```typescript
21 * Effect.gen(function* () {
22 * const encrypt = yield* Fly.Encrypt(Box);
23 * // ...
24 * }).pipe(Effect.provide(Fly.EncryptHttp))
25 * ```
26 *
27 * @layer
28 * @product Secret Key
29 * @provides Fly.Encrypt
30 */
31export const EncryptHttp = Layer.effect(
32 Encrypt,
33 Effect.suspend(() =>
34 makeHttpSecretKeyBinding({
35 makeClient: (auth, appName, secretName) =>
36 Effect.fn("Fly.Encrypt")(function* (request: EncryptRequest) {
37 const res = yield* auth.authorize(
38 machines.encryptSecretKey({
39 app_name: yield* appName,
40 secret_name: yield* secretName,
41 plaintext: bytesToBase64(request.plaintext),
42 associated_data:
43 request.associatedData === undefined
44 ? undefined
45 : bytesToBase64(request.associatedData),
46 }),
47 );
48 return { ciphertext: base64ToBytes(res.ciphertext) };
49 }),
50 }),
51 ),
52).pipe(
53 Layer.provide(FetchHttpClient.layer),
54 Layer.provide(CredentialsFromAmbientOrEnv),
55);