1import * as Cloudflare from "@/Cloudflare";
2import * as Provider from "@/Provider";
3import * as Test from "@/Test/Alchemy";
4import { describe, expect } from "alchemy-test";
5import * as Effect from "effect/Effect";
6import { MinimumLogLevel } from "effect/References";
7const { test } = Test.make({ providers: Cloudflare.providers() });
8
9const logLevel = Effect.provideService(
10 MinimumLogLevel,
11 process.env.DEBUG ? "Debug" : "Info",
12);
13
14describe(
15 "Tunnel Configuration",
16 { tags: ["provider:cloudflare", "provider:cloudflare:tunnel", "live"] },
17 () => {
18 // Canonical `list()` test (parent fan-out singleton): the configuration is a
19 // per-tunnel document with no account-wide enumeration API, so `list()`
20 // enumerates every cfd_tunnel in the account and reads each tunnel's config.
21 // Deploy a tunnel + configuration, then assert the deployed tunnel appears in
22 // the listed result.
23 test.provider(
24 "list enumerates configurations across all tunnels",
25 (stack) =>
26 Effect.gen(function* () {
27 yield* stack.destroy();
28
29 const deployed = yield* stack.deploy(
30 Effect.gen(function* () {
31 const tunnel = yield* Cloudflare.Tunnel.Tunnel("ListTunnel", {
32 name: "alchemy-tunnel-config-list-test",
33 configSrc: "cloudflare",
34 });
35 const config = yield* Cloudflare.Tunnel.Configuration(
36 "ListConfig",
37 {
38 tunnelId: tunnel.tunnelId,
39 ingress: [
40 {
41 hostname: "config-list-test.internal",
42 service: "http://localhost:8080",
43 },
44 ],
45 },
46 );
47 return { tunnelId: tunnel.tunnelId, config };
48 }),
49 );
50
51 const provider = yield* Provider.findProvider(
52 Cloudflare.Tunnel.Configuration,
53 );
54 const all = yield* provider.list();
55
56 expect(all.some((c) => c.tunnelId === deployed.tunnelId)).toBe(true);
57
58 yield* stack.destroy();
59 }).pipe(logLevel),
60 { timeout: 180_000 },
61 );
62 },
63);