UNPKG

@sailplane/lambda-utils

Version:

Use middleware to remove redundancy in AWS Lambda handlers.

160 lines (154 loc) 6.39 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // lib/index.ts var index_exports = {}; __export(index_exports, { apiFailure: () => apiFailure, apiSuccess: () => apiSuccess, loggerContextMiddleware: () => loggerContextMiddleware, resolvedPromiseIsSuccessMiddleware: () => resolvedPromiseIsSuccessMiddleware, unhandledExceptionMiddleware: () => unhandledExceptionMiddleware, wrapApiHandler: () => wrapApiHandler, wrapApiHandlerV1: () => wrapApiHandlerV1, wrapApiHandlerV2: () => wrapApiHandlerV2 }); module.exports = __toCommonJS(index_exports); // lib/handler-utils.ts var import_core = __toESM(require("@middy/core")); var import_http_cors = __toESM(require("@middy/http-cors")); var import_http_event_normalizer = __toESM(require("@middy/http-event-normalizer")); var import_http_header_normalizer = __toESM(require("@middy/http-header-normalizer")); var import_http_json_body_parser = __toESM(require("@middy/http-json-body-parser")); var import_logger3 = require("@sailplane/logger"); // lib/resolved-promise-is-success.ts var resolvedPromiseIsSuccessMiddleware = () => ({ after: async (request) => { const response = request.response; if (!response || typeof response !== "object" || !response.statusCode && !response.body) { request.response = { statusCode: 200, body: response ? JSON.stringify(response) : "", headers: { "content-type": response ? "application/json; charset=utf-8" : "text/plain; charset=utf-8" } }; } } }); // lib/unhandled-exception.ts var import_logger = require("@sailplane/logger"); var logger = new import_logger.Logger("lambda-utils"); var unhandledExceptionMiddleware = () => ({ onError: async (request) => { logger.error("Unhandled exception:", request.error); request.response = request.response || {}; if ((request.response.statusCode || 0) < 400) { const error = findRootCause(request.error); request.response.statusCode = error?.statusCode || 500; request.response.body = error?.toString() ?? ""; request.response.headers = request.response.headers ?? {}; request.response.headers["content-type"] = "text/plain; charset=utf-8"; } logger.info("Response to API Gateway: ", request.response); } }); function findRootCause(error) { const errorWithStatus = error; if (errorWithStatus?.statusCode && errorWithStatus.statusCode >= 400) { return error; } else if (errorWithStatus?.cause) { return findRootCause(errorWithStatus.cause); } else { return error; } } // lib/logger-context.ts var import_logger2 = require("@sailplane/logger"); var loggerContextMiddleware = () => { return { before: async (request) => { import_logger2.Logger.setLambdaContext(request.context); const requestContext = request.event.requestContext; const claims = requestContext?.authorizer?.claims || // API v1 requestContext?.authorizer?.jwt?.claims; const context = { api_request_id: requestContext?.requestId, jwt_sub: claims?.sub }; import_logger2.Logger.addAttributes(context); } }; }; // lib/handler-utils.ts var logger2 = new import_logger3.Logger("lambda-utils"); function wrapApiHandler(handler) { return (0, import_core.default)(handler).use((0, import_http_cors.default)({ origin: "*" })).use(resolvedPromiseIsSuccessMiddleware()).use(unhandledExceptionMiddleware()).use(loggerContextMiddleware()).use((0, import_http_event_normalizer.default)()).use((0, import_http_header_normalizer.default)()).use( // Parse JSON body, but don't throw when there is no body (0, import_http_json_body_parser.default)({ disableContentTypeError: true }) ); } var wrapApiHandlerV1 = wrapApiHandler; function wrapApiHandlerV2(handler) { return (0, import_core.default)(handler).use((0, import_http_cors.default)({ origin: "*" })).use(resolvedPromiseIsSuccessMiddleware()).use(unhandledExceptionMiddleware()).use(loggerContextMiddleware()).use((0, import_http_event_normalizer.default)()).use((0, import_http_header_normalizer.default)()).use( // Parse JSON body, but don't throw when there is no body (0, import_http_json_body_parser.default)({ disableContentTypeError: true }) ); } function apiSuccess(result) { return { statusCode: 200, body: result ? JSON.stringify(result) : "", headers: { "content-type": result ? "application/json; charset=utf-8" : "text/plain; charset=utf-8" } }; } function apiFailure(statusCode, message) { const response = { statusCode, body: message || "", headers: { "content-type": "text/plain; charset=utf-8" } }; logger2.warn("Response to API Gateway: ", response); return response; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { apiFailure, apiSuccess, loggerContextMiddleware, resolvedPromiseIsSuccessMiddleware, unhandledExceptionMiddleware, wrapApiHandler, wrapApiHandlerV1, wrapApiHandlerV2 }); //# sourceMappingURL=index.js.map