@ttoss/lambda-postgres-query 0.6.2 → 1.0.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.
@@ -31,280 +31,324 @@ var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
31
31
  // src/cloudformation/index.ts
32
32
  var cloudformation_exports = {};
33
33
  __export(cloudformation_exports, {
34
+ DATABASE_PARAMETERS_DEFAULT: () => DATABASE_PARAMETERS_DEFAULT,
34
35
  HANDLER_DEFAULT: () => HANDLER_DEFAULT,
35
- HANDLER_READ_ONLY_DEFAULT: () => HANDLER_READ_ONLY_DEFAULT,
36
+ LAMBDA_POSTGRES_QUERY_FUNCTION_DEFAULT_NAME: () => LAMBDA_POSTGRES_QUERY_FUNCTION_DEFAULT_NAME,
36
37
  MEMORY_SIZE_DEFAULT: () => MEMORY_SIZE_DEFAULT,
37
38
  TIMEOUT_DEFAULT: () => TIMEOUT_DEFAULT,
38
39
  createLambdaPostgresQueryTemplate: () => createLambdaPostgresQueryTemplate,
39
- handler: () => handler,
40
- readOnlyHandler: () => readOnlyHandler
40
+ handler: () => handler
41
41
  });
42
42
  module.exports = __toCommonJS(cloudformation_exports);
43
43
 
44
44
  // src/cloudformation/createLambdaPostgresQueryTemplate.ts
45
45
  var HANDLER_DEFAULT = "handler.handler";
46
- var HANDLER_READ_ONLY_DEFAULT = "handler.readOnlyHandler";
46
+ var LAMBDA_POSTGRES_QUERY_FUNCTION_DEFAULT_NAME = "LambdaPostgresQueryFunction";
47
47
  var MEMORY_SIZE_DEFAULT = 128;
48
48
  var TIMEOUT_DEFAULT = 30;
