Skip to content
Source
Sign inSign up

SecretCheck.ts

39 lines1.5 KB

1import type { SecretReference, SecretSourceCheckResult } from "@t3tools/contracts";
2import * as SecretResolver from "@t3tools/secret-provider-core/server/SecretResolver";
3import * as Context from "effect/Context";
4import * as Effect from "effect/Effect";
5import * as Layer from "effect/Layer";
6​
7import * as ProviderRegistry from "../provider/ProviderRegistry.ts";
8​
9export class SecretCheck extends Context.Service<
10 SecretCheck,
11 {
12 /**
13 * Reads one secret fresh for the Settings "check" button and never returns the value. A
14 * readable secret also rebuilds the provider instances that read it, from that same read.
15 */
16 readonly check: (reference: SecretReference) => Effect.Effect<SecretSourceCheckResult>;
17 }
18>()("t3/secrets/SecretCheck") {}
19​
20const make = Effect.gen(function* () {
21 const resolver = yield* SecretResolver.SecretResolver;
22 const providerRegistry = yield* ProviderRegistry.ProviderRegistry;
23​
24 const check = Effect.fn("SecretCheck.check")(function* (reference: SecretReference) {
25 const [value] = yield* resolver.read([reference], { fresh: true });
26 if (value === undefined || value.trim() === "") {
27 return {
28 _tag: "Failed",
29 detail: `Could not read this secret from "${yield* resolver.label(reference.provider)}". Check the provider's settings and that its store is unlocked.`,
30 } as const;
31 }
32 yield* providerRegistry.applySecretAndRefresh(reference, value);
33 return { _tag: "Resolved" } as const;
34 });
35​
36 return SecretCheck.of({ check });
37});
38​
39export const layer = Layer.effect(SecretCheck, make);