Skip to content

@mantleframework/aws

Type-safe AWS SDK v3 client factory and service wrappers with built-in retry, observability, and permission decorators.

Client Factory

Create AWS SDK clients with Lambda-optimized defaults. Clients are cached per Lambda container.

typescript
import {
  createS3Client,
  createSQSClient,
  createSNSClient,
  createEventBridgeClient,
  createLambdaClient,
  createDynamoDBClient,
  createDynamoDBDocumentClient,
  createApiGatewayClient,
  createCloudWatchClient,
} from '@mantleframework/aws'

S3

Operations

typescript
import { getObject, putObject, headObject, deleteObject, createUpload, abortMultipartUpload, exportToS3 } from '@mantleframework/aws'

const data = await getObject('my-bucket', 'path/to/file.json')
await putObject('my-bucket', 'path/to/output.json', JSON.stringify(data))
const metadata = await headObject('my-bucket', 'path/to/file.json')
await deleteObject('my-bucket', 'path/to/file.json')

createUpload(options)

Create a multipart upload. Returns the upload ID.

typescript
import { createUpload } from '@mantleframework/aws'
import type { CreateUploadOptions } from '@mantleframework/aws'

abortMultipartUpload(bucket, key, uploadId)

Abort an in-progress multipart upload.

exportToS3(options)

Write a JSON payload to S3 with a default CacheControl header. Designed for EventBridge export handlers.

typescript
import { exportToS3 } from '@mantleframework/aws'
import type { ExportToS3Options } from '@mantleframework/aws'

await exportToS3({
  bucket: 'my-bucket',
  key: 'exports/items.json',
  data: { generatedAt: new Date().toISOString(), items: [] },
})

S3Vendor

Static class with @RequiresS3 decorators for IAM permission extraction.

typescript
import { S3Vendor } from '@mantleframework/aws'

SQS

Operations

typescript
import { sendMessage, stringAttribute, numberAttribute } from '@mantleframework/aws'
import type { MessageAttributeValue } from '@mantleframework/aws'

await sendMessage('https://sqs.../my-queue', {
  action: 'processItem',
  itemId: '123',
}, {
  messageAttributes: {
    priority: stringAttribute('high'),
    retryCount: numberAttribute(0),
  },
})

SQSVendor

Static class with @RequiresSQS decorators.

SNS

Operations

typescript
import {
  publish,
  subscribe,
  unsubscribe,
  createPlatformEndpoint,
  deleteEndpoint,
  getEndpointAttributes,
  listSubscriptionsByTopic,
} from '@mantleframework/aws'

await publish('arn:aws:sns:...:my-topic', {
  event: 'user.created',
  userId: '123',
})

SNSVendor

Static class with @RequiresSNS decorators.

EventBridge

Operations

typescript
import { putEvents } from '@mantleframework/aws'
import type { PutEventsRequestEntry } from '@mantleframework/aws'

await putEvents([{
  Source: 'my-api',
  DetailType: 'UserCreated',
  Detail: JSON.stringify({ userId: '123' }),
}])

TIP

Prefer emitEvent() / emitEvents() from @mantleframework/core for most use cases -- they provide retry, fire-and-forget error handling, and consistent event structure. Use putEvents() directly only when you need full control over entries.

EventBridgeVendor

Static class with @RequiresEventBridge decorators.

Lambda

Operations

typescript
import { invoke, invokeAsync } from '@mantleframework/aws'

// Synchronous invocation
const result = await invoke('my-function', { key: 'value' })

// Async (fire-and-forget)
await invokeAsync('my-function', { key: 'value' })

LambdaVendor

Static class with @RequiresLambda decorators.

DynamoDB

Operations

typescript
import {
  dynamoGet,
  dynamoPut,
  dynamoQuery,
  dynamoScan,
  dynamoUpdate,
  dynamoDelete,
  dynamoBatchGet,
  dynamoBatchWrite,
} from '@mantleframework/aws'
import type {
  GetCommandInput, GetCommandOutput,
  PutCommandInput, PutCommandOutput,
  QueryCommandInput, QueryCommandOutput,
  ScanCommandInput, ScanCommandOutput,
  UpdateCommandInput, UpdateCommandOutput,
  DeleteCommandInput, DeleteCommandOutput,
  BatchGetCommandInput, BatchGetCommandOutput,
  BatchWriteCommandInput, BatchWriteCommandOutput,
} from '@mantleframework/aws'

DynamoDBVendor

Static class with @RequiresDynamoDB decorators.

API Gateway Management (WebSocket)

Post messages to and manage WebSocket API Gateway connections.

typescript
import { postToConnection, getConnection, deleteConnection } from '@mantleframework/aws'
import type {
  PostToConnectionCommandOutput,
  GetConnectionCommandOutput,
  DeleteConnectionCommandOutput,
} from '@mantleframework/aws'

