| 1 | import type { Config } from "@distilled.cloud/hetzner"; |
| 2 | import { Credentials } from "@distilled.cloud/hetzner"; |
| 3 | import * as Context from "effect/Context"; |
| 4 | import * as Effect from "effect/Effect"; |
| 5 | import * as Layer from "effect/Layer"; |
| 6 | |
| 7 | /** |
| 8 | * Fully-resolved Hetzner Cloud environment for a stack. |
| 9 | * |
| 10 | * A Hetzner Cloud token is issued per project — the token IS the project |
| 11 | * scope, so this service only carries `{ token, apiBaseUrl }`. Resolve |
| 12 | * it inside lifecycle operations with `HetznerEnvironment.current`. |
| 13 | */ |
| 14 | export type HetznerEnvironmentShape = Config; |
| 15 | |
| 16 | export class HetznerEnvironment extends Context.Service< |
| 17 | HetznerEnvironment, |
| 18 | Effect.Effect<HetznerEnvironmentShape> |
| 19 | >()("Hetzner::Environment") { |
| 20 | static current = HetznerEnvironment.use((env) => env); |
| 21 | readonly kind = "Environment" as const; |
| 22 | } |
| 23 | |
| 24 | /** |
| 25 | * Build a `HetznerEnvironment` layer from the distilled `Credentials` |
| 26 | * service. Provide this after `Credentials.fromAuthProvider()`. |
| 27 | */ |
| 28 | export const fromCredentials = () => |
| 29 | Layer.effect( |
| 30 | HetznerEnvironment, |
| 31 | Effect.gen(function* () { |
| 32 | return yield* Credentials; |
| 33 | }), |
| 34 | ); |