49
- var createLambdaPostgresQueryTemplate = /* @__PURE__ */__name(({
50
- handler: handler2 = HANDLER_DEFAULT,
51
- readOnlyHandler: readOnlyHandler2 = HANDLER_READ_ONLY_DEFAULT,
52
- memorySize = 128,
53
- timeout = 30
54
- } = {}) => {
49
+ var DATABASE_PARAMETERS_DEFAULT = {
50
+ host: "DatabaseHost",
51
+ name: "DatabaseName",
52
+ username: "DatabaseUsername",
53
+ password: "DatabasePassword",
54
+ port: "DatabasePort"
55
+ };
56
+ var createParameter = /* @__PURE__ */__name(({
57
+ description,
58
+ noEcho,
59
+ defaultValue
60
+ }) => {
55
61
  return {
56
- AWSTemplateFormatVersion: "2010-09-09",
57
- Description: "A Lambda function to query PostgreSQL.",
58
- Parameters: {
59
- DatabaseHost: {
60
- Type: "String",
61
- Description: "Database host."
62
- },
63
- DatabaseHostReadOnly: {
64
- Type: "String",
65
- Description: "Database host read only."
66
- },
67
- DatabaseName: {
68
- Type: "String",
69
- Description: "Database name."
70
- },
71
- DatabaseUsername: {
72
- Type: "String",
73
- Description: "Database username."
74
- },
75
- DatabasePassword: {
76
- Type: "String",
77
- Description: "Database password.",
78
- NoEcho: true
79
- },
80
- DatabasePort: {
81
- Type: "String",
82
- Default: "5432",
83
- Description: "Database port."
84
- },
85
- DatabaseNameReadOnly: {
86
- Type: "String",
87
- Description: "Database name for read-only access."
88
- },
89
- DatabaseUsernameReadOnly: {
90
- Type: "String",
91
- Description: "Database username for read-only access."
92
- },
93
- DatabasePasswordReadOnly: {
94
- Type: "String",
95
- Description: "Database password for read-only access.",
96
- NoEcho: true
97
- },
98
- DatabasePortReadOnly: {
99
- Type: "String",
100
- Default: "5432",
101
- Description: "Database port for read-only access."
102
- },
103
- LambdaS3Bucket: {
104
- Type: "String",
105
- Description: "The S3 bucket where the Lambda code is stored."
106
- },
107
- LambdaS3Key: {
108
- Type: "String",
109
- Description: "The S3 key where the Lambda code is stored."
110
- },
111
- LambdaS3ObjectVersion: {
112
- Type: "String",
113
- Description: "The S3 object version of the Lambda code."
114
- },
115
- SecurityGroupIds: {
116
- Description: "Security Group IDs",
117
- Type: "List<AWS::EC2::SecurityGroup::Id>"
118
- },
119
- SubnetIds: {
120
- Description: "Subnet IDs",
121
- Type: "List<AWS::EC2::Subnet::Id>"
122
- }
123
- },
124
- Resources: {
125
- LambdaQueryExecutionRole: {
126
- Type: "AWS::IAM::Role",
127
- Properties: {
128
- AssumeRolePolicyDocument: {
129
- Version: "2012-10-17",
130
- Statement: [{
131
- Effect: "Allow",
132
- Principal: {
133
- Service: "lambda.amazonaws.com"
134
- },
135
- Action: "sts:AssumeRole"
136
- }]
137
- },
138
- ManagedPolicyArns: ["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"]
139
- }
140
- },
141
- LambdaQueryFunction: {
142
- Type: "AWS::Lambda::Function",
143
- Properties: {
144
- Code: {
145
- S3Bucket: {
146
- Ref: "LambdaS3Bucket"
147
- },
148
- S3Key: {
149
- Ref: "LambdaS3Key"
150
- },
151
- S3ObjectVersion: {
152
- Ref: "LambdaS3ObjectVersion"
153
- }
154
- },
155
- MemorySize: memorySize,
156
- Timeout: timeout,
157
- Handler: handler2,
158
- Role: {
159
- "Fn::GetAtt": ["LambdaQueryExecutionRole", "Arn"]
62
+ Type: "String",
63
+ Description: description,
64
+ ...(noEcho ? {
65
+ NoEcho: true
66
+ } : {}),
67
+ ...(defaultValue ? {
68
+ Default: defaultValue
69
+ } : {})
70
+ };
71
+ }, "createParameter");
72
+ var createDefaultFunction = /* @__PURE__ */__name(() => {
73
+ return {
74
+ name: LAMBDA_POSTGRES_QUERY_FUNCTION_DEFAULT_NAME,
75
+ handler: HANDLER_DEFAULT,
76
+ databaseParameters: DATABASE_PARAMETERS_DEFAULT,
77
+ outputArnName: "LambdaPostgresQueryFunctionArn"
78
+ };
79
+ }, "createDefaultFunction");
80
+ var resolveFunctionName = /* @__PURE__ */__name(({
81
+ name,
82
+ logicalId
83
+ }) => {
84
+ const functionName = name || logicalId;
85
+ return functionName || LAMBDA_POSTGRES_QUERY_FUNCTION_DEFAULT_NAME;
86
+ }, "resolveFunctionName");
87
+ var normalizeFunctions = /* @__PURE__ */__name(({
88
+ functions
89
+ }) => {
90
+ if (!functions?.length) {
91
+ return [createDefaultFunction()];
92
+ }
93
+ return functions.map(lambdaFunction => {
94
+ const functionName = resolveFunctionName({
95
+ name: lambdaFunction.name,
96
+ logicalId: lambdaFunction.logicalId
97
+ });
98
+ return {
99
+ name: functionName,
100
+ handler: lambdaFunction.handler || HANDLER_DEFAULT,
101
+ outputArnName: lambdaFunction.outputArnName || `${functionName}Arn`,
102
+ databaseParameters: lambdaFunction.databaseParameters || DATABASE_PARAMETERS_DEFAULT
103
+ };
104
+ });
105
+ }, "normalizeFunctions");
106
+ var createDatabaseParametersForFunction = /* @__PURE__ */__name(({
107
+ databaseParameters,
108
+ functionName,
109
+ allParameters
110
+ }) => {
111
+ return {
112
+ [databaseParameters.host]: allParameters[databaseParameters.host] || createParameter({
113
+ description: `Database host for ${functionName}.`
114
+ }),
115
+ [databaseParameters.name]: allParameters[databaseParameters.name] || createParameter({
116
+ description: `Database name for ${functionName}.`
117
+ }),
118
+ [databaseParameters.username]: allParameters[databaseParameters.username] || createParameter({
119
+ description: `Database username for ${functionName}.`
120
+ }),
121
+ [databaseParameters.password]: allParameters[databaseParameters.password] || createParameter({
122
+ description: `Database password for ${functionName}.`,
123
+ noEcho: true
124
+ }),
125
+ [databaseParameters.port]: allParameters[databaseParameters.port] || createParameter({
126
+ description: `Database port for ${functionName}.`,
127
+ defaultValue: "5432"
128
+ })
129
+ };
130
+ }, "createDatabaseParametersForFunction");
131
+ var createCredentialsParameters = /* @__PURE__ */__name(({
132
+ functions
133
+ }) => {
134
+ return functions.reduce((allParameters, lambdaFunction) => {
135
+ return {
136
+ ...allParameters,
137
+ ...createDatabaseParametersForFunction({
138
+ databaseParameters: lambdaFunction.databaseParameters,
139
+ functionName: lambdaFunction.name,
140
+ allParameters
141
+ })
142
+ };
143
+ }, {});
144
+ }, "createCredentialsParameters");
145
+ var createLambdaResource = /* @__PURE__ */__name(({
146
+ functionName,
147
+ handler: handler2,
148
+ databaseParameters,
149
+ memorySize,
150
+ timeout
151
+ }) => {
152
+ return {
153
+ [functionName]: {
154
+ Type: "AWS::Lambda::Function",
155
+ Properties: {
156
+ Code: {
157
+ S3Bucket: {
158
+ Ref: "LambdaS3Bucket"
160
159
  },
161
- Runtime: "nodejs24.x",
162
- Environment: {
163
- Variables: {
164
- DATABASE_HOST: {
165
- Ref: "DatabaseHost"
166
- },
167
- DATABASE_NAME: {
168
- Ref: "DatabaseName"
169
- },
170
- DATABASE_USERNAME: {
171
- Ref: "DatabaseUsername"
172
- },
173
- DATABASE_PASSWORD: {
174
- Ref: "DatabasePassword"
175
- },
176
- DATABASE_PORT: {
177
- Ref: "DatabasePort"
178
- }
179
- }
160
+ S3Key: {
161
+ Ref: "LambdaS3Key"
180
162
  },
181
- VpcConfig: {
182
- SecurityGroupIds: {
183
- Ref: "SecurityGroupIds"
184
- },
185
- SubnetIds: {
186
- Ref: "SubnetIds"
187
- }
163
+ S3ObjectVersion: {
164
+ Ref: "LambdaS3ObjectVersion"
188
165
  }
189
- }
190
- },
191
- LambdaQueryFunctionLogs: {
192
- Type: "AWS::Logs::LogGroup",
193
- DependsOn: "LambdaQueryFunction",
194
- Properties: {
195
- LogGroupName: {
196
- "Fn::Join": ["", ["/aws/lambda/", {
197
- Ref: "LambdaQueryFunction"
198
- }]]
199
- },
200
- RetentionInDays: 3
201
- }
202
- },
203
- LambdaReadOnlyQueryFunction: {
204
- Type: "AWS::Lambda::Function",
205
- Properties: {
206
- Code: {
207
- S3Bucket: {
208
- Ref: "LambdaS3Bucket"
166
+ },
167
+ MemorySize: memorySize,
168
+ Timeout: timeout,
169
+ Handler: handler2,
170
+ Role: {
171
+ "Fn::GetAtt": ["LambdaQueryExecutionRole", "Arn"]
172
+ },
173
+ Runtime: "nodejs24.x",
174
+ Environment: {
175
+ Variables: {
176
+ DATABASE_HOST: {
177
+ Ref: databaseParameters.host
209
178
  },
210
- S3Key: {
211
- Ref: "LambdaS3Key"
179
+ DATABASE_NAME: {
180
+ Ref: databaseParameters.name
212
181
  },
213
- S3ObjectVersion: {
214
- Ref: "LambdaS3ObjectVersion"
215
- }
216
- },
217
- MemorySize: memorySize,
218
- Timeout: timeout,
219
- Handler: readOnlyHandler2,
220
- Role: {
221
- "Fn::GetAtt": ["LambdaQueryExecutionRole", "Arn"]
222
- },
223
- Runtime: "nodejs24.x",
224
- Environment: {
225
- Variables: {
226
- DATABASE_HOST: {
227
- Ref: "DatabaseHost"
228
- },
229
- DATABASE_NAME: {
230
- Ref: "DatabaseName"
231
- },
232
- DATABASE_USERNAME: {
233
- Ref: "DatabaseUsername"
234
- },
235
- DATABASE_PASSWORD: {
236
- Ref: "DatabasePassword"
237
- },
238
- DATABASE_PORT: {
239
- Ref: "DatabasePort"
240
- },
241
- DATABASE_HOST_READ_ONLY: {
242
- Ref: "DatabaseHostReadOnly"
243
- },
244
- DATABASE_NAME_READ_ONLY: {
245
- Ref: "DatabaseNameReadOnly"
246
- },
247
- DATABASE_USERNAME_READ_ONLY: {
248
- Ref: "DatabaseUsernameReadOnly"
249
- },
250
- DATABASE_PASSWORD_READ_ONLY: {
251
- Ref: "DatabasePasswordReadOnly"
252
- },
253
- DATABASE_PORT_READ_ONLY: {
254
- Ref: "DatabasePortReadOnly"
255
- }
256
- }
257
- },
258
- VpcConfig: {
259
- SecurityGroupIds: {
260
- Ref: "SecurityGroupIds"
182
+ DATABASE_USERNAME: {
183
+ Ref: databaseParameters.username
261
184
  },
262
- SubnetIds: {
263
- Ref: "SubnetIds"
185
+ DATABASE_PASSWORD: {
186
+ Ref: databaseParameters.password
187
+ },
188
+ DATABASE_PORT: {
189
+ Ref: databaseParameters.port
264
190
  }
265
191
  }
266
- }
267
- },
268
- LambdaReadOnlyQueryFunctionLogs: {
269
- Type: "AWS::Logs::LogGroup",
270
- DependsOn: "LambdaReadOnlyQueryFunction",
271
- Properties: {
272
- LogGroupName: {
273
- "Fn::Join": ["", ["/aws/lambda/", {
274
- Ref: "LambdaReadOnlyQueryFunction"
275
- }]]
192
+ },
193
+ VpcConfig: {
194
+ SecurityGroupIds: {
195
+ Ref: "SecurityGroupIds"
276
196
  },
277
- RetentionInDays: 3
197
+ SubnetIds: {
198
+ Ref: "SubnetIds"
199
+ }
278
200
  }
279
201
  }
280
- },
281
- Outputs: {
282
- LambdaPostgresQueryFunction: {
283
- Description: "Lambda function to query PostgreSQL.",
284
- Value: {
285
- Ref: "LambdaQueryFunction"
286
- }
287
- },
288
- LambdaPostgresQueryFunctionArn: {
289
- Description: "Lambda function to query PostgreSQL ARN.",
290
- Value: {
291
- "Fn::GetAtt": ["LambdaQueryFunction", "Arn"]
292
- }
293
- },
294
- LambdaPostgresReadOnlyQueryFunction: {
295
- Description: "Lambda function to query PostgreSQL (read-only).",
202
+ }
203
+ };
204
+ }, "createLambdaResource");
205
+ var createLambdaLogResource = /* @__PURE__ */__name(({
206
+ logicalId
207
+ }) => {
208
+ return {
209
+ [`${logicalId}Logs`]: {
210
+ Type: "AWS::Logs::LogGroup",
211
+ DependsOn: logicalId,
212
+ Properties: {
213
+ LogGroupName: {
214
+ "Fn::Join": ["", ["/aws/lambda/", {
215
+ Ref: logicalId
216
+ }]]
217
+ },
218
+ RetentionInDays: 3
219
+ }
220
+ }
221
+ };
222
+ }, "createLambdaLogResource");
223
+ var createResources = /* @__PURE__ */__name(({
224
+ functions,
225
+ memorySize,
226
+ timeout
227
+ }) => {
228
+ return functions.reduce((allResources, lambdaFunction) => {
229
+ const {
230
+ name,
231
+ handler: handler2,
232
+ databaseParameters
233
+ } = lambdaFunction;
234
+ return {
235
+ ...allResources,
236
+ ...createLambdaResource({
237
+ functionName: name,
238
+ handler: handler2,
239
+ databaseParameters,
240
+ memorySize,
241
+ timeout
242
+ }),
243
+ ...createLambdaLogResource({
244
+ logicalId: name
245
+ })
246
+ };
247
+ }, {});
248
+ }, "createResources");
249
+ var createOutputs = /* @__PURE__ */__name(({
250
+ functions
251
+ }) => {
252
+ return functions.reduce((allOutputs, lambdaFunction) => {
253
+ const {
254
+ name,
255
+ outputArnName
256
+ } = lambdaFunction;
257
+ return {
258
+ ...allOutputs,
259
+ [name]: {
260
+ Description: `Lambda function to query PostgreSQL (${name}).`,
296
261
  Value: {
297
- Ref: "LambdaReadOnlyQueryFunction"
262
+ Ref: name
298
263
  }
299
264
  },
300
- LambdaPostgresReadOnlyQueryFunctionArn: {
301
- Description: "Lambda function to query PostgreSQL (read-only) ARN.",
265
+ [outputArnName]: {
266
+ Description: `Lambda function to query PostgreSQL (${name}) ARN.`,
302
267
  Value: {
303
- "Fn::GetAtt": ["LambdaReadOnlyQueryFunction", "Arn"]
268
+ "Fn::GetAtt": [name, "Arn"]
304
269
  }
305
270
  }
271
+ };
272
+ }, {});
273
+ }, "createOutputs");
274
+ var createTemplateParameters = /* @__PURE__ */__name(({
275
+ credentialsParameters
276
+ }) => {
277
+ return {
278
+ ...credentialsParameters,
279
+ LambdaS3Bucket: {
280
+ Type: "String",
281
+ Description: "The S3 bucket where the Lambda code is stored."
282
+ },
283
+ LambdaS3Key: {
284
+ Type: "String",
285
+ Description: "The S3 key where the Lambda code is stored."
286
+ },
287
+ LambdaS3ObjectVersion: {
288
+ Type: "String",
289
+ Description: "The S3 object version of the Lambda code."
290
+ },
291
+ SecurityGroupIds: {
292
+ Description: "Security Group IDs",
293
+ Type: "List<AWS::EC2::SecurityGroup::Id>"
294
+ },
295
+ SubnetIds: {
296
+ Description: "Subnet IDs",
297
+ Type: "List<AWS::EC2::Subnet::Id>"
306
298
  }
307
299
  };
300
+ }, "createTemplateParameters");
301
+ var createExecutionRoleResource = /* @__PURE__ */__name(() => {
302
+ return {
303
+ LambdaQueryExecutionRole: {
304
+ Type: "AWS::IAM::Role",
305
+ Properties: {
306
+ AssumeRolePolicyDocument: {
307
+ Version: "2012-10-17",
308
+ Statement: [{
309
+ Effect: "Allow",
310
+ Principal: {
311
+ Service: "lambda.amazonaws.com"
312
+ },
313
+ Action: "sts:AssumeRole"
314
+ }]
315
+ },
316
+ ManagedPolicyArns: ["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"]
317
+ }
318
+ }
319
+ };
320
+ }, "createExecutionRoleResource");
321
+ var createLambdaPostgresQueryTemplate = /* @__PURE__ */__name(({
322
+ functions,
323
+ memorySize = MEMORY_SIZE_DEFAULT,
324
+ timeout = TIMEOUT_DEFAULT
325
+ } = {}) => {
326
+ const templateFunctions = normalizeFunctions({
327
+ functions
328
+ });
329
+ const credentialsParameters = createCredentialsParameters({
330
+ functions: templateFunctions
331
+ });
332
+ const templateResources = createResources({
333
+ functions: templateFunctions,
334
+ memorySize,
335
+ timeout
336
+ });
337
+ const templateOutputs = createOutputs({
338
+ functions: templateFunctions
339
+ });
340
+ return {
341
+ AWSTemplateFormatVersion: "2010-09-09",
342
+ Description: "A Lambda function to query PostgreSQL.",
343
+ Parameters: createTemplateParameters({
344
+ credentialsParameters
345
+ }),
346
+ Resources: {
347
+ ...createExecutionRoleResource(),
348
+ ...templateResources
349
+ },
350
+ Outputs: templateOutputs
351
+ };
308
352
  }, "createLambdaPostgresQueryTemplate");
309
353
 
310
354
  // src/cloudformation/lambdaQueryHandler.ts
@@ -338,71 +382,13 @@ var handler = /* @__PURE__ */__name(async event => {
338
382
  throw error;
339
383
  }
340
384
  }, "handler");
341
-
342
- // src/cloudformation/lambdaReadOnlyQueryHandler.ts
343
- var import_pg2 = require("pg");
344
- var databaseReadOnly = process.env.DATABASE_NAME_READ_ONLY;
345
- var usernameReadOnly = process.env.DATABASE_USERNAME_READ_ONLY;
346
- var passwordReadOnly = process.env.DATABASE_PASSWORD_READ_ONLY;
347
- var hostReadOnly = process.env.DATABASE_HOST_READ_ONLY;
348
- var portReadOnly = process.env.DATABASE_PORT_READ_ONLY;
349
- var getConnectionConfig = /* @__PURE__ */__name(() => {
350
- return {
351
- database: databaseReadOnly || process.env.DATABASE_NAME,
352
- username: usernameReadOnly || process.env.DATABASE_USERNAME,
353
- password: passwordReadOnly || process.env.DATABASE_PASSWORD,
354
- host: hostReadOnly || process.env.DATABASE_HOST,
355
- port: portReadOnly || process.env.DATABASE_PORT
356
- };
357
- }, "getConnectionConfig");
358
- var readOnlyHandler = /* @__PURE__ */__name(async event => {
359
- if (!databaseReadOnly && !usernameReadOnly && !passwordReadOnly && !hostReadOnly && !portReadOnly) {
360
- throw new Error("At least one read-only override must be defined (DATABASE_NAME_READ_ONLY, DATABASE_USERNAME_READ_ONLY, DATABASE_PASSWORD_READ_ONLY, DATABASE_HOST_READ_ONLY, DATABASE_PORT_READ_ONLY). Unset overrides fall back to the corresponding non-read-only env vars.");
361
- }
362
- const {
363
- database: database2,
364
- username: username2,
365
- password: password2,
366
- host: host2,
367
- port: port2
368
- } = getConnectionConfig();
369
- try {
370
- const client = new import_pg2.Client({
371
- database: database2,
372
- user: username2,
373
- password: password2,
374
- host: host2,
375
- port: Number(port2)
376
- });
377
- await client.connect();
378
- try {
379
- await client.query("BEGIN READ ONLY");
380
- try {
381
- const res = await client.query(event);
382
- await client.query("COMMIT");
383
- return res;
384
- } catch (queryError) {
385
- await client.query("ROLLBACK");
386
- throw queryError;
387
- }
388
- } finally {
389
- await client.end();
390
- }
391
- } catch (error) {
392
- console.error("Error running read-only query", {
393
- error,
394
- event
395
- });
396
- throw error;
397
- }
398
- }, "readOnlyHandler");
399
385
  // Annotate the CommonJS export names for ESM import in node:
400
386
  0 && (module.exports = {
387
+ DATABASE_PARAMETERS_DEFAULT,
401
388
  HANDLER_DEFAULT,
402
- HANDLER_READ_ONLY_DEFAULT,
389
+ LAMBDA_POSTGRES_QUERY_FUNCTION_DEFAULT_NAME,
403
390
  MEMORY_SIZE_DEFAULT,
404
391
  TIMEOUT_DEFAULT,
405
392
  createLambdaPostgresQueryTemplate,
406
- handler,
407
- readOnlyHandler
393
+ handler
408
394
  });