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
JavaScript
;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);