UNPKG

serverless-aws-lambda

Version:

AWS Application Load Balancer and API Gateway - Lambda dev tool for Serverless. Allows Express synthax in handlers. Supports packaging, local invoking and offline ALB, APG, S3, SNS, SQS, DynamoDB Stream server mocking.

20 lines (19 loc) 10.1 kB
"use strict";var G=Object.create;var N=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var V=Object.getOwnPropertyNames;var j=Object.getPrototypeOf,Q=Object.prototype.hasOwnProperty;var J=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of V(e))!Q.call(t,o)&&o!==r&&N(t,o,{get:()=>e[o],enumerable:!(n=q(e,o))||n.enumerable});return t};var K=(t,e,r)=>(r=t!=null?G(j(t)):{},J(e||!t||!t.__esModule?N(r,"default",{value:t,enumerable:!0}):r,t));var c=require("worker_threads");var P=require("stream"),x=class extends P.Writable{#e=!1;#t;#n=new TypeError('Invalid value "undefined" for header "Content-Type"');_onBeforeFirstWrite;constructor(e){super({highWaterMark:e.highWaterMark,write:e.write}),this.#t=this.write.bind(this),this.write=(n,o,l)=>{n=this.#o(n),!this.#e&&typeof this._onBeforeFirstWrite=="function"&&this._onBeforeFirstWrite(m=>this.#t(m));let i=this.#t(n,o,l);return this.#e||(this.#e=!0),i};let r=this.end.bind(this);this.end=(...n)=>{if(n.length){let[o]=n;o&&typeof o!="function"?(this.write(o),r()):r(...n)}else r(...n)}}#o=e=>(typeof e!="string"&&!Buffer.isBuffer(e)&&e?.constructor!==Uint8Array&&(e=JSON.stringify(e)),e);setContentType=e=>{if(!e)throw this.#n;this.emit("ct",e)}};var _=require("async_hooks"),S=require("util"),F=K(require("path")),O=process.cwd(),Y=`${O}/`,A="/dist/lambda/router.",$=O.split(F.default.sep).filter(Boolean)[0],R=new RegExp(`\\((/${$}|${$}).*(\\d+):(\\d+)`),z=clearTimeout.bind(clearTimeout),{AWS_LAMBDA_FUNCTION_NAME:B}=process.env,X=t=>{let e=t.match(/{[\w\W]*}/);if(e)return`${t.slice(0,e.index+1)} \x1B[33m try {\x1B[0m ${t.slice(e.index+1,-1).trim()} \x1B[33m } catch (error) {\x1B[0m \x1B[35m // handle the error\x1B[0m \x1B[33m }\x1B[0m }`},L=t=>{let e={errorType:"string",errorMessage:"",trace:[]};if(t instanceof Error)e.errorType=t.name,e.errorMessage=t.message,typeof t.stack=="string"&&(e.trace=t.stack.split(` `));else{e.errorType=typeof t;try{e.errorMessage=t.toString()}catch{}}return e},Z=t=>{let e="";try{let r=R.exec(t.stack.split("at")[2])?.[0];typeof r=="string"&&(e=r.slice(1))}catch{}return e},D=()=>{let t={assert:console.assert.bind(console.assert),clear:console.clear.bind(console.clear),count:console.count.bind(console.count),countReset:console.countReset.bind(console.countReset),debug:console.debug.bind(console.debug),dir:console.dir.bind(console.dir),dirxml:console.dirxml.bind(console.dirxml),error:console.error.bind(console.error),group:console.group.bind(console.group),groupCollapsed:console.groupCollapsed.bind(console.groupCollapsed),groupEnd:console.groupEnd.bind(console.groupEnd),info:console.info.bind(console.info),log:console.log.bind(console.log),table:console.table.bind(console.table),time:console.time.bind(console.time),timeEnd:console.timeEnd.bind(console.timeEnd),timeLog:console.timeLog.bind(console.timeLog),timeStamp:console.timeStamp.bind(console.timeStamp),trace:console.trace.bind(console.trace),warn:console.warn.bind(console.warn)};console=new Proxy(console,{get(e,r){return typeof e[r]=="function"?(...n)=>{let o={};Error.captureStackTrace(o);let l=Z(o);process.stdout.write(`\x1B[90m${new Date().toISOString()} ${r.toUpperCase()} ${B} ${l?.replace(Y,"")}\x1B[0m `),r=="log"?t.log(...n.map(i=>(0,S.inspect)(i,{colors:!0}))):t[r](...n)}:t[r]}})},H=t=>{let e="",r=0;return t.slice().reverse().filter(n=>n&&!n.includes(__dirname)&&!n.includes(A)).forEach(n=>{let o=R.exec(n)?.[0];o&&(e+=`${o} `.slice(1),r++,e+=" ".repeat(r))}),e},g=class t extends Map{static EMPTY_ARGS=[];static IGNORE=["PROMISE","RANDOMBYTESREQUEST","PerformanceObserver","TIMERWRAP"];onEmpty;requestId;callbackWaitsForEmptyEventLoop=!0;async=!1;hook;static context={};static parentPort;static logTimeoutPossibleCause=e=>{let r=this.context[e];if(!r.timeout)return;let n=[...r.promises.values()].reduce((o,l)=>(l.took&&(l.stack=l.stack.reverse().map(i=>{let m=R.exec(i)?.[0];if(m)return m.slice(1)}).filter(i=>i&&!i.includes(__dirname)&&!i.includes(A)),l.stack.length&&(delete l.start,o.push(l))),o),[]);if(n=n.filter((o,l)=>{if(o.took>.01)return!o.stack.every(i=>n.find((m,d)=>l!=d&&(m.took>o.took||o.stack.length<m.stack.length)&&m.stack.includes(i)))}),n.length){let o=(0,S.inspect)(n,{colors:!0});process.stdout.write(`'${B}' Timeout possible cause: ${o} `)}};constructor(e){super(),this.requestId=e,t.context[e]={timers:new Map,promises:new Map}}static restoreContext=()=>{Object.values(this.context).forEach(({timers:e})=>{let r=[...e.entries()];r.length&&process.stdout.write(`\x1B[31mWarning! Restoring context from previous invokation... This may lead to data leak.\x1B[0m `),r.forEach(([n,o])=>{o.interval?setInterval(o._onTimeout,o.interval):setTimeout(o._onTimeout,o.timerValue),e.delete(n)})})};storeContextTimers=()=>{[...this.entries()].forEach(([e,r])=>{if(r.type!="Timeout")return;let{_idleTimeout:n,_idleStart:o,_onTimeout:l,_repeat:i,_destroyed:m}=r.resource,d=n-o;!m&&(d>-1||i)&&t.context[this.requestId].timers.set(e,{timerValue:d,_onTimeout:l,interval:i}),clearTimeout(r.resource)})};isEmpty=()=>!([...this.values()].filter(r=>!(typeof r.resource.hasRef=="function"&&!r.resource.hasRef())).length>0);add=(e,r,n,o)=>{let l={};Error.captureStackTrace(l);let i=l.stack.split(` `).slice(7);if(r=="PROMISE"&&t.context[this.requestId].promises.set(e,{stack:i,start:Date.now()}),t.IGNORE.includes(r))return this;if(r=="Timeout"){let m=o._repeat?"setInterval":"setTimeout",d=o._onTimeout.toString(),u=o._onTimeout.bind(o._onTimeout),W=o._timerArgs??t.EMPTY_ARGS;o._onTimeout=()=>{try{u(...W)}catch(T){let a=L(T),E=X(d);t.parentPort.postMessage({channel:"uncaught",type:m,data:{error:a,solution:E}})}}}return this.set(e,{resource:o,triggerAsyncId:n,type:r,stack:i})};destroy=e=>{this.delete(e)&&this.isEmpty()&&this.onEmpty&&this.onEmpty()};resolve=e=>{let r=t.context[this.requestId];if(r){let n=r.promises.get(e);n?.start&&(n.took=(Date.now()-n.start)/1e3)}};enable=()=>{t.restoreContext();let e=this,r=function(o){z(o),e.destroy(Number(o))};global.clearTimeout=r,global.clearInterval=r,this.hook=(0,_.createHook)({init:this.add,destroy:this.destroy,promiseResolve:this.resolve}).enable()};disable=()=>{this.hook?.disable(),delete this.hook}};var M=require("util"),b={RED:t=>{},BLUE:t=>{},PINK:t=>{}},h,ee=new Error("Invalid response payload");c.workerData.debug&&(b.RED=t=>{process.stdout.write(`\x1B[31m${t}\x1B[0m `)},b.BLUE=t=>{process.stdout.write(`\x1B[34m${t}\x1B[0m `)},b.PINK=t=>{process.stdout.write(`\x1B[95m${t}\x1B[0m `)},D());g.parentPort=c.parentPort;var y=(t,e)=>{let r=L(e);c.parentPort.postMessage({channel:"fail",data:r,awsRequestId:t})},v=(t,e,r)=>{try{JSON.stringify(r),c.parentPort.postMessage({channel:t,data:r,awsRequestId:e})}catch{y(e,ee)}};process.exit=t=>{process.stdout.write(`\x1B[31musage of process.exit() will throw Runtime error in AWS Lambda\x1B[0m `)};process.on("unhandledRejection",t=>{process.stdout.write((0,M.inspect)(t))});process.on("uncaughtException",t=>{process.stdout.write((0,M.inspect)(t))});var te=async t=>{let{channel:e,data:r,awsRequestId:n}=t;if(e=="import"){let o=await import(`file://${c.workerData.esOutputPath}?version=${Date.now()}`);if(c.workerData.handlerName=="default"&&typeof o.default=="object"&&typeof o.default.default=="function"?h=o.default.default:h=o[c.workerData.handlerName],typeof h!="function")throw new Error(`${c.workerData.name} > ${c.workerData.handlerName} is not a function`);c.parentPort.postMessage({channel:"import"})}else if(e=="complete"){let o=g.context[n];typeof t.timeout=="boolean"&&(o.timeout=!0)}else if(e=="exec"){let{event:o,clientContext:l}=r,i=!1,m=c.workerData.timeout*1e3,d,u=()=>{i=!0},W=Date.now(),T=()=>Math.max(m-(Date.now()-W),0),a=new g(n),E={functionVersion:"$LATEST",functionName:c.workerData.name,memoryLimitInMB:c.workerData.memorySize,logGroupName:`/aws/lambda/${c.workerData.name}`,logStreamName:`${new Date().toLocaleDateString()}[$LATEST]${n.replace(/-/g,"")}`,clientContext:l,identity:void 0,invokedFunctionArn:`arn:aws:lambda:eu-west-1:00000000000:function:${c.workerData.name}`,awsRequestId:n,getRemainingTimeInMillis:T};if(typeof h.stream=="boolean"){let w=(s,p,k)=>{c.parentPort.postMessage({channel:"stream",data:s,awsRequestId:n,type:"write",encoding:p}),k()};d=new x({highWaterMark:h.streamOpt?.highWaterMark,write:w}),d.on("close",()=>{i||(u(),c.parentPort.postMessage({channel:"stream",awsRequestId:n,type:"end"}))}),d.on("error",s=>{i||(u(),b.RED(s),y(n,s))}),d.on("ct",s=>c.parentPort.postMessage({channel:"stream",data:s,awsRequestId:n,type:"ct"}));let f={get callbackWaitsForEmptyEventLoop(){return a.callbackWaitsForEmptyEventLoop},set callbackWaitsForEmptyEventLoop(s){a.callbackWaitsForEmptyEventLoop=s},...E};typeof h(o,d,f)?.catch?.(s=>{d.destroy(),u(),b.RED(s),y(n,s)})?.then!="function"&&(u(),d.destroy(),y(n,new Error("Streaming does not support non-async handlers.")))}else{let w={get callbackWaitsForEmptyEventLoop(){return a.callbackWaitsForEmptyEventLoop},set callbackWaitsForEmptyEventLoop(s){a.callbackWaitsForEmptyEventLoop=s},...E,succeed:s=>{i||(u(),v("succeed",n,s))},fail:s=>{i||(u(),y(n,s))},done:function(s,p){i||(u(),s?y(n,s):v("done",n,p))}},f,C=(s,p)=>{f?b.RED("Invocation has already been reported as done. Cannot call complete more than once per invocation."):f={error:s,res:p}};try{a.enable();let s=h(o,w,C);if(s?.then?.(p=>{a.storeContextTimers(),g.logTimeoutPossibleCause(n),!(f||i)&&(u(),v("return",n,p),a.disable())})?.catch(p=>{u(),y(n,p),a.disable()}),a.async=typeof s?.then=="function",!a.async&&s&&b.RED("Synchronous handler 'return' value is ignored. Consider marking your handler as 'async' or use callback(error, returnValue)"),!i&&(!a.async||f)){let p=()=>{a.storeContextTimers(),a.disable(),f?w.done(f.error,f.res):(u(),v("return",n,null))};if(a.isEmpty())p();else if(!f||a.callbackWaitsForEmptyEventLoop){if(f&&a.callbackWaitsForEmptyEventLoop){b.BLUE("callbackWaitsForEmptyEventLoop...");let k=[...a.values()],U=k[k.length-1],I=H(U.stack);I&&(b.RED("Blocked by:"),b.PINK(I))}a.onEmpty=()=>{p()}}else p()}}catch(s){u(),y(n,s),a.disable()}}}};c.parentPort.on("message",te);