Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 99 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,107 @@ alchemy-effect/src/{cloud}/{service}/{resource}.provider.ts # resource provider
alchemy-effect/src/{cloud}/{service}/{resource}.{capability}.ts
# test files
alchemy-effect/test/{cloud}/{service}/{resource}.provider.test.ts
# docs
alchemy-effect/docs/{cloud}/{service}/index.md # overview and references to each resource in the service
alchemy-effect/docs/{cloud}/{service}/{resource}.md # documents the usage patterns of a resource. This is not an API reference, it is a use-case oriented guide that focuses on providing snippets of common patterns and best practices. It can link out to the API reference for more detailed information.
alchemy-effect/docs/api/{cloud}/{service}/{resource}.md # API reference for the resource generated from comments in the source code (do not manually edit this file).
# docs (auto-generated from source code - do not manually edit)
alchemy-effect/docs/{cloud}/{service}/{resource}.md # API reference for the resource, auto-generated from JSDoc comments
```

# Documentation Generation

**Source of truth:** The source code is the single source of truth for all API documentation. JSDoc comments in the source files are extracted and used to generate markdown documentation.

**How to generate docs:**

```sh
bun run generate:docs
# or directly:
bun scripts/generate-docs.ts
```

This script:
1. Discovers all resource files in `alchemy-effect/src/{cloud}/{service}/`
2. Parses TypeScript using the TypeScript Compiler API
3. Extracts JSDoc comments from Props and Attrs interfaces
4. Extracts capabilities and event sources for each resource
5. Generates one markdown file per resource at `alchemy-effect/docs/{cloud}/{service}/{resource}.md`

**Writing good documentation:** When adding or updating a resource, ensure all Props and Attrs have JSDoc comments:

```typescript
export interface BucketProps {
/**
* Name of the bucket. If omitted, a unique name will be generated.
* Must be lowercase and between 3-63 characters.
*/
bucketName?: string;

/**
* Whether to delete all objects when the bucket is destroyed.
* @default false
*/
forceDestroy?: boolean;
}
```

The `@default` tag is used to document default values and will appear in the generated documentation.

### Examples and Sections (IMPORTANT)

**Examples are critical for documentation.** Every resource should have examples demonstrating common use cases. Use `@section` and `@example` JSDoc tags on the main Resource export to organize examples into a navigable table of contents.

**Format:**
- `@section <Section Title>` - Creates a heading in the Examples section and adds an entry to the Quick Reference table of contents
- `@example <Example Title>` - Creates a subheading for a specific code example (must follow a `@section`)
- Code blocks inside examples use standard markdown fenced code blocks (``` ```)

**Example:**

```typescript
/**
* An S3 bucket for storing objects.
*
* @section Creating a Bucket
* @example Basic Bucket
* ```typescript
* const bucket = yield* Bucket("my-bucket", {});
* ```
*
* @example Bucket with Force Destroy
* ```typescript
* const bucket = yield* Bucket("my-bucket", {
* forceDestroy: true,
* });
* ```
*
* @section Reading Objects
* @example Get Object from Bucket
* ```typescript
* const response = yield* getObject(bucket, { key: "my-key" });
* const body = yield* Effect.tryPromise(() => response.Body?.transformToString());
* ```
*
* @section Writing Objects
* @example Put Object to Bucket
* ```typescript
* yield* putObject(bucket, {
* key: "hello.txt",
* body: "Hello, World!",
* contentType: "text/plain",
* });
* ```
*/
export const Bucket = Resource<...>("AWS.S3.Bucket");
```

This generates:
1. A "Quick Reference" section with links to each `@section`
2. An "Examples" section with organized code examples under each section heading

**Best practices for examples:**
- Start with the simplest use case and progress to more complex ones
- Include examples for all major capabilities (GetObject, PutObject, etc.)
- Show real-world patterns like error handling, combining with other resources
- Use descriptive titles that explain what the example demonstrates

# Workflow

Development of Alchemy-Effect Resources is heavily pattern based. Each Service has many Resources that each have 0 oor more Capabilities and Event Sources. When working on a new Service, the following steps should be followed.
Expand Down
12 changes: 12 additions & 0 deletions alchemy-effect/docs/aws/dynamodb/secondary-index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# SecondaryIndex

**Type:** `AWS.DynamoDB.SecondaryIndex`

## Props

| Property | Type | Required | Default | Description |
|----------|------|----------|---------|-------------|
| table | `new () => Source` | Yes | - | - |
| indexName | `string` | No | - | - |
| partitionKey | `PartitionKey` | Yes | - | - |
| sortKey | `SortKey` | No | - | - |
41 changes: 41 additions & 0 deletions alchemy-effect/docs/aws/dynamodb/table.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Table

**Type:** `AWS.DynamoDB.Table`

## Props

| Property | Type | Required | Default | Description |
|----------|------|----------|---------|-------------|
| items | `type<Items>` | Yes | - | - |
| attributes | `Attributes` | Yes | - | - |
| partitionKey | `PartitionKey` | Yes | - | - |
| sortKey | `SortKey` | No | - | - |
| tableName | `string \| undefined` | No | - | - |
| billingMode | `DynamoDB.BillingMode` | No | - | - |
| deletionProtectionEnabled | `boolean` | No | - | - |
| onDemandThroughput | `DynamoDB.OnDemandThroughput` | No | - | - |
| provisionedThroughput | `DynamoDB.ProvisionedThroughput` | No | - | - |
| sseSpecification | `DynamoDB.SSESpecification` | No | - | - |
| timeToLiveSpecification | `DynamoDB.TimeToLiveSpecification` | No | - | - |
| warmThroughput | `DynamoDB.WarmThroughput` | No | - | - |
| tableClass | `DynamoDB.TableClass` | No | - | - |

## Attributes

| Attribute | Type | Description |
|-----------|------|-------------|
| tableName | `Props["tableName"] extends string ? Props["tableName"] : string` | - |
| tableId | `string` | - |
| tableArn | ``arn:aws:dynamodb:${RegionID}:${AccountID}:table/${this["tableName"]}`` | - |
| partitionKey | `Props["partitionKey"]` | - |
| sortKey | `Props["sortKey"]` | - |

## Capabilities

### GetItem

**Type:** `AWS.DynamoDB.GetItem`

#### Functions

- `getItem(...)`
18 changes: 18 additions & 0 deletions alchemy-effect/docs/aws/ec2/egress-only-internet-gateway.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# EgressOnlyInternetGateway

**Type:** `AWS.EC2.EgressOnlyInternetGateway`

## Props

| Property | Type | Required | Default | Description |
|----------|------|----------|---------|-------------|
| vpcId | `Input<VpcId>` | Yes | - | The VPC for which to create the egress-only internet gateway. |
| tags | `Record<string, Input<string>>` | No | - | Tags to assign to the egress-only internet gateway. |

## Attributes

| Attribute | Type | Description |
|-----------|------|-------------|
| egressOnlyInternetGatewayId | `EgressOnlyInternetGatewayId` | The ID of the egress-only internet gateway. |
| egressOnlyInternetGatewayArn | `EgressOnlyInternetGatewayArn< this["egressOnlyInternetGatewayId"] >` | The Amazon Resource Name (ARN) of the egress-only internet gateway. |
| attachments | `Array<{ /** * The current state of the attachment. */ state: "attaching" \| "attached" \| "detaching" \| "detached"; /** * The ID of the VPC. */ vpcId: Props["vpcId"]; }>` | Information about the attachment of the egress-only internet gateway. |
27 changes: 27 additions & 0 deletions alchemy-effect/docs/aws/ec2/eip.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Eip

**Type:** `AWS.EC2.EIP`

## Props

| Property | Type | Required | Default | Description |
|----------|------|----------|---------|-------------|
| domain | `"vpc" \| "standard"` | No | "vpc" | Indicates whether the Elastic IP address is for use with instances in a VPC or EC2-Classic. |
| publicIpv4Pool | `Input<string>` | No | - | The ID of an address pool that you own. Use this parameter to let Amazon EC2 select an address from the address pool. |
| networkBorderGroup | `Input<string>` | No | - | A unique set of Availability Zones, Local Zones, or Wavelength Zones from which AWS advertises IP addresses. |
| customerOwnedIpv4Pool | `Input<string>` | No | - | The ID of a customer-owned address pool. Use this parameter to let Amazon EC2 select an address from the address pool. |
| tags | `Record<string, Input<string>>` | No | - | Tags to assign to the Elastic IP. These will be merged with alchemy auto-tags. |

## Attributes

| Attribute | Type | Description |
|-----------|------|-------------|
| allocationId | `AllocationId` | The allocation ID for the Elastic IP address. |
| eipArn | ``arn:aws:ec2:${RegionID}:${AccountID}:elastic-ip/${this["allocationId"]}`` | The Amazon Resource Name (ARN) of the Elastic IP. |
| publicIp | `string` | The Elastic IP address. |
| publicIpv4Pool | `string` | The ID of an address pool. |
| domain | `"vpc" \| "standard"` | Indicates whether the Elastic IP address is for use with instances in a VPC or EC2-Classic. |
| networkBorderGroup | `string` | The network border group. |
| customerOwnedIp | `string` | The customer-owned IP address. |
| customerOwnedIpv4Pool | `string` | The ID of the customer-owned address pool. |
| carrierIp | `string` | The carrier IP address associated with the network interface. |
20 changes: 20 additions & 0 deletions alchemy-effect/docs/aws/ec2/internet-gateway.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# InternetGateway

**Type:** `AWS.EC2.InternetGateway`

## Props

| Property | Type | Required | Default | Description |
|----------|------|----------|---------|-------------|
| vpcId | `Input<VpcId>` | No | - | The VPC to attach the internet gateway to. If provided, the internet gateway will be automatically attached to the VPC. Optional - you can create an unattached internet gateway and attach it later. |
| tags | `Record<string, Input<string>>` | No | - | Tags to assign to the internet gateway. These will be merged with alchemy auto-tags (alchemy::app, alchemy::stage, alchemy::id). |

## Attributes

| Attribute | Type | Description |
|-----------|------|-------------|
| internetGatewayId | `InternetGatewayId` | The ID of the internet gateway. |
| internetGatewayArn | ``arn:aws:ec2:${RegionID}:${AccountID}:internet-gateway/${this["internetGatewayId"]}`` | The Amazon Resource Name (ARN) of the internet gateway. |
| vpcId | `Props["vpcId"]` | The ID of the VPC the internet gateway is attached to (if any). |
| ownerId | `string` | The ID of the AWS account that owns the internet gateway. |
| attachments | `Array<{ /** * The current state of the attachment. */ state: "attaching" \| "available" \| "detaching" \| "detached"; /** * The ID of the VPC. */ vpcId: string; }>` | The attachments for the internet gateway. |
34 changes: 34 additions & 0 deletions alchemy-effect/docs/aws/ec2/nat-gateway.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# NatGateway

**Type:** `AWS.EC2.NatGateway`

## Props

| Property | Type | Required | Default | Description |
|----------|------|----------|---------|-------------|
| subnetId | `Input<SubnetId>` | Yes | - | The subnet in which to create the NAT gateway. For public NAT gateways, this must be a public subnet. |
| allocationId | `Input<AllocationId>` | No | - | The allocation ID of the Elastic IP address for the gateway. Required for public NAT gateways. |
| connectivityType | `EC2.ConnectivityType` | No | "public" | Indicates whether the NAT gateway supports public or private connectivity. |
| privateIpAddress | `string` | No | - | The private IPv4 address to assign to the NAT gateway. If you don't provide an address, a private IPv4 address will be automatically assigned. |
| secondaryAllocationIds | `Input<AllocationId>[]` | No | - | Secondary allocation IDs for additional private IP addresses. Only valid for private NAT gateways. |
| secondaryPrivateIpAddresses | `string[]` | No | - | Secondary private IPv4 addresses. Only valid for private NAT gateways. |
| secondaryPrivateIpAddressCount | `number` | No | - | The number of secondary private IPv4 addresses to assign. Only valid for private NAT gateways. |
| tags | `Record<string, Input<string>>` | No | - | Tags to assign to the NAT gateway. |

## Attributes

| Attribute | Type | Description |
|-----------|------|-------------|
| natGatewayId | `NatGatewayId` | The ID of the NAT gateway. |
| natGatewayArn | ``arn:aws:ec2:${RegionID}:${AccountID}:natgateway/${this["natGatewayId"]}`` | The Amazon Resource Name (ARN) of the NAT gateway. |
| subnetId | `Props["subnetId"]` | The ID of the subnet in which the NAT gateway is located. |
| vpcId | `string` | The ID of the VPC in which the NAT gateway is located. |
| state | `EC2.NatGatewayState` | The current state of the NAT gateway. |
| connectivityType | `EC2.ConnectivityType` | The connectivity type of the NAT gateway. |
| publicIp | `string` | The Elastic IP address associated with the NAT gateway (for public NAT gateways). |
| privateIp | `string` | The private IP address associated with the NAT gateway. |
| natGatewayAddresses | `Array<{ allocationId?: string; networkInterfaceId?: string; privateIp?: string; publicIp?: string; associationId?: string; isPrimary?: boolean; failureMessage?: string; status?: EC2.NatGatewayAddressStatus; }>` | Information about the IP addresses and network interface associated with the NAT gateway. |
| failureCode | `string` | If the NAT gateway could not be created, specifies the error code for the failure. |
| failureMessage | `string` | If the NAT gateway could not be created, specifies the error message for the failure. |
| createTime | `string` | The date and time the NAT gateway was created. |
| deleteTime | `string` | The date and time the NAT gateway was deleted, if applicable. |
18 changes: 18 additions & 0 deletions alchemy-effect/docs/aws/ec2/network-acl-association.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# NetworkAclAssociation

**Type:** `AWS.EC2.NetworkAclAssociation`

## Props

| Property | Type | Required | Default | Description |
|----------|------|----------|---------|-------------|
| networkAclId | `Input<NetworkAclId>` | Yes | - | The ID of the new network ACL to associate with the subnet. |
| subnetId | `Input<SubnetId>` | Yes | - | The ID of the subnet to associate with the network ACL. |

## Attributes

| Attribute | Type | Description |
|-----------|------|-------------|
| associationId | `NetworkAclAssociationId` | The ID of the association between the network ACL and subnet. |
| networkAclId | `Props["networkAclId"]` | The ID of the network ACL. |
| subnetId | `Props["subnetId"]` | The ID of the subnet. |
31 changes: 31 additions & 0 deletions alchemy-effect/docs/aws/ec2/network-acl-entry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# NetworkAclEntry

**Type:** `AWS.EC2.NetworkAclEntry`

## Props

| Property | Type | Required | Default | Description |
|----------|------|----------|---------|-------------|
| networkAclId | `Input<NetworkAclId>` | Yes | - | The ID of the network ACL. |
| ruleNumber | `number` | Yes | - | The rule number for the entry (1-32766). Rules are evaluated in order from lowest to highest. |
| protocol | `string` | Yes | - | The protocol number. A value of "-1" means all protocols. Common values: 6 (TCP), 17 (UDP), 1 (ICMP) |
| ruleAction | `EC2.RuleAction` | Yes | - | Whether to allow or deny the traffic that matches the rule. |
| egress | `boolean` | No | false (ingress) | Whether this is an egress (outbound) rule. |
| cidrBlock | `string` | No | - | The IPv4 CIDR block. Either cidrBlock or ipv6CidrBlock must be specified. |
| ipv6CidrBlock | `string` | No | - | The IPv6 CIDR block. Either cidrBlock or ipv6CidrBlock must be specified. |
| icmpTypeCode | `{ /** * The ICMP code. Use -1 to specify all codes. */ code?: number; /** * The ICMP type. Use -1 to specify all types. */ type?: number; }` | No | - | ICMP type and code. Required if protocol is 1 (ICMP) or 58 (ICMPv6). |
| portRange | `{ /** * The first port in the range. */ from?: number; /** * The last port in the range. */ to?: number; }` | No | - | The port range for TCP/UDP protocols. |

## Attributes

| Attribute | Type | Description |
|-----------|------|-------------|
| networkAclId | `Props["networkAclId"]` | The ID of the network ACL. |
| ruleNumber | `Props["ruleNumber"]` | The rule number. |
| egress | `boolean` | Whether this is an egress rule. |
| protocol | `Props["protocol"]` | The protocol. |
| ruleAction | `Props["ruleAction"]` | The rule action (allow or deny). |
| cidrBlock | `Props["cidrBlock"]` | The IPv4 CIDR block. |
| ipv6CidrBlock | `Props["ipv6CidrBlock"]` | The IPv6 CIDR block. |
| icmpTypeCode | `Props["icmpTypeCode"]` | The ICMP type and code. |
| portRange | `Props["portRange"]` | The port range. |
22 changes: 22 additions & 0 deletions alchemy-effect/docs/aws/ec2/network-acl.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# NetworkAcl

**Type:** `AWS.EC2.NetworkAcl`

## Props

| Property | Type | Required | Default | Description |
|----------|------|----------|---------|-------------|
| vpcId | `Input<VpcId>` | Yes | - | The VPC to create the network ACL in. |
| tags | `Record<string, Input<string>>` | No | - | Tags to assign to the network ACL. |

## Attributes

| Attribute | Type | Description |
|-----------|------|-------------|
| networkAclId | `NetworkAclId` | The ID of the network ACL. |
| networkAclArn | `NetworkAclArn<this["networkAclId"]>` | The Amazon Resource Name (ARN) of the network ACL. |
| vpcId | `Props["vpcId"]` | The ID of the VPC for the network ACL. |
| isDefault | `boolean` | Whether this is the default network ACL for the VPC. |
| ownerId | `string` | The ID of the AWS account that owns the network ACL. |
| entries | `Array<{ ruleNumber: number; protocol: string; ruleAction: EC2.RuleAction; egress: boolean; cidrBlock?: string; ipv6CidrBlock?: string; icmpTypeCode?: { code?: number; type?: number; }; portRange?: { from?: number; to?: number; }; }>` | The entries (rules) in the network ACL. |
| associations | `Array<{ networkAclAssociationId: string; networkAclId: string; subnetId: string; }>` | The associations between the network ACL and subnets. |
21 changes: 21 additions & 0 deletions alchemy-effect/docs/aws/ec2/route-table-association.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# RouteTableAssociation

**Type:** `AWS.EC2.RouteTableAssociation`

## Props

| Property | Type | Required | Default | Description |
|----------|------|----------|---------|-------------|
| routeTableId | `Input<RouteTableId>` | Yes | - | The ID of the route table. Required. |
| subnetId | `Input<SubnetId>` | No | - | The ID of the subnet to associate with the route table. Either subnetId or gatewayId is required, but not both. |
| gatewayId | `Input<string>` | No | - | The ID of the gateway (internet gateway or virtual private gateway) to associate with the route table. Either subnetId or gatewayId is required, but not both. |

## Attributes

| Attribute | Type | Description |
|-----------|------|-------------|
| associationId | `RouteTableAssociationId` | The ID of the association. |
| routeTableId | `Props["routeTableId"]` | The ID of the route table. |
| subnetId | `Props["subnetId"]` | The ID of the subnet (if the association is with a subnet). |
| gatewayId | `Props["gatewayId"]` | The ID of the gateway (if the association is with a gateway). |
| associationState | `{ state: EC2.RouteTableAssociationStateCode; statusMessage?: string; }` | The state of the association. |
Loading
Loading