alchemy 2.0.0-beta.1 → 2.0.0-beta.3
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/alchemy-effect.js +31 -16
- package/bin/alchemy-effect.js.map +1 -1
- package/bin/alchemy-effect.sh +2 -3
- package/bin/alchemy-effect.ts +3 -3
- package/lib/cli/index.d.ts +39 -36
- package/lib/cli/index.d.ts.map +1 -1
- package/package.json +18 -9
- package/src/AWS/ACM/Certificate.ts +49 -46
- package/src/AWS/AutoScaling/AutoScalingGroup.ts +4 -1
- package/src/AWS/AutoScaling/LaunchTemplate.ts +3 -1
- package/src/AWS/AutoScaling/ScalingPolicy.ts +4 -1
- package/src/AWS/CloudFront/Distribution.ts +4 -1
- package/src/AWS/CloudFront/Function.ts +4 -1
- package/src/AWS/CloudFront/Invalidation.ts +4 -1
- package/src/AWS/CloudFront/KeyValueStore.ts +4 -1
- package/src/AWS/CloudFront/KvEntries.ts +4 -1
- package/src/AWS/CloudFront/KvRoutesUpdate.ts +4 -1
- package/src/AWS/CloudFront/OriginAccessControl.ts +4 -1
- package/src/AWS/CloudWatch/Alarm.ts +4 -1
- package/src/AWS/CloudWatch/AlarmMuteRule.ts +4 -1
- package/src/AWS/CloudWatch/AnomalyDetector.ts +4 -1
- package/src/AWS/CloudWatch/CompositeAlarm.ts +4 -1
- package/src/AWS/CloudWatch/Dashboard.ts +4 -1
- package/src/AWS/CloudWatch/InsightRule.ts +4 -1
- package/src/AWS/CloudWatch/MetricStream.ts +4 -1
- package/src/AWS/DynamoDB/Table.ts +3 -1
- package/src/AWS/EC2/EIP.ts +4 -1
- package/src/AWS/EC2/EgressOnlyInternetGateway.ts +4 -1
- package/src/AWS/EC2/Instance.ts +3 -1
- package/src/AWS/EC2/InternetGateway.ts +4 -1
- package/src/AWS/EC2/NatGateway.ts +4 -1
- package/src/AWS/EC2/NetworkAcl.ts +4 -1
- package/src/AWS/EC2/NetworkAclAssociation.ts +4 -1
- package/src/AWS/EC2/NetworkAclEntry.ts +4 -1
- package/src/AWS/EC2/Route.ts +4 -1
- package/src/AWS/EC2/RouteTable.ts +4 -1
- package/src/AWS/EC2/RouteTableAssociation.ts +4 -1
- package/src/AWS/EC2/SecurityGroup.ts +4 -1
- package/src/AWS/EC2/SecurityGroupRule.ts +4 -1
- package/src/AWS/EC2/Subnet.ts +4 -1
- package/src/AWS/EC2/Vpc.ts +4 -1
- package/src/AWS/EC2/VpcEndpoint.ts +4 -1
- package/src/AWS/ECR/Repository.ts +4 -1
- package/src/AWS/ECS/Cluster.ts +4 -1
- package/src/AWS/ECS/Service.ts +4 -1
- package/src/AWS/ECS/Task.ts +3 -1
- package/src/AWS/EKS/AccessEntry.ts +4 -1
- package/src/AWS/EKS/Addon.ts +4 -1
- package/src/AWS/EKS/Cluster.ts +3 -1
- package/src/AWS/EKS/PodIdentityAssociation.ts +4 -1
- package/src/AWS/ELBv2/Listener.ts +4 -1
- package/src/AWS/ELBv2/LoadBalancer.ts +4 -1
- package/src/AWS/ELBv2/TargetGroup.ts +4 -1
- package/src/AWS/EventBridge/EventBus.ts +4 -1
- package/src/AWS/EventBridge/Permission.ts +4 -1
- package/src/AWS/EventBridge/Rule.ts +4 -1
- package/src/AWS/IAM/AccessKey.ts +4 -1
- package/src/AWS/IAM/AccountAlias.ts +4 -1
- package/src/AWS/IAM/AccountPasswordPolicy.ts +4 -1
- package/src/AWS/IAM/Group.ts +4 -1
- package/src/AWS/IAM/GroupMembership.ts +4 -1
- package/src/AWS/IAM/InstanceProfile.ts +4 -1
- package/src/AWS/IAM/LoginProfile.ts +4 -1
- package/src/AWS/IAM/OpenIDConnectProvider.ts +4 -1
- package/src/AWS/IAM/Policy.ts +4 -1
- package/src/AWS/IAM/Role.ts +4 -1
- package/src/AWS/IAM/SAMLProvider.ts +4 -1
- package/src/AWS/IAM/SSHPublicKey.ts +4 -1
- package/src/AWS/IAM/ServerCertificate.ts +4 -1
- package/src/AWS/IAM/ServiceSpecificCredential.ts +4 -1
- package/src/AWS/IAM/SigningCertificate.ts +4 -1
- package/src/AWS/IAM/User.ts +4 -1
- package/src/AWS/IAM/VirtualMFADevice.ts +4 -1
- package/src/AWS/IdentityCenter/AccountAssignment.ts +4 -1
- package/src/AWS/IdentityCenter/Group.ts +4 -1
- package/src/AWS/IdentityCenter/Instance.ts +4 -1
- package/src/AWS/IdentityCenter/PermissionSet.ts +4 -1
- package/src/AWS/Kinesis/Stream.ts +4 -1
- package/src/AWS/Kinesis/StreamConsumer.ts +4 -1
- package/src/AWS/Lambda/EventSourceMapping.ts +4 -1
- package/src/AWS/Lambda/Function.ts +3 -1
- package/src/AWS/Lambda/Permission.ts +4 -1
- package/src/AWS/Logs/LogGroup.ts +4 -1
- package/src/AWS/Organizations/Account.ts +4 -1
- package/src/AWS/Organizations/DelegatedAdministrator.ts +4 -1
- package/src/AWS/Organizations/Organization.ts +4 -1
- package/src/AWS/Organizations/OrganizationResourcePolicy.ts +4 -1
- package/src/AWS/Organizations/OrganizationalUnit.ts +4 -1
- package/src/AWS/Organizations/Policy.ts +4 -1
- package/src/AWS/Organizations/PolicyAttachment.ts +4 -1
- package/src/AWS/Organizations/Root.ts +4 -1
- package/src/AWS/Organizations/RootPolicyType.ts +4 -1
- package/src/AWS/Organizations/TrustedServiceAccess.ts +4 -1
- package/src/AWS/Providers.ts +484 -438
- package/src/AWS/RDS/DBCluster.ts +4 -1
- package/src/AWS/RDS/DBClusterEndpoint.ts +4 -1
- package/src/AWS/RDS/DBClusterParameterGroup.ts +4 -1
- package/src/AWS/RDS/DBInstance.ts +4 -1
- package/src/AWS/RDS/DBParameterGroup.ts +4 -1
- package/src/AWS/RDS/DBProxy.ts +4 -1
- package/src/AWS/RDS/DBProxyEndpoint.ts +4 -1
- package/src/AWS/RDS/DBProxyTargetGroup.ts +4 -1
- package/src/AWS/RDS/DBSubnetGroup.ts +4 -1
- package/src/AWS/Route53/Record.ts +4 -1
- package/src/AWS/S3/Bucket.ts +3 -1
- package/src/AWS/SNS/Subscription.ts +4 -1
- package/src/AWS/SNS/Topic.ts +4 -1
- package/src/AWS/SQS/Queue.ts +3 -1
- package/src/AWS/Scheduler/Schedule.ts +4 -1
- package/src/AWS/Scheduler/ScheduleGroup.ts +4 -1
- package/src/AWS/SecretsManager/Secret.ts +4 -1
- package/src/AWS/Website/AssetDeployment.ts +4 -1
- package/src/Apply.ts +3 -3
- package/src/Binding.ts +18 -17
- package/src/Cloudflare/Container/Container.ts +122 -0
- package/src/Cloudflare/Container/ContainerApplication.ts +6 -1
- package/src/Cloudflare/Container/ContainerBinding.ts +1 -1
- package/src/Cloudflare/Container/StartContainer.ts +1 -1
- package/src/Cloudflare/D1/D1Database.ts +27 -5
- package/src/Cloudflare/KV/KVNamespace.ts +32 -4
- package/src/Cloudflare/Providers.ts +62 -60
- package/src/Cloudflare/R2/R2Bucket.ts +47 -1
- package/src/Cloudflare/R2/R2BucketBinding.ts +26 -31
- package/src/Cloudflare/Website/StaticSite.ts +57 -0
- package/src/Cloudflare/Website/Vite.ts +52 -8
- package/src/Cloudflare/Workers/{DurableObject.ts → DurableObjectNamespace.ts} +242 -0
- package/src/Cloudflare/Workers/DynamicWorkerLoader.ts +66 -7
- package/src/Cloudflare/Workers/WebSocket.ts +1 -1
- package/src/Cloudflare/Workers/Worker.ts +315 -8
- package/src/Cloudflare/Workers/Workflow.ts +56 -12
- package/src/Cloudflare/Workers/index.ts +1 -1
- package/src/GitHub/Comment.ts +224 -0
- package/src/GitHub/Secret.ts +212 -0
- package/src/GitHub/Variable.ts +123 -0
- package/src/GitHub/index.ts +3 -0
- package/src/Plan.ts +595 -596
- package/src/Platform.ts +9 -8
- package/src/Provider.ts +145 -23
- package/src/Resource.ts +10 -3
- package/src/Stack.ts +1 -1
- package/src/Util/dedent.ts +56 -0
- package/src/Util/index.ts +1 -0
- package/src/Util/service.ts +1 -1
- package/src/index.ts +10 -7
|
@@ -5,9 +5,10 @@ import { createPhysicalName } from "../../PhysicalName.ts";
|
|
|
5
5
|
import * as Provider from "../../Provider.ts";
|
|
6
6
|
import { Resource } from "../../Resource.ts";
|
|
7
7
|
import { Account } from "../Account.ts";
|
|
8
|
+
import type { Providers } from "../Providers.ts";
|
|
8
9
|
import { KVNamespaceBinding } from "./KVNamespaceBinding.ts";
|
|
9
10
|
|
|
10
|
-
export type
|
|
11
|
+
export type KVNamespaceProps = {
|
|
11
12
|
/**
|
|
12
13
|
* A human-readable string name for the namespace.
|
|
13
14
|
* If omitted, a unique name will be generated.
|
|
@@ -18,20 +19,47 @@ export type NamespaceProps = {
|
|
|
18
19
|
|
|
19
20
|
export type KVNamespace = Resource<
|
|
20
21
|
"Cloudflare.KVNamespace",
|
|
21
|
-
|
|
22
|
+
KVNamespaceProps,
|
|
22
23
|
{
|
|
23
24
|
title: string;
|
|
24
25
|
namespaceId: string;
|
|
25
26
|
supportsUrlEncoding: boolean | undefined;
|
|
26
27
|
accountId: string;
|
|
27
|
-
}
|
|
28
|
+
},
|
|
29
|
+
never,
|
|
30
|
+
Providers
|
|
28
31
|
>;
|
|
29
32
|
|
|
33
|
+
/**
|
|
34
|
+
* A Cloudflare Workers KV namespace for key-value storage at the edge.
|
|
35
|
+
*
|
|
36
|
+
* KV provides eventually-consistent, low-latency reads with global
|
|
37
|
+
* replication. Create a namespace as a resource, then bind it to a Worker
|
|
38
|
+
* to get/put values at runtime.
|
|
39
|
+
*
|
|
40
|
+
* @section Creating a Namespace
|
|
41
|
+
* @example Basic KV namespace
|
|
42
|
+
* ```typescript
|
|
43
|
+
* const kv = yield* Cloudflare.KVNamespace("MyKV");
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* @section Binding to a Worker
|
|
47
|
+
* @example Using KV inside a Worker
|
|
48
|
+
* ```typescript
|
|
49
|
+
* const kv = yield* Cloudflare.KVNamespace.bind(MyKV);
|
|
50
|
+
*
|
|
51
|
+
* // Read a value
|
|
52
|
+
* const value = yield* kv.get("my-key");
|
|
53
|
+
*
|
|
54
|
+
* // Write a value
|
|
55
|
+
* yield* kv.put("my-key", "hello world");
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
30
58
|
export const KVNamespace = Resource<KVNamespace>("Cloudflare.KVNamespace")({
|
|
31
59
|
bind: KVNamespaceBinding.bind,
|
|
32
60
|
});
|
|
33
61
|
|
|
34
|
-
export const
|
|
62
|
+
export const KVNamespaceProvider = () =>
|
|
35
63
|
Provider.effect(
|
|
36
64
|
KVNamespace,
|
|
37
65
|
Effect.gen(function* () {
|
|
@@ -1,75 +1,77 @@
|
|
|
1
1
|
import * as Auth from "@distilled.cloud/cloudflare/Auth";
|
|
2
|
-
import { pipe } from "effect/Function";
|
|
3
2
|
import * as Layer from "effect/Layer";
|
|
4
|
-
import * as FetchHttpClient from "effect/unstable/http/FetchHttpClient";
|
|
5
3
|
import * as Socket from "effect/unstable/socket/Socket";
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
4
|
+
import { Command } from "../Build/Command.ts";
|
|
5
|
+
import * as Build from "../Build/index.ts";
|
|
6
|
+
import * as Provider from "../Provider.ts";
|
|
7
|
+
import { Random, RandomProvider } from "../Random.ts";
|
|
8
8
|
import * as Account from "./Account.ts";
|
|
9
|
-
import
|
|
9
|
+
import * as Containers from "./Container/index.ts";
|
|
10
10
|
import * as D1 from "./D1/index.ts";
|
|
11
11
|
import * as KV from "./KV/index.ts";
|
|
12
12
|
import * as R2 from "./R2/index.ts";
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
import
|
|
13
|
+
import * as Assets from "./Workers/Assets.ts";
|
|
14
|
+
import * as Workers from "./Workers/index.ts";
|
|
15
|
+
import * as Workflows from "./Workers/Workflow.ts";
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
export { Credentials } from "@distilled.cloud/cloudflare/Credentials";
|
|
18
18
|
|
|
19
|
-
export
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
export class Providers extends Provider.ProviderCollection<Providers>()(
|
|
20
|
+
"Cloudflare",
|
|
21
|
+
) {}
|
|
22
|
+
|
|
23
|
+
export type ProviderRequirements = Layer.Services<ReturnType<typeof providers>>;
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Cloudflare providers, bindings, and credentials for Worker-based stacks.
|
|
27
27
|
*/
|
|
28
|
-
export const providers
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
28
|
+
export const providers = () =>
|
|
29
|
+
Layer.effect(
|
|
30
|
+
Providers,
|
|
31
|
+
Provider.collection([
|
|
32
|
+
Command,
|
|
33
|
+
Containers.Container,
|
|
34
|
+
D1.D1ConnectionPolicy,
|
|
35
|
+
D1.D1Database,
|
|
36
|
+
KV.KVNamespace,
|
|
37
|
+
KV.KVNamespaceBindingPolicy,
|
|
38
|
+
R2.R2Bucket,
|
|
39
|
+
R2.R2BucketBindingPolicy,
|
|
40
|
+
Random,
|
|
41
|
+
Workers.BindWorkerPolicy,
|
|
42
|
+
Workers.FetchPolicy,
|
|
43
|
+
Workers.Worker,
|
|
44
|
+
Workflows.WorkflowResource,
|
|
45
|
+
]),
|
|
46
|
+
).pipe(
|
|
47
|
+
Layer.provide(
|
|
48
|
+
Layer.mergeAll(
|
|
49
|
+
Containers.ContainerProvider(),
|
|
50
|
+
D1.D1ConnectionPolicyLive,
|
|
51
|
+
D1.DatabaseProvider(),
|
|
52
|
+
KV.KVNamespaceBindingPolicyLive,
|
|
53
|
+
KV.KVNamespaceProvider(),
|
|
54
|
+
R2.R2BucketBindingPolicyLive,
|
|
55
|
+
R2.R2BucketProvider(),
|
|
56
|
+
Workers.BindWorkerPolicyLive,
|
|
57
|
+
Workers.FetchPolicyLive,
|
|
58
|
+
Workers.WorkerProvider(),
|
|
59
|
+
Workflows.WorkflowProvider(),
|
|
60
|
+
),
|
|
61
|
+
),
|
|
62
|
+
Layer.provideMerge(
|
|
63
|
+
Layer.mergeAll(
|
|
64
|
+
Assets.AssetsProvider(),
|
|
65
|
+
Build.CommandProvider(),
|
|
66
|
+
RandomProvider(),
|
|
67
|
+
),
|
|
68
|
+
),
|
|
69
|
+
Layer.provideMerge(
|
|
70
|
+
Layer.mergeAll(
|
|
71
|
+
Account.fromStageConfig(),
|
|
72
|
+
Auth.fromEnv(),
|
|
73
|
+
Socket.layerWebSocketConstructorGlobal,
|
|
74
|
+
),
|
|
75
|
+
),
|
|
37
76
|
Layer.orDie,
|
|
38
77
|
);
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Cloudflare account credentials and auth context.
|
|
42
|
-
*/
|
|
43
|
-
export const credentials = () =>
|
|
44
|
-
Layer.mergeAll(
|
|
45
|
-
Account.fromStageConfig(),
|
|
46
|
-
Layer.provideMerge(Auth.fromEnv(), FetchHttpClient.layer),
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* All Cloudflare resource providers.
|
|
51
|
-
*/
|
|
52
|
-
export const resources = () =>
|
|
53
|
-
Layer.mergeAll(
|
|
54
|
-
CommandProvider(),
|
|
55
|
-
RandomProvider(),
|
|
56
|
-
ContainerProvider(),
|
|
57
|
-
WorkerProvider(),
|
|
58
|
-
WorkflowProvider(),
|
|
59
|
-
D1.DatabaseProvider(),
|
|
60
|
-
KV.NamespaceProvider(),
|
|
61
|
-
R2.R2BucketProvider(),
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* All Cloudflare binding policies.
|
|
66
|
-
*/
|
|
67
|
-
export const bindings = () =>
|
|
68
|
-
Layer.mergeAll(
|
|
69
|
-
D1.D1ConnectionPolicyLive,
|
|
70
|
-
R2.R2BucketBindingPolicyLive,
|
|
71
|
-
KV.KVNamespaceBindingPolicyLive,
|
|
72
|
-
);
|
|
73
|
-
|
|
74
|
-
const utils = () =>
|
|
75
|
-
Layer.mergeAll(AssetsProvider(), Socket.layerWebSocketConstructorGlobal);
|
|
@@ -6,6 +6,7 @@ import { createPhysicalName } from "../../PhysicalName.ts";
|
|
|
6
6
|
import * as Provider from "../../Provider.ts";
|
|
7
7
|
import { Resource } from "../../Resource.ts";
|
|
8
8
|
import { Account } from "../Account.ts";
|
|
9
|
+
import type { Providers } from "../Providers.ts";
|
|
9
10
|
import { R2BucketBinding } from "./R2BucketBinding.ts";
|
|
10
11
|
|
|
11
12
|
export type R2BucketName = string;
|
|
@@ -41,9 +42,54 @@ export type R2Bucket = Resource<
|
|
|
41
42
|
jurisdiction: R2Bucket.Jurisdiction;
|
|
42
43
|
location: R2Bucket.Location | undefined;
|
|
43
44
|
accountId: string;
|
|
44
|
-
}
|
|
45
|
+
},
|
|
46
|
+
never,
|
|
47
|
+
Providers
|
|
45
48
|
>;
|
|
46
49
|
|
|
50
|
+
/**
|
|
51
|
+
* A Cloudflare R2 object storage bucket with S3-compatible API.
|
|
52
|
+
*
|
|
53
|
+
* R2 provides zero-egress-fee object storage. Create a bucket as a resource,
|
|
54
|
+
* then bind it to a Worker to read and write objects at runtime.
|
|
55
|
+
*
|
|
56
|
+
* @section Creating a Bucket
|
|
57
|
+
* @example Basic R2 bucket
|
|
58
|
+
* ```typescript
|
|
59
|
+
* const bucket = yield* Cloudflare.R2Bucket("MyBucket");
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
* @example Bucket with location hint
|
|
63
|
+
* ```typescript
|
|
64
|
+
* const bucket = yield* Cloudflare.R2Bucket("MyBucket", {
|
|
65
|
+
* locationHint: "wnam",
|
|
66
|
+
* });
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* @section Binding to a Worker
|
|
70
|
+
* @example Reading and writing objects
|
|
71
|
+
* ```typescript
|
|
72
|
+
* const bucket = yield* Cloudflare.R2Bucket.bind(MyBucket);
|
|
73
|
+
*
|
|
74
|
+
* // Write an object
|
|
75
|
+
* yield* bucket.put("hello.txt", "Hello, World!");
|
|
76
|
+
*
|
|
77
|
+
* // Read an object
|
|
78
|
+
* const object = yield* bucket.get("hello.txt");
|
|
79
|
+
* if (object) {
|
|
80
|
+
* const text = yield* object.text();
|
|
81
|
+
* }
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* @example Streaming upload with content length
|
|
85
|
+
* ```typescript
|
|
86
|
+
* const bucket = yield* Cloudflare.R2Bucket.bind(MyBucket);
|
|
87
|
+
*
|
|
88
|
+
* yield* bucket.put("upload.bin", request.stream, {
|
|
89
|
+
* contentLength: Number(request.headers["content-length"] ?? 0),
|
|
90
|
+
* });
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
47
93
|
export const R2Bucket = Resource<R2Bucket>("Cloudflare.R2Bucket")({
|
|
48
94
|
bind: R2BucketBinding.bind,
|
|
49
95
|
});
|
|
@@ -142,7 +142,7 @@ export class R2BucketBinding extends Binding.Service<
|
|
|
142
142
|
export const R2BucketBindingLive = Layer.effect(
|
|
143
143
|
R2BucketBinding,
|
|
144
144
|
Effect.gen(function* () {
|
|
145
|
-
const bind = yield*
|
|
145
|
+
const bind = yield* R2BucketBindingPolicy;
|
|
146
146
|
|
|
147
147
|
return Effect.fn(function* (bucket: R2Bucket) {
|
|
148
148
|
yield* bind(bucket);
|
|
@@ -306,37 +306,32 @@ export const R2BucketBindingLive = Layer.effect(
|
|
|
306
306
|
}),
|
|
307
307
|
);
|
|
308
308
|
|
|
309
|
-
export class
|
|
310
|
-
|
|
309
|
+
export class R2BucketBindingPolicy extends Binding.Policy<
|
|
310
|
+
R2BucketBindingPolicy,
|
|
311
311
|
(bucket: R2Bucket) => Effect.Effect<void>
|
|
312
312
|
>()("Cloudflare.R2Bucket") {}
|
|
313
313
|
|
|
314
|
-
export const R2BucketBindingPolicyLive =
|
|
315
|
-
(
|
|
316
|
-
)
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
name: bucket.LogicalId,
|
|
328
|
-
bucketName: bucket.bucketName,
|
|
329
|
-
jurisdiction: bucket.jurisdiction.pipe(
|
|
330
|
-
Output.map((jurisdiction) =>
|
|
331
|
-
jurisdiction === "default" ? undefined : jurisdiction,
|
|
314
|
+
export const R2BucketBindingPolicyLive = R2BucketBindingPolicy.layer.succeed(
|
|
315
|
+
Effect.fnUntraced(function* (host: ResourceLike, bucket: R2Bucket) {
|
|
316
|
+
if (isWorker(host)) {
|
|
317
|
+
yield* host.bind`${bucket}`({
|
|
318
|
+
bindings: [
|
|
319
|
+
{
|
|
320
|
+
type: "r2_bucket",
|
|
321
|
+
name: bucket.LogicalId,
|
|
322
|
+
bucketName: bucket.bucketName,
|
|
323
|
+
jurisdiction: bucket.jurisdiction.pipe(
|
|
324
|
+
Output.map((jurisdiction) =>
|
|
325
|
+
jurisdiction === "default" ? undefined : jurisdiction,
|
|
326
|
+
),
|
|
332
327
|
),
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
}
|
|
342
|
-
|
|
328
|
+
},
|
|
329
|
+
],
|
|
330
|
+
});
|
|
331
|
+
} else {
|
|
332
|
+
return yield* Effect.die(
|
|
333
|
+
new Error(`BucketBinding does not support runtime '${host.Type}'`),
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
}),
|
|
337
|
+
);
|
|
@@ -19,6 +19,63 @@ export interface StaticSiteProps
|
|
|
19
19
|
|
|
20
20
|
export type StaticSite = ReturnType<typeof StaticSite>;
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
* A Cloudflare Worker that serves static assets built by a shell command.
|
|
24
|
+
*
|
|
25
|
+
* `StaticSite` runs a build command (e.g. `npm run build`), content-hashes
|
|
26
|
+
* the output directory, and deploys the result as a Cloudflare Worker with
|
|
27
|
+
* static assets. Use this when your site has its own build step that
|
|
28
|
+
* produces a directory of files — Hugo, Zola, Eleventy, or any custom
|
|
29
|
+
* pipeline.
|
|
30
|
+
*
|
|
31
|
+
* For Vite-based projects, prefer `Cloudflare.Vite` which handles
|
|
32
|
+
* building automatically.
|
|
33
|
+
*
|
|
34
|
+
* @resource
|
|
35
|
+
*
|
|
36
|
+
* @section Basic Usage
|
|
37
|
+
* Point `command` at your build script and `outdir` at where it writes
|
|
38
|
+
* output. Alchemy runs the command, hashes the output, and deploys it.
|
|
39
|
+
*
|
|
40
|
+
* @example Deploying a Hugo site
|
|
41
|
+
* ```typescript
|
|
42
|
+
* const site = yield* Cloudflare.StaticSite("Blog", {
|
|
43
|
+
* command: "hugo --minify",
|
|
44
|
+
* outdir: "public",
|
|
45
|
+
* });
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @section Asset Configuration
|
|
49
|
+
* Use `assetsConfig` to control how Cloudflare handles routing for
|
|
50
|
+
* your static files — HTML handling, not-found behavior, etc.
|
|
51
|
+
*
|
|
52
|
+
* @example SPA-style routing
|
|
53
|
+
* ```typescript
|
|
54
|
+
* const site = yield* Cloudflare.StaticSite("App", {
|
|
55
|
+
* command: "npm run build",
|
|
56
|
+
* outdir: "dist",
|
|
57
|
+
* assetsConfig: {
|
|
58
|
+
* htmlHandling: "auto-trailing-slash",
|
|
59
|
+
* notFoundHandling: "single-page-application",
|
|
60
|
+
* },
|
|
61
|
+
* });
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* @section Custom Rebuild Scope
|
|
65
|
+
* By default, all non-gitignored files are hashed to decide whether
|
|
66
|
+
* the build should re-run. Use `memo` to narrow the scope.
|
|
67
|
+
*
|
|
68
|
+
* @example Narrowing the memo scope
|
|
69
|
+
* ```typescript
|
|
70
|
+
* const site = yield* Cloudflare.StaticSite("Docs", {
|
|
71
|
+
* command: "npm run build",
|
|
72
|
+
* outdir: "dist",
|
|
73
|
+
* memo: {
|
|
74
|
+
* include: ["content/**", "templates/**", "config.toml"],
|
|
75
|
+
* },
|
|
76
|
+
* });
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
22
79
|
export const StaticSite = (id: string, props: InputProps<StaticSiteProps>) =>
|
|
23
80
|
Effect.gen(function* () {
|
|
24
81
|
// TODO(sam): local dev/hmr support?
|
|
@@ -21,22 +21,31 @@ export interface ViteProps extends Omit<WorkerProps, "vite" | "main"> {
|
|
|
21
21
|
/**
|
|
22
22
|
* A Cloudflare Worker deployed from a Vite project.
|
|
23
23
|
*
|
|
24
|
-
* `Vite` uses the Cloudflare Vite plugin to build both the server bundle
|
|
25
|
-
* client assets in a single `vite build` invocation — no manual
|
|
26
|
-
* entrypoint, build command, output directory, or Wrangler
|
|
27
|
-
* required.
|
|
24
|
+
* `Vite` uses the Cloudflare Vite plugin to build both the server bundle
|
|
25
|
+
* and client assets in a single `vite build` invocation — no manual
|
|
26
|
+
* `main` entrypoint, build command, output directory, or Wrangler
|
|
27
|
+
* configuration required.
|
|
28
28
|
*
|
|
29
29
|
* Input files are content-hashed (respecting `.gitignore` by default) so
|
|
30
30
|
* unchanged projects skip the build and deploy entirely.
|
|
31
31
|
*
|
|
32
|
+
* @resource
|
|
33
|
+
*
|
|
32
34
|
* @section Deploying a Static Site
|
|
33
|
-
*
|
|
35
|
+
* For a pure static site (no SSR), a single call is all you need.
|
|
36
|
+
* Vite builds the project and Alchemy deploys the output as a
|
|
37
|
+
* Cloudflare Worker with static assets.
|
|
38
|
+
*
|
|
39
|
+
* @example Static Vite site
|
|
34
40
|
* ```typescript
|
|
35
41
|
* const site = yield* Cloudflare.Vite("Website");
|
|
36
42
|
* ```
|
|
37
43
|
*
|
|
38
|
-
* @section
|
|
39
|
-
*
|
|
44
|
+
* @section SSR Frameworks
|
|
45
|
+
* For SSR frameworks like TanStack Start, SolidStart, or Nuxt, enable
|
|
46
|
+
* `nodejs_compat` so the server bundle can use Node.js APIs.
|
|
47
|
+
*
|
|
48
|
+
* @example TanStack Start
|
|
40
49
|
* ```typescript
|
|
41
50
|
* const app = yield* Cloudflare.Vite("TanStackStart", {
|
|
42
51
|
* compatibility: {
|
|
@@ -45,8 +54,43 @@ export interface ViteProps extends Omit<WorkerProps, "vite" | "main"> {
|
|
|
45
54
|
* });
|
|
46
55
|
* ```
|
|
47
56
|
*
|
|
57
|
+
* @example SolidStart with worker-first routing
|
|
58
|
+
* ```typescript
|
|
59
|
+
* const app = yield* Cloudflare.Vite("SolidStart", {
|
|
60
|
+
* compatibility: {
|
|
61
|
+
* flags: ["nodejs_compat"],
|
|
62
|
+
* },
|
|
63
|
+
* assets: {
|
|
64
|
+
* config: { runWorkerFirst: true },
|
|
65
|
+
* },
|
|
66
|
+
* });
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* @section Single-Page Applications
|
|
70
|
+
* For SPAs (React, Vue, etc.), configure asset handling so all
|
|
71
|
+
* routes fall back to `index.html`.
|
|
72
|
+
*
|
|
73
|
+
* @example Vue SPA
|
|
74
|
+
* ```typescript
|
|
75
|
+
* const app = yield* Cloudflare.Vite("Vue", {
|
|
76
|
+
* compatibility: {
|
|
77
|
+
* flags: ["nodejs_compat"],
|
|
78
|
+
* },
|
|
79
|
+
* assets: {
|
|
80
|
+
* config: {
|
|
81
|
+
* htmlHandling: "auto-trailing-slash",
|
|
82
|
+
* notFoundHandling: "single-page-application",
|
|
83
|
+
* },
|
|
84
|
+
* },
|
|
85
|
+
* });
|
|
86
|
+
* ```
|
|
87
|
+
*
|
|
48
88
|
* @section Custom Rebuild Scope
|
|
49
|
-
*
|
|
89
|
+
* By default, every non-gitignored file is hashed to decide whether
|
|
90
|
+
* a rebuild is needed. Use `memo` to narrow the scope when your
|
|
91
|
+
* project has large directories that don't affect the build output.
|
|
92
|
+
*
|
|
93
|
+
* @example Narrowing the memo scope
|
|
50
94
|
* ```typescript
|
|
51
95
|
* const site = yield* Cloudflare.Vite("Docs", {
|
|
52
96
|
* memo: {
|