@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 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 document client support
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
- | **[AWS Clients](./docs/README.md)** | Use pre-configured AWS SDK v3 clients in your handlers |
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
- Additional AWS Clients are coming soon.
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
- Example Lambda functions using Lambda Utilities are available in the repository:
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 i}from"@aws-sdk/client-dynamodb";import{DynamoDBDocumentClient as s}from"@aws-sdk/lib-dynamodb";import{z as l}from"zod";const a=e();class c{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,i=r({formatter:e});return n({enabled:this._loggerConfig.enabled,level:this._loggerConfig.level},i)},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 m={contentType:n=>({"Content-Type":n}),json:{"Content-Type":"application/json"},cors:(n="*")=>({"Access-Control-Allow-Origin":n})},f=(n,e,t={})=>({statusCode:n,headers:{...t},body:JSON.stringify(e)}),g=(n,e={})=>f(200,n,e),d=(n,e={})=>f(201,n,e),u=(n={})=>f(204,{},n),h=(n="Bad Request",e={})=>f(400,{message:n},e),p=(n="Not Found",e={})=>f(404,{message:n},e),C=(n="Internal Server Error",e={})=>f(500,{message:n},e);let w=null,y=null;const _=(n,e,t)=>{w=new i(n||{});const o={marshallOptions:e||{},unmarshallOptions:t||{}};return y=s.from(w,o),{client:w,documentClient:y}},b=()=>{if(!w)throw new Error("DynamoDB client not initialized. Call initializeDynamoDBClients() first.");return w},D=()=>{if(!y)throw new Error("DynamoDB Document client not initialized. Call initializeDynamoDBClients() first.");return y},v=()=>{w=null,y=null},j=n=>{let e=null;const t=()=>{try{return n.parse(process.env)}catch(n){if(n instanceof l.ZodError){const e=n.issues.map(n=>`${n.path.join(".")}: ${n.message}`).join("\n");throw new Error(`Configuration validation failed:\n${e}`)}throw n}};return{get:()=>(e||(e=t()),e),refresh:()=>(e=t(),e)}};export{c as Logger,h as badRequest,j as createConfigManager,f as createResponse,d as created,b as getDynamoDBClient,D as getDynamoDBDocumentClient,m as httpHeaders,_ as initializeDynamoDBClients,C as internalServerError,u as noContent,p as notFound,g as ok,v as resetDynamoDBClients,a as withRequestTracking};
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"),t=require("pino-lambda"),n=require("@aws-sdk/client-dynamodb"),r=require("@aws-sdk/lib-dynamodb"),o=require("zod");const i=t.lambdaRequestTracker();const s=(e,t,n={})=>({statusCode:e,headers:{...n},body:JSON.stringify(t)});let a=null,l=null;exports.Logger=class{constructor(n){this._loggerConfig={enabled:!0,level:"info",format:"json"},this._instance=null,this._createLogger=()=>{const n="json"===this._loggerConfig.format?new t.StructuredLogFormatter:new t.CloudwatchLogFormatter,r=t.pinoLambdaDestination({formatter:n});return e({enabled:this._loggerConfig.enabled,level:this._loggerConfig.level},r)},n&&(this._loggerConfig={enabled:n.enabled??!0,level:n.level??"info",format:n.format??"json"})}get instance(){return null===this._instance&&(this._instance=this._createLogger()),this._instance}},exports.badRequest=(e="Bad Request",t={})=>s(400,{message:e},t),exports.createConfigManager=e=>{let t=null;const n=()=>{try{return e.parse(process.env)}catch(e){if(e instanceof o.z.ZodError){const t=e.issues.map(e=>`${e.path.join(".")}: ${e.message}`).join("\n");throw new Error(`Configuration validation failed:\n${t}`)}throw e}};return{get:()=>(t||(t=n()),t),refresh:()=>(t=n(),t)}},exports.createResponse=s,exports.created=(e,t={})=>s(201,e,t),exports.getDynamoDBClient=()=>{if(!a)throw new Error("DynamoDB client not initialized. Call initializeDynamoDBClients() first.");return a},exports.getDynamoDBDocumentClient=()=>{if(!l)throw new Error("DynamoDB Document client not initialized. Call initializeDynamoDBClients() first.");return l},exports.httpHeaders={contentType:e=>({"Content-Type":e}),json:{"Content-Type":"application/json"},cors:(e="*")=>({"Access-Control-Allow-Origin":e})},exports.initializeDynamoDBClients=(e,t,o)=>{a=new n.DynamoDBClient(e||{});const i={marshallOptions:t||{},unmarshallOptions:o||{}};return l=r.DynamoDBDocumentClient.from(a,i),{client:a,documentClient:l}},exports.internalServerError=(e="Internal Server Error",t={})=>s(500,{message:e},t),exports.noContent=(e={})=>s(204,{},e),exports.notFound=(e="Not Found",t={})=>s(404,{message:e},t),exports.ok=(e,t={})=>s(200,e,t),exports.resetDynamoDBClients=()=>{a=null,l=null},exports.withRequestTracking=i;
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