made first lambda function and deployed it successfully

This commit is contained in:
2025-11-12 11:35:06 +05:30
parent 0230105958
commit 5399c8b987
6 changed files with 1752 additions and 225 deletions

1742
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -35,6 +35,7 @@
"@nestjs/throttler": "^5.1.1", "@nestjs/throttler": "^5.1.1",
"@prisma/client": "^5.8.1", "@prisma/client": "^5.8.1",
"@types/http-status": "^1.1.2", "@types/http-status": "^1.1.2",
"ajv": "8.12.0",
"aws-lambda": "^1.0.7", "aws-lambda": "^1.0.7",
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",
"class-transformer": "^0.5.1", "class-transformer": "^0.5.1",
@@ -46,7 +47,7 @@
"passport-local": "^1.0.0", "passport-local": "^1.0.0",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",
"rxjs": "^7.8.1", "rxjs": "^7.8.1",
"serverless": "^4.23.0", "serverless": "4.17.0",
"swagger-ui-express": "^5.0.0", "swagger-ui-express": "^5.0.0",
"yup": "^1.7.1" "yup": "^1.7.1"
}, },
@@ -69,6 +70,7 @@
"jest": "^29.7.0", "jest": "^29.7.0",
"prettier": "^3.2.5", "prettier": "^3.2.5",
"prisma": "^5.8.1", "prisma": "^5.8.1",
"serverless-esbuild": "^1.55.1",
"source-map-support": "^0.5.21", "source-map-support": "^0.5.21",
"supertest": "^6.3.4", "supertest": "^6.3.4",
"ts-jest": "^29.1.2", "ts-jest": "^29.1.2",

View File

@@ -1,25 +1,14 @@
#org: WDI
service: minglarDev service: minglarDev
# plugins:
# - serverless-domain-manager
# custom:
# customDomain:
# domainName: sandbox.tanamicapital.com
# basePath: ''
# stage: dev
# createRoute53Record: true
# endpointType: 'edge'
provider: provider:
name: aws name: aws
versionFunctions: false
runtime: nodejs20.x runtime: nodejs20.x
region: me-south-1 region: ap-south-1
versionFunctions: false
environment: environment:
DATABASE_URL: ${env:DATABASE_URL} DATABASE_URL: ${env:DATABASE_URL}
BY_PASS_EMAIL: ${env:BY_PASS_EMAIL} BY_PASS_EMAIL: ${env:BY_PASS_EMAIL}
BYPASS_OTP: ${env:BYPASS_OTP} BYPASS_OTP: ${env:BYPASS_OTP}
ENCRYPTION_KEY: ${env:ENCRYPTION_KEY}
BREVO_EMAIL_API_KEY: ${env:BREVO_EMAIL_API_KEY} BREVO_EMAIL_API_KEY: ${env:BREVO_EMAIL_API_KEY}
BREVO_API_BASEURL: ${env:BREVO_API_BASEURL} BREVO_API_BASEURL: ${env:BREVO_API_BASEURL}
BREVO_FROM_EMAIL: ${env:BREVO_FROM_EMAIL} BREVO_FROM_EMAIL: ${env:BREVO_FROM_EMAIL}
@@ -27,53 +16,58 @@ provider:
BREVO_SMTP_PORT: ${env:BREVO_SMTP_PORT} BREVO_SMTP_PORT: ${env:BREVO_SMTP_PORT}
BREVO_SMTP_USER: ${env:BREVO_SMTP_USER} BREVO_SMTP_USER: ${env:BREVO_SMTP_USER}
BREVO_SMTP_PASS: ${env:BREVO_SMTP_PASS} BREVO_SMTP_PASS: ${env:BREVO_SMTP_PASS}
TWILIO_ACCOUNT_SID: ${env:TWILIO_ACCOUNT_SID}
TWILIO_AUTH_TOKEN: ${env:TWILIO_AUTH_TOKEN}
TWILIO_SMS_FROM: ${env:TWILIO_SMS_FROM}
TWILIO_ALPHA_SENDER: ${env:TWILIO_ALPHA_SENDER}
REFRESH_TOKEN_SECRET: ${env:REFRESH_TOKEN_SECRET} REFRESH_TOKEN_SECRET: ${env:REFRESH_TOKEN_SECRET}
JWT_SECRET: ${env:JWT_SECRET} JWT_SECRET: ${env:JWT_SECRET}
API_URL: ${env:API_URL}
COGNITO_USER_POOL_ID: ${env:COGNITO_USER_POOL_ID}
COGNITO_CLIENT_ID: ${env:COGNITO_CLIENT_ID}
COGNITO_REGION: ${env:COGNITO_REGION}
DEFAULT_PASSWORD: ${env:DEFAULT_PASSWORD}
SALT_ROUNDS: ${env:SALT_ROUNDS} SALT_ROUNDS: ${env:SALT_ROUNDS}
TEST_NUMBERS: ${env:TEST_NUMBERS}
DEFAULT_OTP: ${env:DEFAULT_OTP}
AWS_S3_BUCKET: ${env:AWS_S3_BUCKET}
iamRoleStatements:
- Effect: Allow
Action:
- cognito-idp:AdminUpdateUserAttributes
Resource: arn:aws:cognito-idp:${env:COGNITO_REGION}:058264420740:userpool/${env:COGNITO_USER_POOL_ID}
httpApi: httpApi:
cors: cors:
allowedOrigins: allowedOrigins: ['*']
- '*'
allowedHeaders: allowedHeaders:
- Content-Type - Content-Type
- X-Amz-Date - X-Amz-Date
- Authorization - Authorization
- X-Api-Key - X-Api-Key
- X-Auth-Token
allowCredentials: false allowCredentials: false
custom:
esbuild:
bundle: true
minify: false
sourcemap: false
exclude: ['aws-sdk']
target: node20
platform: node
concurrency: 10
outdir: dist
package: package:
individually: true individually: true
patterns: patterns:
- '!**/*' # Exclude everything by default - '!node_modules/**' # exclude all node_modules first
- 'src/lambda/**' # Include handler files - '!**/*.spec.ts'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node' # Specific engine file - '!**/*.test.ts'
- 'node_modules/@prisma/client/**' # Prisma client - '!**/*.log'
- '!node_modules/**' # Exclude other node_modules - 'src/**' # include all source files
- '!node_modules/.prisma/client/query-engine-*' # Exclude other engines - 'common/**' # include common modules
- 'node_modules/@prisma/client/**'
- 'node_modules/.prisma/client/**'
- 'prisma/schema.prisma'
functions: functions:
testFunc: # 👇 Example Lambda for Host Module
handler: src/lambda/testFunc.handler
getHosts:
handler: src/modules/host/handlers/host.handler
package:
patterns:
- 'src/modules/host/**'
- 'common/**'
- 'node_modules/.prisma/client/libquery_engine-rhel-openssl-3.0.x.so.node'
- 'node_modules/@prisma/client/**'
- 'prisma/schema.prisma'
events: events:
- httpApi: - httpApi:
path: /testFunc path: /host
method: get method: get

