alchemy 2.0.0-beta.47 → 2.0.0-beta.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/exec.js +28 -5
- package/bin/exec.js.map +1 -1
- package/lib/AWS/Lambda/BucketEventSource.d.ts +1 -1
- package/lib/AWS/Lambda/BucketEventSource.d.ts.map +1 -1
- package/lib/AWS/Lambda/EventBridgeEventSource.d.ts +1 -1
- package/lib/AWS/Lambda/EventBridgeEventSource.d.ts.map +1 -1
- package/lib/AWS/Lambda/QueueEventSource.d.ts +1 -1
- package/lib/AWS/Lambda/QueueEventSource.d.ts.map +1 -1
- package/lib/AWS/Lambda/StreamEventSource.d.ts +1 -1
- package/lib/AWS/Lambda/StreamEventSource.d.ts.map +1 -1
- package/lib/AWS/Lambda/TableEventSource.d.ts +1 -1
- package/lib/AWS/Lambda/TableEventSource.d.ts.map +1 -1
- package/lib/AWS/Lambda/TopicEventSource.d.ts +1 -1
- package/lib/AWS/Lambda/TopicEventSource.d.ts.map +1 -1
- package/lib/AdoptPolicy.js +1 -1
- package/lib/AdoptPolicy.js.map +1 -1
- package/lib/Binding.d.ts +5 -1
- package/lib/Binding.d.ts.map +1 -1
- package/lib/Binding.js.map +1 -1
- package/lib/Cli/commands/cloudflare.d.ts +4 -1
- package/lib/Cli/commands/cloudflare.d.ts.map +1 -1
- package/lib/Cli/commands/cloudflare.js +274 -1
- package/lib/Cli/commands/cloudflare.js.map +1 -1
- package/lib/Cloudflare/AiGateway/AiGateway.d.ts +1 -1
- package/lib/Cloudflare/AiGateway/AiGateway.d.ts.map +1 -1
- package/lib/Cloudflare/AiGateway/AiGateway.js +2 -1
- package/lib/Cloudflare/AiGateway/AiGateway.js.map +1 -1
- package/lib/Cloudflare/ApiToken/AccountApiToken.d.ts +40 -2
- package/lib/Cloudflare/ApiToken/AccountApiToken.d.ts.map +1 -1
- package/lib/Cloudflare/ApiToken/AccountApiToken.js +49 -6
- package/lib/Cloudflare/ApiToken/AccountApiToken.js.map +1 -1
- package/lib/Cloudflare/ApiToken/Common.d.ts +36 -4
- package/lib/Cloudflare/ApiToken/Common.d.ts.map +1 -1
- package/lib/Cloudflare/ApiToken/Common.js +8 -0
- package/lib/Cloudflare/ApiToken/Common.js.map +1 -1
- package/lib/Cloudflare/ApiToken/UserApiToken.d.ts +38 -2
- package/lib/Cloudflare/ApiToken/UserApiToken.d.ts.map +1 -1
- package/lib/Cloudflare/ApiToken/UserApiToken.js +47 -6
- package/lib/Cloudflare/ApiToken/UserApiToken.js.map +1 -1
- package/lib/Cloudflare/Browser/Browser.d.ts +121 -0
- package/lib/Cloudflare/Browser/Browser.d.ts.map +1 -0
- package/lib/Cloudflare/{BrowserRendering/BrowserRendering.js → Browser/Browser.js} +19 -26
- package/lib/Cloudflare/Browser/Browser.js.map +1 -0
- package/lib/Cloudflare/Browser/BrowserBinding.d.ts +55 -0
- package/lib/Cloudflare/Browser/BrowserBinding.d.ts.map +1 -0
- package/lib/Cloudflare/{BrowserRendering/BrowserRenderingBinding.js → Browser/BrowserBinding.js} +11 -11
- package/lib/Cloudflare/Browser/BrowserBinding.js.map +1 -0
- package/lib/Cloudflare/Browser/index.d.ts +3 -0
- package/lib/Cloudflare/Browser/index.d.ts.map +1 -0
- package/lib/Cloudflare/Browser/index.js +3 -0
- package/lib/Cloudflare/Browser/index.js.map +1 -0
- package/lib/Cloudflare/Container/ContainerBinding.d.ts +2 -1
- package/lib/Cloudflare/Container/ContainerBinding.d.ts.map +1 -1
- package/lib/Cloudflare/D1/D1Database.d.ts.map +1 -1
- package/lib/Cloudflare/D1/D1Database.js +2 -1
- package/lib/Cloudflare/D1/D1Database.js.map +1 -1
- package/lib/Cloudflare/Dns/DnsBinding.d.ts +52 -0
- package/lib/Cloudflare/Dns/DnsBinding.d.ts.map +1 -0
- package/lib/Cloudflare/Dns/DnsBinding.js +59 -0
- package/lib/Cloudflare/Dns/DnsBinding.js.map +1 -0
- package/lib/Cloudflare/Dns/DnsRead.d.ts +80 -0
- package/lib/Cloudflare/Dns/DnsRead.d.ts.map +1 -0
- package/lib/Cloudflare/Dns/DnsRead.js +70 -0
- package/lib/Cloudflare/Dns/DnsRead.js.map +1 -0
- package/lib/Cloudflare/Dns/DnsReadWrite.d.ts +79 -0
- package/lib/Cloudflare/Dns/DnsReadWrite.d.ts.map +1 -0
- package/lib/Cloudflare/Dns/DnsReadWrite.js +72 -0
- package/lib/Cloudflare/Dns/DnsReadWrite.js.map +1 -0
- package/lib/Cloudflare/Dns/DnsWrite.d.ts +113 -0
- package/lib/Cloudflare/Dns/DnsWrite.d.ts.map +1 -0
- package/lib/Cloudflare/Dns/DnsWrite.js +100 -0
- package/lib/Cloudflare/Dns/DnsWrite.js.map +1 -0
- package/lib/Cloudflare/Dns/index.d.ts +5 -0
- package/lib/Cloudflare/Dns/index.d.ts.map +1 -0
- package/lib/Cloudflare/Dns/index.js +5 -0
- package/lib/Cloudflare/Dns/index.js.map +1 -0
- package/lib/Cloudflare/Email/EmailRouting.d.ts +1 -1
- package/lib/Cloudflare/Email/EmailRouting.d.ts.map +1 -1
- package/lib/Cloudflare/Email/EmailRouting.js +1 -1
- package/lib/Cloudflare/Email/EmailRouting.js.map +1 -1
- package/lib/Cloudflare/Email/EmailRule.d.ts +1 -1
- package/lib/Cloudflare/Email/EmailRule.d.ts.map +1 -1
- package/lib/Cloudflare/Email/EmailRule.js +1 -1
- package/lib/Cloudflare/Email/EmailRule.js.map +1 -1
- package/lib/Cloudflare/Hyperdrive/Hyperdrive.d.ts +1 -1
- package/lib/Cloudflare/Images/Images.d.ts +32 -23
- package/lib/Cloudflare/Images/Images.d.ts.map +1 -1
- package/lib/Cloudflare/Images/Images.js +10 -13
- package/lib/Cloudflare/Images/Images.js.map +1 -1
- package/lib/Cloudflare/KV/KVNamespace.d.ts +1 -1
- package/lib/Cloudflare/Providers.d.ts.map +1 -1
- package/lib/Cloudflare/Providers.js +14 -3
- package/lib/Cloudflare/Providers.js.map +1 -1
- package/lib/Cloudflare/Queue/Queue.d.ts +1 -1
- package/lib/Cloudflare/R2/R2Bucket.d.ts +2 -2
- package/lib/Cloudflare/R2/R2Bucket.d.ts.map +1 -1
- package/lib/Cloudflare/R2/R2Bucket.js +13 -7
- package/lib/Cloudflare/R2/R2Bucket.js.map +1 -1
- package/lib/Cloudflare/RateLimit/RateLimit.d.ts +132 -0
- package/lib/Cloudflare/RateLimit/RateLimit.d.ts.map +1 -0
- package/lib/Cloudflare/RateLimit/RateLimit.js +80 -0
- package/lib/Cloudflare/RateLimit/RateLimit.js.map +1 -0
- package/lib/Cloudflare/RateLimit/RateLimitBinding.d.ts +30 -0
- package/lib/Cloudflare/RateLimit/RateLimitBinding.d.ts.map +1 -0
- package/lib/Cloudflare/RateLimit/RateLimitBinding.js +50 -0
- package/lib/Cloudflare/RateLimit/RateLimitBinding.js.map +1 -0
- package/lib/Cloudflare/RateLimit/index.d.ts +3 -0
- package/lib/Cloudflare/RateLimit/index.d.ts.map +1 -0
- package/lib/Cloudflare/RateLimit/index.js +3 -0
- package/lib/Cloudflare/RateLimit/index.js.map +1 -0
- package/lib/Cloudflare/SecretsStore/Secret.d.ts +3 -2
- package/lib/Cloudflare/SecretsStore/Secret.d.ts.map +1 -1
- package/lib/Cloudflare/SecretsStore/Secret.js +7 -4
- package/lib/Cloudflare/SecretsStore/Secret.js.map +1 -1
- package/lib/Cloudflare/StateStore/Api.d.ts +1 -1
- package/lib/Cloudflare/Tunnel/Tunnel.d.ts +27 -0
- package/lib/Cloudflare/Tunnel/Tunnel.d.ts.map +1 -1
- package/lib/Cloudflare/Tunnel/Tunnel.js +27 -0
- package/lib/Cloudflare/Tunnel/Tunnel.js.map +1 -1
- package/lib/Cloudflare/Tunnel/TunnelBinding.d.ts +48 -0
- package/lib/Cloudflare/Tunnel/TunnelBinding.d.ts.map +1 -0
- package/lib/Cloudflare/Tunnel/TunnelBinding.js +56 -0
- package/lib/Cloudflare/Tunnel/TunnelBinding.js.map +1 -0
- package/lib/Cloudflare/Tunnel/TunnelRead.d.ts +83 -0
- package/lib/Cloudflare/Tunnel/TunnelRead.d.ts.map +1 -0
- package/lib/Cloudflare/Tunnel/TunnelRead.js +79 -0
- package/lib/Cloudflare/Tunnel/TunnelRead.js.map +1 -0
- package/lib/Cloudflare/Tunnel/TunnelReadWrite.d.ts +70 -0
- package/lib/Cloudflare/Tunnel/TunnelReadWrite.d.ts.map +1 -0
- package/lib/Cloudflare/Tunnel/TunnelReadWrite.js +63 -0
- package/lib/Cloudflare/Tunnel/TunnelReadWrite.js.map +1 -0
- package/lib/Cloudflare/Tunnel/TunnelWrite.d.ts +92 -0
- package/lib/Cloudflare/Tunnel/TunnelWrite.d.ts.map +1 -0
- package/lib/Cloudflare/Tunnel/TunnelWrite.js +88 -0
- package/lib/Cloudflare/Tunnel/TunnelWrite.js.map +1 -0
- package/lib/Cloudflare/Tunnel/index.d.ts +4 -0
- package/lib/Cloudflare/Tunnel/index.d.ts.map +1 -1
- package/lib/Cloudflare/Tunnel/index.js +4 -0
- package/lib/Cloudflare/Tunnel/index.js.map +1 -1
- package/lib/Cloudflare/Vectorize/VectorizeIndex.d.ts +1 -1
- package/lib/Cloudflare/Vectorize/VectorizeIndex.js +1 -0
- package/lib/Cloudflare/Vectorize/VectorizeIndex.js.map +1 -1
- package/lib/Cloudflare/VpcService/VpcService.d.ts +1 -1
- package/lib/Cloudflare/VpcService/VpcService.d.ts.map +1 -1
- package/lib/Cloudflare/VpcService/VpcService.js.map +1 -1
- package/lib/Cloudflare/Workers/DynamicWorkerLoader.d.ts +119 -11
- package/lib/Cloudflare/Workers/DynamicWorkerLoader.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/DynamicWorkerLoader.js +88 -9
- package/lib/Cloudflare/Workers/DynamicWorkerLoader.js.map +1 -1
- package/lib/Cloudflare/Workers/InferEnv.d.ts +1 -1
- package/lib/Cloudflare/Workers/InferEnv.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/LocalWorkerProvider.js +2 -0
- package/lib/Cloudflare/Workers/LocalWorkerProvider.js.map +1 -1
- package/lib/Cloudflare/Workers/WorkerAsyncBindings.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/WorkerAsyncBindings.js +18 -2
- package/lib/Cloudflare/Workers/WorkerAsyncBindings.js.map +1 -1
- package/lib/Cloudflare/Workers/WorkerBinding.d.ts +7 -5
- package/lib/Cloudflare/Workers/WorkerBinding.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/WorkerBinding.js +1 -1
- package/lib/Cloudflare/Workers/WorkerBinding.js.map +1 -1
- package/lib/Cloudflare/Zaraz/ZarazConfig.d.ts +1 -1
- package/lib/Cloudflare/Zaraz/ZarazConfig.d.ts.map +1 -1
- package/lib/Cloudflare/Zaraz/ZarazConfig.js +1 -1
- package/lib/Cloudflare/Zaraz/ZarazConfig.js.map +1 -1
- package/lib/Cloudflare/Zone/Zone.d.ts +170 -0
- package/lib/Cloudflare/Zone/Zone.d.ts.map +1 -0
- package/lib/Cloudflare/Zone/Zone.js +180 -0
- package/lib/Cloudflare/Zone/Zone.js.map +1 -0
- package/lib/Cloudflare/Zone/index.d.ts +3 -0
- package/lib/Cloudflare/Zone/index.d.ts.map +1 -0
- package/lib/Cloudflare/Zone/index.js +3 -0
- package/lib/Cloudflare/Zone/index.js.map +1 -0
- package/lib/Cloudflare/Zone/lookup.d.ts +33 -0
- package/lib/Cloudflare/Zone/lookup.d.ts.map +1 -0
- package/lib/Cloudflare/{Zone.js → Zone/lookup.js} +2 -2
- package/lib/Cloudflare/Zone/lookup.js.map +1 -0
- package/lib/Cloudflare/index.d.ts +4 -1
- package/lib/Cloudflare/index.d.ts.map +1 -1
- package/lib/Cloudflare/index.js +4 -1
- package/lib/Cloudflare/index.js.map +1 -1
- package/lib/Output.d.ts +13 -1
- package/lib/Output.d.ts.map +1 -1
- package/lib/Output.js +43 -11
- package/lib/Output.js.map +1 -1
- package/lib/Plan.d.ts.map +1 -1
- package/lib/Plan.js +8 -0
- package/lib/Plan.js.map +1 -1
- package/lib/Platform.d.ts +5 -5
- package/lib/Platform.d.ts.map +1 -1
- package/lib/Platform.js +5 -2
- package/lib/Platform.js.map +1 -1
- package/lib/RemovalPolicy.js +2 -2
- package/lib/RemovalPolicy.js.map +1 -1
- package/lib/Resource.d.ts +15 -2
- package/lib/Resource.d.ts.map +1 -1
- package/lib/Resource.js +3 -2
- package/lib/Resource.js.map +1 -1
- package/lib/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +7 -7
- package/src/AdoptPolicy.ts +1 -1
- package/src/Binding.ts +5 -1
- package/src/Cli/commands/cloudflare.ts +394 -1
- package/src/Cloudflare/AiGateway/AiGateway.ts +2 -1
- package/src/Cloudflare/ApiToken/AccountApiToken.ts +60 -7
- package/src/Cloudflare/ApiToken/Common.ts +45 -6
- package/src/Cloudflare/ApiToken/UserApiToken.ts +58 -7
- package/src/Cloudflare/Browser/Browser.ts +140 -0
- package/src/Cloudflare/Browser/BrowserBinding.ts +128 -0
- package/src/Cloudflare/Browser/index.ts +11 -0
- package/src/Cloudflare/D1/D1Database.ts +6 -2
- package/src/Cloudflare/Dns/DnsBinding.ts +123 -0
- package/src/Cloudflare/Dns/DnsRead.ts +129 -0
- package/src/Cloudflare/Dns/DnsReadWrite.ts +99 -0
- package/src/Cloudflare/Dns/DnsWrite.ts +209 -0
- package/src/Cloudflare/Dns/index.ts +4 -0
- package/src/Cloudflare/Email/EmailRouting.ts +1 -1
- package/src/Cloudflare/Email/EmailRule.ts +6 -6
- package/src/Cloudflare/Images/Images.ts +40 -27
- package/src/Cloudflare/Providers.ts +22 -3
- package/src/Cloudflare/R2/R2Bucket.ts +17 -9
- package/src/Cloudflare/RateLimit/RateLimit.ts +160 -0
- package/src/Cloudflare/RateLimit/RateLimitBinding.ts +90 -0
- package/src/Cloudflare/RateLimit/index.ts +2 -0
- package/src/Cloudflare/SecretsStore/Secret.ts +12 -6
- package/src/Cloudflare/Tunnel/Tunnel.ts +27 -0
- package/src/Cloudflare/Tunnel/TunnelBinding.ts +114 -0
- package/src/Cloudflare/Tunnel/TunnelRead.ts +168 -0
- package/src/Cloudflare/Tunnel/TunnelReadWrite.ts +88 -0
- package/src/Cloudflare/Tunnel/TunnelWrite.ts +194 -0
- package/src/Cloudflare/Tunnel/index.ts +4 -0
- package/src/Cloudflare/Vectorize/VectorizeIndex.ts +2 -1
- package/src/Cloudflare/VpcService/VpcService.ts +4 -2
- package/src/Cloudflare/Workers/DynamicWorkerLoader.ts +139 -13
- package/src/Cloudflare/Workers/InferEnv.ts +19 -15
- package/src/Cloudflare/Workers/LocalWorkerProvider.ts +13 -2
- package/src/Cloudflare/Workers/WorkerAsyncBindings.ts +16 -2
- package/src/Cloudflare/Workers/WorkerBinding.ts +6 -2
- package/src/Cloudflare/Zaraz/ZarazConfig.ts +1 -1
- package/src/Cloudflare/Zone/Zone.ts +349 -0
- package/src/Cloudflare/Zone/index.ts +2 -0
- package/src/Cloudflare/{Zone.ts → Zone/lookup.ts} +16 -3
- package/src/Cloudflare/index.ts +4 -1
- package/src/Output.ts +67 -11
- package/src/Plan.ts +9 -0
- package/src/Platform.ts +19 -15
- package/src/RemovalPolicy.ts +2 -2
- package/src/Resource.ts +19 -2
- package/lib/Cloudflare/BrowserRendering/BrowserRendering.d.ts +0 -116
- package/lib/Cloudflare/BrowserRendering/BrowserRendering.d.ts.map +0 -1
- package/lib/Cloudflare/BrowserRendering/BrowserRendering.js.map +0 -1
- package/lib/Cloudflare/BrowserRendering/BrowserRenderingBinding.d.ts +0 -55
- package/lib/Cloudflare/BrowserRendering/BrowserRenderingBinding.d.ts.map +0 -1
- package/lib/Cloudflare/BrowserRendering/BrowserRenderingBinding.js.map +0 -1
- package/lib/Cloudflare/BrowserRendering/index.d.ts +0 -3
- package/lib/Cloudflare/BrowserRendering/index.d.ts.map +0 -1
- package/lib/Cloudflare/BrowserRendering/index.js +0 -3
- package/lib/Cloudflare/BrowserRendering/index.js.map +0 -1
- package/lib/Cloudflare/Zone.d.ts +0 -14
- package/lib/Cloudflare/Zone.d.ts.map +0 -1
- package/lib/Cloudflare/Zone.js.map +0 -1
- package/src/Cloudflare/BrowserRendering/BrowserRendering.ts +0 -132
- package/src/Cloudflare/BrowserRendering/BrowserRenderingBinding.ts +0 -137
- package/src/Cloudflare/BrowserRendering/index.ts +0 -11
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
GetTunnelCloudflaredConfigurationError,
|
|
3
|
+
GetTunnelCloudflaredConfigurationResponse,
|
|
4
|
+
GetTunnelCloudflaredError,
|
|
5
|
+
GetTunnelCloudflaredResponse,
|
|
6
|
+
GetTunnelCloudflaredTokenError,
|
|
7
|
+
GetTunnelCloudflaredTokenResponse,
|
|
8
|
+
ListTunnelCloudflaredsError,
|
|
9
|
+
ListTunnelCloudflaredsRequest,
|
|
10
|
+
ListTunnelCloudflaredsResponse,
|
|
11
|
+
} from "@distilled.cloud/cloudflare/zero-trust";
|
|
12
|
+
import * as zeroTrust from "@distilled.cloud/cloudflare/zero-trust";
|
|
13
|
+
import * as Effect from "effect/Effect";
|
|
14
|
+
import * as Layer from "effect/Layer";
|
|
15
|
+
import * as Binding from "../../Binding.ts";
|
|
16
|
+
import type { RuntimeContext } from "../../RuntimeContext.ts";
|
|
17
|
+
import type { AccountApiToken } from "../ApiToken/AccountApiToken.ts";
|
|
18
|
+
import type { Worker } from "../Workers/Worker.ts";
|
|
19
|
+
import {
|
|
20
|
+
authorizeWith,
|
|
21
|
+
makeTunnelClient,
|
|
22
|
+
makeTunnelPolicyLive,
|
|
23
|
+
type TunnelToken,
|
|
24
|
+
} from "./TunnelBinding.ts";
|
|
25
|
+
|
|
26
|
+
/** List-tunnels request, minus the account id (supplied by the binding). */
|
|
27
|
+
export type ListTunnelsRequest = Omit<
|
|
28
|
+
ListTunnelCloudflaredsRequest,
|
|
29
|
+
"accountId"
|
|
30
|
+
>;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Read-only tunnel operations. Backed by the `Cloudflare Tunnel Read`
|
|
34
|
+
* permission group.
|
|
35
|
+
*/
|
|
36
|
+
export interface TunnelReadClient {
|
|
37
|
+
/** Fetch a single tunnel by id. */
|
|
38
|
+
get(
|
|
39
|
+
tunnelId: string,
|
|
40
|
+
): Effect.Effect<
|
|
41
|
+
GetTunnelCloudflaredResponse,
|
|
42
|
+
GetTunnelCloudflaredError,
|
|
43
|
+
RuntimeContext
|
|
44
|
+
>;
|
|
45
|
+
/** List tunnels in the account. */
|
|
46
|
+
list(
|
|
47
|
+
request?: ListTunnelsRequest,
|
|
48
|
+
): Effect.Effect<
|
|
49
|
+
ListTunnelCloudflaredsResponse,
|
|
50
|
+
ListTunnelCloudflaredsError,
|
|
51
|
+
RuntimeContext
|
|
52
|
+
>;
|
|
53
|
+
/** Fetch the connector token used to run the tunnel. */
|
|
54
|
+
getToken(
|
|
55
|
+
tunnelId: string,
|
|
56
|
+
): Effect.Effect<
|
|
57
|
+
GetTunnelCloudflaredTokenResponse,
|
|
58
|
+
GetTunnelCloudflaredTokenError,
|
|
59
|
+
RuntimeContext
|
|
60
|
+
>;
|
|
61
|
+
/** Read the remotely-managed configuration (ingress rules) for a tunnel. */
|
|
62
|
+
getConfiguration(
|
|
63
|
+
tunnelId: string,
|
|
64
|
+
): Effect.Effect<
|
|
65
|
+
GetTunnelCloudflaredConfigurationResponse,
|
|
66
|
+
GetTunnelCloudflaredConfigurationError,
|
|
67
|
+
RuntimeContext
|
|
68
|
+
>;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Build the read-only client over a bound token. */
|
|
72
|
+
export const readClient = (token: TunnelToken): TunnelReadClient => {
|
|
73
|
+
const authorize = authorizeWith(token);
|
|
74
|
+
return {
|
|
75
|
+
get: Effect.fn("Cloudflare.Tunnel.get")(function* (tunnelId) {
|
|
76
|
+
const accountId = yield* token.accountId;
|
|
77
|
+
return yield* authorize(
|
|
78
|
+
zeroTrust.getTunnelCloudflared({ accountId, tunnelId }),
|
|
79
|
+
);
|
|
80
|
+
}),
|
|
81
|
+
list: Effect.fn("Cloudflare.Tunnel.list")(function* (request) {
|
|
82
|
+
const accountId = yield* token.accountId;
|
|
83
|
+
return yield* authorize(
|
|
84
|
+
zeroTrust.listTunnelCloudflareds({ accountId, ...request }),
|
|
85
|
+
);
|
|
86
|
+
}),
|
|
87
|
+
getToken: Effect.fn("Cloudflare.Tunnel.getToken")(function* (tunnelId) {
|
|
88
|
+
const accountId = yield* token.accountId;
|
|
89
|
+
return yield* authorize(
|
|
90
|
+
zeroTrust.getTunnelCloudflaredToken({ accountId, tunnelId }),
|
|
91
|
+
);
|
|
92
|
+
}),
|
|
93
|
+
getConfiguration: Effect.fn("Cloudflare.Tunnel.getConfiguration")(
|
|
94
|
+
function* (tunnelId) {
|
|
95
|
+
const accountId = yield* token.accountId;
|
|
96
|
+
return yield* authorize(
|
|
97
|
+
zeroTrust.getTunnelCloudflaredConfiguration({ accountId, tunnelId }),
|
|
98
|
+
);
|
|
99
|
+
},
|
|
100
|
+
),
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Binding that lets a Worker read Cloudflare Tunnels at runtime.
|
|
106
|
+
*
|
|
107
|
+
* Creates a scoped {@link AccountApiToken} with only the `Cloudflare Tunnel
|
|
108
|
+
* Read` permission and binds its outputs into the Worker (the token value as a
|
|
109
|
+
* `secret_text` binding) so runtime code can authenticate.
|
|
110
|
+
*
|
|
111
|
+
* @binding
|
|
112
|
+
*
|
|
113
|
+
* @section Reading tunnels at runtime
|
|
114
|
+
* @example Bind the read client
|
|
115
|
+
* Bind once in the Init phase; every method is available on the returned client.
|
|
116
|
+
* ```typescript
|
|
117
|
+
* const tunnels = yield* Cloudflare.TunnelRead.bind();
|
|
118
|
+
* ```
|
|
119
|
+
*
|
|
120
|
+
* @example List tunnels
|
|
121
|
+
* ```typescript
|
|
122
|
+
* const { result } = yield* tunnels.list({ isDeleted: false });
|
|
123
|
+
* ```
|
|
124
|
+
*
|
|
125
|
+
* @example Fetch a tunnel and its connector token
|
|
126
|
+
* `getToken` returns the plaintext token used to run `cloudflared`.
|
|
127
|
+
* ```typescript
|
|
128
|
+
* const tunnel = yield* tunnels.get(tunnelId);
|
|
129
|
+
* const token = yield* tunnels.getToken(tunnelId);
|
|
130
|
+
* ```
|
|
131
|
+
*
|
|
132
|
+
* @example Read the ingress configuration
|
|
133
|
+
* ```typescript
|
|
134
|
+
* const { config } = yield* tunnels.getConfiguration(tunnelId);
|
|
135
|
+
* ```
|
|
136
|
+
*
|
|
137
|
+
* @section Runtime Layer
|
|
138
|
+
* Provide {@link TunnelReadLive} in the Worker's runtime layer.
|
|
139
|
+
* ```typescript
|
|
140
|
+
* Effect.provide(Cloudflare.TunnelReadLive)
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
export class TunnelRead extends Binding.Service<
|
|
144
|
+
TunnelRead,
|
|
145
|
+
() => Effect.Effect<TunnelReadClient, never, Worker>
|
|
146
|
+
>()("Cloudflare.TunnelRead") {}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Deploy-time policy for {@link TunnelRead}. Attaches the `Cloudflare Tunnel
|
|
150
|
+
* Read` permission to the token via its binding contract.
|
|
151
|
+
*/
|
|
152
|
+
export class TunnelReadPolicy extends Binding.Policy<
|
|
153
|
+
TunnelReadPolicy,
|
|
154
|
+
(token: AccountApiToken) => Effect.Effect<void>
|
|
155
|
+
>()("Cloudflare.TunnelRead") {}
|
|
156
|
+
|
|
157
|
+
/** Runtime layer for {@link TunnelRead}. */
|
|
158
|
+
export const TunnelReadLive = Layer.effect(
|
|
159
|
+
TunnelRead,
|
|
160
|
+
makeTunnelClient(TunnelReadPolicy, readClient),
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
/** Live deploy-time policy layer for {@link TunnelReadPolicy}. */
|
|
164
|
+
export const TunnelReadPolicyLive = makeTunnelPolicyLive(
|
|
165
|
+
TunnelReadPolicy,
|
|
166
|
+
"Cloudflare.TunnelRead",
|
|
167
|
+
["Cloudflare Tunnel Read"],
|
|
168
|
+
);
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Layer from "effect/Layer";
|
|
3
|
+
import * as Binding from "../../Binding.ts";
|
|
4
|
+
import type { AccountApiToken } from "../ApiToken/AccountApiToken.ts";
|
|
5
|
+
import type { Worker } from "../Workers/Worker.ts";
|
|
6
|
+
import {
|
|
7
|
+
makeTunnelClient,
|
|
8
|
+
makeTunnelPolicyLive,
|
|
9
|
+
type TunnelToken,
|
|
10
|
+
} from "./TunnelBinding.ts";
|
|
11
|
+
import { readClient, type TunnelReadClient } from "./TunnelRead.ts";
|
|
12
|
+
import { writeClient, type TunnelWriteClient } from "./TunnelWrite.ts";
|
|
13
|
+
|
|
14
|
+
/** Combined read + write tunnel operations. */
|
|
15
|
+
export interface TunnelReadWriteClient
|
|
16
|
+
extends TunnelReadClient, TunnelWriteClient {}
|
|
17
|
+
|
|
18
|
+
/** Build the combined read + write client over a bound token. */
|
|
19
|
+
export const readWriteClient = (token: TunnelToken): TunnelReadWriteClient => ({
|
|
20
|
+
...readClient(token),
|
|
21
|
+
...writeClient(token),
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Binding that lets a Worker perform the full Cloudflare Tunnel CRUD surface at
|
|
26
|
+
* runtime.
|
|
27
|
+
*
|
|
28
|
+
* Creates a scoped {@link AccountApiToken} with both the `Cloudflare Tunnel
|
|
29
|
+
* Read` and `Cloudflare Tunnel Write` permissions and binds its outputs into
|
|
30
|
+
* the Worker (the token value as a `secret_text` binding) so runtime code can
|
|
31
|
+
* authenticate.
|
|
32
|
+
*
|
|
33
|
+
* @binding
|
|
34
|
+
*
|
|
35
|
+
* @section Managing tunnels at runtime
|
|
36
|
+
* @example Create, configure, and delete a tunnel from a request handler
|
|
37
|
+
* ```typescript
|
|
38
|
+
* // init
|
|
39
|
+
* const tunnels = yield* Cloudflare.TunnelReadWrite.bind();
|
|
40
|
+
*
|
|
41
|
+
* return {
|
|
42
|
+
* fetch: Effect.gen(function* () {
|
|
43
|
+
* const tunnel = yield* tunnels.create({ name: "on-demand-tunnel" });
|
|
44
|
+
* yield* tunnels.putConfiguration(tunnel.id!, {
|
|
45
|
+
* ingress: [
|
|
46
|
+
* { hostname: "app.example.com", service: "http://localhost:3000" },
|
|
47
|
+
* { service: "http_status:404" },
|
|
48
|
+
* ],
|
|
49
|
+
* });
|
|
50
|
+
* const token = yield* tunnels.getToken(tunnel.id!);
|
|
51
|
+
* return HttpServerResponse.json({ id: tunnel.id, token });
|
|
52
|
+
* }),
|
|
53
|
+
* };
|
|
54
|
+
* ```
|
|
55
|
+
*
|
|
56
|
+
* @section Runtime Layer
|
|
57
|
+
* Provide {@link TunnelReadWriteLive} in the Worker's runtime layer.
|
|
58
|
+
* ```typescript
|
|
59
|
+
* Effect.provide(Cloudflare.TunnelReadWriteLive)
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export class TunnelReadWrite extends Binding.Service<
|
|
63
|
+
TunnelReadWrite,
|
|
64
|
+
() => Effect.Effect<TunnelReadWriteClient, never, Worker>
|
|
65
|
+
>()("Cloudflare.TunnelReadWrite") {}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Deploy-time policy for {@link TunnelReadWrite}. Attaches both the `Cloudflare
|
|
69
|
+
* Tunnel Read` and `Cloudflare Tunnel Write` permissions to the token via its
|
|
70
|
+
* binding contract.
|
|
71
|
+
*/
|
|
72
|
+
export class TunnelReadWritePolicy extends Binding.Policy<
|
|
73
|
+
TunnelReadWritePolicy,
|
|
74
|
+
(token: AccountApiToken) => Effect.Effect<void>
|
|
75
|
+
>()("Cloudflare.TunnelReadWrite") {}
|
|
76
|
+
|
|
77
|
+
/** Runtime layer for {@link TunnelReadWrite}. */
|
|
78
|
+
export const TunnelReadWriteLive = Layer.effect(
|
|
79
|
+
TunnelReadWrite,
|
|
80
|
+
makeTunnelClient(TunnelReadWritePolicy, readWriteClient),
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
/** Live deploy-time policy layer for {@link TunnelReadWritePolicy}. */
|
|
84
|
+
export const TunnelReadWritePolicyLive = makeTunnelPolicyLive(
|
|
85
|
+
TunnelReadWritePolicy,
|
|
86
|
+
"Cloudflare.TunnelReadWrite",
|
|
87
|
+
["Cloudflare Tunnel Read", "Cloudflare Tunnel Write"],
|
|
88
|
+
);
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CreateTunnelCloudflaredError,
|
|
3
|
+
CreateTunnelCloudflaredRequest,
|
|
4
|
+
CreateTunnelCloudflaredResponse,
|
|
5
|
+
DeleteTunnelCloudflaredError,
|
|
6
|
+
DeleteTunnelCloudflaredResponse,
|
|
7
|
+
PatchTunnelCloudflaredError,
|
|
8
|
+
PatchTunnelCloudflaredRequest,
|
|
9
|
+
PatchTunnelCloudflaredResponse,
|
|
10
|
+
PutTunnelCloudflaredConfigurationError,
|
|
11
|
+
PutTunnelCloudflaredConfigurationRequest,
|
|
12
|
+
PutTunnelCloudflaredConfigurationResponse,
|
|
13
|
+
} from "@distilled.cloud/cloudflare/zero-trust";
|
|
14
|
+
import * as zeroTrust from "@distilled.cloud/cloudflare/zero-trust";
|
|
15
|
+
import * as Effect from "effect/Effect";
|
|
16
|
+
import * as Layer from "effect/Layer";
|
|
17
|
+
import * as Binding from "../../Binding.ts";
|
|
18
|
+
import type { RuntimeContext } from "../../RuntimeContext.ts";
|
|
19
|
+
import type { AccountApiToken } from "../ApiToken/AccountApiToken.ts";
|
|
20
|
+
import type { Worker } from "../Workers/Worker.ts";
|
|
21
|
+
import {
|
|
22
|
+
authorizeWith,
|
|
23
|
+
makeTunnelClient,
|
|
24
|
+
makeTunnelPolicyLive,
|
|
25
|
+
type TunnelToken,
|
|
26
|
+
} from "./TunnelBinding.ts";
|
|
27
|
+
|
|
28
|
+
/** Create-tunnel request, minus the account id (supplied by the binding). */
|
|
29
|
+
export type CreateTunnelRequest = Omit<
|
|
30
|
+
CreateTunnelCloudflaredRequest,
|
|
31
|
+
"accountId"
|
|
32
|
+
>;
|
|
33
|
+
|
|
34
|
+
/** Update-tunnel request, minus the account id and tunnel id (positional). */
|
|
35
|
+
export type UpdateTunnelRequest = Omit<
|
|
36
|
+
PatchTunnelCloudflaredRequest,
|
|
37
|
+
"accountId" | "tunnelId"
|
|
38
|
+
>;
|
|
39
|
+
|
|
40
|
+
/** Tunnel configuration body, minus the account id and tunnel id (positional). */
|
|
41
|
+
export type TunnelConfiguration = NonNullable<
|
|
42
|
+
PutTunnelCloudflaredConfigurationRequest["config"]
|
|
43
|
+
>;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Mutating tunnel operations. Backed by the `Cloudflare Tunnel Write`
|
|
47
|
+
* permission group.
|
|
48
|
+
*/
|
|
49
|
+
export interface TunnelWriteClient {
|
|
50
|
+
/** Create a new tunnel. */
|
|
51
|
+
create(
|
|
52
|
+
request: CreateTunnelRequest,
|
|
53
|
+
): Effect.Effect<
|
|
54
|
+
CreateTunnelCloudflaredResponse,
|
|
55
|
+
CreateTunnelCloudflaredError,
|
|
56
|
+
RuntimeContext
|
|
57
|
+
>;
|
|
58
|
+
/** Update a tunnel's mutable fields (name, secret). */
|
|
59
|
+
update(
|
|
60
|
+
tunnelId: string,
|
|
61
|
+
request: UpdateTunnelRequest,
|
|
62
|
+
): Effect.Effect<
|
|
63
|
+
PatchTunnelCloudflaredResponse,
|
|
64
|
+
PatchTunnelCloudflaredError,
|
|
65
|
+
RuntimeContext
|
|
66
|
+
>;
|
|
67
|
+
/** Delete a tunnel by id. */
|
|
68
|
+
delete(
|
|
69
|
+
tunnelId: string,
|
|
70
|
+
): Effect.Effect<
|
|
71
|
+
DeleteTunnelCloudflaredResponse,
|
|
72
|
+
DeleteTunnelCloudflaredError,
|
|
73
|
+
RuntimeContext
|
|
74
|
+
>;
|
|
75
|
+
/** Replace the remotely-managed configuration (ingress rules) for a tunnel. */
|
|
76
|
+
putConfiguration(
|
|
77
|
+
tunnelId: string,
|
|
78
|
+
config: TunnelConfiguration,
|
|
79
|
+
): Effect.Effect<
|
|
80
|
+
PutTunnelCloudflaredConfigurationResponse,
|
|
81
|
+
PutTunnelCloudflaredConfigurationError,
|
|
82
|
+
RuntimeContext
|
|
83
|
+
>;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Build the write client over a bound token. */
|
|
87
|
+
export const writeClient = (token: TunnelToken): TunnelWriteClient => {
|
|
88
|
+
const authorize = authorizeWith(token);
|
|
89
|
+
return {
|
|
90
|
+
create: Effect.fn("Cloudflare.Tunnel.create")(function* (request) {
|
|
91
|
+
const accountId = yield* token.accountId;
|
|
92
|
+
return yield* authorize(
|
|
93
|
+
zeroTrust.createTunnelCloudflared({ accountId, ...request }),
|
|
94
|
+
);
|
|
95
|
+
}),
|
|
96
|
+
update: Effect.fn("Cloudflare.Tunnel.update")(
|
|
97
|
+
function* (tunnelId, request) {
|
|
98
|
+
const accountId = yield* token.accountId;
|
|
99
|
+
return yield* authorize(
|
|
100
|
+
zeroTrust.patchTunnelCloudflared({ accountId, tunnelId, ...request }),
|
|
101
|
+
);
|
|
102
|
+
},
|
|
103
|
+
),
|
|
104
|
+
delete: Effect.fn("Cloudflare.Tunnel.delete")(function* (tunnelId) {
|
|
105
|
+
const accountId = yield* token.accountId;
|
|
106
|
+
return yield* authorize(
|
|
107
|
+
zeroTrust.deleteTunnelCloudflared({ accountId, tunnelId }),
|
|
108
|
+
);
|
|
109
|
+
}),
|
|
110
|
+
putConfiguration: Effect.fn("Cloudflare.Tunnel.putConfiguration")(
|
|
111
|
+
function* (tunnelId, config) {
|
|
112
|
+
const accountId = yield* token.accountId;
|
|
113
|
+
return yield* authorize(
|
|
114
|
+
zeroTrust.putTunnelCloudflaredConfiguration({
|
|
115
|
+
accountId,
|
|
116
|
+
tunnelId,
|
|
117
|
+
config,
|
|
118
|
+
}),
|
|
119
|
+
);
|
|
120
|
+
},
|
|
121
|
+
),
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Binding that lets a Worker create, update, and delete Cloudflare Tunnels at
|
|
127
|
+
* runtime.
|
|
128
|
+
*
|
|
129
|
+
* Creates a scoped {@link AccountApiToken} with only the `Cloudflare Tunnel
|
|
130
|
+
* Write` permission and binds its outputs into the Worker (the token value as a
|
|
131
|
+
* `secret_text` binding) so runtime code can authenticate.
|
|
132
|
+
*
|
|
133
|
+
* @binding
|
|
134
|
+
*
|
|
135
|
+
* @section Mutating tunnels at runtime
|
|
136
|
+
* @example Bind the write client
|
|
137
|
+
* Bind once in the Init phase; every method is available on the returned client.
|
|
138
|
+
* ```typescript
|
|
139
|
+
* const tunnels = yield* Cloudflare.TunnelWrite.bind();
|
|
140
|
+
* ```
|
|
141
|
+
*
|
|
142
|
+
* @example Create a tunnel
|
|
143
|
+
* ```typescript
|
|
144
|
+
* const tunnel = yield* tunnels.create({ name: "on-demand-tunnel" });
|
|
145
|
+
* ```
|
|
146
|
+
*
|
|
147
|
+
* @example Push ingress configuration
|
|
148
|
+
* ```typescript
|
|
149
|
+
* yield* tunnels.putConfiguration(tunnel.id!, {
|
|
150
|
+
* ingress: [
|
|
151
|
+
* { hostname: "app.example.com", service: "http://localhost:3000" },
|
|
152
|
+
* { service: "http_status:404" },
|
|
153
|
+
* ],
|
|
154
|
+
* });
|
|
155
|
+
* ```
|
|
156
|
+
*
|
|
157
|
+
* @example Rename and delete a tunnel
|
|
158
|
+
* ```typescript
|
|
159
|
+
* yield* tunnels.update(tunnel.id!, { name: "renamed-tunnel" });
|
|
160
|
+
* yield* tunnels.delete(tunnel.id!);
|
|
161
|
+
* ```
|
|
162
|
+
*
|
|
163
|
+
* @section Runtime Layer
|
|
164
|
+
* Provide {@link TunnelWriteLive} in the Worker's runtime layer.
|
|
165
|
+
* ```typescript
|
|
166
|
+
* Effect.provide(Cloudflare.TunnelWriteLive)
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
169
|
+
export class TunnelWrite extends Binding.Service<
|
|
170
|
+
TunnelWrite,
|
|
171
|
+
() => Effect.Effect<TunnelWriteClient, never, Worker>
|
|
172
|
+
>()("Cloudflare.TunnelWrite") {}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Deploy-time policy for {@link TunnelWrite}. Attaches the `Cloudflare Tunnel
|
|
176
|
+
* Write` permission to the token via its binding contract.
|
|
177
|
+
*/
|
|
178
|
+
export class TunnelWritePolicy extends Binding.Policy<
|
|
179
|
+
TunnelWritePolicy,
|
|
180
|
+
(token: AccountApiToken) => Effect.Effect<void>
|
|
181
|
+
>()("Cloudflare.TunnelWrite") {}
|
|
182
|
+
|
|
183
|
+
/** Runtime layer for {@link TunnelWrite}. */
|
|
184
|
+
export const TunnelWriteLive = Layer.effect(
|
|
185
|
+
TunnelWrite,
|
|
186
|
+
makeTunnelClient(TunnelWritePolicy, writeClient),
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
/** Live deploy-time policy layer for {@link TunnelWritePolicy}. */
|
|
190
|
+
export const TunnelWritePolicyLive = makeTunnelPolicyLive(
|
|
191
|
+
TunnelWritePolicy,
|
|
192
|
+
"Cloudflare.TunnelWrite",
|
|
193
|
+
["Cloudflare Tunnel Write"],
|
|
194
|
+
);
|
|
@@ -253,7 +253,8 @@ const toAttributes = (
|
|
|
253
253
|
): VectorizeIndexAttributes => ({
|
|
254
254
|
indexName: index.name ?? name,
|
|
255
255
|
dimensions: index.config?.dimensions,
|
|
256
|
-
|
|
256
|
+
// Distilled widened generated string enums to open unions (`string & {}`).
|
|
257
|
+
metric: index.config?.metric as DistanceMetric | undefined,
|
|
257
258
|
description: index.description ?? undefined,
|
|
258
259
|
accountId,
|
|
259
260
|
createdOn: index.createdOn ?? undefined,
|
|
@@ -262,7 +262,9 @@ export const formatVpcService = (
|
|
|
262
262
|
service: {
|
|
263
263
|
serviceId?: string | null;
|
|
264
264
|
name: string;
|
|
265
|
-
|
|
265
|
+
// Distilled widened generated string enums to open unions (`string & {}`);
|
|
266
|
+
// the API only ever returns the known variants here.
|
|
267
|
+
type: string;
|
|
266
268
|
createdAt?: string | null;
|
|
267
269
|
updatedAt?: string | null;
|
|
268
270
|
httpPort?: number | null;
|
|
@@ -300,7 +302,7 @@ export const formatVpcService = (
|
|
|
300
302
|
return {
|
|
301
303
|
serviceId: service.serviceId!,
|
|
302
304
|
serviceName: service.name,
|
|
303
|
-
serviceType: service.type,
|
|
305
|
+
serviceType: service.type as "http" | "tcp",
|
|
304
306
|
httpPort: service.httpPort ?? undefined,
|
|
305
307
|
httpsPort: service.httpsPort ?? undefined,
|
|
306
308
|
host,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as Effect from "effect/Effect";
|
|
2
|
+
import { SingleShotGen } from "effect/Utils";
|
|
2
3
|
import { ALCHEMY_PHASE } from "../../Phase.ts";
|
|
3
4
|
import { fromCloudflareFetcher, type Fetcher } from "../Fetcher.ts";
|
|
4
5
|
import { makeRpcStub } from "./Rpc.ts";
|
|
@@ -56,10 +57,10 @@ export interface DynamicWorkerInstance extends Fetcher {
|
|
|
56
57
|
}
|
|
57
58
|
|
|
58
59
|
/**
|
|
59
|
-
* The handle
|
|
60
|
-
* for spinning up isolated dynamic workers
|
|
60
|
+
* The runtime handle obtained by `yield* Cloudflare.DynamicWorkerLoader(name)`.
|
|
61
|
+
* Provides a `.load()` method for spinning up isolated dynamic workers.
|
|
61
62
|
*/
|
|
62
|
-
export
|
|
63
|
+
export interface DynamicWorkerLoaderHandle {
|
|
63
64
|
Type: DynamicWorkerTypeId;
|
|
64
65
|
name: string;
|
|
65
66
|
/**
|
|
@@ -67,7 +68,57 @@ export type DynamicWorkerLoader = {
|
|
|
67
68
|
* exposes `.getEntrypoint()` and `.fetch()` for calling into the worker.
|
|
68
69
|
*/
|
|
69
70
|
load(options: DynamicWorkerLoadOptions): DynamicWorkerInstance;
|
|
70
|
-
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* The native `worker_loader` runtime binding shape, as seen by an async
|
|
75
|
+
* (non-Effect) Worker that declares the loader through `env`. `InferEnv` maps
|
|
76
|
+
* a `DynamicWorkerLoader` marker in `env` to this type.
|
|
77
|
+
*/
|
|
78
|
+
export interface DynamicWorkerLoaderBinding {
|
|
79
|
+
load(options: DynamicWorkerLoadOptions): {
|
|
80
|
+
getEntrypoint(name?: string): {
|
|
81
|
+
fetch(request: Request): Promise<Response>;
|
|
82
|
+
[method: string]: unknown;
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* The Effect yielded when a `DynamicWorkerLoader` marker is used inside a
|
|
89
|
+
* Worker init phase: it registers the `worker_loader` binding on the
|
|
90
|
+
* surrounding Worker and resolves to a {@link DynamicWorkerLoaderHandle}.
|
|
91
|
+
*/
|
|
92
|
+
type BindEffect = ReturnType<typeof bindLoader>;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Marker for a Cloudflare Worker Loader binding.
|
|
96
|
+
*
|
|
97
|
+
* It is a plain data structure (so it can be declared directly on a Worker's
|
|
98
|
+
* `env`) that is **also** yieldable inside an Effect-native Worker. Yielding it
|
|
99
|
+
* (`yield* Cloudflare.DynamicWorkerLoader(name)`) registers the binding on the
|
|
100
|
+
* surrounding Worker and returns a {@link DynamicWorkerLoaderHandle} with
|
|
101
|
+
* `.load()` — no separate `.bind(...)` step required.
|
|
102
|
+
*
|
|
103
|
+
* The divergence is achieved via `[Symbol.iterator]`: the object is not an
|
|
104
|
+
* `Effect` (so `InferEnv` resolves it to the native
|
|
105
|
+
* {@link DynamicWorkerLoaderBinding} in the `env` position), but it is iterable
|
|
106
|
+
* as one when `yield*`-ed.
|
|
107
|
+
*/
|
|
108
|
+
export interface DynamicWorkerLoader {
|
|
109
|
+
kind: DynamicWorkerTypeId;
|
|
110
|
+
name: string;
|
|
111
|
+
asEffect(): BindEffect;
|
|
112
|
+
[Symbol.iterator](): SingleShotGen<BindEffect, DynamicWorkerLoaderHandle>;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export const isDynamicWorkerLoader = (
|
|
116
|
+
value: unknown,
|
|
117
|
+
): value is DynamicWorkerLoader =>
|
|
118
|
+
typeof value === "object" &&
|
|
119
|
+
value !== null &&
|
|
120
|
+
"kind" in value &&
|
|
121
|
+
(value as DynamicWorkerLoader).kind === DynamicWorkerTypeId;
|
|
71
122
|
|
|
72
123
|
/**
|
|
73
124
|
* Load and run ephemeral Workers at runtime from inline JavaScript
|
|
@@ -86,14 +137,79 @@ export type DynamicWorkerLoader = {
|
|
|
86
137
|
* @resource
|
|
87
138
|
*
|
|
88
139
|
* @section Creating a Loader
|
|
89
|
-
* Yield `Cloudflare.DynamicWorkerLoader` in your Worker's init
|
|
90
|
-
* phase to register the binding
|
|
91
|
-
* binding name on the deployed Worker.
|
|
140
|
+
* Yield `Cloudflare.DynamicWorkerLoader(name)` in your Worker's init
|
|
141
|
+
* phase to register the binding and get back a runtime handle. The
|
|
142
|
+
* string argument becomes the binding name on the deployed Worker.
|
|
92
143
|
*
|
|
93
|
-
* @example Registering a loader
|
|
144
|
+
* @example Registering a loader (effect-native Worker)
|
|
94
145
|
* ```typescript
|
|
95
|
-
*
|
|
96
|
-
*
|
|
146
|
+
* import * as Cloudflare from "alchemy/Cloudflare";
|
|
147
|
+
* import * as Effect from "effect/Effect";
|
|
148
|
+
* import { HttpServerRequest } from "effect/unstable/http/HttpServerRequest";
|
|
149
|
+
* import * as HttpServerResponse from "effect/unstable/http/HttpServerResponse";
|
|
150
|
+
* import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest";
|
|
151
|
+
*
|
|
152
|
+
* export default class EvalWorker extends Cloudflare.Worker<EvalWorker>()(
|
|
153
|
+
* "EvalWorker",
|
|
154
|
+
* { main: import.meta.filename },
|
|
155
|
+
* Effect.gen(function* () {
|
|
156
|
+
* // Registers the `worker_loader` binding on this Worker and returns the
|
|
157
|
+
* // runtime handle in one step — no separate `.bind(...)`.
|
|
158
|
+
* const loader = yield* Cloudflare.DynamicWorkerLoader("LOADER");
|
|
159
|
+
*
|
|
160
|
+
* return {
|
|
161
|
+
* fetch: Effect.gen(function* () {
|
|
162
|
+
* const request = yield* HttpServerRequest;
|
|
163
|
+
* const code = yield* request.text;
|
|
164
|
+
*
|
|
165
|
+
* // Spin up an isolated, sandboxed Worker from inline source.
|
|
166
|
+
* const worker = loader.load({
|
|
167
|
+
* compatibilityDate: "2026-01-28",
|
|
168
|
+
* mainModule: "worker.js",
|
|
169
|
+
* modules: {
|
|
170
|
+
* "worker.js": `export default {
|
|
171
|
+
* async fetch(req) {
|
|
172
|
+
* const result = (0, eval)(await req.text());
|
|
173
|
+
* return new Response(String(result));
|
|
174
|
+
* }
|
|
175
|
+
* }`,
|
|
176
|
+
* },
|
|
177
|
+
* globalOutbound: null, // block outbound network access
|
|
178
|
+
* });
|
|
179
|
+
*
|
|
180
|
+
* // Call the loaded Worker over Effect-native HTTP.
|
|
181
|
+
* const response = yield* worker.fetch(
|
|
182
|
+
* HttpClientRequest.post("https://worker/").pipe(
|
|
183
|
+
* HttpClientRequest.bodyText(code),
|
|
184
|
+
* ),
|
|
185
|
+
* );
|
|
186
|
+
* return HttpServerResponse.fromClientResponse(response);
|
|
187
|
+
* }),
|
|
188
|
+
* };
|
|
189
|
+
* }),
|
|
190
|
+
* ) {}
|
|
191
|
+
* ```
|
|
192
|
+
*
|
|
193
|
+
* @example Declaring on env (async Worker)
|
|
194
|
+
* ```typescript
|
|
195
|
+
* export const Worker = Cloudflare.Worker("Worker", {
|
|
196
|
+
* main: "./src/worker.ts",
|
|
197
|
+
* env: { LOADER: Cloudflare.DynamicWorkerLoader() },
|
|
198
|
+
* });
|
|
199
|
+
*
|
|
200
|
+
* export type WorkerEnv = Cloudflare.InferEnv<typeof Worker>;
|
|
201
|
+
*
|
|
202
|
+
* // worker.ts
|
|
203
|
+
* export default {
|
|
204
|
+
* async fetch(req: Request, env: WorkerEnv) {
|
|
205
|
+
* const worker = env.LOADER.load({
|
|
206
|
+
* compatibilityDate: "2026-01-28",
|
|
207
|
+
* mainModule: "worker.js",
|
|
208
|
+
* modules: { "worker.js": "export default { fetch: () => new Response('ok') }" },
|
|
209
|
+
* });
|
|
210
|
+
* return worker.getEntrypoint().fetch(req);
|
|
211
|
+
* },
|
|
212
|
+
* };
|
|
97
213
|
* ```
|
|
98
214
|
*
|
|
99
215
|
* @section Loading a Worker
|
|
@@ -155,7 +271,17 @@ export type DynamicWorkerLoader = {
|
|
|
155
271
|
* const greeting = yield* api.greet("world");
|
|
156
272
|
* ```
|
|
157
273
|
*/
|
|
158
|
-
export const DynamicWorkerLoader =
|
|
274
|
+
export const DynamicWorkerLoader = (name = "LOADER"): DynamicWorkerLoader => {
|
|
275
|
+
const self: DynamicWorkerLoader = {
|
|
276
|
+
kind: DynamicWorkerTypeId,
|
|
277
|
+
name,
|
|
278
|
+
asEffect: () => bindLoader(name),
|
|
279
|
+
[Symbol.iterator]: () => new SingleShotGen(bindLoader(name)),
|
|
280
|
+
};
|
|
281
|
+
return self;
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
const bindLoader = Effect.fnUntraced(function* (name: string) {
|
|
159
285
|
const worker = yield* Worker;
|
|
160
286
|
|
|
161
287
|
yield* worker.bind`${name}`({
|
|
@@ -177,14 +303,14 @@ export const DynamicWorkerLoader = Effect.fnUntraced(function* (name: string) {
|
|
|
177
303
|
}),
|
|
178
304
|
);
|
|
179
305
|
|
|
180
|
-
const
|
|
306
|
+
const handle: DynamicWorkerLoaderHandle = {
|
|
181
307
|
Type: DynamicWorkerTypeId,
|
|
182
308
|
name,
|
|
183
309
|
load: (options: DynamicWorkerLoadOptions): DynamicWorkerInstance =>
|
|
184
310
|
wrapLoadedWorker(binding.load(options)),
|
|
185
311
|
};
|
|
186
312
|
|
|
187
|
-
return
|
|
313
|
+
return handle;
|
|
188
314
|
});
|
|
189
315
|
|
|
190
316
|
const wrapEntrypoint = <Shape>(raw: any): DynamicWorkerEntrypoint<Shape> =>
|