UNPKG

@geek-fun/serverlessinsight

Version:

Full life cycle cross providers serverless application management for your fast-growing business.

121 lines (120 loc) 5.19 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.functionsHandler = void 0; const common_1 = require("../../common"); const functionRunner_1 = require("./functionRunner"); const node_path_1 = __importDefault(require("node:path")); const node_fs_1 = __importDefault(require("node:fs")); const aliyunFc_1 = require("./aliyunFc"); const utils_1 = require("./utils"); const functionsHandler = async (req, parsed, iac) => { common_1.logger.info(`Function request received by local server -> ${req.method} ${parsed.identifier ?? '/'} `); const fcDef = iac.functions?.find((fn) => fn.key === parsed.identifier); if (!fcDef) { return { statusCode: 404, body: { error: 'Function not found', functionKey: parsed.identifier }, }; } if (!fcDef.code) { return { statusCode: 400, body: { error: 'Function code configuration not found', functionKey: fcDef.key }, }; } let tempDir = null; try { const codePath = node_path_1.default.resolve(process.cwd(), fcDef.code.path); let codeDir; if (codePath.endsWith('.zip') && node_fs_1.default.existsSync(codePath)) { tempDir = await (0, utils_1.extractZipFile)(codePath); codeDir = tempDir; } else if (node_fs_1.default.existsSync(codePath) && node_fs_1.default.statSync(codePath).isDirectory()) { codeDir = codePath; } else { codeDir = node_path_1.default.dirname(codePath); } const funOptions = { codeDir, functionKey: fcDef.key, handler: fcDef.code.handler, servicePath: '', timeout: fcDef.timeout * 1000, }; // Check if provider is Aliyun to use Aliyun FC format const isAliyun = iac.provider.name === common_1.ProviderEnum.ALIYUN; let event; let fcContext; let env; if (isAliyun) { // Aliyun FC format: event is a Buffer containing JSON const requestId = (0, aliyunFc_1.generateRequestId)(); const { event: aliyunEvent } = await (0, aliyunFc_1.transformToAliyunEvent)(req, parsed.url, parsed.query); event = aliyunEvent; // Use serializable context for worker thread (logger will be added inside worker) fcContext = (0, aliyunFc_1.createAliyunContextSerializable)(iac, fcDef.name, fcDef.code.handler, fcDef.memory, fcDef.timeout, requestId); env = { ...fcDef.environment, }; } else { // AWS Lambda format (default) const rawBody = await (0, common_1.readRequestBody)(req); event = rawBody ? JSON.parse(rawBody) : {}; env = { ...fcDef.environment, AWS_REGION: iac.provider.region || 'us-east-1', FUNCTION_NAME: fcDef.name, FUNCTION_MEMORY_SIZE: String(fcDef.memory), FUNCTION_TIMEOUT: String(fcDef.timeout), }; fcContext = { functionName: fcDef.name, functionVersion: '$LATEST', memoryLimitInMB: fcDef.memory, logGroupName: `/aws/lambda/${fcDef.name}`, logStreamName: `${new Date().toISOString().split('T')[0]}/[$LATEST]${Math.random().toString(36).substring(7)}`, invokedFunctionArn: `arn:aws:lambda:${iac.provider.region}:000000000000:function:${fcDef.name}`, awsRequestId: Math.random().toString(36).substring(2, 15), }; } common_1.logger.debug(`Invoking worker with event type: ${isAliyun ? 'Buffer' : 'Object'} and context`); common_1.logger.debug(`Worker codeDir: ${codeDir}, handler: ${funOptions.handler}`); const result = await (0, functionRunner_1.invokeFunction)(funOptions, env, event, fcContext); common_1.logger.info(`Function execution result: ${JSON.stringify(result)}`); // For Aliyun, transform FC response to HTTP response if needed if (isAliyun && result) { const transformed = (0, aliyunFc_1.transformFCResponse)(result); return { statusCode: transformed.statusCode, headers: transformed.headers, body: transformed.body, }; } return { statusCode: 200, body: result, }; } catch (error) { common_1.logger.error(`Function execution error: ${error}`); return { statusCode: 500, body: { error: 'Function execution failed', message: error instanceof Error ? error.message : String(error), }, }; } finally { if (tempDir && node_fs_1.default.existsSync(tempDir)) { node_fs_1.default.rmSync(tempDir, { recursive: true, force: true }); } } }; exports.functionsHandler = functionsHandler;