UNPKG

every-plugin

Version:
75 lines (64 loc) 2.18 kB
import { Context, Effect } from "effect"; import * as z from "zod"; import type { SecretsConfig } from "../../types"; import { PluginRuntimeError } from "../errors"; const configSchema = z .object({ secrets: z.record(z.string(), z.unknown()), }) .passthrough(); export class SecretsConfigTag extends Context.Tag("SecretsConfig")< SecretsConfigTag, SecretsConfig >() {} export class SecretsService extends Effect.Service<SecretsService>()("SecretsService", { effect: Effect.gen(function* () { const secrets = yield* SecretsConfigTag; const hydrateValue = (value: unknown): unknown => { if (typeof value === "string") { let result = value; for (const [key, secretValue] of Object.entries(secrets)) { const pattern = new RegExp(`{{${key}}}`, "g"); result = result.replace(pattern, String(secretValue)); } return result; } if (Array.isArray(value)) { return value.map(hydrateValue); } if (value && typeof value === "object") { const isPlainObject = value.constructor === Object || value.constructor === undefined; if (isPlainObject) { const hydrated: Record<string, unknown> = {}; for (const [key, val] of Object.entries(value)) { hydrated[key] = hydrateValue(val); } return hydrated; } const hydrated = Object.create(Object.getPrototypeOf(value)); for (const [key, val] of Object.entries(value)) { hydrated[key] = hydrateValue(val); } return hydrated; } return value; }; return { hydrateSecrets: <T>(config: T) => Effect.gen(function* () { const parseResult = configSchema.parse(config); try { return hydrateValue(parseResult) as T; } catch (error) { return yield* Effect.fail( new PluginRuntimeError({ operation: "hydrate-secrets", cause: error instanceof Error ? error : new Error(String(error)), retryable: false, }), ); } }), }; }), }) {}