@leanstacks/lambda-utils 0.3.0-alpha.4 → 0.4.0-alpha.1
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/README.md +135 -4
- package/dist/clients/lambda-client.d.ts +78 -0
- package/dist/clients/sns-client.d.ts +75 -0
- package/dist/clients/sqs-client.d.ts +74 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.esm.js +1 -1
- package/dist/index.js +1 -1
- package/docs/CONFIGURATION.md +348 -0
- package/docs/LAMBDA_CLIENT.md +292 -0
- package/docs/README.md +5 -3
- package/docs/SNS_CLIENT.md +363 -0
- package/docs/SQS_CLIENT.md +352 -0
- package/package.json +10 -6
package/README.md
CHANGED
|
@@ -46,6 +46,33 @@ export const handler = async (event: any, context: any) => {
|
|
|
46
46
|
};
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
+
### Configuration Example
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import { z } from 'zod';
|
|
53
|
+
import { createConfigManager } from '@leanstacks/lambda-utils';
|
|
54
|
+
|
|
55
|
+
// Define your configuration schema
|
|
56
|
+
const configSchema = z.object({
|
|
57
|
+
TABLE_NAME: z.string().min(1),
|
|
58
|
+
AWS_REGION: z.string().default('us-east-1'),
|
|
59
|
+
LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
type Config = z.infer<typeof configSchema>;
|
|
63
|
+
|
|
64
|
+
const configManager = createConfigManager(configSchema);
|
|
65
|
+
const config = configManager.get();
|
|
66
|
+
|
|
67
|
+
export const handler = async (event: any) => {
|
|
68
|
+
console.log(`Using table: ${config.TABLE_NAME}`);
|
|
69
|
+
|
|
70
|
+
// Your Lambda handler logic here
|
|
71
|
+
|
|
72
|
+
return { statusCode: 200, body: 'Success' };
|
|
73
|
+
};
|
|
74
|
+
```
|
|
75
|
+
|
|
49
76
|
### API Response Example
|
|
50
77
|
|
|
51
78
|
```typescript
|
|
@@ -67,7 +94,7 @@ export const handler = async (event: APIGatewayProxyEvent) => {
|
|
|
67
94
|
- **📝 Structured Logging** – Pino logger pre-configured for Lambda with automatic AWS request context enrichment
|
|
68
95
|
- **📤 API Response Helpers** – Standard response formatting for API Gateway with proper HTTP status codes
|
|
69
96
|
- **⚙️ Configuration Validation** – Environment variable validation with Zod schema support
|
|
70
|
-
- **🔌 AWS SDK Clients** – Pre-configured AWS SDK v3 clients including DynamoDB with
|
|
97
|
+
- **🔌 AWS SDK Clients** – Pre-configured AWS SDK v3 clients including DynamoDB, Lambda, SNS, and SQS with singleton patterns
|
|
71
98
|
- **🔒 Full TypeScript Support** – Complete type definitions and IDE autocomplete
|
|
72
99
|
- **⚡ Lambda Optimized** – Designed for performance in serverless environments
|
|
73
100
|
|
|
@@ -77,12 +104,38 @@ Comprehensive guides and examples are available in the `docs` directory:
|
|
|
77
104
|
|
|
78
105
|
| Guide | Description |
|
|
79
106
|
| ------------------------------------------------------------ | ---------------------------------------------------------------------- |
|
|
107
|
+
| **[Configuration Guide](./docs/CONFIGURATION.md)** | Validate environment variables with Zod schemas and type safety |
|
|
80
108
|
| **[Logging Guide](./docs/LOGGING.md)** | Configure and use structured logging with automatic AWS Lambda context |
|
|
81
109
|
| **[API Gateway Responses](./docs/API_GATEWAY_RESPONSES.md)** | Format responses for API Gateway with standard HTTP patterns |
|
|
82
|
-
| **[
|
|
110
|
+
| **[DynamoDB Client](./docs/DYNAMODB_CLIENT.md)** | Use pre-configured DynamoDB clients with singleton pattern |
|
|
111
|
+
| **[Lambda Client](./docs/LAMBDA_CLIENT.md)** | Invoke other Lambda functions synchronously or asynchronously |
|
|
112
|
+
| **[SNS Client](./docs/SNS_CLIENT.md)** | Publish messages to SNS topics with message attributes |
|
|
113
|
+
| **[SQS Client](./docs/SQS_CLIENT.md)** | Send messages to SQS queues with message attributes |
|
|
83
114
|
|
|
84
115
|
## Usage
|
|
85
116
|
|
|
117
|
+
### Configuration
|
|
118
|
+
|
|
119
|
+
Validate and manage environment variables with type safety:
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
import { z } from 'zod';
|
|
123
|
+
import { createConfigManager } from '@leanstacks/lambda-utils';
|
|
124
|
+
|
|
125
|
+
const configManager = createConfigManager(
|
|
126
|
+
z.object({
|
|
127
|
+
TABLE_NAME: z.string().min(1),
|
|
128
|
+
AWS_REGION: z.string().default('us-east-1'),
|
|
129
|
+
}),
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
const config = configManager.get();
|
|
133
|
+
// TypeScript infers type from schema
|
|
134
|
+
// Validation errors thrown immediately
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**→ See [Configuration Guide](./docs/CONFIGURATION.md) for detailed validation patterns and best practices**
|
|
138
|
+
|
|
86
139
|
### Logging
|
|
87
140
|
|
|
88
141
|
The Logger utility provides structured logging configured specifically for AWS Lambda:
|
|
@@ -145,11 +198,89 @@ export const handler = async (event: any, context: any) => {
|
|
|
145
198
|
|
|
146
199
|
**→ See [DynamoDB Client Guide](./docs/DYNAMODB_CLIENT.md) for detailed configuration and examples**
|
|
147
200
|
|
|
148
|
-
|
|
201
|
+
#### Lambda Client
|
|
202
|
+
|
|
203
|
+
Invoke other Lambda functions synchronously or asynchronously:
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
import { invokeLambdaSync, invokeLambdaAsync } from '@leanstacks/lambda-utils';
|
|
207
|
+
|
|
208
|
+
export const handler = async (event: any) => {
|
|
209
|
+
// Synchronous invocation - wait for response
|
|
210
|
+
const response = await invokeLambdaSync('my-function-name', {
|
|
211
|
+
key: 'value',
|
|
212
|
+
data: { nested: true },
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
// Asynchronous invocation - fire and forget
|
|
216
|
+
await invokeLambdaAsync('my-async-function', {
|
|
217
|
+
eventType: 'process',
|
|
218
|
+
data: [1, 2, 3],
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
return { statusCode: 200, body: JSON.stringify(response) };
|
|
222
|
+
};
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**→ See [Lambda Client Guide](./docs/LAMBDA_CLIENT.md) for detailed configuration and examples**
|
|
226
|
+
|
|
227
|
+
#### SNS Client
|
|
228
|
+
|
|
229
|
+
Publish messages to SNS topics with optional message attributes:
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
import { publishToTopic, SNSMessageAttributes } from '@leanstacks/lambda-utils';
|
|
233
|
+
|
|
234
|
+
export const handler = async (event: any) => {
|
|
235
|
+
const attributes: SNSMessageAttributes = {
|
|
236
|
+
priority: {
|
|
237
|
+
DataType: 'String',
|
|
238
|
+
StringValue: 'high',
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
const messageId = await publishToTopic(
|
|
243
|
+
'arn:aws:sns:us-east-1:123456789012:MyTopic',
|
|
244
|
+
{ orderId: '12345', status: 'completed' },
|
|
245
|
+
attributes,
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
return { statusCode: 200, body: JSON.stringify({ messageId }) };
|
|
249
|
+
};
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
**→ See [SNS Client Guide](./docs/SNS_CLIENT.md) for detailed configuration and examples**
|
|
253
|
+
|
|
254
|
+
#### SQS Client
|
|
255
|
+
|
|
256
|
+
Send messages to SQS queues with optional message attributes:
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
import { sendToQueue, SQSMessageAttributes } from '@leanstacks/lambda-utils';
|
|
260
|
+
|
|
261
|
+
export const handler = async (event: any) => {
|
|
262
|
+
const attributes: SQSMessageAttributes = {
|
|
263
|
+
priority: {
|
|
264
|
+
DataType: 'String',
|
|
265
|
+
StringValue: 'high',
|
|
266
|
+
},
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
const messageId = await sendToQueue(
|
|
270
|
+
'https://sqs.us-east-1.amazonaws.com/123456789012/MyQueue',
|
|
271
|
+
{ orderId: '12345', status: 'completed' },
|
|
272
|
+
attributes,
|
|
273
|
+
);
|
|
274
|
+
|
|
275
|
+
return { statusCode: 200, body: JSON.stringify({ messageId }) };
|
|
276
|
+
};
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
**→ See [SQS Client Guide](./docs/SQS_CLIENT.md) for detailed configuration and examples**
|
|
149
280
|
|
|
150
281
|
## Examples
|
|
151
282
|
|
|
152
|
-
|
|
283
|
+
To see an example Lambda microservice using the Lambda Utilities, see the LeanStacks [`lambda-starter`](https://github.com/leanstacks/lambda-starter) :octocat: GitHub repository.
|
|
153
284
|
|
|
154
285
|
- API Gateway with logging and response formatting
|
|
155
286
|
- Configuration validation and DynamoDB integration
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { LambdaClient, LambdaClientConfig } from '@aws-sdk/client-lambda';
|
|
2
|
+
/**
|
|
3
|
+
* Initializes the Lambda client with the provided configuration.
|
|
4
|
+
* If the client is already initialized, this will replace it with a new instance.
|
|
5
|
+
*
|
|
6
|
+
* @param config - Lambda client configuration
|
|
7
|
+
* @returns The Lambda client instance
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* // Initialize with default configuration
|
|
12
|
+
* initializeLambdaClient();
|
|
13
|
+
*
|
|
14
|
+
* // Initialize with custom configuration
|
|
15
|
+
* initializeLambdaClient({ region: 'us-east-1' });
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare const initializeLambdaClient: (config?: LambdaClientConfig) => LambdaClient;
|
|
19
|
+
/**
|
|
20
|
+
* Returns the singleton Lambda client instance.
|
|
21
|
+
* If the client has not been initialized, creates one with default configuration.
|
|
22
|
+
*
|
|
23
|
+
* @returns The Lambda client instance
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* const client = getLambdaClient();
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare const getLambdaClient: () => LambdaClient;
|
|
31
|
+
/**
|
|
32
|
+
* Resets the Lambda client instance.
|
|
33
|
+
* Useful for testing or when you need to reinitialize the client with a different configuration.
|
|
34
|
+
*/
|
|
35
|
+
export declare const resetLambdaClient: () => void;
|
|
36
|
+
/**
|
|
37
|
+
* Invokes a Lambda function synchronously (RequestResponse).
|
|
38
|
+
* The function waits for the response and returns the payload.
|
|
39
|
+
*
|
|
40
|
+
* @param functionName - The name or ARN of the Lambda function to invoke
|
|
41
|
+
* @param payload - The JSON payload to pass to the Lambda function
|
|
42
|
+
* @returns Promise that resolves to the response payload from the Lambda function
|
|
43
|
+
* @throws Error if the Lambda invocation fails or returns a function error
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* interface MyResponse {
|
|
48
|
+
* result: string;
|
|
49
|
+
* statusCode: number;
|
|
50
|
+
* }
|
|
51
|
+
*
|
|
52
|
+
* const response = await invokeLambdaSync<MyResponse>(
|
|
53
|
+
* 'my-function-name',
|
|
54
|
+
* { key: 'value', data: { nested: true } }
|
|
55
|
+
* );
|
|
56
|
+
* console.log(response.result);
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export declare const invokeLambdaSync: <T = unknown>(functionName: string, payload: unknown) => Promise<T>;
|
|
60
|
+
/**
|
|
61
|
+
* Invokes a Lambda function asynchronously (Event).
|
|
62
|
+
* The function returns immediately without waiting for the Lambda execution to complete.
|
|
63
|
+
*
|
|
64
|
+
* @param functionName - The name or ARN of the Lambda function to invoke
|
|
65
|
+
* @param payload - The JSON payload to pass to the Lambda function
|
|
66
|
+
* @returns Promise that resolves when the invocation request is accepted
|
|
67
|
+
* @throws Error if the Lambda invocation request fails
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* // Fire and forget invocation
|
|
72
|
+
* await invokeLambdaAsync(
|
|
73
|
+
* 'my-async-function',
|
|
74
|
+
* { eventType: 'process', data: [1, 2, 3] }
|
|
75
|
+
* );
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
export declare const invokeLambdaAsync: (functionName: string, payload: unknown) => Promise<void>;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { SNSClient, SNSClientConfig } from '@aws-sdk/client-sns';
|
|
2
|
+
/**
|
|
3
|
+
* Interface for SNS message attributes.
|
|
4
|
+
* Supports the AWS SNS data types: String, String.Array, Number, and Binary.
|
|
5
|
+
* Note: String.Array is the only array type supported by AWS SNS.
|
|
6
|
+
*/
|
|
7
|
+
export interface SNSMessageAttributes {
|
|
8
|
+
[key: string]: {
|
|
9
|
+
DataType: 'String' | 'String.Array' | 'Number' | 'Binary';
|
|
10
|
+
StringValue?: string;
|
|
11
|
+
BinaryValue?: Uint8Array;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Initializes the SNS client with the provided configuration.
|
|
16
|
+
* If the client is already initialized, this will replace it with a new instance.
|
|
17
|
+
*
|
|
18
|
+
* @param config - SNS client configuration
|
|
19
|
+
* @returns The SNS client instance
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* // Initialize with default configuration
|
|
24
|
+
* initializeSNSClient();
|
|
25
|
+
*
|
|
26
|
+
* // Initialize with custom configuration
|
|
27
|
+
* initializeSNSClient({ region: 'us-east-1' });
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare const initializeSNSClient: (config?: SNSClientConfig) => SNSClient;
|
|
31
|
+
/**
|
|
32
|
+
* Returns the singleton SNS client instance.
|
|
33
|
+
* If the client has not been initialized, creates one with default configuration.
|
|
34
|
+
*
|
|
35
|
+
* @returns The SNS client instance
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* const client = getSNSClient();
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare const getSNSClient: () => SNSClient;
|
|
43
|
+
/**
|
|
44
|
+
* Resets the SNS client instance.
|
|
45
|
+
* Useful for testing or when you need to reinitialize the client with a different configuration.
|
|
46
|
+
*/
|
|
47
|
+
export declare const resetSNSClient: () => void;
|
|
48
|
+
/**
|
|
49
|
+
* Publishes a message to an SNS topic.
|
|
50
|
+
*
|
|
51
|
+
* @param topicArn - The ARN of the SNS topic to publish to
|
|
52
|
+
* @param message - The message content (will be converted to JSON string)
|
|
53
|
+
* @param attributes - Optional message attributes for filtering
|
|
54
|
+
* @returns Promise that resolves to the message ID
|
|
55
|
+
* @throws Error if the SNS publish operation fails
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* const messageId = await publishToTopic(
|
|
60
|
+
* 'arn:aws:sns:us-east-1:123456789012:MyTopic',
|
|
61
|
+
* { orderId: '12345', status: 'completed' },
|
|
62
|
+
* {
|
|
63
|
+
* priority: {
|
|
64
|
+
* DataType: 'String',
|
|
65
|
+
* StringValue: 'high'
|
|
66
|
+
* },
|
|
67
|
+
* categories: {
|
|
68
|
+
* DataType: 'String.Array',
|
|
69
|
+
* StringValue: JSON.stringify(['urgent', 'vip', 'customer-request'])
|
|
70
|
+
* }
|
|
71
|
+
* }
|
|
72
|
+
* );
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
export declare const publishToTopic: (topicArn: string, message: Record<string, unknown>, attributes?: SNSMessageAttributes) => Promise<string>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { SQSClient, SQSClientConfig } from '@aws-sdk/client-sqs';
|
|
2
|
+
/**
|
|
3
|
+
* Interface for SQS message attributes.
|
|
4
|
+
* Supports the AWS SQS data types: String, Number, and Binary.
|
|
5
|
+
*/
|
|
6
|
+
export interface SQSMessageAttributes {
|
|
7
|
+
[key: string]: {
|
|
8
|
+
DataType: 'String' | 'Number' | 'Binary';
|
|
9
|
+
StringValue?: string;
|
|
10
|
+
BinaryValue?: Uint8Array;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Initializes the SQS client with the provided configuration.
|
|
15
|
+
* If the client is already initialized, this will replace it with a new instance.
|
|
16
|
+
*
|
|
17
|
+
* @param config - SQS client configuration
|
|
18
|
+
* @returns The SQS client instance
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* // Initialize with default configuration
|
|
23
|
+
* initializeSQSClient();
|
|
24
|
+
*
|
|
25
|
+
* // Initialize with custom configuration
|
|
26
|
+
* initializeSQSClient({ region: 'us-east-1' });
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare const initializeSQSClient: (config?: SQSClientConfig) => SQSClient;
|
|
30
|
+
/**
|
|
31
|
+
* Returns the singleton SQS client instance.
|
|
32
|
+
* If the client has not been initialized, creates one with default configuration.
|
|
33
|
+
*
|
|
34
|
+
* @returns The SQS client instance
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* const client = getSQSClient();
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export declare const getSQSClient: () => SQSClient;
|
|
42
|
+
/**
|
|
43
|
+
* Resets the SQS client instance.
|
|
44
|
+
* Useful for testing or when you need to reinitialize the client with a different configuration.
|
|
45
|
+
*/
|
|
46
|
+
export declare const resetSQSClient: () => void;
|
|
47
|
+
/**
|
|
48
|
+
* Sends a message to an SQS queue.
|
|
49
|
+
*
|
|
50
|
+
* @param queueUrl - The URL of the SQS queue to send to
|
|
51
|
+
* @param message - The message content (will be converted to JSON string)
|
|
52
|
+
* @param attributes - Optional message attributes for filtering
|
|
53
|
+
* @returns Promise that resolves to the message ID
|
|
54
|
+
* @throws Error if the SQS send operation fails
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```typescript
|
|
58
|
+
* const messageId = await sendToQueue(
|
|
59
|
+
* 'https://sqs.us-east-1.amazonaws.com/123456789012/MyQueue',
|
|
60
|
+
* { orderId: '12345', status: 'completed' },
|
|
61
|
+
* {
|
|
62
|
+
* priority: {
|
|
63
|
+
* DataType: 'String',
|
|
64
|
+
* StringValue: 'high'
|
|
65
|
+
* },
|
|
66
|
+
* attempts: {
|
|
67
|
+
* DataType: 'Number',
|
|
68
|
+
* StringValue: '1'
|
|
69
|
+
* }
|
|
70
|
+
* }
|
|
71
|
+
* );
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export declare const sendToQueue: (queueUrl: string, message: Record<string, unknown>, attributes?: SQSMessageAttributes) => Promise<string>;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export { Logger, LoggerConfig, withRequestTracking } from './logging/logger';
|
|
2
2
|
export { createResponse, ok, created, noContent, badRequest, notFound, internalServerError, httpHeaders, Headers, } from './utils/apigateway-response';
|
|
3
3
|
export { getDynamoDBClient, getDynamoDBDocumentClient, initializeDynamoDBClients, resetDynamoDBClients, } from './clients/dynamodb-client';
|
|
4
|
+
export { getSNSClient, initializeSNSClient, SNSMessageAttributes, publishToTopic, resetSNSClient, } from './clients/sns-client';
|
|
5
|
+
export { getLambdaClient, initializeLambdaClient, invokeLambdaAsync, invokeLambdaSync, resetLambdaClient, } from './clients/lambda-client';
|
|
6
|
+
export { getSQSClient, initializeSQSClient, SQSMessageAttributes, sendToQueue, resetSQSClient, } from './clients/sqs-client';
|
|
4
7
|
export { createConfigManager, ConfigManager } from './validation/config';
|
package/dist/index.esm.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import n from"pino";import{lambdaRequestTracker as e,StructuredLogFormatter as t,CloudwatchLogFormatter as o,pinoLambdaDestination as r}from"pino-lambda";import{DynamoDBClient as
|
|
1
|
+
import n from"pino";import{lambdaRequestTracker as e,StructuredLogFormatter as t,CloudwatchLogFormatter as o,pinoLambdaDestination as r}from"pino-lambda";import{DynamoDBClient as s}from"@aws-sdk/client-dynamodb";import{DynamoDBDocumentClient as i}from"@aws-sdk/lib-dynamodb";import{SNSClient as a,PublishCommand as l}from"@aws-sdk/client-sns";import{LambdaClient as c,InvokeCommand as u}from"@aws-sdk/client-lambda";import{SQSClient as d,SendMessageCommand as m}from"@aws-sdk/client-sqs";import{z as f}from"zod";const g=e();class w{constructor(e){this._loggerConfig={enabled:!0,level:"info",format:"json"},this._instance=null,this._createLogger=()=>{const e="json"===this._loggerConfig.format?new t:new o,s=r({formatter:e});return n({enabled:this._loggerConfig.enabled,level:this._loggerConfig.level},s)},e&&(this._loggerConfig={enabled:e.enabled??!0,level:e.level??"info",format:e.format??"json"})}get instance(){return null===this._instance&&(this._instance=this._createLogger()),this._instance}}const p={contentType:n=>({"Content-Type":n}),json:{"Content-Type":"application/json"},cors:(n="*")=>({"Access-Control-Allow-Origin":n})},y=(n,e,t={})=>({statusCode:n,headers:{...t},body:JSON.stringify(e)}),h=(n,e={})=>y(200,n,e),b=(n,e={})=>y(201,n,e),C=(n={})=>y(204,{},n),E=(n="Bad Request",e={})=>y(400,{message:n},e),v=(n="Not Found",e={})=>y(404,{message:n},e),_=(n="Internal Server Error",e={})=>y(500,{message:n},e);let D=null,N=null;const O=(n,e,t)=>{D=new s(n||{});const o={marshallOptions:e||{},unmarshallOptions:t||{}};return N=i.from(D,o),{client:D,documentClient:N}},j=()=>{if(!D)throw new Error("DynamoDB client not initialized. Call initializeDynamoDBClients() first.");return D},F=()=>{if(!N)throw new Error("DynamoDB Document client not initialized. Call initializeDynamoDBClients() first.");return N},S=()=>{D=null,N=null};let T=null;const B=n=>(T=new a(n||{}),T),J=()=>(T||(T=new a({})),T),M=()=>{T=null},k=async(n,e,t)=>{const o=J(),r=new l({TopicArn:n,Message:JSON.stringify(e),MessageAttributes:t});return(await o.send(r)).MessageId??""};let z=null;const A=n=>(z=new c(n||{}),z),I=()=>(z||(z=new c({})),z),$=()=>{z=null},L=async(n,e)=>{const t=I(),o=new u({FunctionName:n,InvocationType:"RequestResponse",Payload:JSON.stringify(e)}),r=await t.send(o);if(r.FunctionError)throw new Error(`Lambda function error: ${r.FunctionError}`);return r.Payload?JSON.parse((new TextDecoder).decode(r.Payload)):null},P=async(n,e)=>{const t=I(),o=new u({FunctionName:n,InvocationType:"Event",Payload:JSON.stringify(e)}),r=await t.send(o);if(r.FunctionError)throw new Error(`Lambda function error: ${r.FunctionError}`)};let q=null;const R=n=>(q=new d(n||{}),q),x=()=>(q||(q=new d({})),q),Q=()=>{q=null},U=async(n,e,t)=>{const o=x(),r=new m({QueueUrl:n,MessageBody:JSON.stringify(e),MessageAttributes:t});return(await o.send(r)).MessageId??""},Z=n=>{let e=null;const t=()=>{try{return n.parse(process.env)}catch(n){if(n instanceof f.ZodError){const e=n.issues.map(n=>`${n.path.join(".")}: ${n.message}`).join(", ");throw new Error(`Configuration validation failed: ${e}`)}throw n}};return{get:()=>(e||(e=t()),e),refresh:()=>(e=t(),e)}};export{w as Logger,E as badRequest,Z as createConfigManager,y as createResponse,b as created,j as getDynamoDBClient,F as getDynamoDBDocumentClient,I as getLambdaClient,J as getSNSClient,x as getSQSClient,p as httpHeaders,O as initializeDynamoDBClients,A as initializeLambdaClient,B as initializeSNSClient,R as initializeSQSClient,_ as internalServerError,P as invokeLambdaAsync,L as invokeLambdaSync,C as noContent,v as notFound,h as ok,k as publishToTopic,S as resetDynamoDBClients,$ as resetLambdaClient,M as resetSNSClient,Q as resetSQSClient,U as sendToQueue,g as withRequestTracking};
|
|
2
2
|
//# sourceMappingURL=index.esm.js.map
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var e=require("pino"),
|
|
1
|
+
"use strict";var e=require("pino"),n=require("pino-lambda"),t=require("@aws-sdk/client-dynamodb"),r=require("@aws-sdk/lib-dynamodb"),o=require("@aws-sdk/client-sns"),s=require("@aws-sdk/client-lambda"),i=require("@aws-sdk/client-sqs"),a=require("zod");const l=n.lambdaRequestTracker();const c=(e,n,t={})=>({statusCode:e,headers:{...t},body:JSON.stringify(n)});let u=null,d=null;let m=null;const g=()=>(m||(m=new o.SNSClient({})),m);let p=null;const C=()=>(p||(p=new s.LambdaClient({})),p);let w=null;const y=()=>(w||(w=new i.SQSClient({})),w);exports.Logger=class{constructor(t){this._loggerConfig={enabled:!0,level:"info",format:"json"},this._instance=null,this._createLogger=()=>{const t="json"===this._loggerConfig.format?new n.StructuredLogFormatter:new n.CloudwatchLogFormatter,r=n.pinoLambdaDestination({formatter:t});return e({enabled:this._loggerConfig.enabled,level:this._loggerConfig.level},r)},t&&(this._loggerConfig={enabled:t.enabled??!0,level:t.level??"info",format:t.format??"json"})}get instance(){return null===this._instance&&(this._instance=this._createLogger()),this._instance}},exports.badRequest=(e="Bad Request",n={})=>c(400,{message:e},n),exports.createConfigManager=e=>{let n=null;const t=()=>{try{return e.parse(process.env)}catch(e){if(e instanceof a.z.ZodError){const n=e.issues.map(e=>`${e.path.join(".")}: ${e.message}`).join(", ");throw new Error(`Configuration validation failed: ${n}`)}throw e}};return{get:()=>(n||(n=t()),n),refresh:()=>(n=t(),n)}},exports.createResponse=c,exports.created=(e,n={})=>c(201,e,n),exports.getDynamoDBClient=()=>{if(!u)throw new Error("DynamoDB client not initialized. Call initializeDynamoDBClients() first.");return u},exports.getDynamoDBDocumentClient=()=>{if(!d)throw new Error("DynamoDB Document client not initialized. Call initializeDynamoDBClients() first.");return d},exports.getLambdaClient=C,exports.getSNSClient=g,exports.getSQSClient=y,exports.httpHeaders={contentType:e=>({"Content-Type":e}),json:{"Content-Type":"application/json"},cors:(e="*")=>({"Access-Control-Allow-Origin":e})},exports.initializeDynamoDBClients=(e,n,o)=>{u=new t.DynamoDBClient(e||{});const s={marshallOptions:n||{},unmarshallOptions:o||{}};return d=r.DynamoDBDocumentClient.from(u,s),{client:u,documentClient:d}},exports.initializeLambdaClient=e=>(p=new s.LambdaClient(e||{}),p),exports.initializeSNSClient=e=>(m=new o.SNSClient(e||{}),m),exports.initializeSQSClient=e=>(w=new i.SQSClient(e||{}),w),exports.internalServerError=(e="Internal Server Error",n={})=>c(500,{message:e},n),exports.invokeLambdaAsync=async(e,n)=>{const t=C(),r=new s.InvokeCommand({FunctionName:e,InvocationType:"Event",Payload:JSON.stringify(n)}),o=await t.send(r);if(o.FunctionError)throw new Error(`Lambda function error: ${o.FunctionError}`)},exports.invokeLambdaSync=async(e,n)=>{const t=C(),r=new s.InvokeCommand({FunctionName:e,InvocationType:"RequestResponse",Payload:JSON.stringify(n)}),o=await t.send(r);if(o.FunctionError)throw new Error(`Lambda function error: ${o.FunctionError}`);return o.Payload?JSON.parse((new TextDecoder).decode(o.Payload)):null},exports.noContent=(e={})=>c(204,{},e),exports.notFound=(e="Not Found",n={})=>c(404,{message:e},n),exports.ok=(e,n={})=>c(200,e,n),exports.publishToTopic=async(e,n,t)=>{const r=g(),s=new o.PublishCommand({TopicArn:e,Message:JSON.stringify(n),MessageAttributes:t});return(await r.send(s)).MessageId??""},exports.resetDynamoDBClients=()=>{u=null,d=null},exports.resetLambdaClient=()=>{p=null},exports.resetSNSClient=()=>{m=null},exports.resetSQSClient=()=>{w=null},exports.sendToQueue=async(e,n,t)=>{const r=y(),o=new i.SendMessageCommand({QueueUrl:e,MessageBody:JSON.stringify(n),MessageAttributes:t});return(await r.send(o)).MessageId??""},exports.withRequestTracking=l;
|
|
2
2
|
//# sourceMappingURL=index.js.map
|