View File

@@ -0,0 +1,55 @@
// safeHandler.ts
import { APIGatewayProxyEvent, Context, APIGatewayProxyResult } from 'aws-lambda';
import ApiError from '../helper/ApiError';
const stage = process.env.STAGE ?? 'dev';
export const safeHandler = (
handler: (event: APIGatewayProxyEvent, context?: Context) => Promise<APIGatewayProxyResult | undefined>
): ((event: APIGatewayProxyEvent, context: Context) => Promise<APIGatewayProxyResult>) => {
return async (event, context) => {
try {
const result = await handler(event, context);
return (
result ?? {
statusCode: 204,
body: '',
}
);
} catch (error: any) {
console.error('Error occurred:', error);
if (error instanceof ApiError) {
return {
statusCode: error.statusCode,
body: JSON.stringify({
success: false,
message: error.message,
data: null,
error: {
code: error.statusCode,
description: error.message,
statusCode: error.statusCode,
...(process.env.STAGE !== 'prod' && { debug: error.stack ?? error.message }),
},
}),
};
}
return {
statusCode: 500,
body: JSON.stringify({
success: false,
message: 'Internal server error',
data: null,
error: {
code: 500,
description: 'Internal server error',
statusCode: 500,
...(process.env.STAGE !== 'prod' && { debug: error.stack ?? error.message }),
},
}),
};
}
};
};

View File

@@ -1,68 +0,0 @@
// src/modules/host/handler/host.handler.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from 'src/app.module';
import { HostService } from '../services/host.service';
import { APIGatewayProxyHandler } from 'aws-lambda';
import { CreateHostDto, UpdateHostDto } from '../dto/host.dto';
let app;
let hostService: HostService;
async function bootstrap() {
if (!app) {
const nestApp = await NestFactory.createApplicationContext(AppModule);
hostService = nestApp.get(HostService);
app = nestApp;
}
}
export const handler: APIGatewayProxyHandler = async (event) => {
await bootstrap();
const method = event.httpMethod;
const path = event.path;
const body = event.body ? JSON.parse(event.body) : {};
try {
if (method === 'POST' && path.endsWith('/host')) {
const host = await hostService.createHost(body as CreateHostDto);
return response(201, host);
}
if (method === 'GET' && path.endsWith('/host')) {
const hosts = await hostService.getAllHosts();
return response(200, hosts);
}
if (method === 'GET' && path.match(/\/host\/\d+$/)) {
const id = Number(path.split('/').pop());
const host = await hostService.getHostById(id);
return response(200, host);
}
if (method === 'PUT' && path.match(/\/host\/\d+$/)) {
const id = Number(path.split('/').pop());
const host = await hostService.updateHost(id, body as UpdateHostDto);
return response(200, host);
}
if (method === 'DELETE' && path.match(/\/host\/\d+$/)) {
const id = Number(path.split('/').pop());
const host = await hostService.deleteHost(id);
return response(200, { message: 'Host deleted successfully', host });
}
return response(404, { message: 'Not Found' });
} catch (error) {
console.error('Error:', error);
return response(500, { message: error.message || 'Internal Server Error' });
}
};
function response(statusCode: number, body: any) {
return {
statusCode,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
};
}

View File

@@ -0,0 +1,28 @@
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { PrismaClient } from '@prisma/client';
import { safeHandler } from '../../../common/utils/handlers/safeHandler';
const prisma = new PrismaClient();
export const handler = safeHandler(async (
event: APIGatewayProxyEvent
): Promise<APIGatewayProxyResult> => {
const result = await prisma.hostHeader.findMany({
select: {
hostParent: true,
hostRefNumber: true,
hostStatusDisplay: true,
accountManager: true,
},
});
return {
statusCode: 200,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
body: JSON.stringify(result),
}
})