UNPKG

serverless-offline-reasint

Version:

Emulate AWS λ and API Gateway locally when developing your Serverless project

360 lines (354 loc) 11.2 kB
"use strict" const { pathToFileURL } = require("node:url") // node_modules/lambda-runtime/dist/node16/UserFunction.js ;(function () { const __getOwnPropNames = Object.getOwnPropertyNames const __commonJS = (cb, mod) => function __require() { return ( mod || (0, cb[__getOwnPropNames(cb)[0]])( (mod = { exports: {} }).exports, mod, ), mod.exports ) } const require_Errors = __commonJS({ "Errors.js": function (exports2, module2) { "use strict" const util = require("util") function _isError(obj) { return ( obj && obj.name && obj.message && obj.stack && typeof obj.name === "string" && typeof obj.message === "string" && typeof obj.stack === "string" ) } function intoError(err) { if (err instanceof Error) { return err } return new Error(err) } module2.exports.intoError = intoError function toRapidResponse(error) { try { if (util.types.isNativeError(error) || _isError(error)) { return { errorType: error.name, errorMessage: error.message, trace: error.stack.split("\n"), } } return { errorType: typeof error, errorMessage: error.toString(), trace: [], } } catch (_err) { return { errorType: "handled", errorMessage: "callback called with Error argument, but there was a problem while retrieving one or more of its message, name, and stack", } } } module2.exports.toRapidResponse = toRapidResponse module2.exports.toFormatted = (error) => { try { return ` ${JSON.stringify(error, (_k, v) => _withEnumerableProperties(v), )}` } catch (err) { return ` ${JSON.stringify(toRapidResponse(error))}` } } function _withEnumerableProperties(error) { if (error instanceof Error) { const ret = { errorType: error.name, errorMessage: error.message, code: error.code, ...error, } if (typeof error.stack === "string") { ret.stack = error.stack.split("\n") } return ret } return error } const errorClasses = [ class ImportModuleError extends Error {}, class HandlerNotFound extends Error {}, class MalformedHandlerName extends Error {}, class UserCodeSyntaxError extends Error {}, class MalformedStreamingHandler extends Error {}, class InvalidStreamingOperation extends Error {}, class UnhandledPromiseRejection extends Error { constructor(reason, promise) { super(reason) this.reason = reason this.promise = promise } }, ] errorClasses.forEach((e) => { module2.exports[e.name] = e e.prototype.name = `Runtime.${e.name}` }) }, }) const require_VerboseLog = __commonJS({ "VerboseLog.js": function (exports2) { "use strict" const EnvVarName = "AWS_LAMBDA_RUNTIME_VERBOSE" const Tag = "RUNTIME" const Verbosity = (() => { if (!process.env[EnvVarName]) { return 0 } try { const verbosity = parseInt(process.env[EnvVarName]) return verbosity < 0 ? 0 : verbosity > 3 ? 3 : verbosity } catch (_) { return 0 } })() exports2.logger = function (category) { return { verbose() { if (Verbosity >= 1) { console.log.apply(null, [Tag, category, ...arguments]) } }, vverbose() { if (Verbosity >= 2) { console.log.apply(null, [Tag, category, ...arguments]) } }, vvverbose() { if (Verbosity >= 3) { console.log.apply(null, [Tag, category, ...arguments]) } }, } } }, }) const require_HttpResponseStream = __commonJS({ "HttpResponseStream.js": function (exports2, module2) { "use strict" const METADATA_PRELUDE_CONTENT_TYPE = "application/vnd.awslambda.http-integration-response" const DELIMITER_LEN = 8 const HttpResponseStream2 = class { static from(underlyingStream, prelude) { underlyingStream.setContentType(METADATA_PRELUDE_CONTENT_TYPE) const metadataPrelude = JSON.stringify(prelude) underlyingStream._onBeforeFirstWrite = (write) => { write(metadataPrelude) write(new Uint8Array(DELIMITER_LEN)) } return underlyingStream } } module2.exports.HttpResponseStream = HttpResponseStream2 }, }) const path = require("path") const fs = require("fs") const { HandlerNotFound, MalformedHandlerName, ImportModuleError, UserCodeSyntaxError, } = require_Errors() const { verbose } = require_VerboseLog().logger("LOADER") const { HttpResponseStream } = require_HttpResponseStream() const FUNCTION_EXPR = /^([^.]*)\.(.*)$/ const RELATIVE_PATH_SUBSTRING = ".." const HANDLER_STREAMING = Symbol.for("aws.lambda.runtime.handler.streaming") const STREAM_RESPONSE = "response" const NoGlobalAwsLambda = process.env.AWS_LAMBDA_NODEJS_NO_GLOBAL_AWSLAMBDA === "1" || process.env.AWS_LAMBDA_NODEJS_NO_GLOBAL_AWSLAMBDA === "true" function _moduleRootAndHandler(fullHandlerString) { const handlerString = path.basename(fullHandlerString) const moduleRoot = fullHandlerString.substring( 0, fullHandlerString.indexOf(handlerString), ) return [moduleRoot, handlerString] } function _splitHandlerString(handler) { const match = handler.match(FUNCTION_EXPR) if (!match || match.length != 3) { throw new MalformedHandlerName("Bad handler") } return [match[1], match[2]] } function _resolveHandler(object, nestedProperty) { return nestedProperty.split(".").reduce((nested, key) => { return nested && nested[key] }, object) } function _tryRequireFile(file, extension) { const path2 = file + (extension || "") verbose("Try loading as commonjs:", path2) return fs.existsSync(path2) ? require(path2) : void 0 } async function _tryAwaitImport(file, extension) { const path2 = file + (extension || "") verbose("Try loading as esmodule:", path2) if (fs.existsSync(path2)) { return await import(pathToFileURL(path2).href) } return void 0 } function _hasFolderPackageJsonTypeModule(folder) { if (folder.endsWith("/node_modules")) { return false } const pj = path.join(folder, "/package.json") if (fs.existsSync(pj)) { try { const pkg = JSON.parse(fs.readFileSync(pj)) if (pkg) { if (pkg.type === "module") { verbose(`'type: module' detected in ${pj}`) return true } verbose(`'type: module' not detected in ${pj}`) return false } } catch (e) { console.warn( `${pj} cannot be read, it will be ignored for ES module detection purposes.`, e, ) return false } } if (folder === "/") { return false } return _hasFolderPackageJsonTypeModule(path.resolve(folder, "..")) } function _hasPackageJsonTypeModule(file) { const jsPath = `${file}.js` return fs.existsSync(jsPath) ? _hasFolderPackageJsonTypeModule(path.resolve(path.dirname(jsPath))) : false } async function _tryRequire(appRoot, moduleRoot, module2) { verbose( "Try loading as commonjs: ", module2, " with paths: ,", appRoot, moduleRoot, ) const lambdaStylePath = path.resolve(appRoot, moduleRoot, module2) const extensionless = _tryRequireFile(lambdaStylePath) if (extensionless) { return extensionless } const pjHasModule = _hasPackageJsonTypeModule(lambdaStylePath) if (!pjHasModule) { const loaded2 = _tryRequireFile(lambdaStylePath, ".js") if (loaded2) { return loaded2 } } const loaded = (pjHasModule && (await _tryAwaitImport(lambdaStylePath, ".js"))) || (await _tryAwaitImport(lambdaStylePath, ".mjs")) || _tryRequireFile(lambdaStylePath, ".cjs") if (loaded) { return loaded } verbose( "Try loading as commonjs: ", module2, " with path(s): ", appRoot, moduleRoot, ) const nodeStylePath = require.resolve(module2, { paths: [appRoot, moduleRoot], }) return require(nodeStylePath) } async function _loadUserApp(appRoot, moduleRoot, module2) { if (!NoGlobalAwsLambda) { globalThis.awslambda = { streamifyResponse: (handler) => { handler[HANDLER_STREAMING] = STREAM_RESPONSE return handler }, HttpResponseStream, } } try { return await _tryRequire(appRoot, moduleRoot, module2) } catch (e) { if (e instanceof SyntaxError) { throw new UserCodeSyntaxError(e) } else if (e.code !== void 0 && e.code === "MODULE_NOT_FOUND") { verbose("globalPaths", JSON.stringify(require("module").globalPaths)) throw new ImportModuleError(e) } else { throw e } } } function _throwIfInvalidHandler(fullHandlerString) { if (fullHandlerString.includes(RELATIVE_PATH_SUBSTRING)) { throw new MalformedHandlerName( `'${fullHandlerString}' is not a valid handler name. Use absolute paths when specifying root directories in handler names.`, ) } } function _isHandlerStreaming(handler) { if ( typeof handler[HANDLER_STREAMING] === "undefined" || handler[HANDLER_STREAMING] === null || handler[HANDLER_STREAMING] === false ) { return false } if (handler[HANDLER_STREAMING] === STREAM_RESPONSE) { return STREAM_RESPONSE } throw new MalformedStreamingHandler("Only response streaming is supported.") } module.exports.load = async function (appRoot, fullHandlerString) { _throwIfInvalidHandler(fullHandlerString) const [moduleRoot, moduleAndHandler] = _moduleRootAndHandler(fullHandlerString) const [module2, handlerPath] = _splitHandlerString(moduleAndHandler) const userApp = await _loadUserApp(appRoot, moduleRoot, module2) const handlerFunc = _resolveHandler(userApp, handlerPath) if (!handlerFunc) { throw new HandlerNotFound( `${fullHandlerString} is undefined or not exported`, ) } if (typeof handlerFunc !== "function") { throw new HandlerNotFound(`${fullHandlerString} is not a function`) } return handlerFunc } module.exports.getHandlerMetadata = function (handlerFunc) { return { streaming: _isHandlerStreaming(handlerFunc), } } module.exports.STREAM_RESPONSE = STREAM_RESPONSE })()