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 type { Secret } from "./Secret.ts";
7import {
8 type SecretAuth,
9 makeHttpSecretBinding,
10 unwrapSecretValue,
11} from "./SecretHttp.ts";
12import { WriteSecret, type WriteSecretClient } from "./WriteSecret.ts";
13
14/**
15 * HTTP implementation of {@link WriteSecret}. Provide it on the
16 * {@link Service} or Action Effect.
17 *
18 *
19 * ### Provide the layer
20 * **Example:** On an Action
21 * ```typescript
22 * Effect.gen(function* () {
23 * const secrets = yield* Fly.WriteSecret(ApiToken);
24 * // ...
25 * }).pipe(Effect.provide(Fly.WriteSecretHttp))
26 * ```
27 *
28 * @layer
29 * @product Secret
30 * @provides Fly.WriteSecret
31 */
32export const WriteSecretHttp = Layer.effect(
33 WriteSecret,
34 Effect.suspend(() =>
35 makeHttpSecretBinding<Secret, WriteSecretClient>({
36 makeClient: secretWriteClient,
37 }),
38 ),
39).pipe(
40 Layer.provide(FetchHttpClient.layer),
41 Layer.provide(CredentialsFromAmbientOrEnv),
42);
43
44/** Build the write client over an injectable auth and App name. */
45export const secretWriteClient = (
46 auth: SecretAuth,
47 appName: Effect.Effect<string>,
48 _secretName: Effect.Effect<string>,
49): WriteSecretClient => {
50 const authorize = auth.authorize;
51 return {
52 create: Effect.fn("Fly.Secret.create")(function* (name, value) {
53 return yield* authorize(
54 machines.createSecret({
55 app_name: yield* appName,
56 secret_name: name,
57 value: unwrapSecretValue(value),
58 }),
59 );
60 }),
61 update: Effect.fn("Fly.Secret.update")(function* (name, value) {
62 return yield* authorize(
63 machines.updateSecrets({
64 app_name: yield* appName,
65 values: { [name]: unwrapSecretValue(value) },
66 }),
67 );
68 }),
69 delete: Effect.fn("Fly.Secret.delete")(function* (name) {
70 return yield* authorize(
71 machines.deleteSecret({
72 app_name: yield* appName,
73 secret_name: name,
74 }),
75 );
76 }),
77 };
78};