Core type definitions for idempotency options, persistence configuration, record management, and interfaces.
Types for creating and managing idempotency records.
/**
* Options for creating a new IdempotencyRecord
*/
interface IdempotencyRecordOptions {
/** The idempotency key used to identify the record */
idempotencyKey: string;
/** The record status (INPROGRESS | COMPLETED | EXPIRED) */
status: IdempotencyRecordStatusValue;
/** Optional sort key for composite key tables */
sortKey?: string;
/** Expiry timestamp in seconds (Unix epoch) */
expiryTimestamp?: number;
/** In-progress expiry timestamp in milliseconds (Unix epoch) */
inProgressExpiryTimestamp?: number;
/** Response data to return for idempotent requests */
responseData?: JSONValue;
/** Hash of the payload for validation */
payloadHash?: string;
}
/**
* The status of an IdempotencyRecord
*/
type IdempotencyRecordStatusValue =
| "INPROGRESS"
| "COMPLETED"
| "EXPIRED";Types for configuring and implementing persistence layers.
/**
* Base attributes used by persistence layers (DynamoDB, Redis, etc.)
*/
interface BasePersistenceAttributes {
/** Attribute name for expiry timestamp (default: 'expiration') */
expiryAttr?: string;
/** Attribute name for in-progress expiry timestamp (default: 'in_progress_expiration') */
inProgressExpiryAttr?: string;
/** Attribute name for status (default: 'status') */
statusAttr?: string;
/** Attribute name for response data (default: 'data') */
dataAttr?: string;
/** Attribute name for validation hash (default: 'validation') */
validationKeyAttr?: string;
}
/**
* Options for configuring a persistence layer
*/
interface BasePersistenceLayerOptions {
/** IdempotencyConfig instance */
config: IdempotencyConfig;
/** Optional function name for key prefix */
functionName?: string;
/** Optional custom prefix for idempotency keys */
keyPrefix?: string;
}
/**
* Interface that all persistence layers must implement
*/
interface BasePersistenceLayerInterface {
/** Initialize the persistence layer with configuration */
configure(options?: BasePersistenceLayerOptions): void;
/** Check if payload validation is enabled */
isPayloadValidationEnabled(): boolean;
/** Save a record indicating execution is in progress */
saveInProgress(data: unknown, remainingTimeInMillis?: number): Promise<void>;
/** Save a record indicating successful completion */
saveSuccess(data: unknown, result: unknown): Promise<void>;
/** Delete an idempotency record */
deleteRecord(data: unknown): Promise<void>;
/** Retrieve an idempotency record */
getRecord(data: unknown): Promise<IdempotencyRecord>;
}Types for configuring idempotent functions.
/**
* Generic function type for any function signature
*/
type AnyFunction = (...args: Array<any>) => any;
/**
* Conditional type for makeIdempotent and idempotent options.
* Detects Lambda handlers (functions with Context as second argument)
* and allows dataIndexArgument for non-handler functions.
*/
type ItempotentFunctionOptions<T extends Array<any>> = T[1] extends Context
? IdempotencyLambdaHandlerOptions
: IdempotencyLambdaHandlerOptions & {
/** Index of the argument to use as idempotency payload (zero-based) */
dataIndexArgument?: number;
};
/**
* Configuration options for idempotency with Lambda handlers
*/
interface IdempotencyLambdaHandlerOptions {
/** Persistence layer to store idempotency records */
persistenceStore: BasePersistenceLayer;
/** Optional configuration for idempotency behavior */
config?: IdempotencyConfig;
/** Optional custom prefix for idempotency keys */
keyPrefix?: string;
}
/**
* A hook that runs when an idempotent request is made
*/
type ResponseHook = (
response: JSONValue,
record: IdempotencyRecord
) => JSONValue;Types for configuring idempotency behavior.
/**
* Configuration options for IdempotencyConfig
*/
interface IdempotencyConfigOptions {
/** JMESPath expression to extract idempotency key from event */
eventKeyJmesPath?: string;
/** JMESPath expression to extract payload for validation */
payloadValidationJmesPath?: string;
/** Custom JMESPath functions */
jmesPathOptions?: Functions;
/** Throw error if no idempotency key found (default: false) */
throwOnNoIdempotencyKey?: boolean;
/** Number of seconds before record expires (default: 3600) */
expiresAfterSeconds?: number;
/** Whether to locally cache idempotency results (default: false) */
useLocalCache?: boolean;
/** Number of records to keep in local cache (default: 1000) */
maxLocalCacheSize?: number;
/** Hash function to use (default: 'md5') */
hashFunction?: string;
/** AWS Lambda Context object for timeout tracking */
lambdaContext?: Context;
/** Hook that runs when returning idempotent response */
responseHook?: ResponseHook;
}Types specific to DynamoDB persistence.
/**
* Base options for DynamoDB persistence
*/
interface DynamoDBPersistenceOptionsBase extends BasePersistenceAttributes {
/** DynamoDB table name (required) */
tableName: string;
/** Primary key attribute name (default: 'id') */
keyAttr?: string;
/** Sort key attribute name for composite keys */
sortKeyAttr?: string;
/** Static partition key value when using sort keys */
staticPkValue?: string;
}
/**
* DynamoDB options with client configuration
*/
interface DynamoDBPersistenceOptionsWithClientConfig
extends DynamoDBPersistenceOptionsBase {
/** Optional DynamoDB client configuration */
clientConfig?: DynamoDBClientConfig;
/** Must not be provided when using clientConfig */
awsSdkV3Client?: never;
}
/**
* DynamoDB options with client instance
*/
interface DynamoDBPersistenceOptionsWithClientInstance
extends DynamoDBPersistenceOptionsBase {
/** Optional AWS SDK v3 DynamoDBClient instance */
awsSdkV3Client?: DynamoDBClient;
/** Must not be provided when using awsSdkV3Client */
clientConfig?: never;
}
/**
* Union type for DynamoDB persistence options
* Use either clientConfig or awsSdkV3Client, but not both
*/
type DynamoDBPersistenceOptions =
| DynamoDBPersistenceOptionsWithClientConfig
| DynamoDBPersistenceOptionsWithClientInstance;Types specific to cache (Redis/Valkey) persistence.
/**
* Value type for cache operations
*/
type CacheValue = string | Uint8Array<ArrayBufferLike>;
/**
* Interface for clients compatible with Valkey and Redis-OSS operations
*/
interface CacheClient {
/** Retrieve value associated with a key */
get(name: string): Promise<CacheValue | null>;
/** Set value for a key with optional parameters */
set(
name: CacheValue,
value: unknown,
options?: unknown
): Promise<CacheValue | null>;
/** Delete specified keys from cache */
del(keys: string[]): Promise<number>;
}
/**
* Options for cache persistence layer
*/
interface CachePersistenceOptions extends BasePersistenceAttributes {
/** Connected cache client instance (required) */
client: CacheClient;
}Type-Safe Function Wrapper
import type { ItempotentFunctionOptions } from '@aws-lambda-powertools/idempotency/types';
import { makeIdempotent } from '@aws-lambda-powertools/idempotency';
import { DynamoDBPersistenceLayer } from '@aws-lambda-powertools/idempotency/dynamodb';
import type { Context } from 'aws-lambda';
const persistenceStore = new DynamoDBPersistenceLayer({
tableName: 'idempotencyTable',
});
// Type inference works correctly
const lambdaHandler = (event: any, context: Context) => {
return { statusCode: 200 };
};
// No dataIndexArgument needed for Lambda handlers
export const handler = makeIdempotent(lambdaHandler, { persistenceStore });
// For non-handler functions, dataIndexArgument is available
const processRecord = (record: any, userId: string) => {
// Process record
};
const processIdempotently = makeIdempotent(processRecord, {
persistenceStore,
dataIndexArgument: 1, // TypeScript allows this for non-handlers
});Custom Persistence Layer
import type {
BasePersistenceLayerInterface,
BasePersistenceLayerOptions,
IdempotencyRecordOptions,
} from '@aws-lambda-powertools/idempotency/types';
import { BasePersistenceLayer, IdempotencyRecord } from '@aws-lambda-powertools/idempotency/persistence';
// Implement your own persistence layer
class CustomPersistenceLayer extends BasePersistenceLayer
implements BasePersistenceLayerInterface {
protected async _getRecord(idempotencyKey: string): Promise<IdempotencyRecord> {
// Your implementation
const data = await this.customDataStore.get(idempotencyKey);
return new IdempotencyRecord({
idempotencyKey,
status: data.status,
expiryTimestamp: data.expiry,
responseData: data.response,
});
}
protected async _putRecord(record: IdempotencyRecord): Promise<void> {
// Your implementation
await this.customDataStore.put({
key: record.idempotencyKey,
status: record.getStatus(),
expiry: record.expiryTimestamp,
});
}
protected async _updateRecord(record: IdempotencyRecord): Promise<void> {
// Your implementation
}
protected async _deleteRecord(record: IdempotencyRecord): Promise<void> {
// Your implementation
}
}Response Hook with Types
import type { ResponseHook } from '@aws-lambda-powertools/idempotency/types';
import type { JSONValue } from '@aws-lambda-powertools/commons/types';
import type { IdempotencyRecord } from '@aws-lambda-powertools/idempotency/persistence';
import { IdempotencyConfig } from '@aws-lambda-powertools/idempotency';
const myResponseHook: ResponseHook = (
response: JSONValue,
record: IdempotencyRecord
): JSONValue => {
// Type-safe response modification
return {
...response,
cached: true,
recordStatus: record.getStatus(),
};
};
const config = new IdempotencyConfig({
responseHook: myResponseHook,
});Custom Cache Client
import type { CacheClient, CacheValue } from '@aws-lambda-powertools/idempotency/cache/types';
// Implement a custom cache client
class MyCustomCacheClient implements CacheClient {
async get(name: string): Promise<CacheValue | null> {
// Your implementation
return null;
}
async set(
name: CacheValue,
value: unknown,
options?: unknown
): Promise<CacheValue | null> {
// Your implementation
return name;
}
async del(keys: string[]): Promise<number> {
// Your implementation
return keys.length;
}
}
const customClient = new MyCustomCacheClient();
const persistenceStore = new CachePersistenceLayer({
client: customClient,
});Idempotency Record Creation
import type { IdempotencyRecordOptions } from '@aws-lambda-powertools/idempotency/types';
import { IdempotencyRecord } from '@aws-lambda-powertools/idempotency/persistence';
const recordOptions: IdempotencyRecordOptions = {
idempotencyKey: 'my-function#abc123',
status: 'COMPLETED',
expiryTimestamp: Math.floor(Date.now() / 1000) + 3600,
responseData: { statusCode: 200, body: 'Success' },
payloadHash: 'def456',
};
const record = new IdempotencyRecord(recordOptions);
console.log(record.getStatus()); // 'COMPLETED'
console.log(record.getResponse()); // { statusCode: 200, body: 'Success' }BasePersistenceLayerInterface
↑
|
BasePersistenceLayer (abstract)
↑
|
├── DynamoDBPersistenceLayer
└── CachePersistenceLayer
IdempotencyConfig
↓ uses
IdempotencyConfigOptions
makeIdempotent / idempotent
↓ uses
ItempotentFunctionOptions
↓ extends
IdempotencyLambdaHandlerOptions
↓ requires
BasePersistenceLayer// Main types
import type {
IdempotencyConfigOptions,
IdempotencyLambdaHandlerOptions,
ItempotentFunctionOptions,
ResponseHook,
} from '@aws-lambda-powertools/idempotency/types';
// DynamoDB types
import type {
DynamoDBPersistenceOptions,
DynamoDBPersistenceOptionsBase,
DynamoDBPersistenceOptionsWithClientConfig,
DynamoDBPersistenceOptionsWithClientInstance,
} from '@aws-lambda-powertools/idempotency/dynamodb/types';
// Cache types
import type {
CacheClient,
CachePersistenceOptions,
} from '@aws-lambda-powertools/idempotency/cache/types';
// Record types
import type {
IdempotencyRecordOptions,
IdempotencyRecordStatusValue,
} from '@aws-lambda-powertools/idempotency/types';
// Base persistence types
import type {
BasePersistenceAttributes,
BasePersistenceLayerInterface,
BasePersistenceLayerOptions,
} from '@aws-lambda-powertools/idempotency/types';