@lafken/bucket
v0.12.12
Published
Define S3 buckets using TypeScript decorators - automatic infrastructure generation with Lafken
Maintainers
Readme
@lafken/bucket
Define and manage Amazon S3 buckets using TypeScript decorators. @lafken/bucket lets you declare bucket configuration — versioning, ACL, lifecycle rules, transfer acceleration, and EventBridge integration — directly on a class. A built-in repository provides type-safe S3 operations at runtime.
Installation
npm install @lafken/bucketGetting Started
Define a bucket class with @Bucket, register it in the BucketResolver, and use createRepository to interact with it:
import { createApp } from '@lafken/main';
import { BucketResolver } from '@lafken/bucket/resolver';
import { Bucket } from '@lafken/bucket/main';
import { createRepository } from '@lafken/bucket/service';
// 1. Define the bucket
@Bucket({ name: 'project-assets', versioned: true })
export class AssetsBucket {}
// 2. Create a repository for runtime operations
export const assetsRepository = createRepository(AssetsBucket);
// 3. Register the bucket in the resolver
createApp({
name: 'my-app',
resolvers: [new BucketResolver([AssetsBucket])],
});Features
Defining a Bucket
Use the @Bucket decorator on a class to declare an S3 bucket. If name is omitted, the class name is used:
import { Bucket } from '@lafken/bucket/main';
@Bucket({
name: 'upload-storage',
versioned: true,
acl: 'private',
forceDestroy: true,
tags: { environment: 'production' },
})
export class UploadBucket {}Bucket Options
| Option | Type | Default | Description |
| --------------------- | --------------------------------------------- | ------------ | --------------------------------------------------------- |
| name | string | class name | S3 bucket name |
| versioned | boolean | false | Enable object versioning |
| acl | 'private' \| 'public-read' \| 'public-read-write' | — | Access control list |
| forceDestroy | boolean | false | Delete all objects when the bucket is destroyed |
| eventBridgeEnabled | boolean | false | Send bucket events to Amazon EventBridge |
| transferAcceleration| boolean | false | Enable CloudFront-based transfer acceleration |
| tracing | boolean | false | Enable AWS X-Ray tracing on repository operations |
| tags | Record<string, string> | — | Tags applied to the bucket resource |
| lifeCycleRules | Record<string, KeyLifeCycleRule> | — | Object lifecycle management rules |
Lifecycle Rules
Define rules to automatically transition or expire objects based on age and size. Each key in lifeCycleRules represents an object prefix filter:
@Bucket({
name: 'log-archive',
lifeCycleRules: {
'logs/': {
condition: {
objectSizeGreaterThan: 1024,
},
expiration: {
days: 90,
},
transitions: [
{ days: 30, storage: 'standard_ia' },
{ days: 60, storage: 'glacier' },
],
},
'tmp/': {
expiration: {
days: 7,
},
},
},
})
export class LogBucket {}Expiration Options
| Option | Type | Description |
| ---------------------------- | --------- | ------------------------------------------------- |
| days | number | Delete objects after this many days |
| date | Date | Delete objects after a specific date |
| expiredObjectDeleteMarker | boolean | Remove expired object delete markers |
[!NOTE] Only one expiration option can be set per rule.
Condition Options
| Option | Type | Description |
| ------------------------ | -------- | --------------------------------------------- |
| objectSizeGreaterThan | number | Apply rule only to objects larger than (bytes) |
| objectSizeLessThan | number | Apply rule only to objects smaller than (bytes)|
Available Storage Classes
| Storage Class | Description |
| ---------------------- | ------------------------------------------------ |
| standard_ia | Infrequent access, lower cost |
| onezone_ia | Single-AZ infrequent access |
| intelligent_tiering | Automatic cost optimization by access patterns |
| glacier | Long-term archive (minutes to hours retrieval) |
| glacier_ir | Instant retrieval archive |
| deep_archive | Lowest cost (12+ hours retrieval) |
EventBridge Integration
Enable eventBridgeEnabled to send bucket events (object created, deleted, etc.) to Amazon EventBridge. Combine with @lafken/event to process these events:
@Bucket({
name: 'document-uploads',
eventBridgeEnabled: true,
})
export class DocumentBucket {}Repository
createRepository provides a type-safe API for S3 operations at runtime. The bucket name is automatically injected into every command:
import { createRepository } from '@lafken/bucket/service';
export const docsRepository = createRepository(DocumentBucket);Put Object
Upload an object to the bucket:
await docsRepository.putObject({
Key: 'reports/monthly.json',
Body: JSON.stringify({ revenue: 50000 }),
ContentType: 'application/json',
});Get Object
Retrieve an object from the bucket:
const response = await docsRepository.getObject({
Key: 'reports/monthly.json',
});
const body = await response.Body?.transformToString();Delete Object
Remove an object from the bucket:
await docsRepository.deleteObject({
Key: 'reports/old-report.json',
});Copy Object
Copy an object within or across buckets:
await docsRepository.copyObject({
Key: 'archive/monthly.json',
CopySource: 'document-uploads/reports/monthly.json',
});Move Object
Copy an object to a new key and delete the original in a single operation:
await docsRepository.moveObject({
Key: 'processed/monthly.json',
CopySource: 'document-uploads/reports/monthly.json',
});List Objects
List all objects matching a prefix. Pagination is handled automatically:
const result = await docsRepository.listObjects({
Prefix: 'reports/',
});
for (const object of result.Contents) {
console.log(object.Key, object.Size);
}X-Ray Tracing
Enable tracing in the @Bucket decorator to instrument all repository operations with AWS X-Ray:
@Bucket({
name: 'traced-bucket',
tracing: true,
})
export class TracedBucket {}Global Configuration
The BucketResolver accepts a second argument with global defaults applied to all buckets. Per-bucket options override global ones:
new BucketResolver(
[AssetsBucket, LogBucket],
{
forceDestroy: true,
versioned: true,
tags: { team: 'platform' },
}
);Extending Buckets
Apply advanced CDKTN configuration to a bucket using the extends callback:
new BucketResolver([
{
bucket: AssetsBucket,
extends: ({ bucket, scope }) => {
// Add CORS rules, policies, or any CDKTN construct
},
},
]);