exlo 0.0.13 → 0.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{readFile as I}from"node:fs/promises";import p from"node:path";import{pathToFileURL as O}from"node:url";import{parseArgs as Y}from"node:util";var j="exlo",b="0.0.13";var g=!1,R=e=>{g=e},A=()=>g,l=(e,t)=>{g&&console.log(`\x1B[${e}m${t}\x1B[0m`)},C=e=>console.log(`\x1B[31m${e}\x1B[0m`),$=e=>l("32",e),q=e=>l("33",e),L=e=>l("36",e),S=e=>l("90",e),F=e=>l("94",e),_=e=>l("95",e),D=e=>g?console.log(e):void 0,n={GREEN:$,YELLOW:q,CYAN:L,BR_BLUE:F,RED:C,GREY:S,PINK:_,setDebug:R,getDebug:A,info:D};var y={config:{type:"string",short:"c",default:"exlo.config.ts",description:"Path to exlo 'defineConfig' file."},debug:{type:"boolean",default:!1,description:"Enable debug mode. When enabled exlo will print usefull informations."},create:{type:"boolean",default:!1,description:"Create exlo 'defineConfig' file based on passed options."},runtime:{type:"string",short:"r",description:"Lambda default runtime (ex: nodejs22.x, python3.7, ruby2.7 etc.)."},timeout:{type:"string",short:"t",default:"3",description:"Lambda default timeout."},port:{type:"string",short:"p",default:"0",description:"Lambda server port."},definitions:{type:"string",short:"d",description:"Path to .json, .mjs, .cjs file with Lambda function definitions."},functions:{type:"string",short:"f",multiple:!0,description:"Glob pattern to automatically find and define Lambda handlers."},exclude:{type:"string",short:"X",multiple:!0,default:[".(test|spec)."],description:"RegExp string to exclude found enteries from --functions."},"handler-name":{type:"string",default:"handler",description:"Handler function name. To be used with --functions."},env:{type:"string",short:"e",multiple:!0,default:[],description:"Environment variables to be injected into Lambdas. All existing AWS_* are automatically injected.",example:"-e API_KEY=supersecret -e API_URL=https://website.com"},"optimize-build":{type:"boolean",default:!1,description:"externalize dependencies and other stuff"},"shim-require":{type:"boolean",default:!1,description:"shim 'require()', '__dirname' and '__filename' when bundeling Lambdas with ESM format"},help:{type:"boolean",short:"h",skipFullPrint:!0},version:{type:"boolean",short:"v",skipFullPrint:!0},"esbuild-external":{type:"string",multiple:!0,skip:!0},"esbuild-resolveExtensions":{type:"string",multiple:!0,skip:!0},"esbuild-mainFields":{type:"string",multiple:!0,skip:!0},"esbuild-conditions":{type:"string",multiple:!0,skip:!0},"esbuild-entryPoints":{type:"string",multiple:!0,skip:!0},"esbuild-inject":{type:"string",multiple:!0,skip:!0},"esbuild-nodePaths":{type:"string",multiple:!0,skip:!0}};function M(){n.setDebug(!0),n.GREY("Usage examples:"),console.log("exlo -c exlo.config.ts"),console.log(`exlo -p 3000 --debug --functions "src/lambdas/**/*.ts"
2
+ import{readFile as I}from"node:fs/promises";import p from"node:path";import{pathToFileURL as O}from"node:url";import{parseArgs as Y}from"node:util";var j="exlo",b="0.0.14";var g=!1,R=e=>{g=e},A=()=>g,l=(e,t)=>{g&&console.log(`\x1B[${e}m${t}\x1B[0m`)},C=e=>console.log(`\x1B[31m${e}\x1B[0m`),$=e=>l("32",e),q=e=>l("33",e),L=e=>l("36",e),S=e=>l("90",e),F=e=>l("94",e),_=e=>l("95",e),D=e=>g?console.log(e):void 0,n={GREEN:$,YELLOW:q,CYAN:L,BR_BLUE:F,RED:C,GREY:S,PINK:_,setDebug:R,getDebug:A,info:D};var y={config:{type:"string",short:"c",default:"exlo.config.ts",description:"Path to exlo 'defineConfig' file."},debug:{type:"boolean",default:!1,description:"Enable debug mode. When enabled exlo will print usefull informations."},create:{type:"boolean",default:!1,description:"Create exlo 'defineConfig' file based on passed options."},runtime:{type:"string",short:"r",description:"Lambda default runtime (ex: nodejs22.x, python3.7, ruby2.7 etc.)."},timeout:{type:"string",short:"t",default:"3",description:"Lambda default timeout."},port:{type:"string",short:"p",default:"0",description:"Lambda server port."},definitions:{type:"string",short:"d",description:"Path to .json, .mjs, .cjs file with Lambda function definitions."},functions:{type:"string",short:"f",multiple:!0,description:"Glob pattern to automatically find and define Lambda handlers."},exclude:{type:"string",short:"X",multiple:!0,default:[".(test|spec)."],description:"RegExp string to exclude found enteries from --functions."},"handler-name":{type:"string",default:"handler",description:"Handler function name. To be used with --functions."},env:{type:"string",short:"e",multiple:!0,default:[],description:"Environment variables to be injected into Lambdas. All existing AWS_* are automatically injected.",example:"-e API_KEY=supersecret -e API_URL=https://website.com"},"optimize-build":{type:"boolean",default:!1,description:"externalize dependencies and other stuff"},"shim-require":{type:"boolean",default:!1,description:"shim 'require()', '__dirname' and '__filename' when bundeling Lambdas with ESM format"},help:{type:"boolean",short:"h",skipFullPrint:!0},version:{type:"boolean",short:"v",skipFullPrint:!0},"esbuild-external":{type:"string",multiple:!0,skip:!0},"esbuild-resolveExtensions":{type:"string",multiple:!0,skip:!0},"esbuild-mainFields":{type:"string",multiple:!0,skip:!0},"esbuild-conditions":{type:"string",multiple:!0,skip:!0},"esbuild-entryPoints":{type:"string",multiple:!0,skip:!0},"esbuild-inject":{type:"string",multiple:!0,skip:!0},"esbuild-nodePaths":{type:"string",multiple:!0,skip:!0}};function M(){n.setDebug(!0),n.GREY("Usage examples:"),console.log("exlo -c exlo.config.ts"),console.log(`exlo -p 3000 --debug --functions "src/lambdas/**/*.ts"
3
3
  `),n.BR_BLUE("Options:");for(let[e,t]of Object.entries(y)){let i=e;if(t.skip)continue;if(t.short&&(i+=`, -${t.short}`),t.skipFullPrint){n.CYAN(` --${i}
4
4
  `);continue}let s=` type: ${t.type}`;t.description&&(s+=`
5
5
  description: ${t.description}`),"default"in t&&(s+=`
@@ -1 +1 @@
1
- var h="0.0.13";function k(e){let c=new Set;e.plugins&&(e.plugins=e.plugins.filter((i,a)=>typeof i!="object"||!i||!("name"in i)?!1:((!i.name||!i.name.length||typeof i.name!="string")&&(i.name=`plugin-${a}`,console.warn(`No Plugin name provided at index ${a}`)),c.has(i.name)?i.name=i.name+a:c.add(i.name),!0)));async function f({stop:i,lambdas:a,region:g,esbuild:v,getServices:y,setService:d,addLambda:p,log:l,setEndpoint:b,getEndpoint:x,getAwsProviderDefaults:C,setAwsProviderDefaults:S}){let r={build:{esbuild:e?.build?.esbuild??{},shimRequire:e?.build?.shimRequire,optimizeBuild:e?.build?.optimizeBuild},server:{port:e.server?.port,setEndpointEnvVar:e.server?.setEndpointEnvVar},onKill:[]};if(e.defaults&&typeof e.defaults=="object"&&!Array.isArray(e.defaults)&&S(e.defaults),e.functions&&typeof e.functions=="object"&&!Array.isArray(e.functions))for(let[m,s]of Object.entries(e.functions))p(m,s);e.services&&(e.services.sqs&&d("sqs",e.services.sqs),e.services.sns&&d("sns",e.services.sns),e.services.dynamodb&&d("dynamodb",e.services.dynamodb));let o={stop:i,lambdas:a,region:g,esbuild:v,options:e,config:r,getServices:y,setService:d,addLambda:p,log:l,setEndpoint:b,getEndpoint:x,getAwsProviderDefaults:C};if(e.plugins){r.server.onReady=async(s,n)=>{for(let t of e.plugins)if(t.server?.onReady)try{await t.server.onReady.call(o,s,n)}catch(u){l.RED(t.name),console.error(u)}},r.buildCallback=async(s,n)=>{for(let t of e.plugins)if(t.buildCallback)try{await t.buildCallback.call(o,s,n)}catch(u){l.RED(t.name),console.error(u),n||process.exit(1)}};let m=e.plugins.reduce((s,n)=>(n.server?.request?.length&&s.push(...n.server.request),s),[]);m?.length&&(r.server.request=m.map(s=>(s.callback=s.callback.bind(o),s)));for(let s of e.plugins)if(s.onKill&&r.onKill.push(s.onKill.bind(o)),s.onInit)try{await s.onInit.call(o)}catch(n){throw l.RED(s.name),n}}return r}return f.plugins=e.plugins??[],f}export{k as defineConfig,h as exloVersion};
1
+ var h="0.0.14";function k(e){let c=new Set;e.plugins&&(e.plugins=e.plugins.filter((i,a)=>typeof i!="object"||!i||!("name"in i)?!1:((!i.name||!i.name.length||typeof i.name!="string")&&(i.name=`plugin-${a}`,console.warn(`No Plugin name provided at index ${a}`)),c.has(i.name)?i.name=i.name+a:c.add(i.name),!0)));async function f({stop:i,lambdas:a,region:g,esbuild:v,getServices:y,setService:d,addLambda:p,log:l,setEndpoint:b,getEndpoint:x,getAwsProviderDefaults:C,setAwsProviderDefaults:S}){let r={build:{esbuild:e?.build?.esbuild??{},shimRequire:e?.build?.shimRequire,optimizeBuild:e?.build?.optimizeBuild},server:{port:e.server?.port,setEndpointEnvVar:e.server?.setEndpointEnvVar},onKill:[]};if(e.defaults&&typeof e.defaults=="object"&&!Array.isArray(e.defaults)&&S(e.defaults),e.functions&&typeof e.functions=="object"&&!Array.isArray(e.functions))for(let[m,s]of Object.entries(e.functions))p(m,s);e.services&&(e.services.sqs&&d("sqs",e.services.sqs),e.services.sns&&d("sns",e.services.sns),e.services.dynamodb&&d("dynamodb",e.services.dynamodb));let o={stop:i,lambdas:a,region:g,esbuild:v,options:e,config:r,getServices:y,setService:d,addLambda:p,log:l,setEndpoint:b,getEndpoint:x,getAwsProviderDefaults:C};if(e.plugins){r.server.onReady=async(s,n)=>{for(let t of e.plugins)if(t.server?.onReady)try{await t.server.onReady.call(o,s,n)}catch(u){l.RED(t.name),console.error(u)}},r.buildCallback=async(s,n)=>{for(let t of e.plugins)if(t.buildCallback)try{await t.buildCallback.call(o,s,n)}catch(u){l.RED(t.name),console.error(u),n||process.exit(1)}};let m=e.plugins.reduce((s,n)=>(n.server?.request?.length&&s.push(...n.server.request),s),[]);m?.length&&(r.server.request=m.map(s=>(s.callback=s.callback.bind(o),s)));for(let s of e.plugins)if(s.onKill&&r.onKill.push(s.onKill.bind(o)),s.onInit)try{await s.onInit.call(o)}catch(n){throw l.RED(s.name),n}}return r}return f.plugins=e.plugins??[],f}export{k as defineConfig,h as exloVersion};
@@ -5,8 +5,8 @@ import{S3 as ss}from"@aws-sdk/client-s3";import{randomUUID as xe}from"node:crypt
5
5
  <Error><Code>${r}</Code><Message>${e}</Message>${s??""}<RequestId>${t}</RequestId><HostId>local</HostId></Error>`}},v=class extends f{TagKey;constructor({TagKey:r,Message:e,RequestId:t}){super({Code:"InvalidTag",Message:e,SenderFault:!0,statusCode:400,RequestId:t}),this.TagKey=r}toXml(){return super.toXml(`<TagKey>${this.TagKey}</TagKey>`)}},T=class extends f{constructor(r){super({Code:"MalformedXML",Message:"The XML you provided was not well-formed or did not validate against our published schema",RequestId:r})}},P=class extends f{constructor({Message:r,RequestId:e}){super({Code:"BadRequest",Message:r,RequestId:e})}},k=class extends f{ArgumentName;ArgumentValue;constructor({Message:r,RequestId:e,ArgumentName:t,ArgumentValue:s}){super({Code:"InvalidArgument",Message:r,RequestId:e}),this.ArgumentName=t,this.ArgumentValue=s}toXml(){let r=`<ArgumentName>${this.ArgumentName}</ArgumentName>`;return typeof this.ArgumentValue<"u"&&(r+=`<ArgumentValue>${this.ArgumentValue}</ArgumentValue>`),super.toXml(r)}},B=class extends f{PartNumberRequested;ActualPartCount;constructor({RequestId:r,PartNumberRequested:e,ActualPartCount:t}){super({Code:"InvalidPartNumber",Message:"The requested partnumber is not satisfiable",RequestId:r}),this.PartNumberRequested=e,this.ActualPartCount=t}toXml(){return super.toXml(`<PartNumberRequested>${this.PartNumberRequested}</PartNumberRequested><ActualPartCount>${this.ActualPartCount}</ActualPartCount>`)}},ee=class extends f{constructor(r){super({Code:"NoSuchTagSet",Message:"The TagSet does not exist",RequestId:r,statusCode:404})}},N=class extends f{constructor(r,e){super({Code:"UnsupportedCommand",Message:`${r} is currently not supported`,RequestId:e,statusCode:500})}};var Je={PutObject:["ObjectCreated","Put"],CopyObject:["ObjectCreated","Copy"],DeleteObject:["ObjectRemoved","Delete"]},Ye=({bucket:i,eTag:r,size:e,key:t,eventName:s,sourceIPAddress:n,requestId:o})=>({eventVersion:"2.1",eventSource:"aws:s3",awsRegion:"eu-west-3",eventTime:new Date().toUTCString(),eventName:s,userIdentity:{principalId:"AWS:AIDA6ECTW4PP5BZ6IKOGM"},requestParameters:{sourceIPAddress:n},responseElements:{"x-amz-request-id":o,"x-amz-id-2":"K9uTQdtIwO9VVKYvEk0BrLAAO9zWajA33cUGdcrZvjoLHLwBUBocXu1GU50BEcMIfNTLdt2KKmzaagHcGBWncOyUgcXx8UILLYKd26F/pf4="},s3:{s3SchemaVersion:"1.0",configurationId:"975e5867-6fe6-4b2c-925e-ef15389f6d3f",bucket:{name:i,ownerIdentity:{principalId:"A1HCF0AO1IXCSI"},arn:`arn:aws:s3:::${i}`},object:{key:t,size:e,eTag:r,sequencer:"0063E38F8ED88A5726"}}}),Qe=(i,r)=>{if(!i)return!0;if(Array.isArray(i))return i.map(e=>typeof e.prefix=="string"?r.startsWith(e.prefix):typeof e.suffix=="string"?r.endsWith(e.suffix):!1).every(e=>e===!0)},A=async(i,{bucket:r,eTag:e,size:t,key:s,requestCmd:n,sourceIPAddress:o,requestId:c})=>{let a=Je[n];for(let d of i)for(let u of d.s3){if(r!=u.bucket)continue;let[l,p]=u.type;if(l==a[0]&&(p=="*"||p==a[1])&&Qe(u.rules,s))try{await d.invoke({Records:[Ye({bucket:r,eTag:e,size:t,key:s,sourceIPAddress:o,requestId:c,eventName:a.join(":")})]},{kind:"s3",event:u})}catch(g){console.log(g)}}};var ct=["STANDARD","REDUCED_REDUNDANCY","STANDARD_IA","ONEZONE_IA","INTELLIGENT_TIERING","GLACIER","DEEP_ARCHIVE","OUTPOSTS","GLACIER_IR","SNOW"],dt=/\.{2,}/,ut=/^(\d{1,3}\.){3}\d{1,3}$/,lt=/^[a-z0-9]+[a-z0-9.-]+[a-z0-9]$/,b=class i{constructor(r,e=!1,t){this.localStoragePath=r;this.persist=e;this.port=t}static XMLBuilder=new it;static XMLParser=new at;static genLocalKey(r,e,t){return R(j.posix.join(r,e,t??""))}static async getTagsFromRequest(r,e,t){let s;r.on("data",l=>{s=typeof s>"u"?l:Buffer.concat([s,l])});let n=await new Promise(l=>{r.on("end",async()=>{l(s)})}),o=new T(e);if(!n)throw new f({Code:"MissingRequestBodyError",Message:"Request Body is empty",RequestId:e});let c;try{c=i.XMLParser.parse(n)}catch{throw o}if(c.Tagging=="")return;let a=c.Tagging.TagSet.Tag;a&&!Array.isArray(a)&&(a=[a]);let d={};for(let l of a){if(l===null||typeof l!="object"||Array.isArray(l))throw o;let{Key:p,Value:g}=l;if(typeof p!="string"||typeof g!="string")throw o;if(p in d)throw new v({TagKey:p,RequestId:e,Message:"Cannot provide multiple Tags with the same key"});if(p.length>128||p.length<1)throw new v({TagKey:p,RequestId:e,Message:"The TagKey you have provided is invalid"});if(g.length>256)throw new v({TagKey:p,RequestId:e,Message:"The TagValue you have provided is invalid"});d[p]=g}let u=t=="Bucket"?50:10;if(Object.keys(d).length>u)throw new P({Message:`${t} tag count cannot be greater than ${u}`,RequestId:e});return d}persistence={version:2,buckets:{}};callableLambdas=[];accountId="123456789012";ownerId=[xe(),xe()].join("").replaceAll("-","");region="us-east-1";allowToDeleteNonEmptyBuckets=!1;async bootstrap(){try{let r=await rt(j.join(this.localStoragePath,"__state.json"),"utf-8"),e=JSON.parse(r);if(e.version==2){this.persistence=e;return}}catch{}}async createBucket(r,e){let t=j.join(this.localStoragePath,r);et(t,{recursive:!0}),this.persistence.buckets[r]={date:Date.now(),acl:{accessControlPolicy:`<?xml version="1.0" encoding="UTF-8"?>
6
6
  <AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Owner><ID>${this.ownerId}</ID></Owner><AccessControlList><Grant><Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser"><ID>${this.ownerId}</ID></Grantee><Permission>FULL_CONTROL</Permission></Grant></AccessControlList></AccessControlPolicy>`},...e,objects:{},multipartUploads:{}}}saveState(){this.persist?st(j.join(this.localStoragePath,"__state.json"),JSON.stringify(this.persistence)):tt(this.localStoragePath,{force:!0,recursive:!0})}static isValidBucketName(r){let e=r.length;return e<3||e>63||dt.test(r)||ut.test(r)||r.startsWith("xn--")||r.startsWith("sthree-")||r.endsWith("-s3alias")||r.endsWith("--ol-s3")?!1:lt.test(r)}async removeObject(r,e,t,s){let n=this.persistence.buckets[r].objects[e];if(!n)return;let o=j.join(this.localStoragePath,r,n.currentKey);try{let c=await ot(o);c.isFile()&&await nt(o),delete this.persistence.buckets[r].objects[e],setTimeout(async()=>{try{await A(this.callableLambdas,{bucket:r,key:e,requestId:s,requestCmd:"DeleteObject",eTag:n.ETag,sourceIPAddress:t,size:c.size})}catch{}},30)}catch{}}},m=class{constructor(r,e){this.localService=e;this.requestId=r["amz-sdk-invocation-id"]??xe(),Object.keys(r).filter(s=>s.startsWith("x-amz-meta-")).forEach(s=>this.metadata[s]=r[s])}requestId;metadata={};isValidStorageClass(r,e){return ct.includes(r)?!0:(e.writeHead(400,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(`<Error><Code>InvalidStorageClass</Code><Message>The storage class you specified is not valid</Message><StorageClassRequested>${r}</StorageClassRequested><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`),!1)}hasNot(r,e){if(!b.isValidBucketName(r)){e.writeHead(400,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(`<?xml version="1.0" encoding="UTF-8"?>
7
7
  <Error><Code>InvalidBucketName</Code><Message>The specified bucket is not valid.</Message><BucketName>${r}</BucketName><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}if(!this.localService.persistence.buckets[r])return e.writeHead(404,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(Re({Bucket:r,RequestId:this.requestId})),!0}};import{statSync as pt}from"node:fs";import mt from"node:path";var qe=i=>{let r=typeof i=="string"?i:".exlo/s3/";r=mt.resolve(r),r.endsWith("/")||(r+="/");try{if(pt(r).isDirectory())return r;throw new Error(`Provided localStorageDir '${i}' is not a directory`)}catch(e){if(e.code=="ENOENT")return r;throw e.code=="ENOTDIR"?new Error(`Provided localStorageDir '${i}' is not a directory`):e}};import{createServer as es}from"node:http";import{rm as gt}from"node:fs/promises";import ht from"node:path";var D=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let n=decodeURIComponent(e.pathname),[o]=n.split("/").filter(Boolean);this.bucket=o}bucket;async exec(e){if(this.hasNot(this.bucket,e))return;let t=Object.keys(this.localService.persistence.buckets[this.bucket].objects).length>0;if(!this.localService.allowToDeleteNonEmptyBuckets&&t){e.writeHead(404,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(`<?xml version="1.0" encoding="UTF-8"?>
8
- <Error><Code>BucketNotEmpty</Code><Message>The bucket you tried to delete is not empty</Message><BucketName>${this.bucket}</BucketName><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}delete this.localService.persistence.buckets[this.bucket];try{await gt(ht.join(this.localService.localStoragePath,this.bucket),{recursive:!0,force:!0,maxRetries:1})}catch{}e.writeHead(204,{"x-amzn-requestid":this.requestId,Server:"AmazonS3"}).end()}};var K=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let n=decodeURIComponent(e.pathname),[o,...c]=n.split("/").filter(Boolean);this.bucket=o,this.key=c.join("/"),this.version=e.searchParams.get("versionId")}bucket;key;version;async exec(e,t){if(this.hasNot(this.bucket,e))return;e.statusCode=204,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Server","AmazonS3");let s=t.socket.remoteAddress?.split(":")?.[3]??"127.0.0.1";await this.localService.removeObject(this.bucket,this.key,s,this.requestId),e.end()}};var I=class extends m{constructor(e,t,s){super(t,s);this.localService=s}exec(e){e.statusCode=500,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(`<Error><Code>UnknownOperation</Code><Message>Your request is currently not supported.</Message><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`)}};var se=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n}bucket;async exec(e){if(!this.hasNot(this.bucket,e))try{this.localService.persistence.buckets[this.bucket].tags=void 0,e.setHeader("x-amzn-requestid",this.requestId),e.statusCode=204,e.end()}catch(t){if(e.statusCode=400,t instanceof f){e.setHeader("Content-Type","application/xml"),t.statusCode&&(e.statusCode=t.statusCode),e.end(t.toXml());return}if(t instanceof Error){e.setHeader("Content-Type","application/xml"),e.end(f.genericError({Code:"UnknownError",Message:t.message,RequestId:this.requestId}));return}e.end(t?.toString?.())}}};var re=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n,...o]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n,this.key=o.join("/")}bucket;key;async exec(e){if(!this.hasNot(this.bucket,e)){if(!this.localService.persistence.buckets[this.bucket].objects[this.key]){e.writeHead(404,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(x({Key:this.key,RequestId:this.requestId}));return}try{this.localService.persistence.buckets[this.bucket].objects[this.key].tags=void 0,e.setHeader("x-amzn-requestid",this.requestId),e.statusCode=204,e.end()}catch(t){if(e.statusCode=400,t instanceof f){e.setHeader("Content-Type","application/xml"),t.statusCode&&(e.statusCode=t.statusCode),e.end(t.toXml());return}if(t instanceof Error){e.setHeader("Content-Type","application/xml"),e.end(f.genericError({Code:"UnknownError",Message:t.message,RequestId:this.requestId}));return}e.end(t?.toString?.())}}}};import{unlink as ft}from"node:fs/promises";var ne=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let n=decodeURIComponent(e.pathname),[o,...c]=n.split("/").filter(Boolean);this.bucket=o,this.key=c.join("/"),this.uploadId=e.searchParams.get("uploadId")??"invalid"}bucket;key;uploadId;async exec(e,t){if(this.hasNot(this.bucket,e))return;let s=this.localService.persistence.buckets[this.bucket].multipartUploads[this.uploadId];if(!s){e.statusCode=404,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(`<?xml version="1.0" encoding="UTF-8"?>
9
- <Error><Code>NoSuchUpload</Code><UploadId>${this.uploadId}</UploadId><Message>The specified upload does not exist. The upload ID may be invalid, or the upload may have been aborted or completed.</Message><BucketName>${this.bucket}</BucketName><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}s.aborted=!0,e.statusCode=204,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Server","AmazonS3"),e.end(),s.completed||setTimeout(async()=>{for(let n of s.parts)try{await ft(n.filePath)}catch{}},100)}};var oe=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n}bucket;async exec(e){if(this.hasNot(this.bucket,e))return;let t=this.localService.persistence.buckets[this.bucket];t.policy=void 0,e.statusCode=204,e.end()}};var bt=new Set(["rm","rb.rm","mv","delete-object"]),Me=(i,r)=>{let{url:e,headers:t}=i,s=new URL(e,"http://localhost:3000"),n=s.pathname.split("/").filter(Boolean).length==1;if(s.searchParams.has("policy"))return n?new oe(s,t,r):new I(s,t,r);if(s.searchParams.has("tagging"))return n?new se(s,t,r):new re(s,t,r);if(s.searchParams.has("uploadId")&&!n)return new ne(s,t,r);let o=t["user-agent"];if(o?.startsWith("aws-cli")){let[,c]=o.split("command/"),[,...a]=c.split("."),d=a.join(".");if(bt.has(d))return new K(s,t,r);if(d=="rb"||d=="delete-bucket")return new D(s,t,r)}else{let c=s.searchParams.get("x-id");if(!c)return new D(s,t,r);if(c=="DeleteObject")return new K(s,t,r)}return new I(s,t,r)};var ie=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n,this.delimiter=e.searchParams.get("delimiter"),this.encodingType=e.searchParams.get("encoding-type");let o=e.searchParams.get("max-keys");o&&(this.maxKeys=o),this.prefix=e.searchParams.get("prefix"),this.expectedOwner=e.searchParams.get("x-amz-expected-bucket-owner"),this.optionalObjectAttributes=e.searchParams.get("x-amz-optional-object-attributes"),this.requestPayer=e.searchParams.get("x-amz-request-payer")}bucket;delimiter;encodingType;maxKeys=1e3;prefix;expectedOwner;optionalObjectAttributes;requestPayer;getKeys(){let e=Object.keys(this.localService.persistence.buckets[this.bucket].objects);return this.prefix&&(e=e.filter(t=>t.startsWith(this.prefix))),e.sort(),e}isInvalidMaxKeys(e){if(this.maxKeys){if(isNaN(this.maxKeys))return e.statusCode=400,e.setHeader("Server","AmazonS3"),e.setHeader("Content-Type","application/xml"),e.setHeader("x-amzn-requestid",this.requestId),e.end(`<?xml version="1.0" encoding="UTF-8"?>
8
+ <Error><Code>BucketNotEmpty</Code><Message>The bucket you tried to delete is not empty</Message><BucketName>${this.bucket}</BucketName><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}delete this.localService.persistence.buckets[this.bucket];try{await gt(ht.join(this.localService.localStoragePath,this.bucket),{recursive:!0,force:!0,maxRetries:1})}catch{}e.writeHead(204,{"x-amzn-requestid":this.requestId,Server:"AmazonS3"}).end()}};var O=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let n=decodeURIComponent(e.pathname),[o,...c]=n.split("/").filter(Boolean);this.bucket=o,this.key=c.join("/"),this.version=e.searchParams.get("versionId")}bucket;key;version;async exec(e,t){if(this.hasNot(this.bucket,e))return;e.statusCode=204,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Server","AmazonS3");let s=t.socket.remoteAddress?.split(":")?.[3]??"127.0.0.1";await this.localService.removeObject(this.bucket,this.key,s,this.requestId),e.end()}};var I=class extends m{constructor(e,t,s){super(t,s);this.localService=s}exec(e){e.statusCode=500,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(`<Error><Code>UnknownOperation</Code><Message>Your request is currently not supported.</Message><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`)}};var se=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n}bucket;async exec(e){if(!this.hasNot(this.bucket,e))try{this.localService.persistence.buckets[this.bucket].tags=void 0,e.setHeader("x-amzn-requestid",this.requestId),e.statusCode=204,e.end()}catch(t){if(e.statusCode=400,t instanceof f){e.setHeader("Content-Type","application/xml"),t.statusCode&&(e.statusCode=t.statusCode),e.end(t.toXml());return}if(t instanceof Error){e.setHeader("Content-Type","application/xml"),e.end(f.genericError({Code:"UnknownError",Message:t.message,RequestId:this.requestId}));return}e.end(t?.toString?.())}}};var re=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n,...o]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n,this.key=o.join("/")}bucket;key;async exec(e){if(!this.hasNot(this.bucket,e)){if(!this.localService.persistence.buckets[this.bucket].objects[this.key]){e.writeHead(404,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(x({Key:this.key,RequestId:this.requestId}));return}try{this.localService.persistence.buckets[this.bucket].objects[this.key].tags=void 0,e.setHeader("x-amzn-requestid",this.requestId),e.statusCode=204,e.end()}catch(t){if(e.statusCode=400,t instanceof f){e.setHeader("Content-Type","application/xml"),t.statusCode&&(e.statusCode=t.statusCode),e.end(t.toXml());return}if(t instanceof Error){e.setHeader("Content-Type","application/xml"),e.end(f.genericError({Code:"UnknownError",Message:t.message,RequestId:this.requestId}));return}e.end(t?.toString?.())}}}};import{unlink as ft}from"node:fs/promises";var ne=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let n=decodeURIComponent(e.pathname),[o,...c]=n.split("/").filter(Boolean);this.bucket=o,this.key=c.join("/"),this.uploadId=e.searchParams.get("uploadId")??"invalid"}bucket;key;uploadId;async exec(e,t){if(this.hasNot(this.bucket,e))return;let s=this.localService.persistence.buckets[this.bucket].multipartUploads[this.uploadId];if(!s){e.statusCode=404,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(`<?xml version="1.0" encoding="UTF-8"?>
9
+ <Error><Code>NoSuchUpload</Code><UploadId>${this.uploadId}</UploadId><Message>The specified upload does not exist. The upload ID may be invalid, or the upload may have been aborted or completed.</Message><BucketName>${this.bucket}</BucketName><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}s.aborted=!0,e.statusCode=204,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Server","AmazonS3"),e.end(),s.completed||setTimeout(async()=>{for(let n of s.parts)try{await ft(n.filePath)}catch{}},100)}};var oe=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n}bucket;async exec(e){if(this.hasNot(this.bucket,e))return;let t=this.localService.persistence.buckets[this.bucket];t.policy=void 0,e.statusCode=204,e.end()}};var bt=new Set(["rm","rb.rm","mv","delete-object"]),Me=(i,r)=>{let{url:e,headers:t}=i,s=new URL(e,"http://localhost:3000"),n=s.pathname.split("/").filter(Boolean).length==1;if(s.searchParams.has("policy"))return n?new oe(s,t,r):new I(s,t,r);if(s.searchParams.has("tagging"))return n?new se(s,t,r):new re(s,t,r);if(s.searchParams.has("uploadId")&&!n)return new ne(s,t,r);let o=t["user-agent"];if(o?.startsWith("aws-cli")){let[,c]=o.split("command/"),[,...a]=c.split("."),d=a.join(".");if(bt.has(d))return new O(s,t,r);if(d=="rb"||d=="delete-bucket")return new D(s,t,r)}else{let c=s.searchParams.get("x-id");if(!c)return new D(s,t,r);if(c=="DeleteObject")return new O(s,t,r)}return new I(s,t,r)};var ie=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n,this.delimiter=e.searchParams.get("delimiter"),this.encodingType=e.searchParams.get("encoding-type");let o=e.searchParams.get("max-keys");o&&(this.maxKeys=o),this.prefix=e.searchParams.get("prefix"),this.expectedOwner=e.searchParams.get("x-amz-expected-bucket-owner"),this.optionalObjectAttributes=e.searchParams.get("x-amz-optional-object-attributes"),this.requestPayer=e.searchParams.get("x-amz-request-payer")}bucket;delimiter;encodingType;maxKeys=1e3;prefix;expectedOwner;optionalObjectAttributes;requestPayer;getKeys(){let e=Object.keys(this.localService.persistence.buckets[this.bucket].objects);return this.prefix&&(e=e.filter(t=>t.startsWith(this.prefix))),e.sort(),e}isInvalidMaxKeys(e){if(this.maxKeys){if(isNaN(this.maxKeys))return e.statusCode=400,e.setHeader("Server","AmazonS3"),e.setHeader("Content-Type","application/xml"),e.setHeader("x-amzn-requestid",this.requestId),e.end(`<?xml version="1.0" encoding="UTF-8"?>
10
10
  <Error><Code>InvalidArgument</Code><Message>Provided max-keys not an integer or within integer range</Message><ArgumentName>max-keys</ArgumentName><ArgumentValue>${this.maxKeys}</ArgumentValue><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`),!0;if(this.maxKeys=Number(this.maxKeys),this.maxKeys<0||this.maxKeys>2147483647)return e.statusCode=400,e.setHeader("Server","AmazonS3"),e.setHeader("Content-Type","application/xml"),e.setHeader("x-amzn-requestid",this.requestId),e.end(`<?xml version="1.0" encoding="UTF-8"?>
11
11
  <Error><Code>InvalidArgument</Code><Message>Argument maxKeys must be an integer between 0 and 2147483647</Message><ArgumentName>maxKeys</ArgumentName><ArgumentValue>${this.maxKeys}</ArgumentValue><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`),!0}}},q=class extends ie{constructor(e,t,s){super(e,t,s);this.localService=s;this.marker=e.searchParams.get("marker")}marker;exec(e){if(this.hasNot(this.bucket,e)||this.isInvalidMaxKeys(e))return;let t=!1,s="",n="",o=[],c="",a=this.getKeys();if(this.marker){a=a.filter(g=>g.localeCompare(this.marker)>0);let p=a.findIndex(g=>g.startsWith(this.marker));p>-1&&(a=a.slice(p+1))}let d=Number(this.maxKeys),u=a.length;u>d&&(t=!0,a=a.slice(0,d),u>a.length&&(s=a[a.length-1])),this.delimiter&&(n=`<Delimiter>${this.delimiter}</Delimiter>`,o=$(this.prefix??"",this.delimiter,a),this.marker&&(o=o.filter(p=>p!=this.marker))),o.length&&(a=a.filter(p=>!o.some(g=>p.startsWith(g))),c=o.map(p=>`<CommonPrefixes><Prefix>${p}</Prefix></CommonPrefixes>`).join("")),this.marker&&t&&!a.length&&o.length&&(s=o[0]),e.statusCode=200,e.setHeader("Server","AmazonS3"),e.setHeader("Content-Type","application/xml"),e.setHeader("x-amzn-requestid",this.requestId);let l=a.map(p=>{let g=this.localService.persistence.buckets[this.bucket].objects[p];return`<Contents>
12
12
  <Key>${p}</Key>
@@ -44,7 +44,7 @@ import{S3 as ss}from"@aws-sdk/client-s3";import{randomUUID as xe}from"node:crypt
44
44
  ${this.continuationToken?`<ContinuationToken>${this.continuationToken}</ContinuationToken>`:""}
45
45
  ${!this.continuationToken&&this.startAfter?`<StartAfter>${this.startAfter}</StartAfter>`:""}
46
46
  ${g}
47
- </ListBucketResult>`)}};import{randomUUID as yt}from"node:crypto";var E=class extends m{constructor(e,t,s){super(t,s);this.localService=s;e.searchParams.has("bucket-region")&&(this.bucketRegion=e.searchParams.get("bucket-region")),e.searchParams.has("continuation-token")&&(this.continuationToken=e.searchParams.get("continuation-token")),e.searchParams.has("prefix")&&(this.prefix=e.searchParams.get("prefix")),e.searchParams.has("max-buckets")&&(this.rawMaxBuckets=e.searchParams.get("max-buckets"))}bucketRegion;continuationToken;rawMaxBuckets;prefix;isValidToken(e){return!(!e||typeof e!="object"||typeof e.id!="string"||e.port!==this.localService.port||typeof e.prefix<"u"&&typeof e.prefix!="string"||typeof e.nextStartingPosition!="number"||Number(e.nextStartingPosition)<1)}isValidRequest(e){let t=Number(this.rawMaxBuckets);if(this.rawMaxBuckets){if(isNaN(t)||this.rawMaxBuckets.includes(".")||t<1||t>1e4){let n=new k({ArgumentName:"max-buckets",ArgumentValue:this.rawMaxBuckets,Message:"Argument max-buckets must be an integer between 1 and 10000",RequestId:this.requestId}).toXml();e.statusCode=400,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(n);return}}else t=1e4;let s;if(this.continuationToken){let n=new k({ArgumentName:"continuation-token",Message:"The continuation token provided is incorrect",RequestId:this.requestId}).toXml();try{let o=JSON.parse(Buffer.from(this.continuationToken,"base64").toString("utf-8"));this.isValidToken(o)||(e.statusCode=400,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(n)),s=o}catch{e.statusCode=400,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(n);return}}return{maxBuckets:t,continuationToken:s,prefix:this.prefix,bucketRegion:this.bucketRegion}}createContinuationToken(e){let t={id:yt(),port:this.localService.port,prefix:this.prefix??"",nextStartingPosition:e};return Buffer.from(JSON.stringify(t)).toString("base64")}getBucketNames(e,t){let s=Object.keys(this.localService.persistence.buckets).sort((n,o)=>n.localeCompare(o));return e?(e.prefix&&(s=s.filter(n=>n.startsWith(e.prefix))),s=s.slice(e.nextStartingPosition),t&&(s=s.filter(n=>n.startsWith(t))),s):t?s.filter(n=>n.startsWith(t)):s}async exec(e){let t=this.isValidRequest(e);if(!t)return;let{maxBuckets:s,continuationToken:n,prefix:o,bucketRegion:c}=t,a=this.getBucketNames(n,o),d="",u=c;!c&&(this.rawMaxBuckets||this.prefix||this.continuationToken)&&(u=this.localService.region);let l="";u&&(l+=`<BucketRegion>${u}</BucketRegion>`);let p=[];for(let y=0;y<a.length;y++){let C=a[y],Se=this.localService.persistence.buckets[C],S=`<Bucket>${l}<CreationDate>${new Date(Se.date).toISOString()}</CreationDate><Name>${C}</Name></Bucket>`;if(p.push(S),p.length==s){if(a[y+1]){let H=y+1;n&&(H=H+n.nextStartingPosition),d=this.createContinuationToken(H)}break}}let g="";d&&(g=`<ContinuationToken>${d}</ContinuationToken>`);let h="";this.prefix&&(h=`<Prefix>${this.prefix}</Prefix>`),e.writeHead(200,{"x-amz-request-id":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}),e.end(`<?xml version="1.0" encoding="UTF-8"?><ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Buckets>${p.join("")}</Buckets>${g}${h}<Owner><ID>${this.localService.ownerId}</ID></Owner></ListAllMyBucketsResult>`)}};import{createReadStream as It}from"node:fs";import we from"node:path";var O=({ifMatch:i,ifNoneMatch:r,ifModifiedSince:e,ifUnmodifiedSince:t},{ETag:s,LastModified:n})=>i&&i!==s?{statusCode:412,Code:"PreconditionFailed",Condition:"If-Match"}:r&&r===s?{statusCode:304,Code:"PreconditionFailed",Condition:"If-None-Match"}:e&&e>=n?{statusCode:304,Code:"PreconditionFailed",Condition:"If-Modified-Since"}:t&&t<n?{statusCode:412,Code:"PreconditionFailed",Condition:"If-Unmodified-Since"}:200,L=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let n=decodeURIComponent(e.pathname),[o,...c]=n.split("/").filter(Boolean);this.bucket=o,this.key=c.join("/"),this.bucketPath=we.join(this.localService.localStoragePath,o),this.versionId=e.searchParams.get("versionId"),this.hasPartNumber=e.searchParams.has("partNumber");let a=e.searchParams.get("partNumber"),d=Number(a);if(this.partNumber=this.hasPartNumber&&!isNaN(d)?d:a,t.range){this.hasRange=!0;let[u]=t.range.split("bytes=").filter(Boolean),[l,p]=u.split("-");!isNaN(Number(l))&&!isNaN(Number(p))&&(this.range=[Number(l),Number(p)])}this.ifMatch=t["if-match"],this.ifNoneMatch=t["if-none-match"],t["if-modified-since"]&&(this.ifModifiedSince=new Date(t["if-modified-since"]).getTime()),t["if-unmodified-since"]&&(this.ifUnmodifiedSince=new Date(t["if-unmodified-since"]).getTime())}bucketPath;bucket;key;versionId;partNumber;hasPartNumber;hasRange=!1;range;ifMatch;ifNoneMatch;ifModifiedSince;ifUnmodifiedSince;async exec(e){if(!this.hasNot(this.bucket,e)){if(!this.localService.persistence.buckets[this.bucket].objects[this.key]){e.writeHead(404,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(x({Key:this.key,RequestId:this.requestId}));return}try{let t={ifMatch:this.ifMatch,ifModifiedSince:this.ifModifiedSince,ifNoneMatch:this.ifNoneMatch,ifUnmodifiedSince:this.ifUnmodifiedSince},s=this.localService.persistence.buckets[this.bucket].objects[this.key],n=s.currentKey,o=O(t,s);if(this.hasRange&&this.hasPartNumber){e.statusCode=400,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(`<Error><Code>InvalidRequest</Code><Message>Cannot specify both Range header and partNumber query parameter</Message><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}if(o==200){let c=200,a=s.size,d,u=we.join(this.bucketPath,s.currentKey),l={};if(this.hasPartNumber){let g=this.partNumber;if(isNaN(g)||g<1||g>1e4){let h=new k({ArgumentName:"partNumber",ArgumentValue:g,RequestId:this.requestId,Message:"Part number must be an integer between 1 and 10000, inclusive"}).toXml();e.writeHead(400,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(h);return}if(s.versions[n].multipartUploadId){let h=this.localService.persistence.buckets[this.bucket].multipartUploads[s.versions[n].multipartUploadId];c=206;let y;l.start=0;for(let C of h.parts){if(C.partNumber==g){y=C,l.end=l.start+y.size-1;break}l.start=l.start+C.size}if(!y){let C=new B({RequestId:this.requestId,PartNumberRequested:g,ActualPartCount:h.parts.length}).toXml();e.writeHead(416,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(C);return}e.setHeader("x-amz-mp-parts-count",h.parts.length),a=y?.size,d=`bytes ${l.start}-${l.end}/${s.size}`}else if(this.partNumber==1)c=206,d=`bytes 0-${s.size-1}/${s.size}`;else{let h=new B({RequestId:this.requestId,PartNumberRequested:this.partNumber,ActualPartCount:1}).toXml();e.writeHead(416,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(h);return}}let p=s.type;if(this.range){c=206,l.start=this.range[0],l.end=this.range[1];let g=1;l.end>s.size&&(l.end=s.size,g--),a=g+l.end-l.start,d=`bytes ${l.start}-${l.end}/${s.size}`,p="application/octet-stream"}e.statusCode=c,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("x-amz-server-side-encryption","AES256"),e.setHeader("Date",new Date().toUTCString()),e.setHeader("Last-Modified",new Date(s.LastModified).toUTCString()),e.setHeader("ETag",s.ETag),e.setHeader("Accept-Ranges","bytes"),d&&e.setHeader("Content-Range",d),e.setHeader("Content-Length",a),p&&e.setHeader("Content-Type",p),e.setHeader("Server","AmazonS3"),s.cacheControl&&e.setHeader("Cache-Control",s.cacheControl),s.contentDisposition&&e.setHeader("Content-Disposition",s.contentDisposition),s.contentEncoding&&e.setHeader("Content-Encoding",s.contentEncoding),s.contentLanguage&&e.setHeader("Content-Language",s.contentLanguage),s.expires&&e.setHeader("Expires",new Date(s.expires).toUTCString()),s.websiteRedirectLocation&&e.setHeader("x-amz-website-redirect-location",s.websiteRedirectLocation);for(let[g,h]of Object.entries(s.metadata))e.setHeader(g,h);It(u,l).pipe(e)}else e.writeHead(o.statusCode,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(`<?xml version="1.0" encoding="UTF-8"?><Error><Code>${o.Code}</Code><Message>At least one of the pre-conditions you specified did not hold</Message><Condition>${o.Condition}</Condition><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`)}catch{e.statusCode=500,e.end("Internal Server Error")}}}};var V=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n,...o]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n,this.key=o.join("/"),this.versionId=e.searchParams.get("versionId")}bucket;key;versionId;async exec(e){if(!this.hasNot(this.bucket,e)){if(!this.localService.persistence.buckets[this.bucket].objects[this.key]){e.writeHead(404,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(x({Key:this.key,RequestId:this.requestId}));return}try{e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.statusCode=200;let t={Tagging:{TagSet:{Tag:[]}}},s=this.localService.persistence.buckets[this.bucket].objects[this.key].tags;if(s)for(let[o,c]of Object.entries(s))t.Tagging.TagSet.Tag.push({Key:o,Value:c});let n=b.XMLBuilder.build(t);e.end(`<?xml version="1.0" encoding="UTF-8"?>${n}`)}catch(t){if(e.statusCode=400,t instanceof f){e.setHeader("Content-Type","application/xml"),t.statusCode&&(e.statusCode=t.statusCode),e.end(t.toXml());return}if(t instanceof Error){e.setHeader("Content-Type","application/xml"),e.end(f.genericError({Code:"UnknownError",Message:t.message,RequestId:this.requestId}));return}e.end(t?.toString?.())}}}};var F=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n}bucket;async exec(e){if(!this.hasNot(this.bucket,e))try{e.setHeader("x-amzn-requestid",this.requestId);let t=this.localService.persistence.buckets[this.bucket].tags;if(!t)throw new ee(this.requestId);e.statusCode=200;let s={Tagging:{TagSet:{Tag:[]}}};for(let[o,c]of Object.entries(t))s.Tagging.TagSet.Tag.push({Key:o,Value:c});let n=b.XMLBuilder.build(s);e.setHeader("Content-Type","application/xml"),e.end(`<?xml version="1.0" encoding="UTF-8"?>${n}`)}catch(t){if(e.statusCode=400,t instanceof f){e.setHeader("Content-Type","application/xml"),t.statusCode&&(e.statusCode=t.statusCode),e.end(t.toXml());return}if(t instanceof Error){e.setHeader("Content-Type","application/xml"),e.end(f.genericError({Code:"UnknownError",Message:t.message,RequestId:this.requestId}));return}e.end(t?.toString?.())}}};var ae=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n}bucket;async exec(e){if(this.hasNot(this.bucket,e))return;let t=this.localService.persistence.buckets[this.bucket];if(t.policy){e.setHeader("x-amzn-requestid",this.requestId),e.end(JSON.stringify(t.policy));return}e.writeHead(404,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(`<?xml version="1.0" encoding="UTF-8"?>
47
+ </ListBucketResult>`)}};import{randomUUID as yt}from"node:crypto";var E=class extends m{constructor(e,t,s){super(t,s);this.localService=s;e.searchParams.has("bucket-region")&&(this.bucketRegion=e.searchParams.get("bucket-region")),e.searchParams.has("continuation-token")&&(this.continuationToken=e.searchParams.get("continuation-token")),e.searchParams.has("prefix")&&(this.prefix=e.searchParams.get("prefix")),e.searchParams.has("max-buckets")&&(this.rawMaxBuckets=e.searchParams.get("max-buckets"))}bucketRegion;continuationToken;rawMaxBuckets;prefix;isValidToken(e){return!(!e||typeof e!="object"||typeof e.id!="string"||e.port!==this.localService.port||typeof e.prefix<"u"&&typeof e.prefix!="string"||typeof e.nextStartingPosition!="number"||Number(e.nextStartingPosition)<1)}isValidRequest(e){let t=Number(this.rawMaxBuckets);if(this.rawMaxBuckets){if(isNaN(t)||this.rawMaxBuckets.includes(".")||t<1||t>1e4){let n=new k({ArgumentName:"max-buckets",ArgumentValue:this.rawMaxBuckets,Message:"Argument max-buckets must be an integer between 1 and 10000",RequestId:this.requestId}).toXml();e.statusCode=400,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(n);return}}else t=1e4;let s;if(this.continuationToken){let n=new k({ArgumentName:"continuation-token",Message:"The continuation token provided is incorrect",RequestId:this.requestId}).toXml();try{let o=JSON.parse(Buffer.from(this.continuationToken,"base64").toString("utf-8"));this.isValidToken(o)||(e.statusCode=400,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(n)),s=o}catch{e.statusCode=400,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(n);return}}return{maxBuckets:t,continuationToken:s,prefix:this.prefix,bucketRegion:this.bucketRegion}}createContinuationToken(e){let t={id:yt(),port:this.localService.port,prefix:this.prefix??"",nextStartingPosition:e};return Buffer.from(JSON.stringify(t)).toString("base64")}getBucketNames(e,t){let s=Object.keys(this.localService.persistence.buckets).sort((n,o)=>n.localeCompare(o));return e?(e.prefix&&(s=s.filter(n=>n.startsWith(e.prefix))),s=s.slice(e.nextStartingPosition),t&&(s=s.filter(n=>n.startsWith(t))),s):t?s.filter(n=>n.startsWith(t)):s}async exec(e){let t=this.isValidRequest(e);if(!t)return;let{maxBuckets:s,continuationToken:n,prefix:o,bucketRegion:c}=t,a=this.getBucketNames(n,o),d="",u=c;!c&&(this.rawMaxBuckets||this.prefix||this.continuationToken)&&(u=this.localService.region);let l="";u&&(l+=`<BucketRegion>${u}</BucketRegion>`);let p=[];for(let y=0;y<a.length;y++){let C=a[y],Se=this.localService.persistence.buckets[C],S=`<Bucket>${l}<CreationDate>${new Date(Se.date).toISOString()}</CreationDate><Name>${C}</Name></Bucket>`;if(p.push(S),p.length==s){if(a[y+1]){let H=y+1;n&&(H=H+n.nextStartingPosition),d=this.createContinuationToken(H)}break}}let g="";d&&(g=`<ContinuationToken>${d}</ContinuationToken>`);let h="";this.prefix&&(h=`<Prefix>${this.prefix}</Prefix>`),e.writeHead(200,{"x-amz-request-id":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}),e.end(`<?xml version="1.0" encoding="UTF-8"?><ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Buckets>${p.join("")}</Buckets>${g}${h}<Owner><ID>${this.localService.ownerId}</ID></Owner></ListAllMyBucketsResult>`)}};import{createReadStream as It}from"node:fs";import we from"node:path";var K=({ifMatch:i,ifNoneMatch:r,ifModifiedSince:e,ifUnmodifiedSince:t},{ETag:s,LastModified:n})=>i&&i!==s?{statusCode:412,Code:"PreconditionFailed",Condition:"If-Match"}:r&&r===s?{statusCode:304,Code:"PreconditionFailed",Condition:"If-None-Match"}:e&&e>=n?{statusCode:304,Code:"PreconditionFailed",Condition:"If-Modified-Since"}:t&&t<n?{statusCode:412,Code:"PreconditionFailed",Condition:"If-Unmodified-Since"}:200,L=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let n=decodeURIComponent(e.pathname),[o,...c]=n.split("/").filter(Boolean);this.bucket=o,this.key=c.join("/"),this.bucketPath=we.join(this.localService.localStoragePath,o),this.versionId=e.searchParams.get("versionId"),this.hasPartNumber=e.searchParams.has("partNumber");let a=e.searchParams.get("partNumber"),d=Number(a);if(this.partNumber=this.hasPartNumber&&!isNaN(d)?d:a,t.range){this.hasRange=!0;let[u]=t.range.split("bytes=").filter(Boolean),[l,p]=u.split("-");!isNaN(Number(l))&&!isNaN(Number(p))&&(this.range=[Number(l),Number(p)])}this.ifMatch=t["if-match"],this.ifNoneMatch=t["if-none-match"],t["if-modified-since"]&&(this.ifModifiedSince=new Date(t["if-modified-since"]).getTime()),t["if-unmodified-since"]&&(this.ifUnmodifiedSince=new Date(t["if-unmodified-since"]).getTime())}bucketPath;bucket;key;versionId;partNumber;hasPartNumber;hasRange=!1;range;ifMatch;ifNoneMatch;ifModifiedSince;ifUnmodifiedSince;async exec(e){if(!this.hasNot(this.bucket,e)){if(!this.localService.persistence.buckets[this.bucket].objects[this.key]){e.writeHead(404,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(x({Key:this.key,RequestId:this.requestId}));return}try{let t={ifMatch:this.ifMatch,ifModifiedSince:this.ifModifiedSince,ifNoneMatch:this.ifNoneMatch,ifUnmodifiedSince:this.ifUnmodifiedSince},s=this.localService.persistence.buckets[this.bucket].objects[this.key],n=s.currentKey,o=K(t,s);if(this.hasRange&&this.hasPartNumber){e.statusCode=400,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(`<Error><Code>InvalidRequest</Code><Message>Cannot specify both Range header and partNumber query parameter</Message><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}if(o==200){let c=200,a=s.size,d,u=we.join(this.bucketPath,s.currentKey),l={};if(this.hasPartNumber){let g=this.partNumber;if(isNaN(g)||g<1||g>1e4){let h=new k({ArgumentName:"partNumber",ArgumentValue:g,RequestId:this.requestId,Message:"Part number must be an integer between 1 and 10000, inclusive"}).toXml();e.writeHead(400,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(h);return}if(s.versions[n].multipartUploadId){let h=this.localService.persistence.buckets[this.bucket].multipartUploads[s.versions[n].multipartUploadId];c=206;let y;l.start=0;for(let C of h.parts){if(C.partNumber==g){y=C,l.end=l.start+y.size-1;break}l.start=l.start+C.size}if(!y){let C=new B({RequestId:this.requestId,PartNumberRequested:g,ActualPartCount:h.parts.length}).toXml();e.writeHead(416,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(C);return}e.setHeader("x-amz-mp-parts-count",h.parts.length),a=y?.size,d=`bytes ${l.start}-${l.end}/${s.size}`}else if(this.partNumber==1)c=206,d=`bytes 0-${s.size-1}/${s.size}`;else{let h=new B({RequestId:this.requestId,PartNumberRequested:this.partNumber,ActualPartCount:1}).toXml();e.writeHead(416,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(h);return}}let p=s.type;if(this.range){c=206,l.start=this.range[0],l.end=this.range[1];let g=1;l.end>s.size&&(l.end=s.size,g--),a=g+l.end-l.start,d=`bytes ${l.start}-${l.end}/${s.size}`,p="application/octet-stream"}e.statusCode=c,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("x-amz-server-side-encryption","AES256"),e.setHeader("Date",new Date().toUTCString()),e.setHeader("Last-Modified",new Date(s.LastModified).toUTCString()),e.setHeader("ETag",s.ETag),e.setHeader("Accept-Ranges","bytes"),d&&e.setHeader("Content-Range",d),e.setHeader("Content-Length",a),p&&e.setHeader("Content-Type",p),e.setHeader("Server","AmazonS3"),s.cacheControl&&e.setHeader("Cache-Control",s.cacheControl),s.contentDisposition&&e.setHeader("Content-Disposition",s.contentDisposition),s.contentEncoding&&e.setHeader("Content-Encoding",s.contentEncoding),s.contentLanguage&&e.setHeader("Content-Language",s.contentLanguage),s.expires&&e.setHeader("Expires",new Date(s.expires).toUTCString()),s.websiteRedirectLocation&&e.setHeader("x-amz-website-redirect-location",s.websiteRedirectLocation);for(let[g,h]of Object.entries(s.metadata))e.setHeader(g,h);It(u,l).pipe(e)}else e.writeHead(o.statusCode,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(`<?xml version="1.0" encoding="UTF-8"?><Error><Code>${o.Code}</Code><Message>At least one of the pre-conditions you specified did not hold</Message><Condition>${o.Condition}</Condition><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`)}catch{e.statusCode=500,e.end("Internal Server Error")}}}};var V=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n,...o]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n,this.key=o.join("/"),this.versionId=e.searchParams.get("versionId")}bucket;key;versionId;async exec(e){if(!this.hasNot(this.bucket,e)){if(!this.localService.persistence.buckets[this.bucket].objects[this.key]){e.writeHead(404,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(x({Key:this.key,RequestId:this.requestId}));return}try{e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.statusCode=200;let t={Tagging:{TagSet:{Tag:[]}}},s=this.localService.persistence.buckets[this.bucket].objects[this.key].tags;if(s)for(let[o,c]of Object.entries(s))t.Tagging.TagSet.Tag.push({Key:o,Value:c});let n=b.XMLBuilder.build(t);e.end(`<?xml version="1.0" encoding="UTF-8"?>${n}`)}catch(t){if(e.statusCode=400,t instanceof f){e.setHeader("Content-Type","application/xml"),t.statusCode&&(e.statusCode=t.statusCode),e.end(t.toXml());return}if(t instanceof Error){e.setHeader("Content-Type","application/xml"),e.end(f.genericError({Code:"UnknownError",Message:t.message,RequestId:this.requestId}));return}e.end(t?.toString?.())}}}};var F=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n}bucket;async exec(e){if(!this.hasNot(this.bucket,e))try{e.setHeader("x-amzn-requestid",this.requestId);let t=this.localService.persistence.buckets[this.bucket].tags;if(!t)throw new ee(this.requestId);e.statusCode=200;let s={Tagging:{TagSet:{Tag:[]}}};for(let[o,c]of Object.entries(t))s.Tagging.TagSet.Tag.push({Key:o,Value:c});let n=b.XMLBuilder.build(s);e.setHeader("Content-Type","application/xml"),e.end(`<?xml version="1.0" encoding="UTF-8"?>${n}`)}catch(t){if(e.statusCode=400,t instanceof f){e.setHeader("Content-Type","application/xml"),t.statusCode&&(e.statusCode=t.statusCode),e.end(t.toXml());return}if(t instanceof Error){e.setHeader("Content-Type","application/xml"),e.end(f.genericError({Code:"UnknownError",Message:t.message,RequestId:this.requestId}));return}e.end(t?.toString?.())}}};var ae=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n}bucket;async exec(e){if(this.hasNot(this.bucket,e))return;let t=this.localService.persistence.buckets[this.bucket];if(t.policy){e.setHeader("x-amzn-requestid",this.requestId),e.end(JSON.stringify(t.policy));return}e.writeHead(404,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(`<?xml version="1.0" encoding="UTF-8"?>
48
48
  <Error><Code>NoSuchBucketPolicy</Code><BucketName>${this.bucket}</BucketName><Message>The bucket policy does not exist</Message><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`)}};var ce=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let n=decodeURIComponent(e.pathname),[o,...c]=n.split("/").filter(Boolean);this.bucket=o,this.key=c.join("/"),this.uploadId=e.searchParams.get("uploadId"),this.hasPartNumberMarker=e.searchParams.has("part-number-marker"),e.searchParams.has("part-number-marker")&&(this.partNumberMarker=e.searchParams.get("part-number-marker")??""),e.searchParams.has("max-parts")&&(this.maxParts=e.searchParams.get("max-parts")??"")}bucket;key;uploadId;partNumberMarker="";hasPartNumberMarker=!1;maxParts="1000";validateRequest(e){if(this.hasNot(this.bucket,e))return;let t=this.localService.persistence.buckets[this.bucket].multipartUploads[this.uploadId??""];if(!this.uploadId||!t||t.aborted||t.completed){e.statusCode=404,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(`<?xml version="1.0" encoding="UTF-8"?>
49
49
  <Error><Code>NoSuchUpload</Code><UploadId>${this.uploadId}</UploadId><Message>The specified upload does not exist. The upload ID may be invalid, or the upload may have been aborted or completed.</Message><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}let s=Number(this.partNumberMarker);if(this.hasPartNumberMarker&&(!this.partNumberMarker||isNaN(s)||this.partNumberMarker.includes(".")||s<0||s>2147483647)){e.statusCode=400,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(`<?xml version="1.0" encoding="UTF-8"?>
50
50
  <Error><Code>InvalidArgument</Code><ArgumentName>part-number-marker</ArgumentName><ArgumentValue>${this.partNumberMarker}</ArgumentValue><Message>Argument part-number-marker must be an integer between 0 and 2147483647</Message><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}let n=Number(this.maxParts);if(!this.maxParts||isNaN(n)||this.maxParts.includes(".")||n<0||n>2147483647){e.statusCode=400,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(`<?xml version="1.0" encoding="UTF-8"?>
@@ -74,24 +74,24 @@ import{S3 as ss}from"@aws-sdk/client-s3";import{randomUUID as xe}from"node:crypt
74
74
  <Error><Code>InvalidArgument</Code><ArgumentName>max-uploads</ArgumentName><ArgumentValue>${this.maxUploads}</ArgumentValue><Message>Provided max-uploads not an integer or within integer range</Message><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}if(t<0||t>2147483647){e.statusCode=400,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(`<?xml version="1.0" encoding="UTF-8"?>
75
75
  <Error><Code>InvalidArgument</Code><ArgumentName>max-uploads</ArgumentName><ArgumentValue>${this.maxUploads}</ArgumentValue><Message>Argument max-uploads must be an integer between 0 and 2147483647</Message><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}}if(this.hasEncodingType&&this.encodingType.toLowerCase()!="url"){e.statusCode=400,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(`<?xml version="1.0" encoding="UTF-8"?>
76
76
  <Error><Code>InvalidArgument</Code><ArgumentName>encoding-type</ArgumentName><ArgumentValue>${this.encodingType}</ArgumentValue><Message>Invalid Encoding Method specified in Request</Message><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}return!0}collectUploads(e){return e.sort((n,o)=>n.key.localeCompare(o.key)),this.keyMarker?this.uploadIdMarker?e.find(n=>n.key==this.keyMarker&&n.uploadId==this.uploadIdMarker)?e.filter(n=>n.key.localeCompare(this.keyMarker)>=0).filter(n=>n.key==this.keyMarker?n.uploadId.localeCompare(this.uploadIdMarker)>0:!0):new k({ArgumentName:"upload-id-marker",ArgumentValue:this.uploadIdMarker,Message:"Invalid uploadId marker",RequestId:this.requestId}):e.filter(n=>n.key.localeCompare(this.keyMarker)>0):e}getUploads(){let e=[],t=!1,s,n="",o="",c=this.localService.persistence.buckets[this.bucket].multipartUploads;if(c){e=Object.values(c).filter(u=>!u.aborted&&!u.completed),this.prefix&&(e=e.filter(u=>u.key.startsWith(this.prefix)));let a=this.collectUploads(e);if(a instanceof k)return{uploads:e,isTruncated:t,commonPrefixes:s,nextKeyMarker:n,nextUploadIdMarker:o,error:a};let d=a.length;e=a.slice(0,Number(this.maxUploads)),t=d-e.length>0,this.delimiter&&(s=$(this.prefix??"",this.delimiter,e.map(u=>u.key)),e=e.filter(u=>!s.some(l=>u.key.startsWith(l))))}if(e.length){let a=e[e.length-1];n=a.key,o=a.uploadId}return{uploads:e,isTruncated:t,commonPrefixes:s,nextKeyMarker:n,nextUploadIdMarker:o}}async exec(e){if(this.hasNot(this.bucket,e)||!this.validateRequest(e))return;let{uploads:s,isTruncated:n,commonPrefixes:o,nextKeyMarker:c,nextUploadIdMarker:a,error:d}=this.getUploads();if(d){e.statusCode=400,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(d.toXml());return}let u=`<?xml version="1.0" encoding="UTF-8"?>
77
- <ListMultipartUploadsResult><Bucket>${this.bucket}</Bucket><IsTruncated>${n}</IsTruncated><KeyMarker>${this.keyMarker??""}</KeyMarker><MaxUploads>${this.maxUploads??"1000"}</MaxUploads>`;if(u+=`<UploadIdMarker>${this.uploadIdMarker??""}</UploadIdMarker><NextUploadIdMarker>${a}</NextUploadIdMarker><NextKeyMarker>${c}</NextKeyMarker>`,this.prefix&&(u+=`<Prefix>${this.prefix}</Prefix>`),this.delimiter&&(u+=`<Delimiter>${this.delimiter}</Delimiter>`),o)for(let g of o)u+=`<CommonPrefixes><Prefix>${g}</Prefix></CommonPrefixes>`;this.encodingType&&(u+=`<EncodingType>${this.encodingType}</EncodingType>`);let l=`<Owner><ID>${this.localService.ownerId}</ID></Owner>`,p=`<Initiator><ID>${this.localService.ownerId}</ID></Initiator>`;for(let g of s)u+=`<Upload><Initiated>${g.initDate}</Initiated>${p}<Key>${g.key}</Key>${l}<StorageClass>${g.data.StorageClass}</StorageClass><UploadId>${g.uploadId}</UploadId></Upload>`;u+="</ListMultipartUploadsResult>",e.writeHead(200,{"x-amzn-requestid":this.requestId,Server:"AmazonS3"}).end(u)}};var ue=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n}bucket;async exec(e){if(this.hasNot(this.bucket,e))return;let t=this.localService.persistence.buckets[this.bucket];e.writeHead(200,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(t.acl.accessControlPolicy)}};var le=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n}bucket;async exec(e){if(this.hasNot(this.bucket,e))return;let t=this.localService.persistence.buckets[this.bucket];e.writeHead(200,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(t.acl.accessControlPolicy)}};var Te=(i,r)=>{let{url:e,headers:t}=i,s=new URL(e,"http://localhost:3000"),n=t["user-agent"],o=s.pathname.split("/").filter(Boolean).length==1;if(n?.startsWith("aws-cli")){let[,c]=n.split("command/"),[,...a]=c.split(".");switch(a.join(".")){case"ls":return/@s3\/?$/.test(e)?new E(s,t,r):s.searchParams.get("list-type")=="2"?new M(s,t,r):new q(s,t,r);case"list-buckets":return new E(s,t,r);case"list-objects":return new q(s,t,r);case"list-objects-v2":return new M(s,t,r);case"rb.rm":return s.searchParams.get("list-type")=="2"?new M(s,t,r):new q(s,t,r);case"get-object":return new L(s,t,r);case"cp":case"mv":case"sync":return o?s.searchParams.get("list-type")=="2"?new M(s,t,r):new q(s,t,r):new L(s,t,r);case"get-bucket-tagging":return new F(s,t,r);case"get-object-tagging":return new V(s,t,r);default:break}}else return s.searchParams.has("acl")?o?new ue(s,t,r):new le(s,t,r):s.searchParams.has("uploads")?o?new de(s,t,r):new I(s,t,r):s.searchParams.has("policy")?new ae(s,t,r):s.searchParams.has("tagging")?o?new F(s,t,r):new V(s,t,r):s.searchParams.has("uploadId")?o?new I(s,t,r):new ce(s,t,r):s.pathname=="/"?new E(s,t,r):o?s.searchParams.get("list-type")=="2"?new M(s,t,r):new q(s,t,r):new L(s,t,r);return new I(s,t,r)};var pe=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n}bucket;exec(e){this.hasNot(this.bucket,e)||(e.statusCode=200,e.setHeader("x-amz-request-id",this.requestId),e.end())}};import Pe from"node:path";var me=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let n=decodeURIComponent(e.pathname),[o,...c]=n.split("/").filter(Boolean);if(this.bucket=o,this.key=c.join("/"),this.bucketPath=Pe.join(this.localService.localStoragePath,o),this.filePath=Pe.join(this.bucketPath,...c),this.versionId=e.searchParams.get("versionId"),this.partNumber=e.searchParams.has("partNumber")?Number(e.searchParams.get("partNumber")):null,t.range){let[a]=t.range.split("bytes=").filter(Boolean),[d,u]=a.split("-");!isNaN(Number(d))&&!isNaN(Number(u))&&(this.range=[Number(d),Number(u)])}this.ifMatch=t["if-match"],this.ifNoneMatch=t["if-none-match"],t["if-modified-since"]&&(this.ifModifiedSince=new Date(t["if-modified-since"]).getTime()),t["if-unmodified-since"]&&(this.ifUnmodifiedSince=new Date(t["if-unmodified-since"]).getTime())}filePath;bucketPath;bucket;key;versionId;partNumber;range;ifMatch;ifNoneMatch;ifModifiedSince;ifUnmodifiedSince;async exec(e){if(!this.hasNot(this.bucket,e)){if(!this.localService.persistence.buckets[this.bucket].objects[this.key]){e.writeHead(404,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(x({Key:this.key,RequestId:this.requestId}));return}try{let t={ifMatch:this.ifMatch,ifModifiedSince:this.ifModifiedSince,ifNoneMatch:this.ifNoneMatch,ifUnmodifiedSince:this.ifUnmodifiedSince},s=this.localService.persistence.buckets[this.bucket].objects[this.key],n=O(t,s);if(n==200){let o=200,c=s.size,a,d=s.type,u={};if(this.range){o=206,u.start=this.range[0],u.end=this.range[1];let l=1;u.end>s.size&&(u.end=s.size,l--),c=l+u.end-u.start,a=`bytes ${u.start}-${u.end}/${s.size}`,d="application/octet-stream"}e.statusCode=o,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("x-amz-server-side-encryption","AES256"),e.setHeader("Date",new Date().toUTCString()),e.setHeader("Last-Modified",new Date(s.LastModified).toUTCString()),e.setHeader("ETag",s.ETag),e.setHeader("Accept-Ranges","bytes"),a&&e.setHeader("Content-Range",a),e.setHeader("Content-Length",c),d&&e.setHeader("Content-Type",d),e.setHeader("Server","AmazonS3"),s.cacheControl&&e.setHeader("Cache-Control",s.cacheControl),s.contentDisposition&&e.setHeader("Content-Disposition",s.contentDisposition),s.contentEncoding&&e.setHeader("Content-Encoding",s.contentEncoding),s.contentLanguage&&e.setHeader("Content-Language",s.contentLanguage),s.expires&&e.setHeader("Expires",new Date(s.expires).toUTCString()),s.websiteRedirectLocation&&e.setHeader("x-amz-website-redirect-location",s.websiteRedirectLocation);for(let[l,p]of Object.entries(s.metadata))e.setHeader(l,p);e.end()}else e.writeHead(n.statusCode,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(`<?xml version="1.0" encoding="UTF-8"?><Error><Code>${n.Code}</Code><Message>At least one of the pre-conditions you specified did not hold</Message><Condition>${n.Condition}</Condition><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`)}catch{e.statusCode=500,e.end("Internal Server Error")}}}};var Ne=(i,r)=>{let{url:e,headers:t}=i,s=new URL(e,"http://localhost:3000");return s.pathname.split("/").filter(Boolean).length>1?new me(s,t,r):new pe(s,t,r)};var _=class i{static apiId="";static accountId="";static port=3e3;static serve;static contentType={json:"application/json",text:"text/plain; charset=utf-8",octet:"application/octet-stream"};static keepAlive=["Connection","keep-alive"];static dummyHost="http://localhost:3003";static httpErrMsg='{"message":"Internal Server Error"}';static apigJsonParseErrMsg='{"message":"[Unknown error parsing request body]"}';static apigForbiddenErrMsg='{"message":"Forbidden"}';static amzMsgNull='{"message":null}';static apgTimeoutMsg='{"message": "Endpoint request timed out"}';static unavailable='{"message":"Service Unavailable"}';static timeoutRegex=/after.\d+.*seconds/;static apgRequestTimeout=30;static normalizeHeaderKey=r=>r.toLowerCase().split("-").map(Ae).join("-");static getMultiValueHeaders=r=>{let e={},t=r.filter((n,o)=>o%2==0).map(n=>n.toLowerCase()),s=r.filter((n,o)=>o%2!==0);return t.forEach((n,o)=>{n!="x-mock-type"&&(e[n]?e[n].push(s[o]):e[n]=[s[o]])}),e};static getIsBase64Encoded=r=>{let e=r["content-type"];return r["content-encoding"]||!e?!0:!(e.startsWith("application/json")||e.startsWith("application/xml")||e.startsWith("application/javascript")||e.startsWith("text/"))};static knownHeaders=["accept","accept-encoding","user-agent","host","via","content-length"];static getApiGV1Headers(r,e){let{rawHeaders:t}=r,s,n={"X-Forwarded-For":r.socket.remoteAddress,"X-Forwarded-Proto":"http","X-Forwarded-Port":String(i.port)};for(let d=0;d<t.length;){let u=t[d],l=u.toLowerCase();if(["connection","x-mock-type"].includes(l)){d=d+2;continue}this.knownHeaders.includes(l)&&(u=this.normalizeHeaderKey(l));let p=t[d+1];n[u]=p,l=="x-api-key"&&(s=p),d=d+2}let o={};for(let d of Object.keys(n).sort((u,l)=>u.localeCompare(l)))o[d]=n[d];let c={"X-Forwarded-For":[r.socket.remoteAddress],"X-Forwarded-Proto":["http"],"X-Forwarded-Port":[String(i.port)]};for(let d=0;d<t.length;){let u=t[d],l=u.toLowerCase();if(["connection","x-mock-type"].includes(l)){d=d+2;continue}this.knownHeaders.includes(l)&&(u=this.normalizeHeaderKey(l));let p=t[d+1];c[u]?c[u].push(p):c[u]=[p],d=d+2}let a={};for(let d of Object.keys(c).sort((u,l)=>u.localeCompare(l)))a[d]=c[d];return{headers:o,multiValueHeaders:a,apiKey:s}}static getCustomHeaders(r,e){let{headers:t}=r;return delete t["x-mock-type"],delete t.connection,{"X-Forwarded-For":r.socket.remoteAddress,"X-Forwarded-Proto":"http","X-Forwarded-Port":String(i.port),...t}}static getPathParameters(r,e){let t=r.paths[0].split("/"),s=e.pathname.split("/"),n={};return t.forEach((o,c)=>{o.startsWith("{")&&o.endsWith("}")&&!o.endsWith("+}")&&(n[o.slice(1,-1)]=s[c])}),n}static normalizeSearchParams=(r,e)=>{let t={};Array.from(r.keys()).forEach(o=>{let c=r.getAll(o).map(d=>d.toLowerCase()),a=o.toLowerCase();c?t[a]?t[a].push(...c):t[a]=c:t[a]||(t[a]=void 0)});let s="",n=e.indexOf("?");return n!=-1&&(s=e.slice(n+1)),t.toString=()=>s,t};static getMultiValueQueryStringParameters=r=>{let e={};r.delete("x_mock_type");for(let t of Array.from(new Set(r.keys())))e[t]=r.getAll(t).map(encodeURI);return e};static isEndpointTimeoutError=r=>{if(!r)return;let e=r.match(this.timeoutRegex)?.[0];if(e){let t=e.split(" ")[1];if(!isNaN(t))return Number(t)>=i.apgRequestTimeout}}};var ge=!1,St=i=>{ge=i},xt=()=>ge,U=(i,r)=>{ge&&console.log(`\x1B[${i}m${r}\x1B[0m`)},kt=i=>console.log(`\x1B[31m${i}\x1B[0m`),Ct=i=>U("32",i),vt=i=>U("33",i),Ht=i=>U("36",i),Rt=i=>U("90",i),qt=i=>U("94",i),Mt=i=>U("95",i),wt=i=>ge?console.log(i):void 0,Ee={GREEN:Ct,YELLOW:vt,CYAN:Ht,BR_BLUE:qt,RED:kt,GREY:Rt,PINK:Mt,setDebug:St,getDebug:xt,info:wt};var Le="application/vnd.awslambda.http-integration-response",He=class i{buffer;_isHttpIntegrationResponse;_metaDelimiter;_endDelimiter;_ct;_isStreamResponse=!0;#e;static codec=new TextDecoder;static splitMessage=(r,e)=>{if(!r)return;let t=Array.from(r.values()),s=null;if(e)s=e;else for(let n=0;n<t.length;n++)if(t[n]===0&&[t[n+1],t[n+2],t[n+3],t[n+4],t[n+5],t[n+6],t[n+7]].every(a=>a===0)){s=n;break}if(s)return new Uint8Array(t.slice(0,s))};constructor(r){this._isHttpIntegrationResponse=!1,this._metaDelimiter=0,this._endDelimiter=0,this.#e=r}setHeader(r,e){this._isHttpIntegrationResponse=!this.buffer&&e==Le&&(!this._ct||this._ct==Le),this._ct=e}write(r,e){!this._isHttpIntegrationResponse&&!this._metaDelimiter&&(this._metaDelimiter=r.byteLength),this.#s(r)}end(r){this.buffer&&(this._endDelimiter=this.buffer.byteLength),r&&this.#s(r)}destroy(){}#s(r){this.buffer=typeof this.buffer>"u"?r:Buffer.concat([this.buffer,r])}getParsedResponse(){if(!this.#e)return;let r=this.#e.kind;if(r=="alb")return this.#r();if(r=="url")return this.#o();if(r=="apg")return this.#n()}#r(){let r=this._isHttpIntegrationResponse?i.splitMessage(this.buffer):this.buffer,e;return r&&(e=this.#t(r)),e}#n(){if(this._isHttpIntegrationResponse)return Ee.RED("awslambda.HttpResponseStream.from() is not supported with API Gateway"),{statusCode:500,headers:{"Content-Type":_.contentType.json},body:_.httpErrMsg};if(this.buffer)return this.#t(this.buffer)}#o(){let r=i.splitMessage(this.buffer,this._isHttpIntegrationResponse?void 0:this._metaDelimiter),e;return r&&(e=this.#t(r)),e}#t(r){let e=i.codec.decode(r);if(typeof e=="string")try{e=JSON.parse(e)}catch{}return e}};var Ue="<html><head><title>400 Request Header Or Cookie Too Large</title></head><body><center><h1>400 Bad Request</h1></center><center>Request Header Or Cookie Too Large</center></body></html>";var pn=JSON.stringify({Message:null});var ze=async(i,r)=>{let e=Buffer.alloc(0);return i.on("data",s=>{e=Buffer.concat([e,s])}),await new Promise(s=>{i.on("end",async()=>{s(e?e.toString(r?"base64":"utf-8"):void 0)})})};var mn=JSON.stringify({Type:null,message:"Client context must be a valid Base64-encoded JSON object."});var gn=new Error(Ue);var Ae=i=>i.charAt(0).toUpperCase()+i.slice(1);var Tt=i=>{let r=[],e;try{i.split("<Object>").forEach(t=>{let s=t.indexOf("<Key>");if(s==-1)return;let n=t.indexOf("</Key>"),c={Key:t.slice(s+5,n)},a=t.indexOf("<VersionId>");if(a>-1){let d=t.indexOf("</VersionId>"),u=t.slice(a+11,d);c.VersionId=u}r.push(c)})}catch(t){console.error(t)}return{Objects:r,Quiet:e}},he=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let n=decodeURIComponent(e.pathname),[o]=n.split("/").filter(Boolean);this.bucket=o}bucket;async exec(e,t){if(this.hasNot(this.bucket,e))return;let s=await ze(t),{Objects:n,Quiet:o}=Tt(s);if(!n.length){e.statusCode=400,e.setHeader("Content-Type","application/xml"),e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Server","AmazonS3"),e.end(`<Error><Code>MalformedXML</Code><Message>The XML you provided was not well-formed or did not validate against our published schema</Message><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}let c=n.map(d=>`<Deleted><Key>${d.Key}</Key></Deleted>`).join(""),a=t.socket.remoteAddress?.split(":")?.[3]??"127.0.0.1";e.statusCode=200,e.setHeader("Content-Type","application/xml"),e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Server","AmazonS3");for(let d of n)await this.localService.removeObject(this.bucket,d.Key,a,this.requestId);e.end(`<?xml version="1.0" encoding="UTF-8"?><DeleteResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">${c}</DeleteResult>`)}};import{createWriteStream as Pt,mkdirSync as Nt,readFileSync as At,statSync as Et}from"node:fs";import $e from"node:path";var fe=i=>`"${R(i)}"`;var w=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n,...o]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n,this.key=o.join("/"),this.contentType=t["content-type"]??"application/octet-stream",this.cacheControl=t["cache-control"],this.contentDisposition=t["content-disposition"],this.contentEncoding=t["content-encoding"],this.contentLanguage=t["content-language"],this.websiteRedirectLocation=t["x-amz-website-redirect-location"],t["x-amz-tagging"]&&(this.tagging=t["x-amz-tagging"]);let c=t["x-amz-storage-class"];c&&(this.storageClass=c);let a=new Date(t.expires);isNaN(a)||(this.expires=a.getTime())}bucket;key;contentType;cacheControl;contentDisposition;contentEncoding;contentLanguage;websiteRedirectLocation;expires;storageClass="STANDARD";tagging;validateRequest(e){if(this.hasNot(this.bucket,e)||!this.isValidStorageClass(this.storageClass,e))return;let t={};if(this.tagging){let n=()=>{e.statusCode=400,e.setHeader("Content-Type","application/xml"),e.end(new k({ArgumentName:"x-amz-tagging",ArgumentValue:this.tagging,Message:"The header 'x-amz-tagging' shall be encoded as UTF-8 then URLEncoded URL query parameters without tag name duplicates.",RequestId:this.requestId}).toXml())};if(typeof this.tagging!="string"){n();return}if(!Lt(this.tagging)){n();return}let o=new URLSearchParams(this.tagging);for(let c of o.keys()){if(c in t){e.statusCode=400,e.setHeader("Content-Type","application/xml"),e.end(new v({TagKey:c,RequestId:this.requestId,Message:"Cannot provide multiple Tags with the same key"}).toXml());return}if(c.length>128||c.length<1){e.statusCode=400,e.setHeader("Content-Type","application/xml"),e.end(new v({TagKey:c,RequestId:this.requestId,Message:"The TagKey you have provided is invalid"}).toXml());return}let a=o.get(c);if(a.length>256){e.statusCode=400,e.setHeader("Content-Type","application/xml"),e.end(new v({TagKey:c,RequestId:this.requestId,Message:"The TagValue you have provided is invalid"}).toXml());return}t[c]=a}}let s=Object.keys(t).length;if(s>10){e.statusCode=400,e.setHeader("Content-Type","application/xml"),e.end(new P({Message:`Object tag count cannot be greater than ${10}`,RequestId:this.requestId}).toXml());return}return{tagsLen:s,Tags:t}}async exec(e,t){let s=this.validateRequest(e);if(!s)return;let{Tags:n,tagsLen:o}=s,c=b.genLocalKey(this.bucket,this.key),a=$e.join(this.localService.localStoragePath,this.bucket,c);try{Nt($e.dirname(a),{recursive:!0})}catch{}let d=Pt(a,{flush:!0});d.on("finish",async()=>{try{let u=Et(a),l=fe(At(a));this.localService.persistence.buckets[this.bucket].objects[this.key]={currentKey:c,type:this.contentType,cacheControl:this.cacheControl,contentDisposition:this.contentDisposition,contentEncoding:this.contentEncoding,contentLanguage:this.contentLanguage,expires:this.expires,websiteRedirectLocation:this.websiteRedirectLocation,ETag:l,size:u.size,LastModified:u.mtimeMs,StorageClass:this.storageClass,metadata:this.metadata,versions:{[c]:{}},tags:o?n:void 0};let p=t.socket.remoteAddress?.split(":")?.[3]??"127.0.0.1";e.end(),await A(this.localService.callableLambdas,{bucket:this.bucket,key:this.key,requestId:this.requestId,requestCmd:"PutObject",eTag:l,sourceIPAddress:p,size:u.size})}catch(u){console.log(u),e.statusCode=500,e.end()}}),e.setHeader("status",100),e.setHeader("Server","AmazonS3"),e.setHeader("x-amzn-requestid",this.requestId),t.pipe(d)}},Lt=i=>!i.split("&").find(r=>r.split("=").length>2);import{getRandomValues as Ut}from"crypto";var zt="abcdefghijklmnopqrstuvwxyz0123456789_.",Be=`ABCDEFGHIJKLMNOPQRSTUVWXYZ${zt}`,be=class extends m{constructor(e,t,s){super(t,s);this.url=e;this.headers=t;this.localService=s;let n=decodeURIComponent(e.pathname),[o,...c]=n.split("/").filter(Boolean);this.bucket=o,this.key=c.join("/"),this.version=e.searchParams.get("versionId")}bucket;key;version;generateUploadId(){let e="",t=new Uint8Array(128);Ut(t);for(let s=0;s<128;s++)e+=Be[t[s]%Be.length];return e}async exec(e,t){let s=new w(this.url,this.headers,this.localService),n=s.validateRequest(e);if(!n)return;let{Tags:o,tagsLen:c}=n,a=b.genLocalKey(this.bucket,this.key),d=this.generateUploadId();this.localService.persistence.buckets[this.bucket].multipartUploads[d]={uploadId:d,aborted:!1,completed:!1,key:this.key,initDate:new Date().toISOString(),data:{currentKey:a,type:s.contentType,cacheControl:s.cacheControl,contentDisposition:s.contentDisposition,contentEncoding:s.contentEncoding,contentLanguage:s.contentLanguage,expires:s.expires,websiteRedirectLocation:s.websiteRedirectLocation,metadata:s.metadata,StorageClass:s.storageClass,versions:{[a]:{multipartUploadId:d}},tags:c?o:void 0},parts:[]},e.writeHead(200,{"x-amzn-requestid":this.requestId,Server:"AmazonS3"}),e.end(`<?xml version="1.0" encoding="UTF-8"?>
77
+ <ListMultipartUploadsResult><Bucket>${this.bucket}</Bucket><IsTruncated>${n}</IsTruncated><KeyMarker>${this.keyMarker??""}</KeyMarker><MaxUploads>${this.maxUploads??"1000"}</MaxUploads>`;if(u+=`<UploadIdMarker>${this.uploadIdMarker??""}</UploadIdMarker><NextUploadIdMarker>${a}</NextUploadIdMarker><NextKeyMarker>${c}</NextKeyMarker>`,this.prefix&&(u+=`<Prefix>${this.prefix}</Prefix>`),this.delimiter&&(u+=`<Delimiter>${this.delimiter}</Delimiter>`),o)for(let g of o)u+=`<CommonPrefixes><Prefix>${g}</Prefix></CommonPrefixes>`;this.encodingType&&(u+=`<EncodingType>${this.encodingType}</EncodingType>`);let l=`<Owner><ID>${this.localService.ownerId}</ID></Owner>`,p=`<Initiator><ID>${this.localService.ownerId}</ID></Initiator>`;for(let g of s)u+=`<Upload><Initiated>${g.initDate}</Initiated>${p}<Key>${g.key}</Key>${l}<StorageClass>${g.data.StorageClass}</StorageClass><UploadId>${g.uploadId}</UploadId></Upload>`;u+="</ListMultipartUploadsResult>",e.writeHead(200,{"x-amzn-requestid":this.requestId,Server:"AmazonS3"}).end(u)}};var ue=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n}bucket;async exec(e){if(this.hasNot(this.bucket,e))return;let t=this.localService.persistence.buckets[this.bucket];e.writeHead(200,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(t.acl.accessControlPolicy)}};var le=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n}bucket;async exec(e){if(this.hasNot(this.bucket,e))return;let t=this.localService.persistence.buckets[this.bucket];e.writeHead(200,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(t.acl.accessControlPolicy)}};var Te=(i,r)=>{let{url:e,headers:t}=i,s=new URL(e,"http://localhost:3000"),n=t["user-agent"],o=s.pathname.split("/").filter(Boolean).length==1;if(n?.startsWith("aws-cli")){let[,c]=n.split("command/"),[,...a]=c.split(".");switch(a.join(".")){case"ls":return/@s3\/?$/.test(e)?new E(s,t,r):s.searchParams.get("list-type")=="2"?new M(s,t,r):new q(s,t,r);case"list-buckets":return new E(s,t,r);case"list-objects":return new q(s,t,r);case"list-objects-v2":return new M(s,t,r);case"rb.rm":return s.searchParams.get("list-type")=="2"?new M(s,t,r):new q(s,t,r);case"get-object":return new L(s,t,r);case"cp":case"mv":case"sync":return o?s.searchParams.get("list-type")=="2"?new M(s,t,r):new q(s,t,r):new L(s,t,r);case"get-bucket-tagging":return new F(s,t,r);case"get-object-tagging":return new V(s,t,r);default:break}}else return s.searchParams.has("acl")?o?new ue(s,t,r):new le(s,t,r):s.searchParams.has("uploads")?o?new de(s,t,r):new I(s,t,r):s.searchParams.has("policy")?new ae(s,t,r):s.searchParams.has("tagging")?o?new F(s,t,r):new V(s,t,r):s.searchParams.has("uploadId")?o?new I(s,t,r):new ce(s,t,r):s.pathname=="/"?new E(s,t,r):o?s.searchParams.get("list-type")=="2"?new M(s,t,r):new q(s,t,r):new L(s,t,r);return new I(s,t,r)};var pe=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n}bucket;exec(e){this.hasNot(this.bucket,e)||(e.statusCode=200,e.setHeader("x-amz-request-id",this.requestId),e.end())}};import Pe from"node:path";var me=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let n=decodeURIComponent(e.pathname),[o,...c]=n.split("/").filter(Boolean);if(this.bucket=o,this.key=c.join("/"),this.bucketPath=Pe.join(this.localService.localStoragePath,o),this.filePath=Pe.join(this.bucketPath,...c),this.versionId=e.searchParams.get("versionId"),this.partNumber=e.searchParams.has("partNumber")?Number(e.searchParams.get("partNumber")):null,t.range){let[a]=t.range.split("bytes=").filter(Boolean),[d,u]=a.split("-");!isNaN(Number(d))&&!isNaN(Number(u))&&(this.range=[Number(d),Number(u)])}this.ifMatch=t["if-match"],this.ifNoneMatch=t["if-none-match"],t["if-modified-since"]&&(this.ifModifiedSince=new Date(t["if-modified-since"]).getTime()),t["if-unmodified-since"]&&(this.ifUnmodifiedSince=new Date(t["if-unmodified-since"]).getTime())}filePath;bucketPath;bucket;key;versionId;partNumber;range;ifMatch;ifNoneMatch;ifModifiedSince;ifUnmodifiedSince;async exec(e){if(!this.hasNot(this.bucket,e)){if(!this.localService.persistence.buckets[this.bucket].objects[this.key]){e.writeHead(404,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(x({Key:this.key,RequestId:this.requestId}));return}try{let t={ifMatch:this.ifMatch,ifModifiedSince:this.ifModifiedSince,ifNoneMatch:this.ifNoneMatch,ifUnmodifiedSince:this.ifUnmodifiedSince},s=this.localService.persistence.buckets[this.bucket].objects[this.key],n=K(t,s);if(n==200){let o=200,c=s.size,a,d=s.type,u={};if(this.range){o=206,u.start=this.range[0],u.end=this.range[1];let l=1;u.end>s.size&&(u.end=s.size,l--),c=l+u.end-u.start,a=`bytes ${u.start}-${u.end}/${s.size}`,d="application/octet-stream"}e.statusCode=o,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("x-amz-server-side-encryption","AES256"),e.setHeader("Date",new Date().toUTCString()),e.setHeader("Last-Modified",new Date(s.LastModified).toUTCString()),e.setHeader("ETag",s.ETag),e.setHeader("Accept-Ranges","bytes"),a&&e.setHeader("Content-Range",a),e.setHeader("Content-Length",c),d&&e.setHeader("Content-Type",d),e.setHeader("Server","AmazonS3"),s.cacheControl&&e.setHeader("Cache-Control",s.cacheControl),s.contentDisposition&&e.setHeader("Content-Disposition",s.contentDisposition),s.contentEncoding&&e.setHeader("Content-Encoding",s.contentEncoding),s.contentLanguage&&e.setHeader("Content-Language",s.contentLanguage),s.expires&&e.setHeader("Expires",new Date(s.expires).toUTCString()),s.websiteRedirectLocation&&e.setHeader("x-amz-website-redirect-location",s.websiteRedirectLocation);for(let[l,p]of Object.entries(s.metadata))e.setHeader(l,p);e.end()}else e.writeHead(n.statusCode,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(`<?xml version="1.0" encoding="UTF-8"?><Error><Code>${n.Code}</Code><Message>At least one of the pre-conditions you specified did not hold</Message><Condition>${n.Condition}</Condition><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`)}catch{e.statusCode=500,e.end("Internal Server Error")}}}};var Ne=(i,r)=>{let{url:e,headers:t}=i,s=new URL(e,"http://localhost:3000");return s.pathname.split("/").filter(Boolean).length>1?new me(s,t,r):new pe(s,t,r)};var _=class i{static apiId="";static accountId="";static port=3e3;static serve;static contentType={json:"application/json",text:"text/plain; charset=utf-8",octet:"application/octet-stream"};static keepAlive=["Connection","keep-alive"];static dummyHost="http://localhost:3003";static httpErrMsg='{"message":"Internal Server Error"}';static apigJsonParseErrMsg='{"message":"[Unknown error parsing request body]"}';static apigForbiddenErrMsg='{"message":"Forbidden"}';static amzMsgNull='{"message":null}';static apgTimeoutMsg='{"message": "Endpoint request timed out"}';static unavailable='{"message":"Service Unavailable"}';static timeoutRegex=/after.\d+.*seconds/;static apgRequestTimeout=30;static normalizeHeaderKey=r=>r.toLowerCase().split("-").map(Ae).join("-");static getMultiValueHeaders=r=>{let e={},t=r.filter((n,o)=>o%2==0).map(n=>n.toLowerCase()),s=r.filter((n,o)=>o%2!==0);return t.forEach((n,o)=>{n!="x-mock-type"&&(e[n]?e[n].push(s[o]):e[n]=[s[o]])}),e};static getIsBase64Encoded=r=>{let e=r["content-type"];return r["content-encoding"]||!e?!0:!(e.startsWith("application/json")||e.startsWith("application/xml")||e.startsWith("application/javascript")||e.startsWith("text/"))};static knownHeaders=["accept","accept-encoding","user-agent","host","via","content-length"];static getApiGV1Headers(r,e){let{rawHeaders:t}=r,s,n={"X-Forwarded-For":r.socket.remoteAddress,"X-Forwarded-Proto":"http","X-Forwarded-Port":String(i.port)};for(let d=0;d<t.length;){let u=t[d],l=u.toLowerCase();if(["connection","x-mock-type"].includes(l)){d=d+2;continue}this.knownHeaders.includes(l)&&(u=this.normalizeHeaderKey(l));let p=t[d+1];n[u]=p,l=="x-api-key"&&(s=p),d=d+2}let o={};for(let d of Object.keys(n).sort((u,l)=>u.localeCompare(l)))o[d]=n[d];let c={"X-Forwarded-For":[r.socket.remoteAddress],"X-Forwarded-Proto":["http"],"X-Forwarded-Port":[String(i.port)]};for(let d=0;d<t.length;){let u=t[d],l=u.toLowerCase();if(["connection","x-mock-type"].includes(l)){d=d+2;continue}this.knownHeaders.includes(l)&&(u=this.normalizeHeaderKey(l));let p=t[d+1];c[u]?c[u].push(p):c[u]=[p],d=d+2}let a={};for(let d of Object.keys(c).sort((u,l)=>u.localeCompare(l)))a[d]=c[d];return{headers:o,multiValueHeaders:a,apiKey:s}}static getCustomHeaders(r,e){let{headers:t}=r;return delete t["x-mock-type"],delete t.connection,{"X-Forwarded-For":r.socket.remoteAddress,"X-Forwarded-Proto":"http","X-Forwarded-Port":String(i.port),...t}}static getPathParameters(r,e){let t=r.paths[0].split("/"),s=e.pathname.split("/"),n={};return t.forEach((o,c)=>{o.startsWith("{")&&o.endsWith("}")&&!o.endsWith("+}")&&(n[o.slice(1,-1)]=s[c])}),n}static normalizeSearchParams=(r,e)=>{let t={};Array.from(r.keys()).forEach(o=>{let c=r.getAll(o).map(d=>d.toLowerCase()),a=o.toLowerCase();c?t[a]?t[a].push(...c):t[a]=c:t[a]||(t[a]=void 0)});let s="",n=e.indexOf("?");return n!=-1&&(s=e.slice(n+1)),t.toString=()=>s,t};static getMultiValueQueryStringParameters=r=>{let e={};r.delete("x_mock_type");for(let t of Array.from(new Set(r.keys())))e[t]=r.getAll(t).map(encodeURI);return e};static isEndpointTimeoutError=r=>{if(!r)return;let e=r.match(this.timeoutRegex)?.[0];if(e){let t=e.split(" ")[1];if(!isNaN(t))return Number(t)>=i.apgRequestTimeout}}};var ge=!1,St=i=>{ge=i},xt=()=>ge,U=(i,r)=>{ge&&console.log(`\x1B[${i}m${r}\x1B[0m`)},kt=i=>console.log(`\x1B[31m${i}\x1B[0m`),Ct=i=>U("32",i),vt=i=>U("33",i),Ht=i=>U("36",i),Rt=i=>U("90",i),qt=i=>U("94",i),Mt=i=>U("95",i),wt=i=>ge?console.log(i):void 0,Ee={GREEN:Ct,YELLOW:vt,CYAN:Ht,BR_BLUE:qt,RED:kt,GREY:Rt,PINK:Mt,setDebug:St,getDebug:xt,info:wt};var Le="application/vnd.awslambda.http-integration-response",He=class i{buffer;_isHttpIntegrationResponse;_metaDelimiter;_endDelimiter;_ct;_isStreamResponse=!0;#e;static codec=new TextDecoder;static splitMessage=(r,e)=>{if(!r)return;let t=Array.from(r.values()),s=null;if(e)s=e;else for(let n=0;n<t.length;n++)if(t[n]===0&&[t[n+1],t[n+2],t[n+3],t[n+4],t[n+5],t[n+6],t[n+7]].every(a=>a===0)){s=n;break}if(s)return new Uint8Array(t.slice(0,s))};constructor(r){this._isHttpIntegrationResponse=!1,this._metaDelimiter=0,this._endDelimiter=0,this.#e=r}setHeader(r,e){this._isHttpIntegrationResponse=!this.buffer&&e==Le&&(!this._ct||this._ct==Le),this._ct=e}write(r,e){!this._isHttpIntegrationResponse&&!this._metaDelimiter&&(this._metaDelimiter=r.byteLength),this.#s(r)}end(r){this.buffer&&(this._endDelimiter=this.buffer.byteLength),r&&this.#s(r)}destroy(){}#s(r){this.buffer=typeof this.buffer>"u"?r:Buffer.concat([this.buffer,r])}getParsedResponse(){if(!this.#e)return;let r=this.#e.kind;if(r=="alb")return this.#r();if(r=="url")return this.#o();if(r=="apg")return this.#n()}#r(){let r=this._isHttpIntegrationResponse?i.splitMessage(this.buffer):this.buffer,e;return r&&(e=this.#t(r)),e}#n(){if(this._isHttpIntegrationResponse)return Ee.RED("awslambda.HttpResponseStream.from() is not supported with API Gateway"),{statusCode:500,headers:{"Content-Type":_.contentType.json},body:_.httpErrMsg};if(this.buffer)return this.#t(this.buffer)}#o(){let r=i.splitMessage(this.buffer,this._isHttpIntegrationResponse?void 0:this._metaDelimiter),e;return r&&(e=this.#t(r)),e}#t(r){let e=i.codec.decode(r);if(typeof e=="string")try{e=JSON.parse(e)}catch{}return e}};var Ue="<html><head><title>400 Request Header Or Cookie Too Large</title></head><body><center><h1>400 Bad Request</h1></center><center>Request Header Or Cookie Too Large</center></body></html>";var pn=JSON.stringify({Message:null});var ze=async(i,r)=>{let e=Buffer.alloc(0);return i.on("data",s=>{e=Buffer.concat([e,s])}),await new Promise(s=>{i.on("end",async()=>{s(e?e.toString(r?"base64":"utf-8"):void 0)})})};var mn=JSON.stringify({Type:null,message:"Client context must be a valid Base64-encoded JSON object."});var gn=new Error(Ue);var Ae=i=>i.charAt(0).toUpperCase()+i.slice(1);var Tt=i=>{let r=[],e;try{i.split("<Object>").forEach(t=>{let s=t.indexOf("<Key>");if(s==-1)return;let n=t.indexOf("</Key>"),c={Key:t.slice(s+5,n)},a=t.indexOf("<VersionId>");if(a>-1){let d=t.indexOf("</VersionId>"),u=t.slice(a+11,d);c.VersionId=u}r.push(c)})}catch(t){console.error(t)}return{Objects:r,Quiet:e}},he=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let n=decodeURIComponent(e.pathname),[o]=n.split("/").filter(Boolean);this.bucket=o}bucket;async exec(e,t){if(this.hasNot(this.bucket,e))return;let s=await ze(t),{Objects:n,Quiet:o}=Tt(s);if(!n.length){e.statusCode=400,e.setHeader("Content-Type","application/xml"),e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Server","AmazonS3"),e.end(`<Error><Code>MalformedXML</Code><Message>The XML you provided was not well-formed or did not validate against our published schema</Message><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}let c=n.map(d=>`<Deleted><Key>${d.Key}</Key></Deleted>`).join(""),a=t.socket.remoteAddress?.split(":")?.[3]??"127.0.0.1";e.statusCode=200,e.setHeader("Content-Type","application/xml"),e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Server","AmazonS3");for(let d of n)await this.localService.removeObject(this.bucket,d.Key,a,this.requestId);e.end(`<?xml version="1.0" encoding="UTF-8"?><DeleteResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">${c}</DeleteResult>`)}};import{createWriteStream as Pt,mkdirSync as Nt,readFileSync as At,statSync as Et}from"node:fs";import $e from"node:path";var fe=i=>`"${R(i)}"`;var w=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n,...o]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n,this.key=o.join("/"),this.contentType=t["content-type"]??"application/octet-stream",this.cacheControl=t["cache-control"],this.contentDisposition=t["content-disposition"],this.contentEncoding=t["content-encoding"],this.contentLanguage=t["content-language"],this.websiteRedirectLocation=t["x-amz-website-redirect-location"],t["x-amz-tagging"]&&(this.tagging=t["x-amz-tagging"]);let c=t["x-amz-storage-class"];c&&(this.storageClass=c);let a=new Date(t.expires);isNaN(a)||(this.expires=a.getTime())}bucket;key;contentType;cacheControl;contentDisposition;contentEncoding;contentLanguage;websiteRedirectLocation;expires;storageClass="STANDARD";tagging;validateRequest(e){if(this.hasNot(this.bucket,e)||!this.isValidStorageClass(this.storageClass,e))return;let t={};if(this.tagging){let n=()=>{e.statusCode=400,e.setHeader("Content-Type","application/xml"),e.end(new k({ArgumentName:"x-amz-tagging",ArgumentValue:this.tagging,Message:"The header 'x-amz-tagging' shall be encoded as UTF-8 then URLEncoded URL query parameters without tag name duplicates.",RequestId:this.requestId}).toXml())};if(typeof this.tagging!="string"){n();return}if(!Lt(this.tagging)){n();return}let o=new URLSearchParams(this.tagging);for(let c of o.keys()){if(c in t){e.statusCode=400,e.setHeader("Content-Type","application/xml"),e.end(new v({TagKey:c,RequestId:this.requestId,Message:"Cannot provide multiple Tags with the same key"}).toXml());return}if(c.length>128||c.length<1){e.statusCode=400,e.setHeader("Content-Type","application/xml"),e.end(new v({TagKey:c,RequestId:this.requestId,Message:"The TagKey you have provided is invalid"}).toXml());return}let a=o.get(c);if(a.length>256){e.statusCode=400,e.setHeader("Content-Type","application/xml"),e.end(new v({TagKey:c,RequestId:this.requestId,Message:"The TagValue you have provided is invalid"}).toXml());return}t[c]=a}}let s=Object.keys(t).length;if(s>10){e.statusCode=400,e.setHeader("Content-Type","application/xml"),e.end(new P({Message:`Object tag count cannot be greater than ${10}`,RequestId:this.requestId}).toXml());return}return{tagsLen:s,Tags:t}}async exec(e,t){let s=this.validateRequest(e);if(!s)return;let{Tags:n,tagsLen:o}=s,c=b.genLocalKey(this.bucket,this.key),a=$e.join(this.localService.localStoragePath,this.bucket,c);try{Nt($e.dirname(a),{recursive:!0})}catch{}let d=Pt(a,{flush:!0});d.on("finish",async()=>{try{let u=Et(a),l=fe(At(a));this.localService.persistence.buckets[this.bucket].objects[this.key]={currentKey:c,type:this.contentType,cacheControl:this.cacheControl,contentDisposition:this.contentDisposition,contentEncoding:this.contentEncoding,contentLanguage:this.contentLanguage,expires:this.expires,websiteRedirectLocation:this.websiteRedirectLocation,ETag:l,size:u.size,LastModified:u.mtimeMs,StorageClass:this.storageClass,metadata:this.metadata,versions:{[c]:{}},tags:o?n:void 0};let p=t.socket.remoteAddress?.split(":")?.[3]??"127.0.0.1";e.end(),await A(this.localService.callableLambdas,{bucket:this.bucket,key:this.key,requestId:this.requestId,requestCmd:"PutObject",eTag:l,sourceIPAddress:p,size:u.size})}catch(u){console.log(u),e.statusCode=500,e.end()}}),e.setHeader("status",100),e.setHeader("Server","AmazonS3"),e.setHeader("x-amzn-requestid",this.requestId),t.pipe(d)}},Lt=i=>!i.split("&").find(r=>r.split("=").length>2);import{getRandomValues as Ut}from"crypto";var zt="abcdefghijklmnopqrstuvwxyz0123456789_.",Be=`ABCDEFGHIJKLMNOPQRSTUVWXYZ${zt}`,be=class extends m{constructor(e,t,s){super(t,s);this.url=e;this.headers=t;this.localService=s;let n=decodeURIComponent(e.pathname),[o,...c]=n.split("/").filter(Boolean);this.bucket=o,this.key=c.join("/"),this.version=e.searchParams.get("versionId")}bucket;key;version;generateUploadId(){let e="",t=new Uint8Array(128);Ut(t);for(let s=0;s<128;s++)e+=Be[t[s]%Be.length];return e}async exec(e,t){let s=new w(this.url,this.headers,this.localService),n=s.validateRequest(e);if(!n)return;let{Tags:o,tagsLen:c}=n,a=b.genLocalKey(this.bucket,this.key),d=this.generateUploadId();this.localService.persistence.buckets[this.bucket].multipartUploads[d]={uploadId:d,aborted:!1,completed:!1,key:this.key,initDate:new Date().toISOString(),data:{currentKey:a,type:s.contentType,cacheControl:s.cacheControl,contentDisposition:s.contentDisposition,contentEncoding:s.contentEncoding,contentLanguage:s.contentLanguage,expires:s.expires,websiteRedirectLocation:s.websiteRedirectLocation,metadata:s.metadata,StorageClass:s.storageClass,versions:{[a]:{multipartUploadId:d}},tags:c?o:void 0},parts:[]},e.writeHead(200,{"x-amzn-requestid":this.requestId,Server:"AmazonS3"}),e.end(`<?xml version="1.0" encoding="UTF-8"?>
78
78
  <InitiateMultipartUploadResult>
79
79
  <Bucket>${this.bucket}</Bucket>
80
80
  <Key>${this.key}</Key>
81
81
  <UploadId>${d}</UploadId>
82
- </InitiateMultipartUploadResult>`)}};import je from"path";import{readFile as $t,appendFile as Bt,stat as jt,rm as Dt}from"fs/promises";import{mkdirSync as Kt}from"fs";var Ke=5242880,Ot=({uploadId:i,PartNumber:r,ETag:e,requestId:t})=>`<Error><Code>InvalidPart</Code><UploadId>${i}</UploadId><PartNumber>${r}</PartNumber><ETag>${e}</ETag><Message>One or more of the specified parts could not be found. The part may not have been uploaded, or the specified entity tag may not match the part's entity tag.</Message><RequestId>${t}</RequestId><HostId>local</HostId></Error>`,De=i=>`<Error><Code>MalformedXML</Code><Message>The XML you provided was not well-formed or did not validate against our published schema</Message><RequestId>${i}</RequestId><HostId>local</HostId></Error>`,Vt=(i,r)=>`<Error><Code>InvalidPartOrder</Code><UploadId>${r}</UploadId><Message>The list of parts was not in ascending order. Parts must be ordered by part number.</Message><RequestId>${i}</RequestId><HostId>local</HostId></Error>`,Ft=({requestId:i,ArgumentName:r,ArgumentValue:e,Message:t})=>`<Error><Code>InvalidArgument</Code><ArgumentName>${r}</ArgumentName><ArgumentValue>${e}</ArgumentValue><Message>${t}</Message><RequestId>${i}</RequestId><HostId>local</HostId></Error>`,_t=({ProposedSize:i,ETag:r,PartNumber:e,requestId:t})=>`<Error><Code>EntityTooSmall</Code><ProposedSize>${i}</ProposedSize><MinSizeAllowed>${Ke}</MinSizeAllowed><PartNumber>${e}</PartNumber><ETag>${r}</ETag><Message>Your proposed upload is smaller than the minimum allowed size</Message><RequestId>${t}</RequestId><HostId>local</HostId></Error>`,ye=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let n=decodeURIComponent(e.pathname),[o,...c]=n.split("/").filter(Boolean);this.bucket=o,this.key=c.join("/"),this.uploadId=e.searchParams.get("uploadId")}bucket;key;uploadId;validateRequest(e){if(this.hasNot(this.bucket,e))return;if(!this.uploadId){e.statusCode=400,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(`<?xml version="1.0" encoding="UTF-8"?>
82
+ </InitiateMultipartUploadResult>`)}};import je from"path";import{readFile as $t,appendFile as Bt,stat as jt,rm as Dt}from"fs/promises";import{mkdirSync as Ot}from"fs";var Oe=5242880,Kt=({uploadId:i,PartNumber:r,ETag:e,requestId:t})=>`<Error><Code>InvalidPart</Code><UploadId>${i}</UploadId><PartNumber>${r}</PartNumber><ETag>${e}</ETag><Message>One or more of the specified parts could not be found. The part may not have been uploaded, or the specified entity tag may not match the part's entity tag.</Message><RequestId>${t}</RequestId><HostId>local</HostId></Error>`,De=i=>`<Error><Code>MalformedXML</Code><Message>The XML you provided was not well-formed or did not validate against our published schema</Message><RequestId>${i}</RequestId><HostId>local</HostId></Error>`,Vt=(i,r)=>`<Error><Code>InvalidPartOrder</Code><UploadId>${r}</UploadId><Message>The list of parts was not in ascending order. Parts must be ordered by part number.</Message><RequestId>${i}</RequestId><HostId>local</HostId></Error>`,Ft=({requestId:i,ArgumentName:r,ArgumentValue:e,Message:t})=>`<Error><Code>InvalidArgument</Code><ArgumentName>${r}</ArgumentName><ArgumentValue>${e}</ArgumentValue><Message>${t}</Message><RequestId>${i}</RequestId><HostId>local</HostId></Error>`,_t=({ProposedSize:i,ETag:r,PartNumber:e,requestId:t})=>`<Error><Code>EntityTooSmall</Code><ProposedSize>${i}</ProposedSize><MinSizeAllowed>${Oe}</MinSizeAllowed><PartNumber>${e}</PartNumber><ETag>${r}</ETag><Message>Your proposed upload is smaller than the minimum allowed size</Message><RequestId>${t}</RequestId><HostId>local</HostId></Error>`,ye=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let n=decodeURIComponent(e.pathname),[o,...c]=n.split("/").filter(Boolean);this.bucket=o,this.key=c.join("/"),this.uploadId=e.searchParams.get("uploadId")}bucket;key;uploadId;validateRequest(e){if(this.hasNot(this.bucket,e))return;if(!this.uploadId){e.statusCode=400,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(`<?xml version="1.0" encoding="UTF-8"?>
83
83
  <Error><Code>InvalidArgument</Code><ArgumentName>partNumber</ArgumentName><ArgumentValue>partNumber</ArgumentValue><Message>This operation does not accept partNumber without uploadId</Message><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}let t=this.localService.persistence.buckets[this.bucket].multipartUploads[this.uploadId];if(!t||t.aborted){e.statusCode=404,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(`<?xml version="1.0" encoding="UTF-8"?>
84
- <Error><Code>NoSuchUpload</Code><UploadId>${this.uploadId}</UploadId><Message>The specified upload does not exist. The upload ID may be invalid, or the upload may have been aborted or completed.</Message><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}return{uploadId:this.uploadId}}async collectBody(e){let t=Buffer.alloc(0);return e.on("data",s=>{t=Buffer.concat([t,s])}),new Promise(s=>{e.on("end",async()=>{s(t.toString("utf-8"))})})}async getRequestBody(e){let t=await this.collectBody(e);return b.XMLParser.parse(t)}async verifyCompleteMultiPartUploadParts(e,t,s){let n={verifiedParts:[]},o=[];if(Array.isArray(e.CompleteMultipartUpload?.Part))o=e.CompleteMultipartUpload.Part;else if(e.CompleteMultipartUpload?.Part&&typeof e.CompleteMultipartUpload.Part=="object")o=[e.CompleteMultipartUpload.Part];else return n.hasCompleteMultiPartUploadError=De(this.requestId),n;for(let c=0;c<o.length;c++){let a=o[c];if(typeof a.PartNumber!="number"||typeof a.ETag!="string")return n.hasCompleteMultiPartUploadError=De(this.requestId),n;if(a.PartNumber<1)return n.hasCompleteMultiPartUploadError=Ft({ArgumentName:"PartNumber",ArgumentValue:a.PartNumber,requestId:this.requestId,Message:"PartNumber must be >= 1"}),n;let d=a.ETag.slice(1,-1);if(n.verifiedParts.find(p=>p.partNumber>=a.PartNumber))return n.hasCompleteMultiPartUploadError=Vt(this.requestId,t),n;let l=s.parts.find(p=>a?.PartNumber==p.partNumber&&d==p.eTag);if(!l)return n.hasCompleteMultiPartUploadError=Ot({uploadId:t,PartNumber:a.PartNumber,ETag:a.ETag,requestId:this.requestId}),n;if(l.size<Ke&&c!=o.length-1)return n.hasCompleteMultiPartUploadError=_t({requestId:this.requestId,PartNumber:l.partNumber,ETag:l.eTag,ProposedSize:l.size}),n;n.verifiedParts.push(l)}return n}async safeCreateObject(e){let t=je.join(this.localService.localStoragePath,this.bucket,e.data.currentKey);try{Kt(je.dirname(t),{recursive:!0})}catch{}return{filePath:t}}async exec(e,t){let s=this.validateRequest(e);if(!s)return;let{uploadId:n}=s,o=this.localService.persistence.buckets[this.bucket].multipartUploads[n],c=await this.getRequestBody(t);e.writeHead(200,["x-amzn-requestid",this.requestId,"Server","AmazonS3"]);function a(){e.writable&&(e.write(""),setTimeout(a,1e3))}a();let{hasCompleteMultiPartUploadError:d,verifiedParts:u}=await this.verifyCompleteMultiPartUploadParts(c,n,o);if(d){e.end(d);return}let l=u.map(S=>S.eTag).join(""),{filePath:p}=await this.safeCreateObject(o);for(let S of u){let H=await $t(S.filePath,{flag:"r"});await Bt(p,H)}let h=`"${R(Buffer.from(l,"hex"))}-${u.length}"`,y=await jt(p),C=u.map((S,H)=>({...S,partNumber:H+1})).sort((S,H)=>S.partNumber-H.partNumber),Se=o.parts.map(S=>S.filePath);o.parts=C,o.completed=!0,this.localService.persistence.buckets[this.bucket].objects[this.key]={...o.data,ETag:h,size:y.size,LastModified:y.mtimeMs},e.end(`<?xml version="1.0" encoding="UTF-8"?>
84
+ <Error><Code>NoSuchUpload</Code><UploadId>${this.uploadId}</UploadId><Message>The specified upload does not exist. The upload ID may be invalid, or the upload may have been aborted or completed.</Message><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}return{uploadId:this.uploadId}}async collectBody(e){let t=Buffer.alloc(0);return e.on("data",s=>{t=Buffer.concat([t,s])}),new Promise(s=>{e.on("end",async()=>{s(t.toString("utf-8"))})})}async getRequestBody(e){let t=await this.collectBody(e);return b.XMLParser.parse(t)}async verifyCompleteMultiPartUploadParts(e,t,s){let n={verifiedParts:[]},o=[];if(Array.isArray(e.CompleteMultipartUpload?.Part))o=e.CompleteMultipartUpload.Part;else if(e.CompleteMultipartUpload?.Part&&typeof e.CompleteMultipartUpload.Part=="object")o=[e.CompleteMultipartUpload.Part];else return n.hasCompleteMultiPartUploadError=De(this.requestId),n;for(let c=0;c<o.length;c++){let a=o[c];if(typeof a.PartNumber!="number"||typeof a.ETag!="string")return n.hasCompleteMultiPartUploadError=De(this.requestId),n;if(a.PartNumber<1)return n.hasCompleteMultiPartUploadError=Ft({ArgumentName:"PartNumber",ArgumentValue:a.PartNumber,requestId:this.requestId,Message:"PartNumber must be >= 1"}),n;let d=a.ETag.slice(1,-1);if(n.verifiedParts.find(p=>p.partNumber>=a.PartNumber))return n.hasCompleteMultiPartUploadError=Vt(this.requestId,t),n;let l=s.parts.find(p=>a?.PartNumber==p.partNumber&&d==p.eTag);if(!l)return n.hasCompleteMultiPartUploadError=Kt({uploadId:t,PartNumber:a.PartNumber,ETag:a.ETag,requestId:this.requestId}),n;if(l.size<Oe&&c!=o.length-1)return n.hasCompleteMultiPartUploadError=_t({requestId:this.requestId,PartNumber:l.partNumber,ETag:l.eTag,ProposedSize:l.size}),n;n.verifiedParts.push(l)}return n}async safeCreateObject(e){let t=je.join(this.localService.localStoragePath,this.bucket,e.data.currentKey);try{Ot(je.dirname(t),{recursive:!0})}catch{}return{filePath:t}}async exec(e,t){let s=this.validateRequest(e);if(!s)return;let{uploadId:n}=s,o=this.localService.persistence.buckets[this.bucket].multipartUploads[n],c=await this.getRequestBody(t);e.writeHead(200,["x-amzn-requestid",this.requestId,"Server","AmazonS3"]);function a(){e.writable&&(e.write(""),setTimeout(a,1e3))}a();let{hasCompleteMultiPartUploadError:d,verifiedParts:u}=await this.verifyCompleteMultiPartUploadParts(c,n,o);if(d){e.end(d);return}let l=u.map(S=>S.eTag).join(""),{filePath:p}=await this.safeCreateObject(o);for(let S of u){let H=await $t(S.filePath,{flag:"r"});await Bt(p,H)}let h=`"${R(Buffer.from(l,"hex"))}-${u.length}"`,y=await jt(p),C=u.map((S,H)=>({...S,partNumber:H+1})).sort((S,H)=>S.partNumber-H.partNumber),Se=o.parts.map(S=>S.filePath);o.parts=C,o.completed=!0,this.localService.persistence.buckets[this.bucket].objects[this.key]={...o.data,ETag:h,size:y.size,LastModified:y.mtimeMs},e.end(`<?xml version="1.0" encoding="UTF-8"?>
85
85
  <CompleteMultipartUploadResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
86
86
  <Location>http://127.0.0.1:${this.localService.port}/${this.bucket}/${encodeURIComponent(this.key)}</Location>
87
87
  <Bucket>${this.bucket}</Bucket>
88
88
  <Key>${this.key}</Key>
89
89
  <ETag>${h}</ETag>
90
- </CompleteMultipartUploadResult>`),setTimeout(async()=>{for(let S of Se)try{await Dt(S,{maxRetries:5,force:!0,retryDelay:200})}catch{}},100)}};var Oe=(i,r)=>{let{url:e,headers:t}=i,s=new URL(e,"http://localhost:3000");if(s.pathname.split("/").filter(Boolean).length==1){if(s.searchParams.has("delete"))return new he(s,t,r)}else{if(s.searchParams.has("uploads"))return new be(s,t,r);if(s.searchParams.has("uploadId"))return new ye(s,t,r)}return new I(s,t,r)};var X=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n}bucket;async exec(e){if(!b.isValidBucketName(this.bucket)){e.writeHead(400,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(`<?xml version="1.0" encoding="UTF-8"?>
90
+ </CompleteMultipartUploadResult>`),setTimeout(async()=>{for(let S of Se)try{await Dt(S,{maxRetries:5,force:!0,retryDelay:200})}catch{}},100)}};var Ke=(i,r)=>{let{url:e,headers:t}=i,s=new URL(e,"http://localhost:3000");if(s.pathname.split("/").filter(Boolean).length==1){if(s.searchParams.has("delete"))return new he(s,t,r)}else{if(s.searchParams.has("uploads"))return new be(s,t,r);if(s.searchParams.has("uploadId"))return new ye(s,t,r)}return new I(s,t,r)};var X=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n}bucket;async exec(e){if(!b.isValidBucketName(this.bucket)){e.writeHead(400,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(`<?xml version="1.0" encoding="UTF-8"?>
91
91
  <Error><Code>InvalidBucketName</Code><Message>The specified bucket is not valid.</Message><BucketName>${this.bucket}</BucketName><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}if(this.localService.persistence.buckets[this.bucket]){e.statusCode=409,e.setHeader("Content-Type","application/xml"),e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Server","AmazonS3"),e.end(`<?xml version="1.0" encoding="UTF-8"?>
92
- <Error><Code>BucketAlreadyOwnedByYou</Code><Message>Your previous request to create the named bucket succeeded and you already own it.</Message><BucketName>${this.bucket}</BucketName><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}await this.localService.createBucket(this.bucket),e.statusCode=200,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Location",`/${this.bucket}`),e.setHeader("Server","AmazonS3"),e.end()}};import{copyFile as Xt,readFile as Gt,stat as Wt}from"node:fs/promises";import Ve from"node:path";var z=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n,...o]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n,this.key=o.join("/"),this.contentType=t["content-type"]??"application/octet-stream",this.cacheControl=t["cache-control"],this.contentDisposition=t["content-disposition"],this.contentEncoding=t["content-encoding"],this.contentLanguage=t["content-language"],this.websiteRedirectLocation=t["x-amz-website-redirect-location"];let c=t["x-amz-storage-class"];c&&(this.storageClass=c);let a=new Date(t.expires);isNaN(a)||(this.expires=a.getTime()),this.metadataDirective=t["x-amz-metadata-directive"];let d=t["x-amz-copy-source"]??"",[u,...l]=decodeURIComponent(d).split("/").filter(Boolean);this.sourceBucket=u,this.sourceKey=l.join("/"),this.ifMatch=t["x-amz-copy-source-if-match"],this.ifNoneMatch=t["x-amz-copy-source-if-none-match"],t["x-amz-copy-source-if-modified-since"]&&(this.ifModifiedSince=new Date(t["x-amz-copy-source-if-modified-since"]).getTime()),t["x-amz-copy-source-if-unmodified-since"]&&(this.ifUnmodifiedSince=new Date(t["x-amz-copy-source-if-unmodified-since"]).getTime())}bucket;key;sourceBucket;sourceKey;contentType;cacheControl;contentDisposition;contentEncoding;contentLanguage;websiteRedirectLocation;expires;storageClass="STANDARD";metadataDirective;ifMatch;ifNoneMatch;ifModifiedSince;ifUnmodifiedSince;async exec(e,t){if(this.sourceKey==""){e.statusCode=400,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(`<?xml version="1.0" encoding="UTF-8"?><Error><Code>InvalidArgument</Code><Message>Invalid copy source object key</Message><ArgumentName>x-amz-copy-source</ArgumentName><ArgumentValue>x-amz-copy-source</ArgumentValue><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}if(this.hasNot(this.bucket,e)||this.hasNot(this.sourceBucket,e)||!this.isValidStorageClass(this.storageClass,e))return;if(!this.localService.persistence.buckets[this.sourceBucket].objects[this.sourceKey]){e.writeHead(404,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(x({Key:this.sourceKey,RequestId:this.requestId}));return}let s=this.localService.persistence.buckets[this.sourceBucket].objects[this.sourceKey];if([this.bucket,this.key].join("/")==[this.sourceBucket,this.sourceKey].join("/")&&[this.storageClass==s.StorageClass,this.websiteRedirectLocation==s.websiteRedirectLocation].every(l=>l===!0)){e.statusCode=400,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(`<Error><Code>InvalidRequest</Code><Message>This copy request is illegal because it is trying to copy an object to itself without changing the object's metadata, storage class, website redirect location or encryption attributes.</Message><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}let n={ifMatch:this.ifMatch,ifNoneMatch:this.ifNoneMatch,ifModifiedSince:this.ifModifiedSince,ifUnmodifiedSince:this.ifUnmodifiedSince},o=O(n,s);if(o!==200){e.writeHead(o.statusCode,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(`<?xml version="1.0" encoding="UTF-8"?><Error><Code>${o.Code}</Code><Message>At least one of the pre-conditions you specified did not hold</Message><Condition>${o.Condition}</Condition><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}let c=Ve.join(this.localService.localStoragePath,this.sourceBucket,s.currentKey),a=b.genLocalKey(this.bucket,this.key),d=Ve.join(this.localService.localStoragePath,this.bucket,a);try{await Xt(c,d);let u=await Wt(d),l=fe(await Gt(d));this.metadataDirective=="COPY"?this.localService.persistence.buckets[this.bucket].objects[this.key]={currentKey:a,type:s.type,cacheControl:s.cacheControl,contentDisposition:s.contentDisposition,contentEncoding:s.contentEncoding,contentLanguage:s.contentLanguage,expires:s.expires,ETag:l,StorageClass:s.StorageClass,LastModified:u.mtimeMs,size:u.size,metadata:s.metadata,versions:{[a]:{}}}:this.localService.persistence.buckets[this.bucket].objects[this.key]={currentKey:a,type:this.contentType,cacheControl:this.cacheControl,contentDisposition:this.contentDisposition,contentEncoding:this.contentEncoding,contentLanguage:this.contentLanguage,expires:this.expires,ETag:l,StorageClass:this.storageClass,LastModified:u.mtimeMs,size:u.size,metadata:this.metadata,websiteRedirectLocation:this.websiteRedirectLocation,versions:{[a]:{}}};let p=new Date(u.mtimeMs).toISOString();e.statusCode=200,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(`<?xml version="1.0" encoding="UTF-8"?>
92
+ <Error><Code>BucketAlreadyOwnedByYou</Code><Message>Your previous request to create the named bucket succeeded and you already own it.</Message><BucketName>${this.bucket}</BucketName><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}await this.localService.createBucket(this.bucket),e.statusCode=200,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Location",`/${this.bucket}`),e.setHeader("Server","AmazonS3"),e.end()}};import{copyFile as Xt,readFile as Gt,stat as Wt}from"node:fs/promises";import Ve from"node:path";var z=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n,...o]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n,this.key=o.join("/"),this.contentType=t["content-type"]??"application/octet-stream",this.cacheControl=t["cache-control"],this.contentDisposition=t["content-disposition"],this.contentEncoding=t["content-encoding"],this.contentLanguage=t["content-language"],this.websiteRedirectLocation=t["x-amz-website-redirect-location"];let c=t["x-amz-storage-class"];c&&(this.storageClass=c);let a=new Date(t.expires);isNaN(a)||(this.expires=a.getTime()),this.metadataDirective=t["x-amz-metadata-directive"];let d=t["x-amz-copy-source"]??"",[u,...l]=decodeURIComponent(d).split("/").filter(Boolean);this.sourceBucket=u,this.sourceKey=l.join("/"),this.ifMatch=t["x-amz-copy-source-if-match"],this.ifNoneMatch=t["x-amz-copy-source-if-none-match"],t["x-amz-copy-source-if-modified-since"]&&(this.ifModifiedSince=new Date(t["x-amz-copy-source-if-modified-since"]).getTime()),t["x-amz-copy-source-if-unmodified-since"]&&(this.ifUnmodifiedSince=new Date(t["x-amz-copy-source-if-unmodified-since"]).getTime())}bucket;key;sourceBucket;sourceKey;contentType;cacheControl;contentDisposition;contentEncoding;contentLanguage;websiteRedirectLocation;expires;storageClass="STANDARD";metadataDirective;ifMatch;ifNoneMatch;ifModifiedSince;ifUnmodifiedSince;async exec(e,t){if(this.sourceKey==""){e.statusCode=400,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(`<?xml version="1.0" encoding="UTF-8"?><Error><Code>InvalidArgument</Code><Message>Invalid copy source object key</Message><ArgumentName>x-amz-copy-source</ArgumentName><ArgumentValue>x-amz-copy-source</ArgumentValue><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}if(this.hasNot(this.bucket,e)||this.hasNot(this.sourceBucket,e)||!this.isValidStorageClass(this.storageClass,e))return;if(!this.localService.persistence.buckets[this.sourceBucket].objects[this.sourceKey]){e.writeHead(404,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(x({Key:this.sourceKey,RequestId:this.requestId}));return}let s=this.localService.persistence.buckets[this.sourceBucket].objects[this.sourceKey];if([this.bucket,this.key].join("/")==[this.sourceBucket,this.sourceKey].join("/")&&[this.storageClass==s.StorageClass,this.websiteRedirectLocation==s.websiteRedirectLocation].every(l=>l===!0)){e.statusCode=400,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(`<Error><Code>InvalidRequest</Code><Message>This copy request is illegal because it is trying to copy an object to itself without changing the object's metadata, storage class, website redirect location or encryption attributes.</Message><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}let n={ifMatch:this.ifMatch,ifNoneMatch:this.ifNoneMatch,ifModifiedSince:this.ifModifiedSince,ifUnmodifiedSince:this.ifUnmodifiedSince},o=K(n,s);if(o!==200){e.writeHead(o.statusCode,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(`<?xml version="1.0" encoding="UTF-8"?><Error><Code>${o.Code}</Code><Message>At least one of the pre-conditions you specified did not hold</Message><Condition>${o.Condition}</Condition><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}let c=Ve.join(this.localService.localStoragePath,this.sourceBucket,s.currentKey),a=b.genLocalKey(this.bucket,this.key),d=Ve.join(this.localService.localStoragePath,this.bucket,a);try{await Xt(c,d);let u=await Wt(d),l=fe(await Gt(d));this.metadataDirective=="COPY"?this.localService.persistence.buckets[this.bucket].objects[this.key]={currentKey:a,type:s.type,cacheControl:s.cacheControl,contentDisposition:s.contentDisposition,contentEncoding:s.contentEncoding,contentLanguage:s.contentLanguage,expires:s.expires,ETag:l,StorageClass:s.StorageClass,LastModified:u.mtimeMs,size:u.size,metadata:s.metadata,versions:{[a]:{}}}:this.localService.persistence.buckets[this.bucket].objects[this.key]={currentKey:a,type:this.contentType,cacheControl:this.cacheControl,contentDisposition:this.contentDisposition,contentEncoding:this.contentEncoding,contentLanguage:this.contentLanguage,expires:this.expires,ETag:l,StorageClass:this.storageClass,LastModified:u.mtimeMs,size:u.size,metadata:this.metadata,websiteRedirectLocation:this.websiteRedirectLocation,versions:{[a]:{}}};let p=new Date(u.mtimeMs).toISOString();e.statusCode=200,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(`<?xml version="1.0" encoding="UTF-8"?>
93
93
  <CopyObjectResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><LastModified>${p}</LastModified><ETag>${l}</ETag></CopyObjectResult>`);let g=t.socket.remoteAddress?.split(":")?.[3]??"127.0.0.1";await A(this.localService.callableLambdas,{bucket:this.bucket,key:this.key,requestId:this.requestId,requestCmd:"CopyObject",eTag:l,sourceIPAddress:g,size:u.size})}catch(u){console.error(u),e.statusCode=500,e.end("Internal Server Error")}}};var G=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n}bucket;async exec(e,t){if(!this.hasNot(this.bucket,e))try{e.setHeader("x-amzn-requestid",this.requestId),this.localService.persistence.buckets[this.bucket].tags=await b.getTagsFromRequest(t,this.requestId,"Bucket"),e.statusCode=204,e.end()}catch(s){if(e.statusCode=400,s instanceof f){e.setHeader("Content-Type","application/xml"),s.statusCode&&(e.statusCode=s.statusCode),e.end(s.toXml());return}if(s instanceof Error){e.setHeader("Content-Type","application/xml"),e.end(f.genericError({Code:"UnknownError",Message:s.message,RequestId:this.requestId}));return}e.end(s?.toString?.())}}};var W=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n,...o]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n,this.key=o.join("/")}bucket;key;async exec(e,t){if(!this.hasNot(this.bucket,e)){if(!this.localService.persistence.buckets[this.bucket].objects[this.key]){e.writeHead(404,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(x({Key:this.key,RequestId:this.requestId}));return}try{e.setHeader("x-amzn-requestid",this.requestId),this.localService.persistence.buckets[this.bucket].objects[this.key].tags=await b.getTagsFromRequest(t,this.requestId,"Object"),e.statusCode=200,e.end()}catch(s){if(e.statusCode=400,s instanceof f){e.setHeader("Content-Type","application/xml"),s.statusCode&&(e.statusCode=s.statusCode),e.end(s.toXml());return}if(s instanceof Error){e.setHeader("Content-Type","application/xml"),e.end(f.genericError({Code:"UnknownError",Message:s.message,RequestId:this.requestId}));return}e.end(s?.toString?.())}}}};var J=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n}bucket;async collectBody(e){let t=Buffer.alloc(0);return e.on("data",s=>{t=Buffer.concat([t,s])}),new Promise(s=>{e.on("end",async()=>{s(t.toString("utf-8"))})})}async exec(e,t){if(!this.hasNot(this.bucket,e))try{let s=await this.collectBody(t),n=JSON.parse(s),o=this.localService.persistence.buckets[this.bucket];o.policy=n,e.end()}catch{e.writeHead(400,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(`<?xml version="1.0" encoding="UTF-8"?>
94
94
  <Error><Code>MalformedPolicy</Code><Message>Policies must be valid JSON</Message><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`)}}};var Y=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n}bucket;async exec(e,t){this.hasNot(this.bucket,e)||(e.statusCode=500,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.end(new N("PutBucketCors",this.requestId).toXml()))}};var Q=class i extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n}bucket;static aclHeaders=["x-amz-acl","x-amz-grant-full-control","x-amz-grant-read","x-amz-grant-read-acp","x-amz-grant-write","x-amz-grant-write-acp"];async collectBody(e){let t=Buffer.alloc(0);return e.on("data",s=>{t=Buffer.concat([t,s])}),new Promise(s=>{e.on("end",async()=>{s(t.toString("utf-8"))})})}getAclHeaders(e){let t={};for(let s of i.aclHeaders){let n=e[s];n&&(t[s]=n)}return t}async exec(e,t){if(!this.hasNot(this.bucket,e))try{let s=await this.collectBody(t),n=this.getAclHeaders(t.headers),o=this.localService.persistence.buckets[this.bucket];s&&(b.XMLParser.parse(s),o.acl.accessControlPolicy=s),o.acl.headers=n,e.end();return}catch{e.statusCode=400,e.setHeader("Content-Type","application/xml"),e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Server","AmazonS3"),e.end(new T(this.requestId).toXml())}}};var Z=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let[n]=decodeURIComponent(e.pathname).split("/").filter(Boolean);this.bucket=n}bucket;async exec(e,t){this.hasNot(this.bucket,e)||(e.statusCode=500,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.end(new N("PutObjectAcl",this.requestId).toXml()))}};import{createWriteStream as Jt,mkdirSync as Yt,readFileSync as Qt,statSync as Zt}from"node:fs";import Fe from"node:path";var Ie=class extends m{constructor(e,t,s){super(t,s);this.localService=s;let n=decodeURIComponent(e.pathname),[o,...c]=n.split("/").filter(Boolean);this.bucket=o,this.key=c.join("/"),this.uploadId=e.searchParams.get("uploadId"),e.searchParams.has("partNumber")&&(this.partNumber=e.searchParams.get("partNumber")??"")}bucket;key;uploadId;partNumber="";validateRequest(e){if(this.hasNot(this.bucket,e))return;if(!this.uploadId){e.statusCode=400,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(`<?xml version="1.0" encoding="UTF-8"?>
95
95
  <Error><Code>InvalidArgument</Code><ArgumentName>partNumber</ArgumentName><ArgumentValue>partNumber</ArgumentValue><Message>This operation does not accept partNumber without uploadId</Message><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}let t=Number(this.partNumber);if(!this.partNumber||isNaN(t)||this.partNumber.includes(".")||t<1||t>1e4){e.statusCode=400,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(`<?xml version="1.0" encoding="UTF-8"?>
96
96
  <Error><Code>InvalidArgument</Code><ArgumentName>partNumber</ArgumentName><ArgumentValue>${this.partNumber}</ArgumentValue><Message>Part number must be an integer between 1 and 10000, inclusive</Message><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}let s=this.localService.persistence.buckets[this.bucket].multipartUploads[this.uploadId];if(!s||s.aborted||s.completed){e.statusCode=404,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Content-Type","application/xml"),e.setHeader("Server","AmazonS3"),e.end(`<?xml version="1.0" encoding="UTF-8"?>
97
- <Error><Code>NoSuchUpload</Code><UploadId>${this.uploadId}</UploadId><Message>The specified upload does not exist. The upload ID may be invalid, or the upload may have been aborted or completed.</Message><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}return{partNumber:t,uploadId:this.uploadId}}async exec(e,t){let s=this.validateRequest(e);if(!s)return;let{partNumber:n,uploadId:o}=s,c=this.localService.persistence.buckets[this.bucket].multipartUploads[o],a=b.genLocalKey(this.bucket,this.key,`${o}-${n}`),d=Fe.join(this.localService.localStoragePath,this.bucket,a);try{Yt(Fe.dirname(d),{recursive:!0})}catch{}let u=Jt(d,{flush:!0});u.on("finish",async()=>{try{let l=R(Qt(d)),p=c.parts.find(h=>h.partNumber==n),g=Zt(d);p?(p.eTag=l,p.size=g.size,p.lastModified=g.mtime.toISOString()):c.parts.push({filePath:d,eTag:l,partNumber:n,size:g.size,lastModified:g.mtime.toISOString()}),e.setHeader("status",200),e.setHeader("ETag",`"${l}"`),e.end()}catch(l){console.log(l),e.statusCode=500,e.end()}}),e.setHeader("status",100),e.setHeader("Server","AmazonS3"),e.setHeader("x-amzn-requestid",this.requestId),t.pipe(u)}};var _e=(i,r)=>{let{url:e,headers:t}=i,s=new URL(e,"http://localhost:3000"),n=t["user-agent"],o=typeof t["x-amz-copy-source"]=="string";if(n?.startsWith("aws-cli")){let[,c]=n.split("command/"),[,...a]=c.split(".");switch(a.join(".")){case"cp":case"sync":case"mv":return o?new z(s,t,r):new w(s,t,r);case"mb":case"create-bucket":return new X(s,t,r);case"copy-object":return new z(s,t,r);case"put-object":return new w(s,t,r);case"put-bucket-tagging":return new G(s,t,r);case"put-object-tagging":return new W(s,t,r);case"put-bucket-policy":return new J(s,t,r);case"put-bucket-cors":return new Y(s,t,r);case"put-bucket-acl":return new Q(s,t,r);case"put-object-acl":return new Z(s,t,r);default:break}}else{let c=s.pathname.split("/").filter(Boolean).length==1;return!c&&s.searchParams.has("partNumber")&&s.searchParams.has("uploadId")?o?new I(s,t,r):new Ie(s,t,r):s.searchParams.has("policy")?c?new J(s,t,r):new I(s,t,r):s.searchParams.has("cors")?c?new Y(s,t,r):new I(s,t,r):s.searchParams.has("acl")?c?new Q(s,t,r):new Z(s,t,r):s.searchParams.has("tagging")?c?new G(s,t,r):new W(s,t,r):o?c?new I(s,t,r):new z(s,t,r):c?new X(s,t,r):new w(s,t,r)}return new I(s,t,r)};var ts=async(i,r,e)=>{switch(i.method){case"HEAD":await Ne(i,e).exec(r);break;case"GET":await Te(i,e).exec(r);break;case"PUT":await _e(i,e).exec(r,i);break;case"DELETE":await Me(i,e).exec(r,i);break;case"POST":await Oe(i,e).exec(r,i);break;default:break}},Xe=i=>{let r={port:0,localStorageDir:"./.exlo/s3",...i},e=new b(r.localStorageDir,r.persist,r.port);return i?.accountId&&(e.accountId=i.accountId),i?.region&&(e.region=i.region),new Promise(t=>{let s=es((c,a)=>{ts(c,a,e)}),n=async()=>{let c=s.address();c&&typeof c=="object"&&(e.port=c.port),t({server:s,localService:e})},o=[r.port];r.hostname&&o.push(r.hostname),o.push(n),s.listen(...o)})};var Ge=[],Jo=i=>{let r=qe(i?.localStorageDir),e={setEndpointEnvVar:!0,...i,localStorageDir:r},t,s;return{name:"s3-local",onInit:async function(){let{accountId:n,region:o}=this.getAwsProviderDefaults(),{localService:c,server:a}=await Xe({accountId:n,region:o,...e});t=c,typeof e.allowToDeleteNonEmptyBuckets=="boolean"&&(t.allowToDeleteNonEmptyBuckets=e.allowToDeleteNonEmptyBuckets),s=a,s.unref(),Ge=[],t.callableLambdas=Ge;let u=`http://127.0.0.1:${s.address().port}`;try{await t.bootstrap(),this.setEndpoint("s3",u,e.setEndpointEnvVar?"AWS_ENDPOINT_URL_S3":void 0)}catch{}if(!this.getServices().s3){let l=new ss({region:o,endpoint:u,forcePathStyle:!0,credentials:{accessKeyId:"test",secretAccessKey:"test"}});this.setService("s3",l)}this.log.PINK(`S3 endpoint: ${u}`)},async onKill(){try{t.saveState()}catch{}},server:{async onReady(){let n=e.buckets??{};for(let o of Object.keys(n)){if(!b.isValidBucketName(o)){console.error(`Invalid Bucket Name: "${o}"`);continue}await t.createBucket(o,n[o])}}}}};export{Jo as s3Plugin};
97
+ <Error><Code>NoSuchUpload</Code><UploadId>${this.uploadId}</UploadId><Message>The specified upload does not exist. The upload ID may be invalid, or the upload may have been aborted or completed.</Message><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}return{partNumber:t,uploadId:this.uploadId}}async exec(e,t){let s=this.validateRequest(e);if(!s)return;let{partNumber:n,uploadId:o}=s,c=this.localService.persistence.buckets[this.bucket].multipartUploads[o],a=b.genLocalKey(this.bucket,this.key,`${o}-${n}`),d=Fe.join(this.localService.localStoragePath,this.bucket,a);try{Yt(Fe.dirname(d),{recursive:!0})}catch{}let u=Jt(d,{flush:!0});u.on("finish",async()=>{try{let l=R(Qt(d)),p=c.parts.find(h=>h.partNumber==n),g=Zt(d);p?(p.eTag=l,p.size=g.size,p.lastModified=g.mtime.toISOString()):c.parts.push({filePath:d,eTag:l,partNumber:n,size:g.size,lastModified:g.mtime.toISOString()}),e.setHeader("status",200),e.setHeader("ETag",`"${l}"`),e.end()}catch(l){console.log(l),e.statusCode=500,e.end()}}),e.setHeader("status",100),e.setHeader("Server","AmazonS3"),e.setHeader("x-amzn-requestid",this.requestId),t.pipe(u)}};var _e=(i,r)=>{let{url:e,headers:t}=i,s=new URL(e,"http://localhost:3000"),n=t["user-agent"],o=typeof t["x-amz-copy-source"]=="string";if(n?.startsWith("aws-cli")){let[,c]=n.split("command/"),[,...a]=c.split(".");switch(a.join(".")){case"cp":case"sync":case"mv":return o?new z(s,t,r):new w(s,t,r);case"mb":case"create-bucket":return new X(s,t,r);case"copy-object":return new z(s,t,r);case"put-object":return new w(s,t,r);case"put-bucket-tagging":return new G(s,t,r);case"put-object-tagging":return new W(s,t,r);case"put-bucket-policy":return new J(s,t,r);case"put-bucket-cors":return new Y(s,t,r);case"put-bucket-acl":return new Q(s,t,r);case"put-object-acl":return new Z(s,t,r);default:break}}else{let c=s.pathname.split("/").filter(Boolean).length==1;return!c&&s.searchParams.has("partNumber")&&s.searchParams.has("uploadId")?o?new I(s,t,r):new Ie(s,t,r):s.searchParams.has("policy")?c?new J(s,t,r):new I(s,t,r):s.searchParams.has("cors")?c?new Y(s,t,r):new I(s,t,r):s.searchParams.has("acl")?c?new Q(s,t,r):new Z(s,t,r):s.searchParams.has("tagging")?c?new G(s,t,r):new W(s,t,r):o?c?new I(s,t,r):new z(s,t,r):c?new X(s,t,r):new w(s,t,r)}return new I(s,t,r)};var ts=async(i,r,e)=>{switch(i.method){case"HEAD":await Ne(i,e).exec(r);break;case"GET":await Te(i,e).exec(r);break;case"PUT":await _e(i,e).exec(r,i);break;case"DELETE":await Me(i,e).exec(r,i);break;case"POST":await Ke(i,e).exec(r,i);break;case"OPTIONS":r.writeHead(200,"OK",{"access-control-allow-origin":i.headers.origin,"access-control-allow-headers":"*","access-control-allow-methods":i.headers["access-control-request-method"],"access-control-max-age":"86400"}),r.end();break;default:break}},Xe=i=>{let r={port:0,localStorageDir:"./.exlo/s3",...i},e=new b(r.localStorageDir,r.persist,r.port);return i?.accountId&&(e.accountId=i.accountId),i?.region&&(e.region=i.region),new Promise(t=>{let s=es((c,a)=>{ts(c,a,e)}),n=async()=>{let c=s.address();c&&typeof c=="object"&&(e.port=c.port),t({server:s,localService:e})},o=[r.port];r.hostname&&o.push(r.hostname),o.push(n),s.listen(...o)})};var Ge=[],Jo=i=>{let r=qe(i?.localStorageDir),e={setEndpointEnvVar:!0,...i,localStorageDir:r},t,s;return{name:"s3-local",onInit:async function(){let{accountId:n,region:o}=this.getAwsProviderDefaults(),{localService:c,server:a}=await Xe({accountId:n,region:o,...e});t=c,typeof e.allowToDeleteNonEmptyBuckets=="boolean"&&(t.allowToDeleteNonEmptyBuckets=e.allowToDeleteNonEmptyBuckets),s=a,s.unref(),Ge=[],t.callableLambdas=Ge;let u=`http://127.0.0.1:${s.address().port}`;try{await t.bootstrap(),this.setEndpoint("s3",u,e.setEndpointEnvVar?"AWS_ENDPOINT_URL_S3":void 0)}catch{}if(!this.getServices().s3){let l=new ss({region:o,endpoint:u,forcePathStyle:!0,credentials:{accessKeyId:"test",secretAccessKey:"test"}});this.setService("s3",l)}this.log.PINK(`S3 endpoint: ${u}`)},async onKill(){try{t.saveState()}catch{}},server:{async onReady(){let n=e.buckets??{};for(let o of Object.keys(n)){if(!b.isValidBucketName(o)){console.error(`Invalid Bucket Name: "${o}"`);continue}await t.createBucket(o,n[o])}}}}};export{Jo as s3Plugin};
@@ -6,7 +6,7 @@ Please verify provided SQS Client validity.`),console.error(d)}}},cn=/(-|\w+)/g,
6
6
  `)}else I=R;I.trim()&&console.log(I)}}catch(L){console.log("err",L),y(L)}};this.python.stdout.on("data",u);let S=w=>{let E=w.toString();if(E.includes(t.ERR_RESPONSE))try{E=JSON.parse(E.split(t.ERR_RESPONSE)[1]),E.requestId=p}catch{}finally{this.python.stdout.removeListener("data",u),this.python.stderr.removeListener("data",S),y(E)}else console.log(E)};this.python.stderr.on("data",S),this.python.stdin.write(`${f}
7
7
  `)}),this.watcherListener=()=>{this.isMounted&&(this.unmount(!0),this.watchers.forEach(d=>d.close()),this.watchers=[],this.emitRebuild())}}setWatchFiles=async e=>{try{let n=e.split(t.WATCH),s=n[n.length-1].split(t.WATCHEND)[0],i=JSON.parse(s).map(o=>`${o.replace(/\./g,H.default.sep)}.py`);for(let o of i)try{await(0,fe.access)(o),this.watchers.push((0,at.watch)(o,{persistent:!1},this.watcherListener))}catch{}}catch(n){console.log(n)}};findPython(){let[e]=this.runtime.split("."),n=e.split("python")[1];if(ot(`${e} --version`))return e;let r=ot("python --version");if(!r)throw new Error("Can not find python on your OS. Make sure it is installed.");if(n){let s=r.split(" ")[1]?.split(".")[0];s&&s!=n&&b.YELLOW("found python binary but with different version")}return"python"}load=()=>{this.bin||(this.bin=this.findPython()),this.python=(0,ie.spawn)(this.bin,["-u",t.wrapper,this.handlerFileAbsolutePath,this.pyModulePath,this.handlerName,String(this.timeout)],{env:this.environment}),this.python.pid||(console.error(`Can not find ${this.bin} in your PATH`),process.exit(1)),this.isMounted=!0};onComplete=e=>{}};var ct=require("node:child_process"),lt=require("node:fs"),he=require("node:fs/promises"),$=P(require("node:path"));var oe=class t{invoke;mount;unmount;name;timeout;memorySize;environment;handlerPath;modulePath;handlerDir;handlerName;runtime;bin;ruby;isMounted=!1;emitRebuild;watcherListener;watchers=[];static wrapper=$.default.resolve(q("exlo"),"./src/lib/runtime/runners/ruby/index.rb");static DELIMITER="__|response|__";static ERR_RESPONSE="__|error|__";static WATCH="__|watch|__";constructor({name:e,timeout:n,memorySize:r,environment:s,handlerPath:i,handlerName:o,runtime:a},l){this.name=e,this.timeout=n,this.memorySize=r,this.environment=s,this.handlerName=o,this.runtime=a,this.emitRebuild=l;let c=$.default.resolve(i);this.handlerDir=$.default.dirname(c),this.handlerPath=$.default.basename(c,`.${this.handlerName}`),this.modulePath=`${this.handlerDir}/${this.handlerPath}.rb`,this.mount=async()=>{if(!this.ruby)try{await(0,he.access)(this.modulePath),this.load()}catch{console.error(`Can not find ${this.name}'s handler at: "${this.modulePath}"`),process.exit(1)}},this.unmount=d=>{d&&(this.ruby?.kill(),this.ruby=void 0,this.isMounted=!1)},this.invoke=async({event:d,info:m,clientContext:h,awsRequestId:p})=>new Promise((g,y)=>{let f=JSON.stringify({event:d,awsRequestId:p,context:h??""}),v=S=>{let w=null,E=S.toString();try{if(E.includes(t.WATCH))this.setWatchFiles(E);else if(E.includes(t.DELIMITER)){let R=E.split(t.DELIMITER),L=R[R.length-1];if(R.length>1){let I=R.slice(0,-1).join(`
8
8
  `);I.trim()&&console.log(I)}L&&(w=JSON.parse(L)),this.ruby.stdout.removeListener("data",v),this.ruby.stderr.removeListener("data",u),g(w)}else E.trim()&&console.log(E)}catch(R){y(R)}};this.ruby.stdout.on("data",v);let u=S=>{let w=S.toString();if(w.includes(t.ERR_RESPONSE))try{w=JSON.parse(w.split(t.ERR_RESPONSE)[1]),w.requestId=p}catch{}finally{this.ruby.stdout.removeListener("data",v),this.ruby.stderr.removeListener("data",u),y(w)}else console.log(w)};this.ruby.stderr.on("data",u),this.ruby.stdin.write(`${f}
9
- `)}),this.watcherListener=()=>{this.isMounted&&(this.unmount(!0),this.watchers.forEach(d=>d.close()),this.watchers=[],this.emitRebuild())}}setWatchFiles=async e=>{try{let n=e.split(t.WATCH),r=n[n.length-1],s=JSON.parse(r);s.push(this.modulePath);for(let i of s)try{await(0,he.access)(i),this.watchers.push((0,lt.watch)(i,{persistent:!1},this.watcherListener))}catch{}}catch(n){console.log(n)}};load=()=>{this.bin||(this.bin=process.platform==="win32"?"ruby.exe":"ruby"),this.ruby=(0,ct.spawn)(this.bin,[t.wrapper,this.modulePath,this.handlerName,this.name,String(this.timeout)],{env:this.environment,shell:!0}),this.ruby.pid||(console.error(`Can not find ${this.bin} in your PATH`),process.exit(1)),this.isMounted=!0};onComplete=e=>{}};var gn=["@invoke","@url"],k=class t{handlers=[];static ip="127.0.0.1";debug=!1;port=0;constructor(e){this.debug=e.debug}static parseNameFromUrl(e){let n=e.split("/"),r=gn.includes(n[1])?n[2]:n[3];if(r=decodeURIComponent(r),r.includes(":function:")){let s=r.split(":function:");r=s[s.length-1]}if(r.includes(":")){let s=r.split(":");s.length==2&&(r=s[0])}return r}getHandlerByName(e){if(!e)return;let n=t.parseNameFromUrl(e);return this.handlers.find(r=>r.name==n)}addHandler(e){let n=this.handlers.findIndex(r=>r.name==e.name&&r.esOutputPath==e.esOutputPath);n==-1?(this.handlers.push(e),this.#e("POST",`/2015-03-31/functions/${e.name}/invocations`),e.url&&this.#e("ANY",`/@url/${e.name}`,"34")):this.handlers[n].runtime.startsWith("n")&&(this.handlers[n].clear(),this.handlers[n]=e)}#e(e,n,r="90"){let s=`${e} http://localhost:${this.port}${n}`;console.log(`\x1B[${r}m${s}\x1B[0m`)}};var ae;ye.networkInterfaces&&(ae=Object.values((0,ye.networkInterfaces)()).reduce((t,e)=>(t.push(...e),t),[])?.filter(t=>!t.internal&&t.family==="IPv4").find(Boolean)?.address);var bn=mt.default?.url()!=null;bn&&(console.warn("Lambdas timeout are disabled when a Debugger is attached"),C.ENABLE_TIMEOUT=!1);var Sn={errors:[],warnings:[],outputFiles:[],metafile:{inputs:{},outputs:{}},mangleCache:{}},ce=class extends k{#e;runtimeConfig={};#t;sco=[];aws;customOfflineRequests=[];customBuildCallback;onReady;stop(e){this.#e.close(e)}constructor(e,n={debug:!1}){super(n),b.setDebug(n.debug),this.aws=e.aws,this.sco=[],this.#e=pt.default.createServer({maxHeaderSize:105536},this.#r.bind(this)),this.#e.on("connection",s=>{s.on("close",()=>{let i=this.sco.findIndex(o=>o==s);i!=-1&&this.sco.splice(i,1)}),this.sco.push(s)});let r=(0,dt.randomUUID)();x.accountId=Buffer.from(r).toString("hex").slice(0,16),x.apiId=Buffer.from(r).toString("ascii").slice(0,10),x.port=this.port}setPort(e){this.port=e,x.port=e}listen(e=0,n){if(isNaN(e))throw Error("port should be a number");this.#e.once("error",async r=>{r.code==="EADDRINUSE"?(b.RED(r.message),process.exit(1)):console.log(r)}),this.#e.listen(e,async()=>{let{port:r,address:s}=this.#e.address();this.setPort(r),ae&&(k.ip=ae),typeof n=="function"&&await n(r,ae);try{await this.onReady?.(r,k.ip),await Ke(this.handlers,this.aws)}catch(i){console.error(i)}})}#n(e,n){n=n.endsWith("/")?n:`${n}/`;let r=this.customOfflineRequests.find(s=>{let i=!1,o=!0;return typeof s.filter=="string"?(s.filter.endsWith("/")||(s.filter+="/"),i=s.filter==n):s.filter instanceof RegExp&&(i=s.filter.test(n)),typeof s.method=="string"&&s.method.toUpperCase()!="ANY"?o=s.method.toUpperCase()==e:Array.isArray(s.method)&&(s.method.findIndex(l=>l.toUpperCase()=="ANY")!==-1||(o=s.method.findIndex(l=>l.toUpperCase()==e)!==-1)),i&&o});if(r)return r.callback}async#r(e,n){let{url:r,method:s}=e,i=new URL(r,x.dummyHost),o=this.#n(s,i.pathname);if(o)try{await o(e,n)}catch{n.writableFinished||n.end("Internal Server Error")}else{e.on("error",l=>{console.error(l.stack)});let a=()=>{n.setHeader("Content-Type","text/html"),n.statusCode=404,n.end(qe)};this.#t?this.#t(e,n,a):a()}}fakeRebuildEmitter=async()=>{if(this.customBuildCallback)try{await this.customBuildCallback(Sn,!0)}catch(e){console.log(e)}console.log(`\x1B[32m${new Date().toLocaleString()} \u{1F504}\u2705 Rebuild\x1B[0m`)};async load(e){for(let n of e){let r=n.runtime.charAt(0);n.runner=r=="n"?new re(n):r=="p"?new se(n,this.fakeRebuildEmitter):r=="r"?new oe(n,this.fakeRebuildEmitter):new ne(n.runtime);let s=new C(n);this.addHandler(s)}}};var ht=require("node:fs/promises"),N=P(require("node:path")),yt=require("node:url"),gt=P(require("esbuild"));var ut="0.0.13";function ft(t){let e=new Set;t.plugins&&(t.plugins=t.plugins.filter((r,s)=>typeof r!="object"||!r||!("name"in r)?!1:((!r.name||!r.name.length||typeof r.name!="string")&&(r.name=`plugin-${s}`,console.warn(`No Plugin name provided at index ${s}`)),e.has(r.name)?r.name=r.name+s:e.add(r.name),!0)));async function n({stop:r,lambdas:s,region:i,esbuild:o,getServices:a,setService:l,addLambda:c,log:d,setEndpoint:m,getEndpoint:h,getAwsProviderDefaults:p,setAwsProviderDefaults:g}){let y={build:{esbuild:t?.build?.esbuild??{},shimRequire:t?.build?.shimRequire,optimizeBuild:t?.build?.optimizeBuild},server:{port:t.server?.port,setEndpointEnvVar:t.server?.setEndpointEnvVar},onKill:[]};if(t.defaults&&typeof t.defaults=="object"&&!Array.isArray(t.defaults)&&g(t.defaults),t.functions&&typeof t.functions=="object"&&!Array.isArray(t.functions))for(let[v,u]of Object.entries(t.functions))c(v,u);t.services&&(t.services.sqs&&l("sqs",t.services.sqs),t.services.sns&&l("sns",t.services.sns),t.services.dynamodb&&l("dynamodb",t.services.dynamodb));let f={stop:r,lambdas:s,region:i,esbuild:o,options:t,config:y,getServices:a,setService:l,addLambda:c,log:d,setEndpoint:m,getEndpoint:h,getAwsProviderDefaults:p};if(t.plugins){y.server.onReady=async(u,S)=>{for(let w of t.plugins)if(w.server?.onReady)try{await w.server.onReady.call(f,u,S)}catch(E){d.RED(w.name),console.error(E)}},y.buildCallback=async(u,S)=>{for(let w of t.plugins)if(w.buildCallback)try{await w.buildCallback.call(f,u,S)}catch(E){d.RED(w.name),console.error(E),S||process.exit(1)}};let v=t.plugins.reduce((u,S)=>(S.server?.request?.length&&u.push(...S.server.request),u),[]);v?.length&&(y.server.request=v.map(u=>(u.callback=u.callback.bind(f),u)));for(let u of t.plugins)if(u.onKill&&y.onKill.push(u.onKill.bind(f)),u.onInit)try{await u.onInit.call(f)}catch(S){throw d.RED(u.name),S}}return y}return n.plugins=t.plugins??[],n}var xn=["js","mjs","cjs","ts","cts","mts"],wn=async t=>{let e=N.default.dirname(N.default.toNamespacedPath(t)),n=N.default.basename(t,N.default.extname(t)),r=N.default.join(e,`__${n}.mjs`);await gt.default.build({outfile:r,entryPoints:[t],bundle:!0,packages:"external",platform:"node",format:"esm",target:`node${process.versions.node.split(".")[0]}`,minify:!0,sourcemap:"inline",sourcesContent:!0});try{return await import((0,yt.pathToFileURL)(r).href)}catch(s){throw s}finally{await(0,ht.rm)(r)}},bt=async t=>{if(t){if(typeof t=="string"){let e=N.default.posix.parse(t),n=N.default.posix.join(e.dir,e.name),r=e.ext.slice(1),s=N.default.posix.resolve(n);xn.includes(r)&&(s+=`.${r}`);let i;try{i=await wn(s)}catch(o){b.YELLOW(`Can not read 'defineConfig' from ${t}`),console.error(o),process.exit(1)}return{exportedFunc:i,configObjectName:r,configPath:s}}if(typeof t=="object"&&!Array.isArray(t))return{configObjectName:"__inline_config__",configPath:"inline define config",exportedFunc:ft(t)}}};var En=t=>{let e=t.split(";");return e.findIndex(r=>r.trim().toLowerCase().startsWith("path="))==-1&&e.push("Path=/"),e.join(";")},ge=(t,e,n)=>{let r={};if(t&&Object.entries(t).forEach(([s,i])=>{r[s.toLowerCase()]=Array.isArray(i)?`[${i.join(", ")}]`:i}),n)for(let[s,i]of Object.entries(n))r[s]=i;if(!Array.isArray(e))return r;if(!e.every(s=>typeof s=="string")){let s=new Error("Wrong 'cookies'. must be string[]",{cause:e}),i={"Content-Type":r["content-type"]??"application/json","x-amzn-ErrorType":"InternalFailure",...n};throw r["set-cookie"]&&(i["set-cookie"]=r["set-cookie"]),s.headers=i,s}return e=e.map(En),r["set-cookie"]=r["set-cookie"]?[r["set-cookie"],...e]:e,r};var be=require("node:crypto");var le=class t extends x{res;mockEvent;payload;constructor({res:e,req:n,body:r,mockEvent:s,multiValueHeaders:i,isBase64Encoded:o,lambdaName:a,parsedURL:l,requestId:c}){super(),this.res=e,this.mockEvent=s,this.payload=s.version==1?t.createApgV1Event({req:n,mockEvent:s,parsedURL:l,lambdaName:a,multiValueHeaders:i,isBase64Encoded:o,requestId:c,body:r}):t.createApgV2Event({req:n,mockEvent:s,parsedURL:l,requestId:c,isBase64Encoded:o,body:r})}static skipHeaders=["connection","content"];static createApgV2Event=({req:e,mockEvent:n,parsedURL:r,requestId:s,isBase64Encoded:i,body:o})=>{let{method:a,headers:l}=e,c=t.getPathParameters(n,r),d,m=n.methods.find(S=>S==a)??"ANY",h={},p="";for(let S of Array.from(new Set(r.searchParams.keys()))){let w=r.searchParams.getAll(S);p+=`&${w.map(E=>encodeURI(`${S}=${E}`)).join("&")}`,h[S]=w.join(",")}p&&(p=p.slice(1));let g=n.paths[0]=="/*"?"$default":`${m} ${r.pathname}`,y=new Date,f="127.0.0.1",v=l.host?.startsWith("localhost")?f:l.host?l.host.split(":")[0]:f,u={version:"2.0",routeKey:g,rawPath:r.pathname,rawQueryString:p,headers:t.getCustomHeaders(e,n),requestContext:{accountId:String(t.accountId),apiId:t.apiId,domainName:`localhost:${t.port}`,domainPrefix:"localhost",http:{method:a,path:r.pathname,protocol:"HTTP/1.1",sourceIp:v,userAgent:l["user-agent"]??""},requestId:s,routeKey:g,stage:"$default",time:y.toISOString(),timeEpoch:y.getTime()}};return o?(u.body=o,u.isBase64Encoded=i):u.isBase64Encoded=!1,Object.keys(h).length&&(u.queryStringParameters=h),Object.keys(c).length&&(u.pathParameters=c),l.cookie&&(u.cookies=l.cookie.split("; ")),d=u,d.headers["x-mock-type"]&&delete d.headers["x-mock-type"],d};static createApgV1Event=({req:e,mockEvent:n,parsedURL:r,lambdaName:s,isBase64Encoded:i,requestId:o,body:a})=>{let{method:l}=e,c={};n.proxy=="httpApi"&&(c.version="1.0");let d=n.paths[0];c.resource=d,c.path=r.pathname,c.httpMethod=l;let{headers:m,multiValueHeaders:h,apiKey:p}=t.getApiGV1Headers(e,n);c.headers=m,c.multiValueHeaders=h;let g=String(e.socket.remoteAddress),y=Object.fromEntries(r.searchParams);c.queryStringParameters=Object.keys(y).length?y:null;let f=t.getMultiValueQueryStringParameters(r.searchParams);c.multiValueQueryStringParameters=Object.keys(f).length?f:null;let v=new Date,u={accountId:String(t.accountId),apiId:t.apiId,domainName:`localhost:${t.port}`,domainPrefix:"localhost",extendedRequestId:"fake-id",httpMethod:l,identity:{accessKey:null,accountId:null,caller:null,cognitoAuthenticationProvider:null,cognitoAuthenticationType:null,cognitoIdentityId:null,cognitoIdentityPoolId:null,principalOrgId:null,sourceIp:g,user:null,userAgent:e.headers["user-agent"],userArn:null},path:r.pathname,protocol:"HTTP/1.1",requestId:o,requestTime:v.toISOString(),requestTimeEpoch:v.getTime(),resourceId:"exhmtv",resourcePath:d};n.proxy=="httpApi"?(u.identity.cognitoAmr=null,u.stage="$default"):(u.stage="dev",n.private&&(u.identity.apiKey=p,u.identity.apiKeyId="abcdefghjk")),c.requestContext=u;let S=t.getPathParameters(n,r);return c.pathParameters=Object.keys(S).length?S:null,c.stageVariables=null,c.body=a??null,c.isBase64Encoded=a?i:!1,c};returnError=e=>{if(this.res.writableFinished)return!0;let n=500,r=t.httpErrMsg;e&&t.isEndpointTimeoutError(e.errorMessage)&&(this.mockEvent.proxy=="httpApi"?(n=503,r=t.unavailable):(n=504,r=t.apgTimeoutMsg));let s=[["Date",new Date().toUTCString()],["Content-Type",t.contentType.json],["Content-Length",String(r.length)],t.keepAlive,["Apigw-Requestid","ETuSEj-PiGYEJdQ="]];return this.res.shouldKeepAlive=!1,this.res.writeHead(n,s),this.res.end(r)};#e=e=>{let n="",r=typeof e;if(r=="string"||r=="number"||r=="boolean")n=String(e);else if(e===null)n="";else throw new Error("");return n};sendV1Response=e=>{let n=[["Date",new Date().toUTCString()],["Apigw-Requestid",Buffer.from((0,be.randomUUID)()).toString("base64").slice(0,16)],t.keepAlive],r=200;if(!e||isNaN(e.statusCode))throw b.RED(`Valid 'http' response payload must be an object which includes a valid 'statusCode'.
9
+ `)}),this.watcherListener=()=>{this.isMounted&&(this.unmount(!0),this.watchers.forEach(d=>d.close()),this.watchers=[],this.emitRebuild())}}setWatchFiles=async e=>{try{let n=e.split(t.WATCH),r=n[n.length-1],s=JSON.parse(r);s.push(this.modulePath);for(let i of s)try{await(0,he.access)(i),this.watchers.push((0,lt.watch)(i,{persistent:!1},this.watcherListener))}catch{}}catch(n){console.log(n)}};load=()=>{this.bin||(this.bin=process.platform==="win32"?"ruby.exe":"ruby"),this.ruby=(0,ct.spawn)(this.bin,[t.wrapper,this.modulePath,this.handlerName,this.name,String(this.timeout)],{env:this.environment,shell:!0}),this.ruby.pid||(console.error(`Can not find ${this.bin} in your PATH`),process.exit(1)),this.isMounted=!0};onComplete=e=>{}};var gn=["@invoke","@url"],k=class t{handlers=[];static ip="127.0.0.1";debug=!1;port=0;constructor(e){this.debug=e.debug}static parseNameFromUrl(e){let n=e.split("/"),r=gn.includes(n[1])?n[2]:n[3];if(r=decodeURIComponent(r),r.includes(":function:")){let s=r.split(":function:");r=s[s.length-1]}if(r.includes(":")){let s=r.split(":");s.length==2&&(r=s[0])}return r}getHandlerByName(e){if(!e)return;let n=t.parseNameFromUrl(e);return this.handlers.find(r=>r.name==n)}addHandler(e){let n=this.handlers.findIndex(r=>r.name==e.name&&r.esOutputPath==e.esOutputPath);n==-1?(this.handlers.push(e),this.#e("POST",`/2015-03-31/functions/${e.name}/invocations`),e.url&&this.#e("ANY",`/@url/${e.name}`,"34")):this.handlers[n].runtime.startsWith("n")&&(this.handlers[n].clear(),this.handlers[n]=e)}#e(e,n,r="90"){let s=`${e} http://localhost:${this.port}${n}`;console.log(`\x1B[${r}m${s}\x1B[0m`)}};var ae;ye.networkInterfaces&&(ae=Object.values((0,ye.networkInterfaces)()).reduce((t,e)=>(t.push(...e),t),[])?.filter(t=>!t.internal&&t.family==="IPv4").find(Boolean)?.address);var bn=mt.default?.url()!=null;bn&&(console.warn("Lambdas timeout are disabled when a Debugger is attached"),C.ENABLE_TIMEOUT=!1);var Sn={errors:[],warnings:[],outputFiles:[],metafile:{inputs:{},outputs:{}},mangleCache:{}},ce=class extends k{#e;runtimeConfig={};#t;sco=[];aws;customOfflineRequests=[];customBuildCallback;onReady;stop(e){this.#e.close(e)}constructor(e,n={debug:!1}){super(n),b.setDebug(n.debug),this.aws=e.aws,this.sco=[],this.#e=pt.default.createServer({maxHeaderSize:105536},this.#r.bind(this)),this.#e.on("connection",s=>{s.on("close",()=>{let i=this.sco.findIndex(o=>o==s);i!=-1&&this.sco.splice(i,1)}),this.sco.push(s)});let r=(0,dt.randomUUID)();x.accountId=Buffer.from(r).toString("hex").slice(0,16),x.apiId=Buffer.from(r).toString("ascii").slice(0,10),x.port=this.port}setPort(e){this.port=e,x.port=e}listen(e=0,n){if(isNaN(e))throw Error("port should be a number");this.#e.once("error",async r=>{r.code==="EADDRINUSE"?(b.RED(r.message),process.exit(1)):console.log(r)}),this.#e.listen(e,async()=>{let{port:r,address:s}=this.#e.address();this.setPort(r),ae&&(k.ip=ae),typeof n=="function"&&await n(r,ae);try{await this.onReady?.(r,k.ip),await Ke(this.handlers,this.aws)}catch(i){console.error(i)}})}#n(e,n){n=n.endsWith("/")?n:`${n}/`;let r=this.customOfflineRequests.find(s=>{let i=!1,o=!0;return typeof s.filter=="string"?(s.filter.endsWith("/")||(s.filter+="/"),i=s.filter==n):s.filter instanceof RegExp&&(i=s.filter.test(n)),typeof s.method=="string"&&s.method.toUpperCase()!="ANY"?o=s.method.toUpperCase()==e:Array.isArray(s.method)&&(s.method.findIndex(l=>l.toUpperCase()=="ANY")!==-1||(o=s.method.findIndex(l=>l.toUpperCase()==e)!==-1)),i&&o});if(r)return r.callback}async#r(e,n){let{url:r,method:s}=e,i=new URL(r,x.dummyHost),o=this.#n(s,i.pathname);if(o)try{await o(e,n)}catch{n.writableFinished||n.end("Internal Server Error")}else{e.on("error",l=>{console.error(l.stack)});let a=()=>{n.setHeader("Content-Type","text/html"),n.statusCode=404,n.end(qe)};this.#t?this.#t(e,n,a):a()}}fakeRebuildEmitter=async()=>{if(this.customBuildCallback)try{await this.customBuildCallback(Sn,!0)}catch(e){console.log(e)}console.log(`\x1B[32m${new Date().toLocaleString()} \u{1F504}\u2705 Rebuild\x1B[0m`)};async load(e){for(let n of e){let r=n.runtime.charAt(0);n.runner=r=="n"?new re(n):r=="p"?new se(n,this.fakeRebuildEmitter):r=="r"?new oe(n,this.fakeRebuildEmitter):new ne(n.runtime);let s=new C(n);this.addHandler(s)}}};var ht=require("node:fs/promises"),N=P(require("node:path")),yt=require("node:url"),gt=P(require("esbuild"));var ut="0.0.14";function ft(t){let e=new Set;t.plugins&&(t.plugins=t.plugins.filter((r,s)=>typeof r!="object"||!r||!("name"in r)?!1:((!r.name||!r.name.length||typeof r.name!="string")&&(r.name=`plugin-${s}`,console.warn(`No Plugin name provided at index ${s}`)),e.has(r.name)?r.name=r.name+s:e.add(r.name),!0)));async function n({stop:r,lambdas:s,region:i,esbuild:o,getServices:a,setService:l,addLambda:c,log:d,setEndpoint:m,getEndpoint:h,getAwsProviderDefaults:p,setAwsProviderDefaults:g}){let y={build:{esbuild:t?.build?.esbuild??{},shimRequire:t?.build?.shimRequire,optimizeBuild:t?.build?.optimizeBuild},server:{port:t.server?.port,setEndpointEnvVar:t.server?.setEndpointEnvVar},onKill:[]};if(t.defaults&&typeof t.defaults=="object"&&!Array.isArray(t.defaults)&&g(t.defaults),t.functions&&typeof t.functions=="object"&&!Array.isArray(t.functions))for(let[v,u]of Object.entries(t.functions))c(v,u);t.services&&(t.services.sqs&&l("sqs",t.services.sqs),t.services.sns&&l("sns",t.services.sns),t.services.dynamodb&&l("dynamodb",t.services.dynamodb));let f={stop:r,lambdas:s,region:i,esbuild:o,options:t,config:y,getServices:a,setService:l,addLambda:c,log:d,setEndpoint:m,getEndpoint:h,getAwsProviderDefaults:p};if(t.plugins){y.server.onReady=async(u,S)=>{for(let w of t.plugins)if(w.server?.onReady)try{await w.server.onReady.call(f,u,S)}catch(E){d.RED(w.name),console.error(E)}},y.buildCallback=async(u,S)=>{for(let w of t.plugins)if(w.buildCallback)try{await w.buildCallback.call(f,u,S)}catch(E){d.RED(w.name),console.error(E),S||process.exit(1)}};let v=t.plugins.reduce((u,S)=>(S.server?.request?.length&&u.push(...S.server.request),u),[]);v?.length&&(y.server.request=v.map(u=>(u.callback=u.callback.bind(f),u)));for(let u of t.plugins)if(u.onKill&&y.onKill.push(u.onKill.bind(f)),u.onInit)try{await u.onInit.call(f)}catch(S){throw d.RED(u.name),S}}return y}return n.plugins=t.plugins??[],n}var xn=["js","mjs","cjs","ts","cts","mts"],wn=async t=>{let e=N.default.dirname(N.default.toNamespacedPath(t)),n=N.default.basename(t,N.default.extname(t)),r=N.default.join(e,`__${n}.mjs`);await gt.default.build({outfile:r,entryPoints:[t],bundle:!0,packages:"external",platform:"node",format:"esm",target:`node${process.versions.node.split(".")[0]}`,minify:!0,sourcemap:"inline",sourcesContent:!0});try{return await import((0,yt.pathToFileURL)(r).href)}catch(s){throw s}finally{await(0,ht.rm)(r)}},bt=async t=>{if(t){if(typeof t=="string"){let e=N.default.posix.parse(t),n=N.default.posix.join(e.dir,e.name),r=e.ext.slice(1),s=N.default.posix.resolve(n);xn.includes(r)&&(s+=`.${r}`);let i;try{i=await wn(s)}catch(o){b.YELLOW(`Can not read 'defineConfig' from ${t}`),console.error(o),process.exit(1)}return{exportedFunc:i,configObjectName:r,configPath:s}}if(typeof t=="object"&&!Array.isArray(t))return{configObjectName:"__inline_config__",configPath:"inline define config",exportedFunc:ft(t)}}};var En=t=>{let e=t.split(";");return e.findIndex(r=>r.trim().toLowerCase().startsWith("path="))==-1&&e.push("Path=/"),e.join(";")},ge=(t,e,n)=>{let r={};if(t&&Object.entries(t).forEach(([s,i])=>{r[s.toLowerCase()]=Array.isArray(i)?`[${i.join(", ")}]`:i}),n)for(let[s,i]of Object.entries(n))r[s]=i;if(!Array.isArray(e))return r;if(!e.every(s=>typeof s=="string")){let s=new Error("Wrong 'cookies'. must be string[]",{cause:e}),i={"Content-Type":r["content-type"]??"application/json","x-amzn-ErrorType":"InternalFailure",...n};throw r["set-cookie"]&&(i["set-cookie"]=r["set-cookie"]),s.headers=i,s}return e=e.map(En),r["set-cookie"]=r["set-cookie"]?[r["set-cookie"],...e]:e,r};var be=require("node:crypto");var le=class t extends x{res;mockEvent;payload;constructor({res:e,req:n,body:r,mockEvent:s,multiValueHeaders:i,isBase64Encoded:o,lambdaName:a,parsedURL:l,requestId:c}){super(),this.res=e,this.mockEvent=s,this.payload=s.version==1?t.createApgV1Event({req:n,mockEvent:s,parsedURL:l,lambdaName:a,multiValueHeaders:i,isBase64Encoded:o,requestId:c,body:r}):t.createApgV2Event({req:n,mockEvent:s,parsedURL:l,requestId:c,isBase64Encoded:o,body:r})}static skipHeaders=["connection","content"];static createApgV2Event=({req:e,mockEvent:n,parsedURL:r,requestId:s,isBase64Encoded:i,body:o})=>{let{method:a,headers:l}=e,c=t.getPathParameters(n,r),d,m=n.methods.find(S=>S==a)??"ANY",h={},p="";for(let S of Array.from(new Set(r.searchParams.keys()))){let w=r.searchParams.getAll(S);p+=`&${w.map(E=>encodeURI(`${S}=${E}`)).join("&")}`,h[S]=w.join(",")}p&&(p=p.slice(1));let g=n.paths[0]=="/*"?"$default":`${m} ${r.pathname}`,y=new Date,f="127.0.0.1",v=l.host?.startsWith("localhost")?f:l.host?l.host.split(":")[0]:f,u={version:"2.0",routeKey:g,rawPath:r.pathname,rawQueryString:p,headers:t.getCustomHeaders(e,n),requestContext:{accountId:String(t.accountId),apiId:t.apiId,domainName:`localhost:${t.port}`,domainPrefix:"localhost",http:{method:a,path:r.pathname,protocol:"HTTP/1.1",sourceIp:v,userAgent:l["user-agent"]??""},requestId:s,routeKey:g,stage:"$default",time:y.toISOString(),timeEpoch:y.getTime()}};return o?(u.body=o,u.isBase64Encoded=i):u.isBase64Encoded=!1,Object.keys(h).length&&(u.queryStringParameters=h),Object.keys(c).length&&(u.pathParameters=c),l.cookie&&(u.cookies=l.cookie.split("; ")),d=u,d.headers["x-mock-type"]&&delete d.headers["x-mock-type"],d};static createApgV1Event=({req:e,mockEvent:n,parsedURL:r,lambdaName:s,isBase64Encoded:i,requestId:o,body:a})=>{let{method:l}=e,c={};n.proxy=="httpApi"&&(c.version="1.0");let d=n.paths[0];c.resource=d,c.path=r.pathname,c.httpMethod=l;let{headers:m,multiValueHeaders:h,apiKey:p}=t.getApiGV1Headers(e,n);c.headers=m,c.multiValueHeaders=h;let g=String(e.socket.remoteAddress),y=Object.fromEntries(r.searchParams);c.queryStringParameters=Object.keys(y).length?y:null;let f=t.getMultiValueQueryStringParameters(r.searchParams);c.multiValueQueryStringParameters=Object.keys(f).length?f:null;let v=new Date,u={accountId:String(t.accountId),apiId:t.apiId,domainName:`localhost:${t.port}`,domainPrefix:"localhost",extendedRequestId:"fake-id",httpMethod:l,identity:{accessKey:null,accountId:null,caller:null,cognitoAuthenticationProvider:null,cognitoAuthenticationType:null,cognitoIdentityId:null,cognitoIdentityPoolId:null,principalOrgId:null,sourceIp:g,user:null,userAgent:e.headers["user-agent"],userArn:null},path:r.pathname,protocol:"HTTP/1.1",requestId:o,requestTime:v.toISOString(),requestTimeEpoch:v.getTime(),resourceId:"exhmtv",resourcePath:d};n.proxy=="httpApi"?(u.identity.cognitoAmr=null,u.stage="$default"):(u.stage="dev",n.private&&(u.identity.apiKey=p,u.identity.apiKeyId="abcdefghjk")),c.requestContext=u;let S=t.getPathParameters(n,r);return c.pathParameters=Object.keys(S).length?S:null,c.stageVariables=null,c.body=a??null,c.isBase64Encoded=a?i:!1,c};returnError=e=>{if(this.res.writableFinished)return!0;let n=500,r=t.httpErrMsg;e&&t.isEndpointTimeoutError(e.errorMessage)&&(this.mockEvent.proxy=="httpApi"?(n=503,r=t.unavailable):(n=504,r=t.apgTimeoutMsg));let s=[["Date",new Date().toUTCString()],["Content-Type",t.contentType.json],["Content-Length",String(r.length)],t.keepAlive,["Apigw-Requestid","ETuSEj-PiGYEJdQ="]];return this.res.shouldKeepAlive=!1,this.res.writeHead(n,s),this.res.end(r)};#e=e=>{let n="",r=typeof e;if(r=="string"||r=="number"||r=="boolean")n=String(e);else if(e===null)n="";else throw new Error("");return n};sendV1Response=e=>{let n=[["Date",new Date().toUTCString()],["Apigw-Requestid",Buffer.from((0,be.randomUUID)()).toString("base64").slice(0,16)],t.keepAlive],r=200;if(!e||isNaN(e.statusCode))throw b.RED(`Valid 'http' response payload must be an object which includes a valid 'statusCode'.
10
10
  Received:`),console.log(e),new Error;r=e.statusCode,e.headers&&typeof e.headers=="object"&&!Array.isArray(e.headers)&&Object.entries(e.headers).forEach(([c,d])=>{let m=t.normalizeHeaderKey(c),h=this.#e(d);n.push([m,h])}),e.multiValueHeaders&&typeof e.multiValueHeaders=="object"&&!Array.isArray(e.multiValueHeaders)&&Object.entries(e.multiValueHeaders).forEach(([c,d])=>{let m=t.normalizeHeaderKey(c);if(!Array.isArray(d))throw new Error;d.map(p=>this.#e(p)).forEach(p=>{n.push([m,p])})});let s=e.body;if(e.isBase64Encoded&&s){if(typeof s!="string")throw new Error;let c=Buffer.from(s,"base64").toString();if(Buffer.from(c).toString("base64")!=s)throw b.RED("response body is not properly base64 encoded"),new Error;s=c}n.findIndex(c=>c[0].toLowerCase()=="content-type")==-1&&n.push(["Content-Type",t.contentType.json]);let o=n.findIndex(c=>c[0].toLowerCase()=="content-length");o!=-1&&n.splice(o,1);let a=typeof s;a=="number"||a=="boolean"?s=String(s):s&&a!="string"&&b.YELLOW("API Gateway payload v1 return body must be typeof string, number or boolean ");let l=r==204?"0":s?String(Buffer.from(s).byteLength):"0";n.push(["Content-Length",l]),this.res.shouldKeepAlive=!1,this.res.writeHead(r,n),this.res.end(s)};sendV2Response=e=>{this.res.setHeader("Apigw-Requestid",Buffer.from((0,be.randomUUID)()).toString("base64").slice(0,16)),this.res.setHeader("Date",new Date().toUTCString()),e?(typeof e.headers=="object"&&!Array.isArray(e.headers)&&Object.keys(e.headers).filter(s=>s!=="Apigw-Requestid"&&s!=="Date").forEach(s=>{this.res.setHeader(s,e.headers[s])}),e.statusCode?(this.res.statusCode=e.statusCode,e.cookies?.length&&this.res.setHeader("Set-Cookie",e.cookies)):this.res.statusCode=200):this.res.statusCode=200;let n="";if(!e)return this.res.end();if(typeof e=="object"&&typeof e.body=="string"&&(n=e.body,e.isBase64Encoded)){let r=Buffer.from(n,"base64").toString();if(Buffer.from(r).toString("base64")!=n)throw b.RED("response body is not properly base64 encoded"),new Error;n=r}typeof e=="string"?(this.res.setHeader("Content-Type",t.contentType.json),n=e):typeof e=="object"&&!e.statusCode&&(this.res.setHeader("Content-Type",t.contentType.json),n=JSON.stringify(e)),this.res.end(n)};sendResponse=e=>{if(!this.res.writableFinished)return this.mockEvent.version==1?this.sendV1Response(e):this.sendV2Response(e)}};var Rn=(t,e)=>{let n=e.url.stream?t:void 0;if(n){let r=!1,s=t.write.bind(t),i=t.setHeader.bind(t),o,a,l=m=>{a=a?Buffer.concat([a,m]):m},c=()=>{if(a){let m=_e(a),h=m.statusCode??200;try{let p=ge(m.headers,m.cookies);t.writeHead(h,p)}catch(p){t.writeHead(500,p.headers),t.end?.(x.amzMsgNull),delete p.headers}}else t.writeHead(200)};n.setHeader=(m,h)=>{if(m.toLowerCase()=="content-type"){if(h=="application/vnd.awslambda.http-integration-response")return r=!0,i("Content-Type",x.contentType.json);o=h}return i(m,h)};let d=!1;return n.write=(m,h,p)=>{if(n.headersSent)return s(m,h,p);if(d)try{let g=A.codec.decode(m),y=JSON.parse(g);if(Array.isArray(y))throw new Error("Invalid stream response");return y&&typeof y=="object"?(c(),s(m,h,p)):(t.writeHead(200,{"Content-Type":x.contentType.octet}),t.end())}catch(g){let y=new Error(`When using HttpResponseStream first chunk of .write() must be valid JSON and not be Array. Number and null will respones with 200.
11
11
  '${e.name}'`);return y.cause=g.message,console.error(y),Z(t)}else if(r)Ce(m)?d=!0:l(m);else{if(o==x.contentType.json)try{let y=A.codec.decode(m),f=JSON.parse(y);if(f===null||typeof f=="number")throw new Error(y)}catch(y){let f=new Error(`When 'Content-Type' is 'application/json' first chunk of .write() must be parsable JSON and not be null or number.
12
12
  '${e.name}'`);return f.cause=y.message,console.error(f),Z(t)}let g={"Content-Type":o??x.contentType.octet};return n.writeHead(200,g),s(m,h,p)}},n}},In=(t,e,n,r)=>{let s=K(t),i=s?t.getParsedResponse():t,o,a=!1;if(i&&typeof i=="object"&&i.statusCode){let l=isNaN(i.statusCode),c=l?500:i.statusCode;if(a=!l&&(i.isBase64Encoded==!0||i.isBase64Encoded=="true"),i.headers||i.cookies)try{let d=ge(i.headers,i.cookies,r);e.writeHead(c,d)}catch(d){return e.writeHead(500,d.headers),delete d.headers,console.error(d),e.end(x.amzMsgNull)}else e.writeHead(c,{"Content-Type":x.contentType.json,...r});n?o=i:(typeof i.body<"u"&&(o=i.body),e.headersSent||e.setHeader("Content-Type",s?x.contentType.octet:x.contentType.json))}else e.writeHead(200,{"Content-Type":x.contentType.json,...r}),o=i;!e.headersSent&&!n&&s&&e.setHeader("Content-Type",x.contentType.octet),n?o instanceof Uint8Array?e.end(o):e.end(JSON.stringify(o)):((typeof o=="number"||typeof o=="boolean"||o==null||o instanceof Object)&&(o=JSON.stringify(o)),o&&a&&(o=Buffer.from(o,"base64")),e.end(o))};function An(t,e){let n=t["access-control-request-method"];return e=="OPTIONS"&&t.origin&&n&&["GET","HEAD","POST","PUT","DELETE","PATCH"].includes(n)}function St(t,e){let n=e.origin;return n&&t.allowOrigins.find(s=>s=="*"||s=="http://*"||s=="https://*")?!0:!!t.allowOrigins.find(s=>s==n)}function kn(t,e){if(!t.allowMethods?.length)return!1;if(t.allowMethods.find(s=>s=="*"))return!0;let r=e["access-control-request-method"];return!!t.allowMethods.find(s=>s==r)}function Pn(t,e){if(!kn(t,e)||!St(t,e))return!1;let n=e["access-control-request-headers"]?e["access-control-request-headers"].split(",").filter(Boolean):[];return n.length?t.allowHeaders?.length?n.every(r=>t.allowHeaders.find(s=>s.toLowerCase()==r.toLowerCase())):!1:!0}var vt=t=>({filter:/^\/@url\//,callback:async(e,n)=>{let{url:r,method:s,headers:i}=e;if(He(n,s))return;let o=new URL(r,x.dummyHost),a=F(n),l=k.parseNameFromUrl(o.pathname),c=t.handlers.find(f=>f.name==l);if(!c?.url)return n.statusCode=404,n.end("Not Found");let d;if(c.url.cors){if(An(i,s)){let v=Pn(c.url.cors,i),u={"Content-Type":x.contentType.json};return v&&(u["access-control-allow-origin"]=i.origin,c.url.cors.allowMethods.find(S=>S=="*")?u["access-control-allow-methods"]=i["access-control-request-method"]:u["access-control-allow-methods"]=c.url.cors.allowMethods.join(","),c.url.cors.allowHeaders?.length&&(u["access-control-allow-headers"]=c.url.cors.allowHeaders.join(",")),typeof c.url.cors.maxAge=="number"&&c.url.cors.maxAge>-1&&(u["access-control-max-age"]=`${c.url.cors.maxAge}`),c.url.cors.allowCredentials&&(u["access-control-allow-credentials"]="true")),n.writeHead(200,u),n.end()}St(c.url.cors,i)&&(d={"access-control-allow-origin":i.origin},c.url.cors.exposeHeaders?.length&&(d["access-control-expose-headers"]=c.url.cors.exposeHeaders.join(",")),c.url.cors.allowCredentials&&(d["access-control-allow-credentials"]="true"))}let m=x.getIsBase64Encoded(i),h=await D(e,m),p=le.createApgV2Event({req:e,mockEvent:c.url,parsedURL:o,requestId:a,body:h,isBase64Encoded:m}),g=`/@url/${c.name}`,y=o.pathname.slice(g.length);y||(y="/"),p.requestContext.accountId="anonymous",p.rawPath=y,p.requestContext.http.path=y;try{let f=Rn(n,c),v=await c.invoke(p,c.url,void 0,f);if(!v)return n.end();In(v,n,f,d)}catch(f){console.error(f),Z(n,d)}}});var xt=t=>({filter:/(^\/2015-03-31\/functions\/.*\/invocations)|(^\/@invoke\/)/,callback:async(e,n)=>{let{url:r,headers:s}=e,i=new URL(r,"http://localhost:3003"),o=k.parseNameFromUrl(i.pathname),a=t.handlers.find(f=>f.name==o),l=F(n);if(n.setHeader("Content-Type","application/json"),e.on("error",f=>{n.statusCode=502,n.end(JSON.stringify(f))}),!a){let{region:f,accountId:v}=t.aws;return n.statusCode=404,n.setHeader("x-amzn-errortype","ResourceNotFoundException"),n.end(X(o,f,v))}let c=s["x-amz-invocation-type"],d=J(s["x-amz-client-context"]);if(d instanceof Error)return n.setHeader("x-amzn-errortype","InvalidRequestContentException"),n.statusCode=400,n.end(Y);let m=c=="DryRun"?204:c=="Event"?202:200,h=await D(e),p=Q(h);if(n.setHeader("X-Amzn-Trace-Id","root=1-xxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx;sampled=0"),p instanceof Error)return n.statusCode=400,n.setHeader("x-amzn-errortype","InvalidRequestContentException"),n.end(G(p.message));n.setHeader("X-Amz-Executed-Version","$LATEST");let g=new Date,y={};n.statusCode=m,m!==200&&n.end(),m==202&&(y.kind="async");try{let f=await a.invoke(p,y,d);if(m==200){if(typeof f>"u"){n.end();return}let v=K(f),u=v?f.buffer:f;v?u=A.codec.decode(u):typeof u!="string"&&(u=JSON.stringify(u)),n.end(u)}}catch(f){n.writableFinished||(n.setHeader("X-Amz-Function-Error",f.errorType??f.message??""),n.statusCode=200,n.end(JSON.stringify(f)))}}});var Se=require("node:crypto"),wt=require("node:timers/promises");var Et=t=>({filter:"/2015-03-31/functions",method:"POST",async callback(e,n){let r=await D(e),s=JSON.parse(r),{FunctionName:i,Handler:o,Environment:a,Runtime:l,Timeout:c,MemorySize:d}=s;t.addLambda(i,{handler:o,environment:a?.Variables,runtime:l,timeout:c,memorySize:d}),t.isDynamicBuild=!0,t.setEsBuildConfig(),await t.buildContext.dispose(),await t.buildAndWatch(),await(0,wt.setTimeout)(100),n.statusCode=201,n.end(r)}}),Rt=t=>({filter:/\/2015-03-31\/functions\/*/,method:"GET",async callback(e,n){let{url:r}=e,i=new URL(r,"http://localhost:3003").pathname.slice(22),o=t.getLambdaByName(i);if(!o){n.statusCode=404,n.end();return}let a={Code:{RepositoryType:"S3",Location:"https://s3.com/snapshots/1234543"},Tags:{},Configuration:{Architectures:["arm64"],CodeSha256:"WrLckXVmmfsSPvP/15FqPi9Nt9qQBaspP6RV3T137K4=",SigningJobArn:"",FunctionArn:`arn:aws:lambda:${t.aws.region}:${t.aws.accountId}:function:${i}`,FunctionName:i,Handler:o.handlerPath,Timeout:o.timeout,Runtime:o.runtime,MemorySize:o.memorySize,Environment:{Variables:It(o.environment)},State:"Active",LastUpdateStatus:"Successful",LastModified:new Date().toISOString(),Version:"$LATEST",Role:`arn:aws:iam::${t.aws.accountId}:role/fake-role-name`,RevisionId:(0,Se.randomUUID)(),PackageType:"Zip",Description:"",EphemeralStorage:{Size:512},TracingConfig:{Mode:"PassThrough"},VpcConfig:{Ipv6AllowedForDualStack:!1,VpcId:"",SecurityGroupIds:[],SubnetIds:[]},CodeSize:5867,SnapStart:{OptimizationStatus:"Off",ApplyOn:"None"},LoggingConfig:{LogFormat:"Text",LogGroup:`/aws/lambda/${i}`}}};n.end(JSON.stringify(a))}}),Ln=["AWS_EXECUTION_ENV","AWS_LAMBDA_FUNCTION_VERSION","AWS_LAMBDA_FUNCTION_NAME","_HANDLER","IS_OFFLINE","IS_LOCAL","AWS_SAM_LOCAL","AWS_LAMBDA_FUNCTION_MEMORY_SIZE"];function It(t){let e={};for(let[n,r]of Object.entries(t))Ln.includes(n)||(e[n]=String(r));return e}var At=t=>({method:"GET",filter:/\/2015-03-31\/functions\/.*\/versions/,async callback(e,n){let{url:r}=e,i=new URL(r,"http://localhost:3003").pathname.slice(22);i=i.slice(0,i.indexOf("/"));let o=t.getLambdaByName(i);if(!o){n.statusCode=404,n.end();return}let a={Versions:[{Architectures:["arm64"],CodeSha256:"WrLckXVmmfsSPvP/15FqPi9Nt9qQBaspP6RV3T137K4=",SigningJobArn:"",FunctionArn:`arn:aws:lambda:${t.aws.region}:${t.aws.accountId}:function:${i}`,FunctionName:i,Handler:o.handlerPath,Timeout:o.timeout,Runtime:o.runtime,MemorySize:o.memorySize,Environment:{Variables:It(o.environment)},State:"Active",LastUpdateStatus:"Successful",LastModified:new Date().toISOString(),Version:"$LATEST",Role:`arn:aws:iam::${t.aws.accountId}:role/fake-role-name`,RevisionId:(0,Se.randomUUID)(),PackageType:"Zip",Description:"",EphemeralStorage:{Size:512},TracingConfig:{Mode:"PassThrough"},VpcConfig:{Ipv6AllowedForDualStack:!1,VpcId:"",SecurityGroupIds:[],SubnetIds:[]},CodeSize:5867,SnapStart:{OptimizationStatus:"Off",ApplyOn:"None"},LoggingConfig:{LogFormat:"Text",LogGroup:`/aws/lambda/${i}`}}]};n.end(JSON.stringify(a))}}),kt=t=>({method:"GET",filter:/\/2020-06-30\/functions\/.*\/code-signing-config/,async callback(e,n){let{url:r}=e,i=new URL(r,"http://localhost:3003").pathname.slice(22);if(i=i.slice(0,i.indexOf("/")),!t.getLambdaByName(i)){n.statusCode=404,n.end();return}let a={CodeSigningConfigArn:"",FunctionName:i};n.end(JSON.stringify(a))}});var Pt=require("@smithy/eventstream-codec");var Nn=(t,e)=>{let n=Buffer.from(t,e);return new Uint8Array(n.buffer,n.byteOffset,n.byteLength/Uint8Array.BYTES_PER_ELEMENT)},Dn=t=>Buffer.from(t,t.byteOffset,t.byteLength).toString("utf8"),ve=new Pt.EventStreamCodec(Dn,Nn),de=class t{res;static complete=Buffer.from([0,0,0,102,0,0,0,84,31,86,200,105,11,58,101,118,101,110,116,45,116,121,112,101,7,0,14,73,110,118,111,107,101,67,111,109,112,108,101,116,101,13,58,99,111,110,116,101,110,116,45,116,121,112,101,7,0,16,97,112,112,108,105,99,97,116,105,111,110,47,106,115,111,110,13,58,109,101,115,115,97,103,101,45,116,121,112,101,7,0,5,101,118,101,110,116,123,125,112,6,212,103]);constructor(e){this.res=e}write(e,n,r){this.res.write(ve.encode({headers:this.#e("PayloadChunk",x.contentType.octet),body:e}),n,r)}end(e){e?this.write(e,"utf8",()=>{this.res.end(t.complete)}):this.res.end(t.complete)}setHeader(e,n){e=="Content-Type"&&this.res.setHeader("Content-Type",n)}destroy(){this.res.destroy()}endWithError(e){let n={ErrorCode:e.errorType,ErrorDetails:JSON.stringify(e)},r=Array.from(Buffer.from(JSON.stringify(n)).values());this.res.end(ve.encode({headers:this.#e("InvokeComplete",x.contentType.json),body:new Uint8Array(r)}))}endWithJson(e){let n=Array.from(Buffer.from(JSON.stringify(e)).values());this.res.write(ve.encode({headers:this.#e("PayloadChunk",x.contentType.octet),body:new Uint8Array(n)}),()=>{this.res.end(t.complete)})}#e(e,n,r="event"){return{":event-type":{type:"string",value:e},":content-type":{type:"string",value:n},":message-type":{type:"string",value:r}}}};var Ot=t=>({filter:/^\/2021-11-15\/functions\//,callback:async(e,n)=>{let{url:r,headers:s}=e,i=new URL(r,"http://localhost:3003"),o=F(n),a=k.parseNameFromUrl(i.pathname),l=t.handlers.find(p=>p.name==a),c=await D(e),d=Q(c);if(n.setHeader("X-Amzn-Trace-Id","root=1-xxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx;sampled=0"),d instanceof Error)return n.statusCode=400,n.setHeader("x-amzn-errortype","InvalidRequestContentException"),n.end(G(d.message));let m=J(s["x-amz-client-context"]);if(m instanceof Error)return n.setHeader("x-amzn-errortype","InvalidRequestContentException"),n.statusCode=400,n.end(Y);let h=new de(n);if(l){let p=l.url?.stream??{};try{let g=await l.invoke(d,p,m,h);g&&h.endWithJson(g)}catch(g){n.writableFinished||h.endWithError(g)}}else{let{region:p,accountId:g}=t.aws;n.statusCode=404,n.end(X(a,p,g))}}});var Lt=t=>[Et(t),At(t),kt(t),xt(t),Ot(t),vt(t),Rt(t)];var we=process.cwd(),Tn=3,Mn=1024,qn={IS_OFFLINE:!0,IS_LOCAL:!0,AWS_SAM_LOCAL:!0},jn=we.split(O.default.sep)[0],Fn=new RegExp(`^.*:${jn}`),Hn=t=>Fn.test(t);process.title="node (exlo)";var pe=class extends ce{#e;options;config;esBuildConfig;buildContext={};customEsBuildConfig;optimizeBuild=!1;nodeVersion=!1;onKill=[];shimRequire=!1;port=0;onceServerReady=[];isDynamicBuild=!1;endpoints={};setLambdaEndpointEnvVar=!0;constructor(e,n){super(e,{debug:typeof n.debug=="boolean"?n.debug:!1}),this.#e=[],this.options=n,this.options.customEsBuildConfig&&(this.customEsBuildConfig=this.options.customEsBuildConfig),typeof this.options.config?.server?.setEndpointEnvVar=="boolean"&&(this.setLambdaEndpointEnvVar=this.options.config.server.setEndpointEnvVar),this.options.config&&(typeof this.options.config=="string"||typeof this.options.config=="object"&&!Array.isArray(this.options.config))&&(this.config=this.options.config),typeof this.options.optimizeBuild=="boolean"&&(this.optimizeBuild=this.options.optimizeBuild),typeof this.options.shimRequire=="boolean"&&(this.shimRequire=this.options.shimRequire),this.aws.runtime?.startsWith("node")?this.nodeVersion=this.aws.runtime?.replace(/[^0-9]/g,""):this.nodeVersion="20",b.BR_BLUE("Starting exlo...")}async start(){this.#s(),this.#e=this.#r(),await this.#o(),this.setEsBuildConfig(),await this.buildAndWatch()}setEsBuildConfig(){let n={sourcemap:!0,minify:!1,entryPoints:this.#e.filter(r=>r.runtime.startsWith("n")).map(r=>r.esEntryPoint),outdir:O.default.join(we,".exlo","build"),metafile:!0,bundle:!0,platform:"node",target:"node20",format:"cjs",outbase:"src",plugins:[],external:["esbuild"],dropLabels:[]};if(typeof process.env.NODE_ENV=="string"&&(n.define={"process.env.NODE_ENV":`"${process.env.NODE_ENV}"`}),typeof this.nodeVersion=="string"&&!isNaN(Number(this.nodeVersion))){Number(process.versions.node.slice(0,2))<Number(this.nodeVersion)&&b.RED(`You are running on NodeJS ${process.version} which is lower than defined '${this.nodeVersion}'.`),n.target=`node${this.nodeVersion}`;let r=()=>this.sco;n.plugins?.push(ke({nodeVersion:Number(this.nodeVersion),shimRequire:this.shimRequire,optimizeBuild:this.optimizeBuild,buildCallback:this.buildCallback,getSockets:r}))}this.customEsBuildConfig&&(n=Pe(n,this.customEsBuildConfig)),this.esBuildConfig=n}async buildAndWatch(){this.buildContext=await xe.default.context(this.esBuildConfig),await this.buildContext.watch()}buildCallback=async(e,n)=>{if(n||this.isDynamicBuild)await this.#t(e);else{let{outputs:r}=e.metafile;if(this.#i(r),this.customBuildCallback)try{await this.customBuildCallback(e,!1)}catch(o){console.log(o)}this.#a();let s=this,i=await new Promise(o=>{this.listen(this.port,async(a,l)=>{let c=`http://localhost:${a}`;b.PINK(`Lambda endpoint: ${c}`),this.endpoints.lambda=c,this.setLambdaEndpointEnvVar&&(this.runtimeConfig.environment.AWS_ENDPOINT_URL_LAMBDA=c),await s.load(s.#e);for(let d of s.#e)d.setEnv("LOCAL_PORT",a),d.setEnv("AWS_LAMBDA_RUNTIME_API",`127.0.0.1:${a}`),this.setLambdaEndpointEnvVar&&d.setEnv("AWS_ENDPOINT_URL_LAMBDA",c);o({url:c,port:a})})});this.onceServerReady.forEach(o=>{o(i)})}};async#t(e){if(e?.errors?.length)b.RED("Build failed:"),console.error(e.errors);else{this.#i(e.metafile.outputs);try{await this.load(this.#e),this.customBuildCallback&&await this.customBuildCallback(e,!0)}catch(n){console.error(n)}console.log(`\x1B[32m${new Date().toLocaleString()} \u{1F504}\u2705 Rebuild\x1B[0m`)}}#n(e){let n=this.aws,r=n.runtime,s=this.runtimeConfig.environment.AWS_REGION??this.runtimeConfig.environment.REGION,o=n.functions[e],a=o.handler,l=O.default.extname(a),c=l.slice(1),d=O.default.resolve(a.replace(l,"")),m=n.getFunction(e),h=m.runtime??r,p={name:e,runtime:m.runtime??r,handlerPath:a,handlerName:c,esEntryPoint:d,memorySize:o.memorySize??this.runtimeConfig.memorySize??Mn,timeout:o.timeout??this.runtimeConfig.timeout??Tn,sqs:[],ddb:[],environment:{AWS_EXECUTION_ENV:`AWS_Lambda_${h}`,AWS_LAMBDA_FUNCTION_VERSION:"$LATEST",AWS_LAMBDA_FUNCTION_NAME:e,_HANDLER:O.default.basename(a),...this.runtimeConfig.environment,...o.environment,...qn},invoke:async(g,y)=>{let f=this.getHandlerByName(`/@invoke/${e}`);if(f)return await f.invoke(g,y);b.RED(`'${e}' is not mounted yet.
@@ -6,7 +6,7 @@ Please verify provided SQS Client validity.`),console.error(d)}}},Nt=/(-|\w+)/g,
6
6
  `)}else I=R;I.trim()&&console.log(I)}}catch(P){console.log("err",P),y(P)}};this.python.stdout.on("data",u);let S=w=>{let E=w.toString();if(E.includes(t.ERR_RESPONSE))try{E=JSON.parse(E.split(t.ERR_RESPONSE)[1]),E.requestId=p}catch{}finally{this.python.stdout.removeListener("data",u),this.python.stderr.removeListener("data",S),y(E)}else console.log(E)};this.python.stderr.on("data",S),this.python.stdin.write(`${f}
7
7
  `)}),this.watcherListener=()=>{this.isMounted&&(this.unmount(!0),this.watchers.forEach(d=>d.close()),this.watchers=[],this.emitRebuild())}}setWatchFiles=async e=>{try{let n=e.split(t.WATCH),s=n[n.length-1].split(t.WATCHEND)[0],i=JSON.parse(s).map(o=>`${o.replace(/\./g,_.sep)}.py`);for(let o of i)try{await Ue(o),this.watchers.push(Bt(o,{persistent:!1},this.watcherListener))}catch{}}catch(n){console.log(n)}};findPython(){let[e]=this.runtime.split("."),n=e.split("python")[1];if(We(`${e} --version`))return e;let r=We("python --version");if(!r)throw new Error("Can not find python on your OS. Make sure it is installed.");if(n){let s=r.split(" ")[1]?.split(".")[0];s&&s!=n&&b.YELLOW("found python binary but with different version")}return"python"}load=()=>{this.bin||(this.bin=this.findPython()),this.python=Vt(this.bin,["-u",t.wrapper,this.handlerFileAbsolutePath,this.pyModulePath,this.handlerName,String(this.timeout)],{env:this.environment}),this.python.pid||(console.error(`Can not find ${this.bin} in your PATH`),process.exit(1)),this.isMounted=!0};onComplete=e=>{}};import{spawn as Qt}from"node:child_process";import{watch as Kt}from"node:fs";import{access as ze}from"node:fs/promises";import ne from"node:path";var re=class t{invoke;mount;unmount;name;timeout;memorySize;environment;handlerPath;modulePath;handlerDir;handlerName;runtime;bin;ruby;isMounted=!1;emitRebuild;watcherListener;watchers=[];static wrapper=ne.resolve(M("exlo"),"./src/lib/runtime/runners/ruby/index.rb");static DELIMITER="__|response|__";static ERR_RESPONSE="__|error|__";static WATCH="__|watch|__";constructor({name:e,timeout:n,memorySize:r,environment:s,handlerPath:i,handlerName:o,runtime:a},l){this.name=e,this.timeout=n,this.memorySize=r,this.environment=s,this.handlerName=o,this.runtime=a,this.emitRebuild=l;let c=ne.resolve(i);this.handlerDir=ne.dirname(c),this.handlerPath=ne.basename(c,`.${this.handlerName}`),this.modulePath=`${this.handlerDir}/${this.handlerPath}.rb`,this.mount=async()=>{if(!this.ruby)try{await ze(this.modulePath),this.load()}catch{console.error(`Can not find ${this.name}'s handler at: "${this.modulePath}"`),process.exit(1)}},this.unmount=d=>{d&&(this.ruby?.kill(),this.ruby=void 0,this.isMounted=!1)},this.invoke=async({event:d,info:m,clientContext:h,awsRequestId:p})=>new Promise((g,y)=>{let f=JSON.stringify({event:d,awsRequestId:p,context:h??""}),v=S=>{let w=null,E=S.toString();try{if(E.includes(t.WATCH))this.setWatchFiles(E);else if(E.includes(t.DELIMITER)){let R=E.split(t.DELIMITER),P=R[R.length-1];if(R.length>1){let I=R.slice(0,-1).join(`
8
8
  `);I.trim()&&console.log(I)}P&&(w=JSON.parse(P)),this.ruby.stdout.removeListener("data",v),this.ruby.stderr.removeListener("data",u),g(w)}else E.trim()&&console.log(E)}catch(R){y(R)}};this.ruby.stdout.on("data",v);let u=S=>{let w=S.toString();if(w.includes(t.ERR_RESPONSE))try{w=JSON.parse(w.split(t.ERR_RESPONSE)[1]),w.requestId=p}catch{}finally{this.ruby.stdout.removeListener("data",v),this.ruby.stderr.removeListener("data",u),y(w)}else console.log(w)};this.ruby.stderr.on("data",u),this.ruby.stdin.write(`${f}
9
- `)}),this.watcherListener=()=>{this.isMounted&&(this.unmount(!0),this.watchers.forEach(d=>d.close()),this.watchers=[],this.emitRebuild())}}setWatchFiles=async e=>{try{let n=e.split(t.WATCH),r=n[n.length-1],s=JSON.parse(r);s.push(this.modulePath);for(let i of s)try{await ze(i),this.watchers.push(Kt(i,{persistent:!1},this.watcherListener))}catch{}}catch(n){console.log(n)}};load=()=>{this.bin||(this.bin=process.platform==="win32"?"ruby.exe":"ruby"),this.ruby=Qt(this.bin,[t.wrapper,this.modulePath,this.handlerName,this.name,String(this.timeout)],{env:this.environment,shell:!0}),this.ruby.pid||(console.error(`Can not find ${this.bin} in your PATH`),process.exit(1)),this.isMounted=!0};onComplete=e=>{}};var Gt=["@invoke","@url"],k=class t{handlers=[];static ip="127.0.0.1";debug=!1;port=0;constructor(e){this.debug=e.debug}static parseNameFromUrl(e){let n=e.split("/"),r=Gt.includes(n[1])?n[2]:n[3];if(r=decodeURIComponent(r),r.includes(":function:")){let s=r.split(":function:");r=s[s.length-1]}if(r.includes(":")){let s=r.split(":");s.length==2&&(r=s[0])}return r}getHandlerByName(e){if(!e)return;let n=t.parseNameFromUrl(e);return this.handlers.find(r=>r.name==n)}addHandler(e){let n=this.handlers.findIndex(r=>r.name==e.name&&r.esOutputPath==e.esOutputPath);n==-1?(this.handlers.push(e),this.#e("POST",`/2015-03-31/functions/${e.name}/invocations`),e.url&&this.#e("ANY",`/@url/${e.name}`,"34")):this.handlers[n].runtime.startsWith("n")&&(this.handlers[n].clear(),this.handlers[n]=e)}#e(e,n,r="90"){let s=`${e} http://localhost:${this.port}${n}`;console.log(`\x1B[${r}m${s}\x1B[0m`)}};var se;Ve&&(se=Object.values(Ve()).reduce((t,e)=>(t.push(...e),t),[])?.filter(t=>!t.internal&&t.family==="IPv4").find(Boolean)?.address);var en=Zt?.url()!=null;en&&(console.warn("Lambdas timeout are disabled when a Debugger is attached"),H.ENABLE_TIMEOUT=!1);var tn={errors:[],warnings:[],outputFiles:[],metafile:{inputs:{},outputs:{}},mangleCache:{}},ie=class extends k{#e;runtimeConfig={};#t;sco=[];aws;customOfflineRequests=[];customBuildCallback;onReady;stop(e){this.#e.close(e)}constructor(e,n={debug:!1}){super(n),b.setDebug(n.debug),this.aws=e.aws,this.sco=[],this.#e=Xt.createServer({maxHeaderSize:105536},this.#r.bind(this)),this.#e.on("connection",s=>{s.on("close",()=>{let i=this.sco.findIndex(o=>o==s);i!=-1&&this.sco.splice(i,1)}),this.sco.push(s)});let r=Yt();x.accountId=Buffer.from(r).toString("hex").slice(0,16),x.apiId=Buffer.from(r).toString("ascii").slice(0,10),x.port=this.port}setPort(e){this.port=e,x.port=e}listen(e=0,n){if(isNaN(e))throw Error("port should be a number");this.#e.once("error",async r=>{r.code==="EADDRINUSE"?(b.RED(r.message),process.exit(1)):console.log(r)}),this.#e.listen(e,async()=>{let{port:r,address:s}=this.#e.address();this.setPort(r),se&&(k.ip=se),typeof n=="function"&&await n(r,se);try{await this.onReady?.(r,k.ip),await je(this.handlers,this.aws)}catch(i){console.error(i)}})}#n(e,n){n=n.endsWith("/")?n:`${n}/`;let r=this.customOfflineRequests.find(s=>{let i=!1,o=!0;return typeof s.filter=="string"?(s.filter.endsWith("/")||(s.filter+="/"),i=s.filter==n):s.filter instanceof RegExp&&(i=s.filter.test(n)),typeof s.method=="string"&&s.method.toUpperCase()!="ANY"?o=s.method.toUpperCase()==e:Array.isArray(s.method)&&(s.method.findIndex(l=>l.toUpperCase()=="ANY")!==-1||(o=s.method.findIndex(l=>l.toUpperCase()==e)!==-1)),i&&o});if(r)return r.callback}async#r(e,n){let{url:r,method:s}=e,i=new URL(r,x.dummyHost),o=this.#n(s,i.pathname);if(o)try{await o(e,n)}catch{n.writableFinished||n.end("Internal Server Error")}else{e.on("error",l=>{console.error(l.stack)});let a=()=>{n.setHeader("Content-Type","text/html"),n.statusCode=404,n.end(Ie)};this.#t?this.#t(e,n,a):a()}}fakeRebuildEmitter=async()=>{if(this.customBuildCallback)try{await this.customBuildCallback(tn,!0)}catch(e){console.log(e)}console.log(`\x1B[32m${new Date().toLocaleString()} \u{1F504}\u2705 Rebuild\x1B[0m`)};async load(e){for(let n of e){let r=n.runtime.charAt(0);n.runner=r=="n"?new ee(n):r=="p"?new te(n,this.fakeRebuildEmitter):r=="r"?new re(n,this.fakeRebuildEmitter):new Z(n.runtime);let s=new H(n);this.addHandler(s)}}};import{rm as sn}from"node:fs/promises";import N from"node:path";import{pathToFileURL as on}from"node:url";import an from"esbuild";var rn="0.0.13";function Be(t){let e=new Set;t.plugins&&(t.plugins=t.plugins.filter((r,s)=>typeof r!="object"||!r||!("name"in r)?!1:((!r.name||!r.name.length||typeof r.name!="string")&&(r.name=`plugin-${s}`,console.warn(`No Plugin name provided at index ${s}`)),e.has(r.name)?r.name=r.name+s:e.add(r.name),!0)));async function n({stop:r,lambdas:s,region:i,esbuild:o,getServices:a,setService:l,addLambda:c,log:d,setEndpoint:m,getEndpoint:h,getAwsProviderDefaults:p,setAwsProviderDefaults:g}){let y={build:{esbuild:t?.build?.esbuild??{},shimRequire:t?.build?.shimRequire,optimizeBuild:t?.build?.optimizeBuild},server:{port:t.server?.port,setEndpointEnvVar:t.server?.setEndpointEnvVar},onKill:[]};if(t.defaults&&typeof t.defaults=="object"&&!Array.isArray(t.defaults)&&g(t.defaults),t.functions&&typeof t.functions=="object"&&!Array.isArray(t.functions))for(let[v,u]of Object.entries(t.functions))c(v,u);t.services&&(t.services.sqs&&l("sqs",t.services.sqs),t.services.sns&&l("sns",t.services.sns),t.services.dynamodb&&l("dynamodb",t.services.dynamodb));let f={stop:r,lambdas:s,region:i,esbuild:o,options:t,config:y,getServices:a,setService:l,addLambda:c,log:d,setEndpoint:m,getEndpoint:h,getAwsProviderDefaults:p};if(t.plugins){y.server.onReady=async(u,S)=>{for(let w of t.plugins)if(w.server?.onReady)try{await w.server.onReady.call(f,u,S)}catch(E){d.RED(w.name),console.error(E)}},y.buildCallback=async(u,S)=>{for(let w of t.plugins)if(w.buildCallback)try{await w.buildCallback.call(f,u,S)}catch(E){d.RED(w.name),console.error(E),S||process.exit(1)}};let v=t.plugins.reduce((u,S)=>(S.server?.request?.length&&u.push(...S.server.request),u),[]);v?.length&&(y.server.request=v.map(u=>(u.callback=u.callback.bind(f),u)));for(let u of t.plugins)if(u.onKill&&y.onKill.push(u.onKill.bind(f)),u.onInit)try{await u.onInit.call(f)}catch(S){throw d.RED(u.name),S}}return y}return n.plugins=t.plugins??[],n}var cn=["js","mjs","cjs","ts","cts","mts"],ln=async t=>{let e=N.dirname(N.toNamespacedPath(t)),n=N.basename(t,N.extname(t)),r=N.join(e,`__${n}.mjs`);await an.build({outfile:r,entryPoints:[t],bundle:!0,packages:"external",platform:"node",format:"esm",target:`node${process.versions.node.split(".")[0]}`,minify:!0,sourcemap:"inline",sourcesContent:!0});try{return await import(on(r).href)}catch(s){throw s}finally{await sn(r)}},Je=async t=>{if(t){if(typeof t=="string"){let e=N.posix.parse(t),n=N.posix.join(e.dir,e.name),r=e.ext.slice(1),s=N.posix.resolve(n);cn.includes(r)&&(s+=`.${r}`);let i;try{i=await ln(s)}catch(o){b.YELLOW(`Can not read 'defineConfig' from ${t}`),console.error(o),process.exit(1)}return{exportedFunc:i,configObjectName:r,configPath:s}}if(typeof t=="object"&&!Array.isArray(t))return{configObjectName:"__inline_config__",configPath:"inline define config",exportedFunc:Be(t)}}};var dn=t=>{let e=t.split(";");return e.findIndex(r=>r.trim().toLowerCase().startsWith("path="))==-1&&e.push("Path=/"),e.join(";")},de=(t,e,n)=>{let r={};if(t&&Object.entries(t).forEach(([s,i])=>{r[s.toLowerCase()]=Array.isArray(i)?`[${i.join(", ")}]`:i}),n)for(let[s,i]of Object.entries(n))r[s]=i;if(!Array.isArray(e))return r;if(!e.every(s=>typeof s=="string")){let s=new Error("Wrong 'cookies'. must be string[]",{cause:e}),i={"Content-Type":r["content-type"]??"application/json","x-amzn-ErrorType":"InternalFailure",...n};throw r["set-cookie"]&&(i["set-cookie"]=r["set-cookie"]),s.headers=i,s}return e=e.map(dn),r["set-cookie"]=r["set-cookie"]?[r["set-cookie"],...e]:e,r};import{randomUUID as Qe}from"node:crypto";var oe=class t extends x{res;mockEvent;payload;constructor({res:e,req:n,body:r,mockEvent:s,multiValueHeaders:i,isBase64Encoded:o,lambdaName:a,parsedURL:l,requestId:c}){super(),this.res=e,this.mockEvent=s,this.payload=s.version==1?t.createApgV1Event({req:n,mockEvent:s,parsedURL:l,lambdaName:a,multiValueHeaders:i,isBase64Encoded:o,requestId:c,body:r}):t.createApgV2Event({req:n,mockEvent:s,parsedURL:l,requestId:c,isBase64Encoded:o,body:r})}static skipHeaders=["connection","content"];static createApgV2Event=({req:e,mockEvent:n,parsedURL:r,requestId:s,isBase64Encoded:i,body:o})=>{let{method:a,headers:l}=e,c=t.getPathParameters(n,r),d,m=n.methods.find(S=>S==a)??"ANY",h={},p="";for(let S of Array.from(new Set(r.searchParams.keys()))){let w=r.searchParams.getAll(S);p+=`&${w.map(E=>encodeURI(`${S}=${E}`)).join("&")}`,h[S]=w.join(",")}p&&(p=p.slice(1));let g=n.paths[0]=="/*"?"$default":`${m} ${r.pathname}`,y=new Date,f="127.0.0.1",v=l.host?.startsWith("localhost")?f:l.host?l.host.split(":")[0]:f,u={version:"2.0",routeKey:g,rawPath:r.pathname,rawQueryString:p,headers:t.getCustomHeaders(e,n),requestContext:{accountId:String(t.accountId),apiId:t.apiId,domainName:`localhost:${t.port}`,domainPrefix:"localhost",http:{method:a,path:r.pathname,protocol:"HTTP/1.1",sourceIp:v,userAgent:l["user-agent"]??""},requestId:s,routeKey:g,stage:"$default",time:y.toISOString(),timeEpoch:y.getTime()}};return o?(u.body=o,u.isBase64Encoded=i):u.isBase64Encoded=!1,Object.keys(h).length&&(u.queryStringParameters=h),Object.keys(c).length&&(u.pathParameters=c),l.cookie&&(u.cookies=l.cookie.split("; ")),d=u,d.headers["x-mock-type"]&&delete d.headers["x-mock-type"],d};static createApgV1Event=({req:e,mockEvent:n,parsedURL:r,lambdaName:s,isBase64Encoded:i,requestId:o,body:a})=>{let{method:l}=e,c={};n.proxy=="httpApi"&&(c.version="1.0");let d=n.paths[0];c.resource=d,c.path=r.pathname,c.httpMethod=l;let{headers:m,multiValueHeaders:h,apiKey:p}=t.getApiGV1Headers(e,n);c.headers=m,c.multiValueHeaders=h;let g=String(e.socket.remoteAddress),y=Object.fromEntries(r.searchParams);c.queryStringParameters=Object.keys(y).length?y:null;let f=t.getMultiValueQueryStringParameters(r.searchParams);c.multiValueQueryStringParameters=Object.keys(f).length?f:null;let v=new Date,u={accountId:String(t.accountId),apiId:t.apiId,domainName:`localhost:${t.port}`,domainPrefix:"localhost",extendedRequestId:"fake-id",httpMethod:l,identity:{accessKey:null,accountId:null,caller:null,cognitoAuthenticationProvider:null,cognitoAuthenticationType:null,cognitoIdentityId:null,cognitoIdentityPoolId:null,principalOrgId:null,sourceIp:g,user:null,userAgent:e.headers["user-agent"],userArn:null},path:r.pathname,protocol:"HTTP/1.1",requestId:o,requestTime:v.toISOString(),requestTimeEpoch:v.getTime(),resourceId:"exhmtv",resourcePath:d};n.proxy=="httpApi"?(u.identity.cognitoAmr=null,u.stage="$default"):(u.stage="dev",n.private&&(u.identity.apiKey=p,u.identity.apiKeyId="abcdefghjk")),c.requestContext=u;let S=t.getPathParameters(n,r);return c.pathParameters=Object.keys(S).length?S:null,c.stageVariables=null,c.body=a??null,c.isBase64Encoded=a?i:!1,c};returnError=e=>{if(this.res.writableFinished)return!0;let n=500,r=t.httpErrMsg;e&&t.isEndpointTimeoutError(e.errorMessage)&&(this.mockEvent.proxy=="httpApi"?(n=503,r=t.unavailable):(n=504,r=t.apgTimeoutMsg));let s=[["Date",new Date().toUTCString()],["Content-Type",t.contentType.json],["Content-Length",String(r.length)],t.keepAlive,["Apigw-Requestid","ETuSEj-PiGYEJdQ="]];return this.res.shouldKeepAlive=!1,this.res.writeHead(n,s),this.res.end(r)};#e=e=>{let n="",r=typeof e;if(r=="string"||r=="number"||r=="boolean")n=String(e);else if(e===null)n="";else throw new Error("");return n};sendV1Response=e=>{let n=[["Date",new Date().toUTCString()],["Apigw-Requestid",Buffer.from(Qe()).toString("base64").slice(0,16)],t.keepAlive],r=200;if(!e||isNaN(e.statusCode))throw b.RED(`Valid 'http' response payload must be an object which includes a valid 'statusCode'.
9
+ `)}),this.watcherListener=()=>{this.isMounted&&(this.unmount(!0),this.watchers.forEach(d=>d.close()),this.watchers=[],this.emitRebuild())}}setWatchFiles=async e=>{try{let n=e.split(t.WATCH),r=n[n.length-1],s=JSON.parse(r);s.push(this.modulePath);for(let i of s)try{await ze(i),this.watchers.push(Kt(i,{persistent:!1},this.watcherListener))}catch{}}catch(n){console.log(n)}};load=()=>{this.bin||(this.bin=process.platform==="win32"?"ruby.exe":"ruby"),this.ruby=Qt(this.bin,[t.wrapper,this.modulePath,this.handlerName,this.name,String(this.timeout)],{env:this.environment,shell:!0}),this.ruby.pid||(console.error(`Can not find ${this.bin} in your PATH`),process.exit(1)),this.isMounted=!0};onComplete=e=>{}};var Gt=["@invoke","@url"],k=class t{handlers=[];static ip="127.0.0.1";debug=!1;port=0;constructor(e){this.debug=e.debug}static parseNameFromUrl(e){let n=e.split("/"),r=Gt.includes(n[1])?n[2]:n[3];if(r=decodeURIComponent(r),r.includes(":function:")){let s=r.split(":function:");r=s[s.length-1]}if(r.includes(":")){let s=r.split(":");s.length==2&&(r=s[0])}return r}getHandlerByName(e){if(!e)return;let n=t.parseNameFromUrl(e);return this.handlers.find(r=>r.name==n)}addHandler(e){let n=this.handlers.findIndex(r=>r.name==e.name&&r.esOutputPath==e.esOutputPath);n==-1?(this.handlers.push(e),this.#e("POST",`/2015-03-31/functions/${e.name}/invocations`),e.url&&this.#e("ANY",`/@url/${e.name}`,"34")):this.handlers[n].runtime.startsWith("n")&&(this.handlers[n].clear(),this.handlers[n]=e)}#e(e,n,r="90"){let s=`${e} http://localhost:${this.port}${n}`;console.log(`\x1B[${r}m${s}\x1B[0m`)}};var se;Ve&&(se=Object.values(Ve()).reduce((t,e)=>(t.push(...e),t),[])?.filter(t=>!t.internal&&t.family==="IPv4").find(Boolean)?.address);var en=Zt?.url()!=null;en&&(console.warn("Lambdas timeout are disabled when a Debugger is attached"),H.ENABLE_TIMEOUT=!1);var tn={errors:[],warnings:[],outputFiles:[],metafile:{inputs:{},outputs:{}},mangleCache:{}},ie=class extends k{#e;runtimeConfig={};#t;sco=[];aws;customOfflineRequests=[];customBuildCallback;onReady;stop(e){this.#e.close(e)}constructor(e,n={debug:!1}){super(n),b.setDebug(n.debug),this.aws=e.aws,this.sco=[],this.#e=Xt.createServer({maxHeaderSize:105536},this.#r.bind(this)),this.#e.on("connection",s=>{s.on("close",()=>{let i=this.sco.findIndex(o=>o==s);i!=-1&&this.sco.splice(i,1)}),this.sco.push(s)});let r=Yt();x.accountId=Buffer.from(r).toString("hex").slice(0,16),x.apiId=Buffer.from(r).toString("ascii").slice(0,10),x.port=this.port}setPort(e){this.port=e,x.port=e}listen(e=0,n){if(isNaN(e))throw Error("port should be a number");this.#e.once("error",async r=>{r.code==="EADDRINUSE"?(b.RED(r.message),process.exit(1)):console.log(r)}),this.#e.listen(e,async()=>{let{port:r,address:s}=this.#e.address();this.setPort(r),se&&(k.ip=se),typeof n=="function"&&await n(r,se);try{await this.onReady?.(r,k.ip),await je(this.handlers,this.aws)}catch(i){console.error(i)}})}#n(e,n){n=n.endsWith("/")?n:`${n}/`;let r=this.customOfflineRequests.find(s=>{let i=!1,o=!0;return typeof s.filter=="string"?(s.filter.endsWith("/")||(s.filter+="/"),i=s.filter==n):s.filter instanceof RegExp&&(i=s.filter.test(n)),typeof s.method=="string"&&s.method.toUpperCase()!="ANY"?o=s.method.toUpperCase()==e:Array.isArray(s.method)&&(s.method.findIndex(l=>l.toUpperCase()=="ANY")!==-1||(o=s.method.findIndex(l=>l.toUpperCase()==e)!==-1)),i&&o});if(r)return r.callback}async#r(e,n){let{url:r,method:s}=e,i=new URL(r,x.dummyHost),o=this.#n(s,i.pathname);if(o)try{await o(e,n)}catch{n.writableFinished||n.end("Internal Server Error")}else{e.on("error",l=>{console.error(l.stack)});let a=()=>{n.setHeader("Content-Type","text/html"),n.statusCode=404,n.end(Ie)};this.#t?this.#t(e,n,a):a()}}fakeRebuildEmitter=async()=>{if(this.customBuildCallback)try{await this.customBuildCallback(tn,!0)}catch(e){console.log(e)}console.log(`\x1B[32m${new Date().toLocaleString()} \u{1F504}\u2705 Rebuild\x1B[0m`)};async load(e){for(let n of e){let r=n.runtime.charAt(0);n.runner=r=="n"?new ee(n):r=="p"?new te(n,this.fakeRebuildEmitter):r=="r"?new re(n,this.fakeRebuildEmitter):new Z(n.runtime);let s=new H(n);this.addHandler(s)}}};import{rm as sn}from"node:fs/promises";import N from"node:path";import{pathToFileURL as on}from"node:url";import an from"esbuild";var rn="0.0.14";function Be(t){let e=new Set;t.plugins&&(t.plugins=t.plugins.filter((r,s)=>typeof r!="object"||!r||!("name"in r)?!1:((!r.name||!r.name.length||typeof r.name!="string")&&(r.name=`plugin-${s}`,console.warn(`No Plugin name provided at index ${s}`)),e.has(r.name)?r.name=r.name+s:e.add(r.name),!0)));async function n({stop:r,lambdas:s,region:i,esbuild:o,getServices:a,setService:l,addLambda:c,log:d,setEndpoint:m,getEndpoint:h,getAwsProviderDefaults:p,setAwsProviderDefaults:g}){let y={build:{esbuild:t?.build?.esbuild??{},shimRequire:t?.build?.shimRequire,optimizeBuild:t?.build?.optimizeBuild},server:{port:t.server?.port,setEndpointEnvVar:t.server?.setEndpointEnvVar},onKill:[]};if(t.defaults&&typeof t.defaults=="object"&&!Array.isArray(t.defaults)&&g(t.defaults),t.functions&&typeof t.functions=="object"&&!Array.isArray(t.functions))for(let[v,u]of Object.entries(t.functions))c(v,u);t.services&&(t.services.sqs&&l("sqs",t.services.sqs),t.services.sns&&l("sns",t.services.sns),t.services.dynamodb&&l("dynamodb",t.services.dynamodb));let f={stop:r,lambdas:s,region:i,esbuild:o,options:t,config:y,getServices:a,setService:l,addLambda:c,log:d,setEndpoint:m,getEndpoint:h,getAwsProviderDefaults:p};if(t.plugins){y.server.onReady=async(u,S)=>{for(let w of t.plugins)if(w.server?.onReady)try{await w.server.onReady.call(f,u,S)}catch(E){d.RED(w.name),console.error(E)}},y.buildCallback=async(u,S)=>{for(let w of t.plugins)if(w.buildCallback)try{await w.buildCallback.call(f,u,S)}catch(E){d.RED(w.name),console.error(E),S||process.exit(1)}};let v=t.plugins.reduce((u,S)=>(S.server?.request?.length&&u.push(...S.server.request),u),[]);v?.length&&(y.server.request=v.map(u=>(u.callback=u.callback.bind(f),u)));for(let u of t.plugins)if(u.onKill&&y.onKill.push(u.onKill.bind(f)),u.onInit)try{await u.onInit.call(f)}catch(S){throw d.RED(u.name),S}}return y}return n.plugins=t.plugins??[],n}var cn=["js","mjs","cjs","ts","cts","mts"],ln=async t=>{let e=N.dirname(N.toNamespacedPath(t)),n=N.basename(t,N.extname(t)),r=N.join(e,`__${n}.mjs`);await an.build({outfile:r,entryPoints:[t],bundle:!0,packages:"external",platform:"node",format:"esm",target:`node${process.versions.node.split(".")[0]}`,minify:!0,sourcemap:"inline",sourcesContent:!0});try{return await import(on(r).href)}catch(s){throw s}finally{await sn(r)}},Je=async t=>{if(t){if(typeof t=="string"){let e=N.posix.parse(t),n=N.posix.join(e.dir,e.name),r=e.ext.slice(1),s=N.posix.resolve(n);cn.includes(r)&&(s+=`.${r}`);let i;try{i=await ln(s)}catch(o){b.YELLOW(`Can not read 'defineConfig' from ${t}`),console.error(o),process.exit(1)}return{exportedFunc:i,configObjectName:r,configPath:s}}if(typeof t=="object"&&!Array.isArray(t))return{configObjectName:"__inline_config__",configPath:"inline define config",exportedFunc:Be(t)}}};var dn=t=>{let e=t.split(";");return e.findIndex(r=>r.trim().toLowerCase().startsWith("path="))==-1&&e.push("Path=/"),e.join(";")},de=(t,e,n)=>{let r={};if(t&&Object.entries(t).forEach(([s,i])=>{r[s.toLowerCase()]=Array.isArray(i)?`[${i.join(", ")}]`:i}),n)for(let[s,i]of Object.entries(n))r[s]=i;if(!Array.isArray(e))return r;if(!e.every(s=>typeof s=="string")){let s=new Error("Wrong 'cookies'. must be string[]",{cause:e}),i={"Content-Type":r["content-type"]??"application/json","x-amzn-ErrorType":"InternalFailure",...n};throw r["set-cookie"]&&(i["set-cookie"]=r["set-cookie"]),s.headers=i,s}return e=e.map(dn),r["set-cookie"]=r["set-cookie"]?[r["set-cookie"],...e]:e,r};import{randomUUID as Qe}from"node:crypto";var oe=class t extends x{res;mockEvent;payload;constructor({res:e,req:n,body:r,mockEvent:s,multiValueHeaders:i,isBase64Encoded:o,lambdaName:a,parsedURL:l,requestId:c}){super(),this.res=e,this.mockEvent=s,this.payload=s.version==1?t.createApgV1Event({req:n,mockEvent:s,parsedURL:l,lambdaName:a,multiValueHeaders:i,isBase64Encoded:o,requestId:c,body:r}):t.createApgV2Event({req:n,mockEvent:s,parsedURL:l,requestId:c,isBase64Encoded:o,body:r})}static skipHeaders=["connection","content"];static createApgV2Event=({req:e,mockEvent:n,parsedURL:r,requestId:s,isBase64Encoded:i,body:o})=>{let{method:a,headers:l}=e,c=t.getPathParameters(n,r),d,m=n.methods.find(S=>S==a)??"ANY",h={},p="";for(let S of Array.from(new Set(r.searchParams.keys()))){let w=r.searchParams.getAll(S);p+=`&${w.map(E=>encodeURI(`${S}=${E}`)).join("&")}`,h[S]=w.join(",")}p&&(p=p.slice(1));let g=n.paths[0]=="/*"?"$default":`${m} ${r.pathname}`,y=new Date,f="127.0.0.1",v=l.host?.startsWith("localhost")?f:l.host?l.host.split(":")[0]:f,u={version:"2.0",routeKey:g,rawPath:r.pathname,rawQueryString:p,headers:t.getCustomHeaders(e,n),requestContext:{accountId:String(t.accountId),apiId:t.apiId,domainName:`localhost:${t.port}`,domainPrefix:"localhost",http:{method:a,path:r.pathname,protocol:"HTTP/1.1",sourceIp:v,userAgent:l["user-agent"]??""},requestId:s,routeKey:g,stage:"$default",time:y.toISOString(),timeEpoch:y.getTime()}};return o?(u.body=o,u.isBase64Encoded=i):u.isBase64Encoded=!1,Object.keys(h).length&&(u.queryStringParameters=h),Object.keys(c).length&&(u.pathParameters=c),l.cookie&&(u.cookies=l.cookie.split("; ")),d=u,d.headers["x-mock-type"]&&delete d.headers["x-mock-type"],d};static createApgV1Event=({req:e,mockEvent:n,parsedURL:r,lambdaName:s,isBase64Encoded:i,requestId:o,body:a})=>{let{method:l}=e,c={};n.proxy=="httpApi"&&(c.version="1.0");let d=n.paths[0];c.resource=d,c.path=r.pathname,c.httpMethod=l;let{headers:m,multiValueHeaders:h,apiKey:p}=t.getApiGV1Headers(e,n);c.headers=m,c.multiValueHeaders=h;let g=String(e.socket.remoteAddress),y=Object.fromEntries(r.searchParams);c.queryStringParameters=Object.keys(y).length?y:null;let f=t.getMultiValueQueryStringParameters(r.searchParams);c.multiValueQueryStringParameters=Object.keys(f).length?f:null;let v=new Date,u={accountId:String(t.accountId),apiId:t.apiId,domainName:`localhost:${t.port}`,domainPrefix:"localhost",extendedRequestId:"fake-id",httpMethod:l,identity:{accessKey:null,accountId:null,caller:null,cognitoAuthenticationProvider:null,cognitoAuthenticationType:null,cognitoIdentityId:null,cognitoIdentityPoolId:null,principalOrgId:null,sourceIp:g,user:null,userAgent:e.headers["user-agent"],userArn:null},path:r.pathname,protocol:"HTTP/1.1",requestId:o,requestTime:v.toISOString(),requestTimeEpoch:v.getTime(),resourceId:"exhmtv",resourcePath:d};n.proxy=="httpApi"?(u.identity.cognitoAmr=null,u.stage="$default"):(u.stage="dev",n.private&&(u.identity.apiKey=p,u.identity.apiKeyId="abcdefghjk")),c.requestContext=u;let S=t.getPathParameters(n,r);return c.pathParameters=Object.keys(S).length?S:null,c.stageVariables=null,c.body=a??null,c.isBase64Encoded=a?i:!1,c};returnError=e=>{if(this.res.writableFinished)return!0;let n=500,r=t.httpErrMsg;e&&t.isEndpointTimeoutError(e.errorMessage)&&(this.mockEvent.proxy=="httpApi"?(n=503,r=t.unavailable):(n=504,r=t.apgTimeoutMsg));let s=[["Date",new Date().toUTCString()],["Content-Type",t.contentType.json],["Content-Length",String(r.length)],t.keepAlive,["Apigw-Requestid","ETuSEj-PiGYEJdQ="]];return this.res.shouldKeepAlive=!1,this.res.writeHead(n,s),this.res.end(r)};#e=e=>{let n="",r=typeof e;if(r=="string"||r=="number"||r=="boolean")n=String(e);else if(e===null)n="";else throw new Error("");return n};sendV1Response=e=>{let n=[["Date",new Date().toUTCString()],["Apigw-Requestid",Buffer.from(Qe()).toString("base64").slice(0,16)],t.keepAlive],r=200;if(!e||isNaN(e.statusCode))throw b.RED(`Valid 'http' response payload must be an object which includes a valid 'statusCode'.
10
10
  Received:`),console.log(e),new Error;r=e.statusCode,e.headers&&typeof e.headers=="object"&&!Array.isArray(e.headers)&&Object.entries(e.headers).forEach(([c,d])=>{let m=t.normalizeHeaderKey(c),h=this.#e(d);n.push([m,h])}),e.multiValueHeaders&&typeof e.multiValueHeaders=="object"&&!Array.isArray(e.multiValueHeaders)&&Object.entries(e.multiValueHeaders).forEach(([c,d])=>{let m=t.normalizeHeaderKey(c);if(!Array.isArray(d))throw new Error;d.map(p=>this.#e(p)).forEach(p=>{n.push([m,p])})});let s=e.body;if(e.isBase64Encoded&&s){if(typeof s!="string")throw new Error;let c=Buffer.from(s,"base64").toString();if(Buffer.from(c).toString("base64")!=s)throw b.RED("response body is not properly base64 encoded"),new Error;s=c}n.findIndex(c=>c[0].toLowerCase()=="content-type")==-1&&n.push(["Content-Type",t.contentType.json]);let o=n.findIndex(c=>c[0].toLowerCase()=="content-length");o!=-1&&n.splice(o,1);let a=typeof s;a=="number"||a=="boolean"?s=String(s):s&&a!="string"&&b.YELLOW("API Gateway payload v1 return body must be typeof string, number or boolean ");let l=r==204?"0":s?String(Buffer.from(s).byteLength):"0";n.push(["Content-Length",l]),this.res.shouldKeepAlive=!1,this.res.writeHead(r,n),this.res.end(s)};sendV2Response=e=>{this.res.setHeader("Apigw-Requestid",Buffer.from(Qe()).toString("base64").slice(0,16)),this.res.setHeader("Date",new Date().toUTCString()),e?(typeof e.headers=="object"&&!Array.isArray(e.headers)&&Object.keys(e.headers).filter(s=>s!=="Apigw-Requestid"&&s!=="Date").forEach(s=>{this.res.setHeader(s,e.headers[s])}),e.statusCode?(this.res.statusCode=e.statusCode,e.cookies?.length&&this.res.setHeader("Set-Cookie",e.cookies)):this.res.statusCode=200):this.res.statusCode=200;let n="";if(!e)return this.res.end();if(typeof e=="object"&&typeof e.body=="string"&&(n=e.body,e.isBase64Encoded)){let r=Buffer.from(n,"base64").toString();if(Buffer.from(r).toString("base64")!=n)throw b.RED("response body is not properly base64 encoded"),new Error;n=r}typeof e=="string"?(this.res.setHeader("Content-Type",t.contentType.json),n=e):typeof e=="object"&&!e.statusCode&&(this.res.setHeader("Content-Type",t.contentType.json),n=JSON.stringify(e)),this.res.end(n)};sendResponse=e=>{if(!this.res.writableFinished)return this.mockEvent.version==1?this.sendV1Response(e):this.sendV2Response(e)}};var pn=(t,e)=>{let n=e.url.stream?t:void 0;if(n){let r=!1,s=t.write.bind(t),i=t.setHeader.bind(t),o,a,l=m=>{a=a?Buffer.concat([a,m]):m},c=()=>{if(a){let m=Pe(a),h=m.statusCode??200;try{let p=de(m.headers,m.cookies);t.writeHead(h,p)}catch(p){t.writeHead(500,p.headers),t.end?.(x.amzMsgNull),delete p.headers}}else t.writeHead(200)};n.setHeader=(m,h)=>{if(m.toLowerCase()=="content-type"){if(h=="application/vnd.awslambda.http-integration-response")return r=!0,i("Content-Type",x.contentType.json);o=h}return i(m,h)};let d=!1;return n.write=(m,h,p)=>{if(n.headersSent)return s(m,h,p);if(d)try{let g=A.codec.decode(m),y=JSON.parse(g);if(Array.isArray(y))throw new Error("Invalid stream response");return y&&typeof y=="object"?(c(),s(m,h,p)):(t.writeHead(200,{"Content-Type":x.contentType.octet}),t.end())}catch(g){let y=new Error(`When using HttpResponseStream first chunk of .write() must be valid JSON and not be Array. Number and null will respones with 200.
11
11
  '${e.name}'`);return y.cause=g.message,console.error(y),G(t)}else if(r)Oe(m)?d=!0:l(m);else{if(o==x.contentType.json)try{let y=A.codec.decode(m),f=JSON.parse(y);if(f===null||typeof f=="number")throw new Error(y)}catch(y){let f=new Error(`When 'Content-Type' is 'application/json' first chunk of .write() must be parsable JSON and not be null or number.
12
12
  '${e.name}'`);return f.cause=y.message,console.error(f),G(t)}let g={"Content-Type":o??x.contentType.octet};return n.writeHead(200,g),s(m,h,p)}},n}},mn=(t,e,n,r)=>{let s=B(t),i=s?t.getParsedResponse():t,o,a=!1;if(i&&typeof i=="object"&&i.statusCode){let l=isNaN(i.statusCode),c=l?500:i.statusCode;if(a=!l&&(i.isBase64Encoded==!0||i.isBase64Encoded=="true"),i.headers||i.cookies)try{let d=de(i.headers,i.cookies,r);e.writeHead(c,d)}catch(d){return e.writeHead(500,d.headers),delete d.headers,console.error(d),e.end(x.amzMsgNull)}else e.writeHead(c,{"Content-Type":x.contentType.json,...r});n?o=i:(typeof i.body<"u"&&(o=i.body),e.headersSent||e.setHeader("Content-Type",s?x.contentType.octet:x.contentType.json))}else e.writeHead(200,{"Content-Type":x.contentType.json,...r}),o=i;!e.headersSent&&!n&&s&&e.setHeader("Content-Type",x.contentType.octet),n?o instanceof Uint8Array?e.end(o):e.end(JSON.stringify(o)):((typeof o=="number"||typeof o=="boolean"||o==null||o instanceof Object)&&(o=JSON.stringify(o)),o&&a&&(o=Buffer.from(o,"base64")),e.end(o))};function un(t,e){let n=t["access-control-request-method"];return e=="OPTIONS"&&t.origin&&n&&["GET","HEAD","POST","PUT","DELETE","PATCH"].includes(n)}function Ke(t,e){let n=e.origin;return n&&t.allowOrigins.find(s=>s=="*"||s=="http://*"||s=="https://*")?!0:!!t.allowOrigins.find(s=>s==n)}function fn(t,e){if(!t.allowMethods?.length)return!1;if(t.allowMethods.find(s=>s=="*"))return!0;let r=e["access-control-request-method"];return!!t.allowMethods.find(s=>s==r)}function hn(t,e){if(!fn(t,e)||!Ke(t,e))return!1;let n=e["access-control-request-headers"]?e["access-control-request-headers"].split(",").filter(Boolean):[];return n.length?t.allowHeaders?.length?n.every(r=>t.allowHeaders.find(s=>s.toLowerCase()==r.toLowerCase())):!1:!0}var Ge=t=>({filter:/^\/@url\//,callback:async(e,n)=>{let{url:r,method:s,headers:i}=e;if(ke(n,s))return;let o=new URL(r,x.dummyHost),a=j(n),l=k.parseNameFromUrl(o.pathname),c=t.handlers.find(f=>f.name==l);if(!c?.url)return n.statusCode=404,n.end("Not Found");let d;if(c.url.cors){if(un(i,s)){let v=hn(c.url.cors,i),u={"Content-Type":x.contentType.json};return v&&(u["access-control-allow-origin"]=i.origin,c.url.cors.allowMethods.find(S=>S=="*")?u["access-control-allow-methods"]=i["access-control-request-method"]:u["access-control-allow-methods"]=c.url.cors.allowMethods.join(","),c.url.cors.allowHeaders?.length&&(u["access-control-allow-headers"]=c.url.cors.allowHeaders.join(",")),typeof c.url.cors.maxAge=="number"&&c.url.cors.maxAge>-1&&(u["access-control-max-age"]=`${c.url.cors.maxAge}`),c.url.cors.allowCredentials&&(u["access-control-allow-credentials"]="true")),n.writeHead(200,u),n.end()}Ke(c.url.cors,i)&&(d={"access-control-allow-origin":i.origin},c.url.cors.exposeHeaders?.length&&(d["access-control-expose-headers"]=c.url.cors.exposeHeaders.join(",")),c.url.cors.allowCredentials&&(d["access-control-allow-credentials"]="true"))}let m=x.getIsBase64Encoded(i),h=await L(e,m),p=oe.createApgV2Event({req:e,mockEvent:c.url,parsedURL:o,requestId:a,body:h,isBase64Encoded:m}),g=`/@url/${c.name}`,y=o.pathname.slice(g.length);y||(y="/"),p.requestContext.accountId="anonymous",p.rawPath=y,p.requestContext.http.path=y;try{let f=pn(n,c),v=await c.invoke(p,c.url,void 0,f);if(!v)return n.end();mn(v,n,f,d)}catch(f){console.error(f),G(n,d)}}});var Ye=t=>({filter:/(^\/2015-03-31\/functions\/.*\/invocations)|(^\/@invoke\/)/,callback:async(e,n)=>{let{url:r,headers:s}=e,i=new URL(r,"http://localhost:3003"),o=k.parseNameFromUrl(i.pathname),a=t.handlers.find(f=>f.name==o),l=j(n);if(n.setHeader("Content-Type","application/json"),e.on("error",f=>{n.statusCode=502,n.end(JSON.stringify(f))}),!a){let{region:f,accountId:v}=t.aws;return n.statusCode=404,n.setHeader("x-amzn-errortype","ResourceNotFoundException"),n.end(K(o,f,v))}let c=s["x-amz-invocation-type"],d=z(s["x-amz-client-context"]);if(d instanceof Error)return n.setHeader("x-amzn-errortype","InvalidRequestContentException"),n.statusCode=400,n.end(Q);let m=c=="DryRun"?204:c=="Event"?202:200,h=await L(e),p=V(h);if(n.setHeader("X-Amzn-Trace-Id","root=1-xxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx;sampled=0"),p instanceof Error)return n.statusCode=400,n.setHeader("x-amzn-errortype","InvalidRequestContentException"),n.end(J(p.message));n.setHeader("X-Amz-Executed-Version","$LATEST");let g=new Date,y={};n.statusCode=m,m!==200&&n.end(),m==202&&(y.kind="async");try{let f=await a.invoke(p,y,d);if(m==200){if(typeof f>"u"){n.end();return}let v=B(f),u=v?f.buffer:f;v?u=A.codec.decode(u):typeof u!="string"&&(u=JSON.stringify(u)),n.end(u)}}catch(f){n.writableFinished||(n.setHeader("X-Amz-Function-Error",f.errorType??f.message??""),n.statusCode=200,n.end(JSON.stringify(f)))}}});import{randomUUID as Xe}from"node:crypto";import{setTimeout as gn}from"node:timers/promises";var Ze=t=>({filter:"/2015-03-31/functions",method:"POST",async callback(e,n){let r=await L(e),s=JSON.parse(r),{FunctionName:i,Handler:o,Environment:a,Runtime:l,Timeout:c,MemorySize:d}=s;t.addLambda(i,{handler:o,environment:a?.Variables,runtime:l,timeout:c,memorySize:d}),t.isDynamicBuild=!0,t.setEsBuildConfig(),await t.buildContext.dispose(),await t.buildAndWatch(),await gn(100),n.statusCode=201,n.end(r)}}),et=t=>({filter:/\/2015-03-31\/functions\/*/,method:"GET",async callback(e,n){let{url:r}=e,i=new URL(r,"http://localhost:3003").pathname.slice(22),o=t.getLambdaByName(i);if(!o){n.statusCode=404,n.end();return}let a={Code:{RepositoryType:"S3",Location:"https://s3.com/snapshots/1234543"},Tags:{},Configuration:{Architectures:["arm64"],CodeSha256:"WrLckXVmmfsSPvP/15FqPi9Nt9qQBaspP6RV3T137K4=",SigningJobArn:"",FunctionArn:`arn:aws:lambda:${t.aws.region}:${t.aws.accountId}:function:${i}`,FunctionName:i,Handler:o.handlerPath,Timeout:o.timeout,Runtime:o.runtime,MemorySize:o.memorySize,Environment:{Variables:tt(o.environment)},State:"Active",LastUpdateStatus:"Successful",LastModified:new Date().toISOString(),Version:"$LATEST",Role:`arn:aws:iam::${t.aws.accountId}:role/fake-role-name`,RevisionId:Xe(),PackageType:"Zip",Description:"",EphemeralStorage:{Size:512},TracingConfig:{Mode:"PassThrough"},VpcConfig:{Ipv6AllowedForDualStack:!1,VpcId:"",SecurityGroupIds:[],SubnetIds:[]},CodeSize:5867,SnapStart:{OptimizationStatus:"Off",ApplyOn:"None"},LoggingConfig:{LogFormat:"Text",LogGroup:`/aws/lambda/${i}`}}};n.end(JSON.stringify(a))}}),bn=["AWS_EXECUTION_ENV","AWS_LAMBDA_FUNCTION_VERSION","AWS_LAMBDA_FUNCTION_NAME","_HANDLER","IS_OFFLINE","IS_LOCAL","AWS_SAM_LOCAL","AWS_LAMBDA_FUNCTION_MEMORY_SIZE"];function tt(t){let e={};for(let[n,r]of Object.entries(t))bn.includes(n)||(e[n]=String(r));return e}var nt=t=>({method:"GET",filter:/\/2015-03-31\/functions\/.*\/versions/,async callback(e,n){let{url:r}=e,i=new URL(r,"http://localhost:3003").pathname.slice(22);i=i.slice(0,i.indexOf("/"));let o=t.getLambdaByName(i);if(!o){n.statusCode=404,n.end();return}let a={Versions:[{Architectures:["arm64"],CodeSha256:"WrLckXVmmfsSPvP/15FqPi9Nt9qQBaspP6RV3T137K4=",SigningJobArn:"",FunctionArn:`arn:aws:lambda:${t.aws.region}:${t.aws.accountId}:function:${i}`,FunctionName:i,Handler:o.handlerPath,Timeout:o.timeout,Runtime:o.runtime,MemorySize:o.memorySize,Environment:{Variables:tt(o.environment)},State:"Active",LastUpdateStatus:"Successful",LastModified:new Date().toISOString(),Version:"$LATEST",Role:`arn:aws:iam::${t.aws.accountId}:role/fake-role-name`,RevisionId:Xe(),PackageType:"Zip",Description:"",EphemeralStorage:{Size:512},TracingConfig:{Mode:"PassThrough"},VpcConfig:{Ipv6AllowedForDualStack:!1,VpcId:"",SecurityGroupIds:[],SubnetIds:[]},CodeSize:5867,SnapStart:{OptimizationStatus:"Off",ApplyOn:"None"},LoggingConfig:{LogFormat:"Text",LogGroup:`/aws/lambda/${i}`}}]};n.end(JSON.stringify(a))}}),rt=t=>({method:"GET",filter:/\/2020-06-30\/functions\/.*\/code-signing-config/,async callback(e,n){let{url:r}=e,i=new URL(r,"http://localhost:3003").pathname.slice(22);if(i=i.slice(0,i.indexOf("/")),!t.getLambdaByName(i)){n.statusCode=404,n.end();return}let a={CodeSigningConfigArn:"",FunctionName:i};n.end(JSON.stringify(a))}});import{EventStreamCodec as Sn}from"@smithy/eventstream-codec";var vn=(t,e)=>{let n=Buffer.from(t,e);return new Uint8Array(n.buffer,n.byteOffset,n.byteLength/Uint8Array.BYTES_PER_ELEMENT)},xn=t=>Buffer.from(t,t.byteOffset,t.byteLength).toString("utf8"),pe=new Sn(xn,vn),ae=class t{res;static complete=Buffer.from([0,0,0,102,0,0,0,84,31,86,200,105,11,58,101,118,101,110,116,45,116,121,112,101,7,0,14,73,110,118,111,107,101,67,111,109,112,108,101,116,101,13,58,99,111,110,116,101,110,116,45,116,121,112,101,7,0,16,97,112,112,108,105,99,97,116,105,111,110,47,106,115,111,110,13,58,109,101,115,115,97,103,101,45,116,121,112,101,7,0,5,101,118,101,110,116,123,125,112,6,212,103]);constructor(e){this.res=e}write(e,n,r){this.res.write(pe.encode({headers:this.#e("PayloadChunk",x.contentType.octet),body:e}),n,r)}end(e){e?this.write(e,"utf8",()=>{this.res.end(t.complete)}):this.res.end(t.complete)}setHeader(e,n){e=="Content-Type"&&this.res.setHeader("Content-Type",n)}destroy(){this.res.destroy()}endWithError(e){let n={ErrorCode:e.errorType,ErrorDetails:JSON.stringify(e)},r=Array.from(Buffer.from(JSON.stringify(n)).values());this.res.end(pe.encode({headers:this.#e("InvokeComplete",x.contentType.json),body:new Uint8Array(r)}))}endWithJson(e){let n=Array.from(Buffer.from(JSON.stringify(e)).values());this.res.write(pe.encode({headers:this.#e("PayloadChunk",x.contentType.octet),body:new Uint8Array(n)}),()=>{this.res.end(t.complete)})}#e(e,n,r="event"){return{":event-type":{type:"string",value:e},":content-type":{type:"string",value:n},":message-type":{type:"string",value:r}}}};var st=t=>({filter:/^\/2021-11-15\/functions\//,callback:async(e,n)=>{let{url:r,headers:s}=e,i=new URL(r,"http://localhost:3003"),o=j(n),a=k.parseNameFromUrl(i.pathname),l=t.handlers.find(p=>p.name==a),c=await L(e),d=V(c);if(n.setHeader("X-Amzn-Trace-Id","root=1-xxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx;sampled=0"),d instanceof Error)return n.statusCode=400,n.setHeader("x-amzn-errortype","InvalidRequestContentException"),n.end(J(d.message));let m=z(s["x-amz-client-context"]);if(m instanceof Error)return n.setHeader("x-amzn-errortype","InvalidRequestContentException"),n.statusCode=400,n.end(Q);let h=new ae(n);if(l){let p=l.url?.stream??{};try{let g=await l.invoke(d,p,m,h);g&&h.endWithJson(g)}catch(g){n.writableFinished||h.endWithError(g)}}else{let{region:p,accountId:g}=t.aws;n.statusCode=404,n.end(K(a,p,g))}}});var it=t=>[Ze(t),nt(t),rt(t),Ye(t),st(t),Ge(t),et(t)];var me=process.cwd(),En=3,Rn=1024,In={IS_OFFLINE:!0,IS_LOCAL:!0,AWS_SAM_LOCAL:!0},An=me.split(O.sep)[0],kn=new RegExp(`^.*:${An}`),Pn=t=>kn.test(t);process.title="node (exlo)";var ce=class extends ie{#e;options;config;esBuildConfig;buildContext={};customEsBuildConfig;optimizeBuild=!1;nodeVersion=!1;onKill=[];shimRequire=!1;port=0;onceServerReady=[];isDynamicBuild=!1;endpoints={};setLambdaEndpointEnvVar=!0;constructor(e,n){super(e,{debug:typeof n.debug=="boolean"?n.debug:!1}),this.#e=[],this.options=n,this.options.customEsBuildConfig&&(this.customEsBuildConfig=this.options.customEsBuildConfig),typeof this.options.config?.server?.setEndpointEnvVar=="boolean"&&(this.setLambdaEndpointEnvVar=this.options.config.server.setEndpointEnvVar),this.options.config&&(typeof this.options.config=="string"||typeof this.options.config=="object"&&!Array.isArray(this.options.config))&&(this.config=this.options.config),typeof this.options.optimizeBuild=="boolean"&&(this.optimizeBuild=this.options.optimizeBuild),typeof this.options.shimRequire=="boolean"&&(this.shimRequire=this.options.shimRequire),this.aws.runtime?.startsWith("node")?this.nodeVersion=this.aws.runtime?.replace(/[^0-9]/g,""):this.nodeVersion="20",b.BR_BLUE("Starting exlo...")}async start(){this.#s(),this.#e=this.#r(),await this.#o(),this.setEsBuildConfig(),await this.buildAndWatch()}setEsBuildConfig(){let n={sourcemap:!0,minify:!1,entryPoints:this.#e.filter(r=>r.runtime.startsWith("n")).map(r=>r.esEntryPoint),outdir:O.join(me,".exlo","build"),metafile:!0,bundle:!0,platform:"node",target:"node20",format:"cjs",outbase:"src",plugins:[],external:["esbuild"],dropLabels:[]};if(typeof process.env.NODE_ENV=="string"&&(n.define={"process.env.NODE_ENV":`"${process.env.NODE_ENV}"`}),typeof this.nodeVersion=="string"&&!isNaN(Number(this.nodeVersion))){Number(process.versions.node.slice(0,2))<Number(this.nodeVersion)&&b.RED(`You are running on NodeJS ${process.version} which is lower than defined '${this.nodeVersion}'.`),n.target=`node${this.nodeVersion}`;let r=()=>this.sco;n.plugins?.push(ge({nodeVersion:Number(this.nodeVersion),shimRequire:this.shimRequire,optimizeBuild:this.optimizeBuild,buildCallback:this.buildCallback,getSockets:r}))}this.customEsBuildConfig&&(n=be(n,this.customEsBuildConfig)),this.esBuildConfig=n}async buildAndWatch(){this.buildContext=await ot.context(this.esBuildConfig),await this.buildContext.watch()}buildCallback=async(e,n)=>{if(n||this.isDynamicBuild)await this.#t(e);else{let{outputs:r}=e.metafile;if(this.#i(r),this.customBuildCallback)try{await this.customBuildCallback(e,!1)}catch(o){console.log(o)}this.#a();let s=this,i=await new Promise(o=>{this.listen(this.port,async(a,l)=>{let c=`http://localhost:${a}`;b.PINK(`Lambda endpoint: ${c}`),this.endpoints.lambda=c,this.setLambdaEndpointEnvVar&&(this.runtimeConfig.environment.AWS_ENDPOINT_URL_LAMBDA=c),await s.load(s.#e);for(let d of s.#e)d.setEnv("LOCAL_PORT",a),d.setEnv("AWS_LAMBDA_RUNTIME_API",`127.0.0.1:${a}`),this.setLambdaEndpointEnvVar&&d.setEnv("AWS_ENDPOINT_URL_LAMBDA",c);o({url:c,port:a})})});this.onceServerReady.forEach(o=>{o(i)})}};async#t(e){if(e?.errors?.length)b.RED("Build failed:"),console.error(e.errors);else{this.#i(e.metafile.outputs);try{await this.load(this.#e),this.customBuildCallback&&await this.customBuildCallback(e,!0)}catch(n){console.error(n)}console.log(`\x1B[32m${new Date().toLocaleString()} \u{1F504}\u2705 Rebuild\x1B[0m`)}}#n(e){let n=this.aws,r=n.runtime,s=this.runtimeConfig.environment.AWS_REGION??this.runtimeConfig.environment.REGION,o=n.functions[e],a=o.handler,l=O.extname(a),c=l.slice(1),d=O.resolve(a.replace(l,"")),m=n.getFunction(e),h=m.runtime??r,p={name:e,runtime:m.runtime??r,handlerPath:a,handlerName:c,esEntryPoint:d,memorySize:o.memorySize??this.runtimeConfig.memorySize??Rn,timeout:o.timeout??this.runtimeConfig.timeout??En,sqs:[],ddb:[],environment:{AWS_EXECUTION_ENV:`AWS_Lambda_${h}`,AWS_LAMBDA_FUNCTION_VERSION:"$LATEST",AWS_LAMBDA_FUNCTION_NAME:e,_HANDLER:O.basename(a),...this.runtimeConfig.environment,...o.environment,...In},invoke:async(g,y)=>{let f=this.getHandlerByName(`/@invoke/${e}`);if(f)return await f.invoke(g,y);b.RED(`'${e}' is not mounted yet.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "exlo",
3
- "version": "0.0.13",
3
+ "version": "0.0.14",
4
4
  "description": "A modular toolkit to emulate cloud services locally using high-quality built-in plugins and custom extensions. Includes support for Lambda, S3, SNS, SQS, Secrets Manager, DynamoDB, REST API Gateway and more.",
5
5
  "author": "Inqnuam",
6
6
  "license": "MIT",