await postToConnection(connectionId, data)
const conn = await getConnection(connectionId)
await deleteConnection(connectionId)

resetApiGatewayManagementClient()

Reset the cached API Gateway Management client (useful when the endpoint changes between invocations).

ApiGatewayManagementVendor

Static class with @RequiresApiGatewayManagement decorators.

WebSocket Connections

Higher-level DynamoDB-backed connection store for WebSocket APIs.

typescript
import {
  storeConnection,
  removeConnection,
  getStoredConnection,
  getActiveConnections,
  broadcastToConnections,
} from '@mantleframework/aws'
import type { ConnectionRecord, ConnectionMetadata, BroadcastOptions } from '@mantleframework/aws'

await storeConnection(connectionId, metadata)
await removeConnection(connectionId)
const conn = await getStoredConnection(connectionId)
const connections = await getActiveConnections()
await broadcastToConnections(data, options)

WebSocketConnectionsVendor

Static class backing the connection store operations.

API Gateway (Admin)

Query API Gateway admin endpoints for key and usage plan management.

typescript
import { getApiKeys, getUsage, getUsagePlans } from '@mantleframework/aws'

const keys = await getApiKeys()
const plans = await getUsagePlans()
const usage = await getUsage(usagePlanId, startDate, endDate)

ApiGatewayVendor

Static class with @RequiresApiGateway decorators.

CloudWatch

putMetricData(params)

Publish custom metric data to CloudWatch.

typescript
import { putMetricData } from '@mantleframework/aws'
import type { MetricData } from '@mantleframework/aws'

await putMetricData({
  Namespace: 'MyApp',
  MetricData: [{ MetricName: 'ItemsProcessed', Value: 42, Unit: 'Count' }],
})

CloudWatchVendor

Static class with @RequiresCloudWatch decorators.

Retry

withRetry(fn, options?)

Generic retry wrapper with exponential backoff and jitter.

typescript
import { withRetry } from '@mantleframework/aws'
import type { RetryOptions } from '@mantleframework/aws'

const result = await withRetry(
  () => callExternalService(),
  { maxRetries: 3, baseDelayMs: 100 },
)

sleep(ms)

Promise-based sleep utility.

calculateDelayWithJitter(baseMs, attempt)

Calculate exponential backoff delay with random jitter.

Permission Decorators

Stage 3 method decorators that declare IAM permissions. The CLI extracts these at build time for automatic inline policy generation.

DecoratorServiceOperations Enum
@RequiresS3(resource, ops)S3S3Operation
@RequiresSQS(resource, ops)SQSSQSOperation
@RequiresSNS(resource, ops)SNSSNSOperation
@RequiresEventBridge(resource, ops)EventBridgeEventBridgeOperation
@RequiresLambda(resource, ops)LambdaLambdaOperation
@RequiresDynamoDB(resource, ops)DynamoDBDynamoDBOperation
@RequiresApiGatewayManagement(resource, ops)API GW MgmtApiGatewayManagementOperation
@RequiresApiGateway(resource, ops)API GatewayApiGatewayOperation
@RequiresCloudWatch(resource, ops)CloudWatchCloudWatchOperation

Resource is '*' on vendor wrappers (generic). Actual resource ARNs are resolved at build time by the CLI based on which env vars the Lambda uses.

Permission Retrieval

typescript
import {
  getS3Permissions,
  getSQSPermissions,
  getSNSPermissions,
  getEventBridgePermissions,
  getLambdaPermissions,
  getDynamoDBPermissions,
  getApiGatewayManagementPermissions,
  getApiGatewayPermissions,
  getCloudWatchPermissions,
  getServicePermissions,
} from '@mantleframework/aws'

// Get all service permissions from a class
const permissions = getServicePermissions(MyVendor)

Service Types

typescript
import {
  AWSService,
  S3Operation,
  SQSOperation,
  SNSOperation,
  EventBridgeOperation,
  LambdaOperation,
  DynamoDBOperation,
  ApiGatewayManagementOperation,
  ApiGatewayOperation,
  CloudWatchOperation,
} from '@mantleframework/aws'
import type { ServiceOperation, ServicePermission } from '@mantleframework/aws'

Testing

Inject mock clients for unit testing:

typescript
import {
  setTestS3Client,
  setTestSQSClient,
  setTestSNSClient,
  setTestEventBridgeClient,
  setTestLambdaClient,
  setTestDynamoDBClient,
  setTestDynamoDBDocumentClient,
  setTestApiGatewayClient,
  setTestCloudWatchClient,
  setTestApiGatewayManagementClient,
  resetAllClients,
} from '@mantleframework/aws'

import { mockClient } from 'aws-sdk-client-mock'
import { S3Client } from '@aws-sdk/client-s3'

const s3Mock = mockClient(S3Client)
setTestS3Client(s3Mock as any)

// After tests
resetAllClients()