1import * as Layer from "effect/Layer";
2import * as FetchHttpClient from "effect/http/FetchHttpClient";
3import { CredentialsStoreLive } from "../Auth/Credentials.ts";
4import { ProfileStoreLive } from "../Auth/Profile.ts";
5import * as Command from "../Command/index.ts";
6import * as Provider from "../Provider.ts";
7import { HetznerAuth } from "./AuthProvider.ts";
8import { Certificate, CertificateProvider } from "./Certificate.ts";
9import * as Credentials from "./Credentials.ts";
10import { fromCredentials } from "./Environment.ts";
11import { Firewall, FirewallProvider } from "./Firewall.ts";
12import { FloatingIp, FloatingIpProvider } from "./FloatingIp.ts";
13import {
14 FloatingIpAssignment,
15 FloatingIpAssignmentProvider,
16} from "./FloatingIpAssignment.ts";
17import { Image, ImageProvider } from "./Image.ts";
18import { LoadBalancer, LoadBalancerProvider } from "./LoadBalancer.ts";
19import { Network, NetworkProvider } from "./Network.ts";
20import { PlacementGroup, PlacementGroupProvider } from "./PlacementGroup.ts";
21import { PrimaryIp, PrimaryIpProvider } from "./PrimaryIp.ts";
22import { ReadDnsHttp } from "./ReadDnsHttp.ts";
23import { ReadWriteDnsHttp } from "./ReadWriteDnsHttp.ts";
24import { MountVolumeLive } from "./MountVolume.ts";
25import { RecordSet, RecordSetProvider } from "./RecordSet.ts";
26import { Server, ServerProvider } from "./Server.ts";
27import { Service, ServiceProvider } from "./Service.ts";
28import { SshLive } from "./Ssh.ts";
29import { WriteDnsHttp } from "./WriteDnsHttp.ts";
30import { SshKey, SshKeyProvider } from "./SshKey.ts";
31import { Volume, VolumeProvider } from "./Volume.ts";
32import {
33 VolumeAttachment,
34 VolumeAttachmentProvider,
35} from "./VolumeAttachment.ts";
36import { Zone, ZoneProvider } from "./Zone.ts";
37import {
38 Server as WebsiteServer,
39 ServerProvider as WebsiteServerProvider,
40} from "../Website/Server.ts";
41
42export class Providers extends Provider.ProviderCollection<Providers>()(
43 "Hetzner",
44) {}
45
46export type ProviderRequirements = Layer.Services<ReturnType<typeof providers>>;
47
48/**
49 * Build a layer that registers all Hetzner resource providers, the Hetzner
50 * `AuthProvider`, the resolved `Credentials`, and an `HttpClient`. Include
51 * this from your stack alongside other cloud `providers()` layers.
52 *
53 * Resource providers are inserted into {@link Provider.collection} as they
54 * land.
55 *
56 * @example
57 * ```typescript
58 * import * as Alchemy from "alchemy";
59 * import * as Hetzner from "alchemy/Hetzner";
60 * import * as Effect from "effect/Effect";
61 *
62 * export default Alchemy.Stack(
63 * "MyStack",
64 * {
65 * providers: Hetzner.providers(),
66 * state: Alchemy.localState(),
67 * },
68 * Effect.gen(function* () {
69 * return {};
70 * }),
71 * );
72 * ```
73 */
74export const providers = () =>
75 Layer.effect(
76 Providers,
77 Provider.collection([
78 Certificate,
79 Firewall,
80 FloatingIp,
81 FloatingIpAssignment,
82 Image,
83 LoadBalancer,
84 Network,
85 PlacementGroup,
86 PrimaryIp,
87 RecordSet,
88 Server,
89 Service,
90 SshKey,
91 Volume,
92 VolumeAttachment,
93 WebsiteServer,
94 Zone,
95 ]),
96 ).pipe(
97 Layer.provide(
98 Layer.mergeAll(
99 CertificateProvider(),
100 FirewallProvider(),
101 FloatingIpProvider(),
102 FloatingIpAssignmentProvider(),
103 ImageProvider(),
104 LoadBalancerProvider(),
105 NetworkProvider(),
106 PlacementGroupProvider(),
107 PrimaryIpProvider(),
108 RecordSetProvider(),
109 ServerProvider(),
110 ServiceProvider(),
111 SshKeyProvider(),
112 VolumeProvider(),
113 VolumeAttachmentProvider(),
114 WebsiteServerProvider(),
115 ZoneProvider(),
116 ),
117 ),
118 Layer.provideMerge(ReadDnsHttp),
119 Layer.provideMerge(WriteDnsHttp),
120 Layer.provideMerge(ReadWriteDnsHttp),
121 Layer.provideMerge(SshLive),
122 Layer.provideMerge(MountVolumeLive),
123 Layer.provideMerge(fromCredentials()),
124 Layer.provideMerge(Credentials.fromAuthProvider()),
125 Layer.provideMerge(HetznerAuth),
126 Layer.provideMerge(ProfileStoreLive),
127 Layer.provideMerge(CredentialsStoreLive),
128 Layer.provideMerge(FetchHttpClient.layer),
129 Layer.provideMerge(Command.providers()),
130 Layer.orDie,
131 );