UNPKG

serverless-aws-lambda

Version:

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

61 lines 54.3 kB
"use strict";var $e=Object.create;var Y=Object.defineProperty;var _e=Object.getOwnPropertyDescriptor;var Fe=Object.getOwnPropertyNames;var Ve=Object.getPrototypeOf,Xe=Object.prototype.hasOwnProperty;var Ge=(r,e)=>{for(var t in e)Y(r,t,{get:e[t],enumerable:!0})},Ie=(r,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Fe(e))!Xe.call(r,n)&&n!==t&&Y(r,n,{get:()=>e[n],enumerable:!(s=_e(e,n))||s.enumerable});return r};var R=(r,e,t)=>(t=r!=null?$e(Ve(r)):{},Ie(e||!r||!r.__esModule?Y(t,"default",{value:r,enumerable:!0}):t,r)),We=r=>Ie(Y({},"__esModule",{value:!0}),r);var bt={};Ge(bt,{default:()=>yt,s3Plugin:()=>Oe});module.exports=We(bt);var ke=require("fs"),Se=R(require("path")),xe=r=>{let e=typeof r=="string"?r:"localS3/";e=Se.default.resolve(e),e.endsWith("/")||(e+="/");try{if((0,ke.statSync)(e).isDirectory())return e;throw new Error(`Provided localStorageDir '${r}' is not a directory`)}catch(t){if(t.code=="ENOENT")return e;throw t.code=="ENOTDIR"?new Error(`Provided localStorageDir '${r}' is not a directory`):t}};var He=require("crypto"),y=require("fs/promises"),ne=require("fs"),T=R(require("path"));var Ce=({Bucket:r,RequestId:e})=>`<?xml version="1.0" encoding="UTF-8"?> <Error><Code>NoSuchBucket</Code><Message>The specified bucket does not exist</Message><BucketName>${r}</BucketName><RequestId>${e}</RequestId><HostId>local</HostId></Error> `,f=({Key:r,RequestId:e})=>`<?xml version="1.0" encoding="UTF-8"?> <Error><Code>NoSuchKey</Code><Message>The specified key does not exist.</Message><Key>${r}</Key><RequestId>${e}</RequestId><HostId>local</HostId></Error>`;var Je={PutObject:["ObjectCreated","Put"],CopyObject:["ObjectCreated","Copy"],DeleteObject:["ObjectRemoved","Delete"]},Ye=({bucket:r,eTag:e,size:t,key:s,eventName:n,sourceIPAddress:o,requestId:c})=>({eventVersion:"2.1",eventSource:"aws:s3",awsRegion:"eu-west-3",eventTime:new Date().toUTCString(),eventName:n,userIdentity:{principalId:"AWS:AIDA6ECTW4PP5BZ6IKOGM"},requestParameters:{sourceIPAddress:o},responseElements:{"x-amz-request-id":c,"x-amz-id-2":"K9uTQdtIwO9VVKYvEk0BrLAAO9zWajA33cUGdcrZvjoLHLwBUBocXu1GU50BEcMIfNTLdt2KKmzaagHcGBWncOyUgcXx8UILLYKd26F/pf4="},s3:{s3SchemaVersion:"1.0",configurationId:"975e5867-6fe6-4b2c-925e-ef15389f6d3f",bucket:{name:r,ownerIdentity:{principalId:"A1HCF0AO1IXCSI"},arn:`arn:aws:s3:::${r}`},object:{key:s,size:t,eTag:e,sequencer:"0063E38F8ED88A5726"}}}),Qe=(r,e)=>{if(r){if(Array.isArray(r))return r.map(t=>typeof t.prefix=="string"?e.startsWith(t.prefix):typeof t.suffix=="string"?e.endsWith(t.suffix):!1).every(t=>t===!0)}else return!0},H=async(r,{bucket:e,eTag:t,size:s,key:n,requestCmd:o,sourceIPAddress:c,requestId:a})=>{let u=Je[o];for(let d of r)for(let m of d.s3){if(e!=m.bucket)continue;let[p,l]=m.type;if(p==u[0]&&(l=="*"||l==u[1])&&Qe(m.rules,n))try{await d.invoke({Records:[Ye({bucket:e,eTag:t,size:s,key:n,sourceIPAddress:c,requestId:a,eventName:u.join(":")})]},{kind:"s3",event:m})}catch(h){console.log(h)}}};var Re=require("crypto"),Q=r=>(0,Re.createHash)("md5").update(r).digest("hex");var Ht=5*1024*1024;var w=r=>`"${Q(r)}"`;var g=class r extends Error{statusCode;Code;SenderFault=!0;RequestId;constructor({Code:e,Message:t,SenderFault:s,RequestId:n,statusCode:o}){super(t),this.Code=e,this.RequestId=n,this.statusCode=o,typeof s=="boolean"&&(this.SenderFault=s)}toXml(e=""){return r.genericError({Code:this.Code,Message:this.message,RequestId:this.RequestId,info:e})}static genericError({Code:e,Message:t,RequestId:s,info:n}){return`<?xml version="1.0" encoding="UTF-8"?> <Error><Code>${e}</Code><Message>${t}</Message>${n??""}<RequestId>${s}</RequestId><HostId>local</HostId></Error>`}},I=class extends g{TagKey;constructor({TagKey:e,Message:t,RequestId:s}){super({Code:"InvalidTag",Message:t,SenderFault:!0,statusCode:400,RequestId:s}),this.TagKey=e}toXml(){return super.toXml(`<TagKey>${this.TagKey}</TagKey>`)}},Z=class extends g{constructor(e){super({Code:"MalformedXML",Message:"The XML you provided was not well-formed or did not validate against our published schema",RequestId:e})}},v=class extends g{constructor({Message:e,RequestId:t}){super({Code:"BadRequest",Message:e,RequestId:t})}},ee=class extends g{ArgumentName;ArgumentValue;constructor({Message:e,RequestId:t,ArgumentName:s,ArgumentValue:n}){super({Code:"InvalidArgument",Message:e,RequestId:t}),this.ArgumentName=s,this.ArgumentValue=n}toXml(){return super.toXml(`<ArgumentName>${this.ArgumentName}</ArgumentName><ArgumentValue>${this.ArgumentValue}</ArgumentValue>`)}},te=class extends g{constructor(e){super({Code:"NoSuchTagSet",Message:"The TagSet does not exist",RequestId:e,statusCode:404})}},k=class extends g{constructor(e,t){super({Code:"UnsupportedCommand",Message:`${e} is currently not supported`,RequestId:t,statusCode:500})}};var re=require("fast-xml-parser"),et=new re.XMLParser,tt=["STANDARD","REDUCED_REDUNDANCY","STANDARD_IA","ONEZONE_IA","INTELLIGENT_TIERING","GLACIER","DEEP_ARCHIVE","OUTPOSTS","GLACIER_IR","SNOW"],st=/\.{2,}/,nt=/^(\d{1,3}\.){3}\d{1,3}$/,rt=/^[a-z0-9]+[a-z0-9.-]+[a-z0-9]$/,i=class r{static localStoragePath;static persist=!0;static persistence={version:2,buckets:{}};static XMLBuilder=new re.XMLBuilder;static genLocalKey(e,t,s){return Q(T.default.posix.join(e,t,s??""))}static#e=async e=>{let t={version:2,buckets:{}};for(let[s,n]of Object.entries(e.files))try{let[o,...c]=s.replace(this.localStoragePath,"").split("/").filter(Boolean),a=await(0,y.stat)(s),u=c.join("/"),d=this.genLocalKey(o,u),m={currentKey:d,type:n.type,cacheControl:n.cacheControl,StorageClass:"STANDARD",size:a.size,LastModified:a.mtimeMs,ETag:w(await(0,y.readFile)(s)),metadata:{},versions:{[d]:{}}};t.buckets[o]?t.buckets[o].objects[u]=m:t.buckets[o]={date:Date.now(),deletionPolicy:"Retain",objects:{[u]:m}}}catch{}return t};static async bootstrap(){try{let e=await(0,y.readFile)(T.default.join(this.localStoragePath,"__items.json"),"utf-8"),t=JSON.parse(e);if(t.version==2){this.persistence=t;return}this.persistence=await this.#e(t)}catch{}}static async createBucketDir(e,t){let s=T.default.join(this.localStoragePath,e);try{if(!(await(0,y.stat)(s)).isDirectory())throw await(0,y.rm)(s),new Error}catch{try{await(0,y.mkdir)(s,{recursive:!0}),this.persistence.buckets[e]={date:Date.now(),...t,objects:{}}}catch(o){console.error(o)}}}static saveState(){r.persist?(0,ne.writeFileSync)(T.default.join(this.localStoragePath,"__items.json"),JSON.stringify(this.persistence)):(0,ne.rmSync)(this.localStoragePath,{force:!0,recursive:!0})}static isValidBucketName(e){let t=e.length;return t<3||t>63||st.test(e)||nt.test(e)||e.startsWith("xn--")||e.startsWith("sthree-")||e.endsWith("-s3alias")||e.endsWith("--ol-s3")?!1:rt.test(e)}isValidStorageClass(e,t){return tt.includes(e)?!0:(t.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>${e}</StorageClassRequested><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`),!1)}static callableLambdas=[];requestId;metadata={};constructor(e){this.requestId=e["amz-sdk-invocation-id"]??(0,He.randomUUID)(),Object.keys(e).filter(s=>s.startsWith("x-amz-meta-")).forEach(s=>this.metadata[s]=e[s])}hasNot(e,t){if(!r.isValidBucketName(e)){t.writeHead(400,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(`<?xml version="1.0" encoding="UTF-8"?> <Error><Code>InvalidBucketName</Code><Message>The specified bucket is not valid.</Message><BucketName>${e}</BucketName><RequestId>${this.requestId}</RequestId><HostId>local</HostId></Error>`);return}if(!r.persistence.buckets[e])return t.writeHead(404,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(Ce({Bucket:e,RequestId:this.requestId})),!0}static async removeObject(e,t,s,n){let o=this.persistence.buckets[e].objects[t];if(!o)return;let c=T.default.join(this.localStoragePath,e,o.currentKey);try{let a=await(0,y.stat)(c);a.isFile()&&await(0,y.rm)(c),await H(this.callableLambdas,{bucket:e,key:t,requestId:n,requestCmd:"DeleteObject",eTag:o.ETag,sourceIPAddress:s,size:a.size}),delete this.persistence.buckets[e].objects[t]}catch{}}static async getTagsFromRequest(e,t,s){let n;e.on("data",p=>{n=typeof n>"u"?p:Buffer.concat([n,p])});let o=await new Promise(p=>{e.on("end",async()=>{p(n)})}),c=new Z(t);if(!o)throw new g({Code:"MissingRequestBodyError",Message:"Request Body is empty",RequestId:t});let a;try{a=et.parse(o)}catch{throw c}if(a.Tagging=="")return;let u=a.Tagging.TagSet.Tag;u&&!Array.isArray(u)&&(u=[u]);let d={};for(let p of u){if(p===null||typeof p!="object"||Array.isArray(p))throw c;let{Key:l,Value:h}=p;if(typeof l!="string"||typeof h!="string")throw c;if(l in d)throw new I({TagKey:l,RequestId:t,Message:"Cannot provide multiple Tags with the same key"});if(l.length>128||l.length<1)throw new I({TagKey:l,RequestId:t,Message:"The TagKey you have provided is invalid"});if(h.length>256)throw new I({TagKey:l,RequestId:t,Message:"The TagValue you have provided is invalid"});d[l]=h}let m=s=="Bucket"?50:10;if(Object.keys(d).length>m)throw new v({Message:`${s} tag count cannot be greater than ${m}`,RequestId:t});return d}};var oe=class extends i{bucket;delimiter;encodingType;maxKeys=1e3;prefix;expectedOwner;optionalObjectAttributes;requestPayer;constructor(e,t){super(t);let[s]=decodeURIComponent(e.pathname.replace("/%40s3/","").replace("/@s3/","")).split("/").filter(Boolean);this.bucket=s,this.delimiter=e.searchParams.get("delimiter"),this.encodingType=e.searchParams.get("encoding-type");let n=e.searchParams.get("max-keys");n&&(this.maxKeys=n),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")}getKeys(){let e=Object.keys(i.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"?> <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"?> <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}}};function we(r,e,t){let s=[];for(let n of t)if(n.startsWith(r)){let o=n.indexOf(e,r.length);if(o>0){let c=n.substring(0,o+e.length);s.includes(c)||s.push(c)}}return s}var x=class extends oe{marker;constructor(e,t){super(e,t),this.marker=e.searchParams.get("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(l=>l.localeCompare(this.marker)>0);let p=a.findIndex(l=>l.startsWith(this.marker));p>-1&&(a=a.slice(p+1))}let u=Number(this.maxKeys),d=a.length;d>u&&(t=!0,a=a.slice(0,u),d>a.length&&(s=a[a.length-1])),this.delimiter&&(n=`<Delimiter>${this.delimiter}</Delimiter>`,o=we(this.prefix??"",this.delimiter,a),this.marker&&(o=o.filter(p=>p!=this.marker))),o.length&&(a=a.filter(p=>!o.some(l=>p.startsWith(l))),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 m=a.map(p=>{let l=i.persistence.buckets[this.bucket].objects[p];return`<Contents> <Key>${p}</Key> <LastModified>${new Date(l.LastModified).toISOString()}</LastModified> <ETag>${l.ETag}</ETag> <Size>${l.size}</Size> <StorageClass>${l.StorageClass}</StorageClass> </Contents>`}).join("");e.end(`<?xml version="1.0" encoding="UTF-8"?> <ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <Name>${this.bucket}</Name> <Prefix>${this.prefix??""}</Prefix> ${this.marker?`<Marker>${this.marker}</Marker>`:""} ${n} ${c} ${s?`<NextMarker>${s}</NextMarker>`:""} <MaxKeys>${this.maxKeys}</MaxKeys> <IsTruncated>${t}</IsTruncated> ${m} </ListBucketResult>`)}},C=class extends oe{continuationToken;fetchOwner;startAfter;constructor(e,t){super(e,t),this.continuationToken=e.searchParams.get("continuation-token"),this.fetchOwner=e.searchParams.get("fetch-owner"),this.startAfter=e.searchParams.get("start-after")}exec(e){if(this.hasNot(this.bucket,e)||this.isInvalidMaxKeys(e))return;let t=!1,s="",n="",o=[],c="",a=this.getKeys(),u="";if(this.continuationToken?u=Buffer.from(this.continuationToken,"base64").toString():this.startAfter&&(u=this.startAfter),u){a=a.filter(b=>b.localeCompare(u)>0);let h=a.findIndex(b=>b.startsWith(u));h>-1&&(a=a.slice(h+1))}let d=Number(this.maxKeys);a.length>d&&(t=!0,a=a.slice(0,d)),this.delimiter&&(n=`<Delimiter>${this.delimiter}</Delimiter>`,o=we(this.prefix??"",this.delimiter,a),u&&(o=o.filter(h=>h!=u))),o.length&&(a=a.filter(h=>!o.some(b=>h.startsWith(b))),c=o.map(h=>`<CommonPrefixes><Prefix>${h}</Prefix></CommonPrefixes>`).join(""));let p=a.length+o.length;t&&(a.length?s=Buffer.from(a[a.length-1]).toString("base64"):o.length&&(s=Buffer.from(o[0]).toString("base64"))),e.statusCode=200,e.setHeader("Server","AmazonS3"),e.setHeader("Content-Type","application/xml"),e.setHeader("x-amzn-requestid",this.requestId);let l=a.map(h=>{let b=i.persistence.buckets[this.bucket].objects[h];return`<Contents> <Key>${h}</Key> <LastModified>${new Date(b.LastModified).toISOString()}</LastModified> <ETag>${b.ETag}</ETag> <Size>${b.size}</Size> <StorageClass>${b.StorageClass}</StorageClass> </Contents>`}).join("");e.end(`<?xml version="1.0" encoding="UTF-8"?> <ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <Name>${this.bucket}</Name> <Prefix>${this.prefix??""}</Prefix> ${n} ${c} <KeyCount>${p}</KeyCount> ${s?`<NextContinuationToken>${s}</NextContinuationToken>`:""} <MaxKeys>${this.maxKeys}</MaxKeys> <IsTruncated>${t}</IsTruncated> ${this.continuationToken?`<ContinuationToken>${this.continuationToken}</ContinuationToken>`:""} ${!this.continuationToken&&this.startAfter?`<StartAfter>${this.startAfter}</StartAfter>`:""} ${l} </ListBucketResult>`)}};var q=class extends i{constructor(e,t){super(t)}async exec(e){let t=[];Object.entries(i.persistence.buckets).forEach(([s,n])=>{t.push({name:s,date:new Date(n.date).toISOString()})}),e.writeHead(200,{"x-amz-request-id":this.requestId,"Content-Type":"application/xml","transfer-encoding":"chunked",Server:"AmazonS3"}),e.end(`<?xml version="1.0" encoding="UTF-8"?> <ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <Owner> <DisplayName>local-User</DisplayName> <ID>1234567890123456789</ID> </Owner> <Buckets> ${t.map(s=>`<Bucket> <CreationDate>${s.date}</CreationDate> <Name>${s.name}</Name> </Bucket>`).join(` `)} </Buckets> </ListAllMyBucketsResult>`)}};var ve=require("fs"),ge=R(require("path"));var N=({ifMatch:r,ifNoneMatch:e,ifModifiedSince:t,ifUnmodifiedSince:s},{ETag:n,LastModified:o})=>r&&r!==n?{statusCode:412,Code:"PreconditionFailed",Condition:"If-Match"}:e&&e===n?{statusCode:304,Code:"PreconditionFailed",Condition:"If-None-Match"}:t&&t>=o?{statusCode:304,Code:"PreconditionFailed",Condition:"If-Modified-Since"}:s&&s<o?{statusCode:412,Code:"PreconditionFailed",Condition:"If-Unmodified-Since"}:200,E=class r extends i{bucketPath;bucket;key;versionId;partNumber;range;ifMatch;ifNoneMatch;ifModifiedSince;ifUnmodifiedSince;constructor(e,t){super(t);let s=decodeURIComponent(e.pathname.replace("/%40s3/","").replace("/@s3/","")),[n,...o]=s.split("/").filter(Boolean);if(this.bucket=n,this.key=o.join("/"),this.bucketPath=ge.default.join(r.localStoragePath,n),this.versionId=e.searchParams.get("versionId"),this.partNumber=e.searchParams.has("partNumber")?Number(e.searchParams.get("partNumber")):null,t.range){let[c]=t.range.split("bytes=").filter(Boolean),[a,u]=c.split("-");!isNaN(Number(a))&&!isNaN(Number(u))&&(this.range=[Number(a),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())}async exec(e){if(!this.hasNot(this.bucket,e)){if(!i.persistence.buckets[this.bucket].objects[this.key]){e.writeHead(404,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(f({Key:this.key,RequestId:this.requestId}));return}try{let t={ifMatch:this.ifMatch,ifModifiedSince:this.ifModifiedSince,ifNoneMatch:this.ifNoneMatch,ifUnmodifiedSince:this.ifUnmodifiedSince},s=i.persistence.buckets[this.bucket].objects[this.key],n=N(t,s);if(n==200){let o=200,c=s.size,a,u=s.type,d={};if(this.range){o=206,d.start=this.range[0],d.end=this.range[1];let m=1;d.end>s.size&&(d.end=s.size,m--),c=m+d.end-d.start,a=`bytes ${d.start}-${d.end}/${s.size}`,u="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),u&&e.setHeader("Content-Type",u),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),Object.entries(s.metadata).forEach(([m,p])=>{e.setHeader(m,p)}),(0,ve.createReadStream)(ge.default.join(this.bucketPath,s.currentKey),d).pipe(e)}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 S=class extends i{constructor(e,t){super(t)}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 z=class extends i{bucket;key;versionId;constructor(e,t){super(t);let[s,...n]=decodeURIComponent(e.pathname.replace("/%40s3/","").replace("/@s3/","")).split("/").filter(Boolean);this.bucket=s,this.key=n.join("/"),this.versionId=e.searchParams.get("versionId")}async exec(e){if(!this.hasNot(this.bucket,e)){if(!i.persistence.buckets[this.bucket].objects[this.key]){e.writeHead(404,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(f({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=i.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=i.XMLBuilder.build(t);e.end(`<?xml version="1.0" encoding="UTF-8"?>${n}`)}catch(t){if(e.statusCode=400,t instanceof g){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(g.genericError({Code:"UnknownError",Message:t.message,RequestId:this.requestId}));return}e.end(t?.toString?.())}}}};var B=class extends i{bucket;constructor(e,t){super(t);let[s]=decodeURIComponent(e.pathname.replace("/%40s3/","").replace("/@s3/","")).split("/").filter(Boolean);this.bucket=s}async exec(e){if(!this.hasNot(this.bucket,e))try{e.setHeader("x-amzn-requestid",this.requestId);let t=i.persistence.buckets[this.bucket].tags;if(!t)throw new te(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=i.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 g){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(g.genericError({Code:"UnknownError",Message:t.message,RequestId:this.requestId}));return}e.end(t?.toString?.())}}};var Te=r=>{let{url:e,headers:t}=r,s=new URL(e,"http://localhost:3000"),n=s.searchParams.get("x-id"),o=t["user-agent"],c=s.pathname.replace("/%40s3/","").replace("/@s3/","").split("/").filter(Boolean).length==1;if(o&&o.startsWith("aws-cli")){let[,a]=o.split("command/"),[,...u]=a.split(".");switch(u.join(".")){case"ls":return/@s3\/?$/.test(e)?new q(s,t):s.searchParams.get("list-type")=="2"?new C(s,t):new x(s,t);case"list-buckets":return new q(s,t);case"list-objects":return new x(s,t);case"list-objects-v2":return new C(s,t);case"rb.rm":return s.searchParams.get("list-type")=="2"?new C(s,t):new x(s,t);case"get-object":return new E(s,t);case"cp":case"mv":case"sync":return c?s.searchParams.get("list-type")=="2"?new C(s,t):new x(s,t):new E(s,t);case"get-bucket-tagging":return new B(s,t);case"get-object-tagging":return new z(s,t);default:break}}else{if(!n)return s.searchParams.has("tagging")?c?new B(s,t):new z(s,t):e.endsWith("@s3/")?new q(s,t):s.searchParams.get("list-type")=="2"?new C(s,t):new x(s,t);if(n=="GetObject")return new E(s,t)}return new S(s,t)};var qe=require("fs"),he=R(require("path")),M=require("fs/promises");var L=class extends i{bucket;key;contentType;cacheControl;contentDisposition;contentEncoding;contentLanguage;websiteRedirectLocation;expires;storageClass="STANDARD";tagging;constructor(e,t){super(t);let[s,...n]=decodeURIComponent(e.pathname.replace("/%40s3/","").replace("/@s3/","")).split("/").filter(Boolean);this.bucket=s,this.key=n.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 o=t["x-amz-storage-class"];o&&(this.storageClass=o);let c=new Date(t.expires);isNaN(c)||(this.expires=c.getTime())}async exec(e,t){if(this.hasNot(this.bucket,e)||!this.isValidStorageClass(this.storageClass,e))return;let s={};if(this.tagging){let u=()=>{e.statusCode=400,e.setHeader("Content-Type","application/xml"),e.end(new ee({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"||!ot(this.tagging))return u();let d=new URLSearchParams(this.tagging);for(let m of d.keys()){if(m in s){e.statusCode=400,e.setHeader("Content-Type","application/xml"),e.end(new I({TagKey:m,RequestId:this.requestId,Message:"Cannot provide multiple Tags with the same key"}).toXml());return}if(m.length>128||m.length<1){e.statusCode=400,e.setHeader("Content-Type","application/xml"),e.end(new I({TagKey:m,RequestId:this.requestId,Message:"The TagKey you have provided is invalid"}).toXml());return}let p=d.get(m);if(p.length>256){e.statusCode=400,e.setHeader("Content-Type","application/xml"),e.end(new I({TagKey:m,RequestId:this.requestId,Message:"The TagValue you have provided is invalid"}).toXml());return}s[m]=p}}let n=Object.keys(s).length;if(n>10){e.statusCode=400,e.setHeader("Content-Type","application/xml"),e.end(new v({Message:`Object tag count cannot be greater than ${10}`,RequestId:this.requestId}).toXml());return}let o=i.genLocalKey(this.bucket,this.key),c=he.default.join(i.localStoragePath,this.bucket,o);try{await(0,M.mkdir)(he.default.dirname(c),{recursive:!0})}catch{}let a=(0,qe.createWriteStream)(c);a.on("close",async()=>{try{let u=await(0,M.stat)(c),d=w(await(0,M.readFile)(c));i.persistence.buckets[this.bucket].objects[this.key]={currentKey:o,type:this.contentType,cacheControl:this.cacheControl,contentDisposition:this.contentDisposition,contentEncoding:this.contentEncoding,contentLanguage:this.contentLanguage,expires:this.expires,websiteRedirectLocation:this.websiteRedirectLocation,ETag:d,size:u.size,LastModified:u.mtimeMs,StorageClass:this.storageClass,metadata:this.metadata,versions:{[o]:{}},tags:n?s:void 0};let m=t.socket.remoteAddress?.split(":")?.[3]??"127.0.0.1";e.end(),await H(i.callableLambdas,{bucket:this.bucket,key:this.key,requestId:this.requestId,requestCmd:"PutObject",eTag:d,sourceIPAddress:m,size:u.size})}catch(u){console.log(u)}}),e.setHeader("status",100),e.setHeader("Server","AmazonS3"),e.setHeader("x-amzn-requestid",this.requestId),t.pipe(a)}},ot=r=>!r.split("&").find(e=>e.split("=").length>2);var j=class extends i{bucket;constructor(e,t){super(t);let[s]=decodeURIComponent(e.pathname.replace("/%40s3/","").replace("/@s3/","")).split("/").filter(Boolean);this.bucket=s}async exec(e){if(!i.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"?> <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(i.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"?> <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 i.createBucketDir(this.bucket,{deletionPolicy:"Retain"}),e.statusCode=200,e.setHeader("x-amzn-requestid",this.requestId),e.setHeader("Location",`/${this.bucket}`),e.setHeader("Server","AmazonS3"),e.end()}};var fe=R(require("path")),P=require("fs/promises");var A=class extends i{bucket;key;sourceBucket;sourceKey;contentType;cacheControl;contentDisposition;contentEncoding;contentLanguage;websiteRedirectLocation;expires;storageClass="STANDARD";metadataDirective;ifMatch;ifNoneMatch;ifModifiedSince;ifUnmodifiedSince;constructor(e,t){super(t);let[s,...n]=decodeURIComponent(e.pathname.replace("/%40s3/","").replace("/@s3/","")).split("/").filter(Boolean);this.bucket=s,this.key=n.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 o=t["x-amz-storage-class"];o&&(this.storageClass=o);let c=new Date(t.expires);isNaN(c)||(this.expires=c.getTime()),this.metadataDirective=t["x-amz-metadata-directive"];let a=t["x-amz-copy-source"]??"",[u,...d]=decodeURIComponent(a.replace("/@s3/","")).split("/").filter(Boolean);this.sourceBucket=u,this.sourceKey=d.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())}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(!i.persistence.buckets[this.sourceBucket].objects[this.sourceKey]){e.writeHead(404,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(f({Key:this.sourceKey,RequestId:this.requestId}));return}let s=i.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(m=>m===!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=N(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=fe.default.join(i.localStoragePath,this.sourceBucket,s.currentKey),a=i.genLocalKey(this.bucket,this.key),u=fe.default.join(i.localStoragePath,this.bucket,a);try{await(0,P.copyFile)(c,u);let d=await(0,P.stat)(u),m=w(await(0,P.readFile)(u));this.metadataDirective=="COPY"?i.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:m,StorageClass:s.StorageClass,LastModified:d.mtimeMs,size:d.size,metadata:s.metadata,versions:{[a]:{}}}:i.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:m,StorageClass:this.storageClass,LastModified:d.mtimeMs,size:d.size,metadata:this.metadata,websiteRedirectLocation:this.websiteRedirectLocation,versions:{[a]:{}}};let p=new Date(d.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"?> <CopyObjectResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><LastModified>${p}</LastModified><ETag>${m}</ETag></CopyObjectResult>`);let l=t.socket.remoteAddress?.split(":")?.[3]??"127.0.0.1";await H(i.callableLambdas,{bucket:this.bucket,key:this.key,requestId:this.requestId,requestCmd:"CopyObject",eTag:m,sourceIPAddress:l,size:d.size})}catch(d){console.error(d),e.statusCode=500,e.end("Internal Server Error")}}};var U=class extends i{bucket;constructor(e,t){super(t);let[s]=decodeURIComponent(e.pathname.replace("/%40s3/","").replace("/@s3/","")).split("/").filter(Boolean);this.bucket=s}async exec(e,t){if(!this.hasNot(this.bucket,e))try{e.setHeader("x-amzn-requestid",this.requestId),i.persistence.buckets[this.bucket].tags=await i.getTagsFromRequest(t,this.requestId,"Bucket"),e.statusCode=204,e.end()}catch(s){if(e.statusCode=400,s instanceof g){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(g.genericError({Code:"UnknownError",Message:s.message,RequestId:this.requestId}));return}e.end(s?.toString?.())}}};var D=class extends i{bucket;key;constructor(e,t){super(t);let[s,...n]=decodeURIComponent(e.pathname.replace("/%40s3/","").replace("/@s3/","")).split("/").filter(Boolean);this.bucket=s,this.key=n.join("/")}async exec(e,t){if(!this.hasNot(this.bucket,e)){if(!i.persistence.buckets[this.bucket].objects[this.key]){e.writeHead(404,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(f({Key:this.key,RequestId:this.requestId}));return}try{e.setHeader("x-amzn-requestid",this.requestId),i.persistence.buckets[this.bucket].objects[this.key].tags=await i.getTagsFromRequest(t,this.requestId,"Object"),e.statusCode=200,e.end()}catch(s){if(e.statusCode=400,s instanceof g){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(g.genericError({Code:"UnknownError",Message:s.message,RequestId:this.requestId}));return}e.end(s?.toString?.())}}}};var K=class extends i{bucket;constructor(e,t){super(t);let[s]=decodeURIComponent(e.pathname.replace("/%40s3/","").replace("/@s3/","")).split("/").filter(Boolean);this.bucket=s}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 k("PutBucketPolicy",this.requestId).toXml()))}};var O=class extends i{bucket;constructor(e,t){super(t);let[s]=decodeURIComponent(e.pathname.replace("/%40s3/","").replace("/@s3/","")).split("/").filter(Boolean);this.bucket=s}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 k("PutBucketCors",this.requestId).toXml()))}};var $=class extends i{bucket;constructor(e,t){super(t);let[s]=decodeURIComponent(e.pathname.replace("/%40s3/","").replace("/@s3/","")).split("/").filter(Boolean);this.bucket=s}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 k("PutBucketAcl",this.requestId).toXml()))}};var _=class extends i{bucket;constructor(e,t){super(t);let[s]=decodeURIComponent(e.pathname.replace("/%40s3/","").replace("/@s3/","")).split("/").filter(Boolean);this.bucket=s}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 k("PutObjectAcl",this.requestId).toXml()))}};var Ee=r=>{let{url:e,headers:t}=r,s=new URL(e,"http://localhost:3000"),n=s.searchParams.get("x-id"),o=t["user-agent"];if(o&&o.startsWith("aws-cli")){let[,c]=o.split("command/"),[,...a]=c.split("."),u=a.join("."),d=typeof t["x-amz-copy-source"]=="string";switch(u){case"cp":case"sync":case"mv":return d?new A(s,t):new L(s,t);case"mb":case"create-bucket":return new j(s,t);case"copy-object":return new A(s,t);case"put-object":return new L(s,t);case"put-bucket-tagging":return new U(s,t);case"put-object-tagging":return new D(s,t);case"put-bucket-policy":return new K(s,t);case"put-bucket-cors":return new O(s,t);case"put-bucket-acl":return new $(s,t);case"put-object-acl":return new _(s,t);default:break}}else{if(!n){let c=s.pathname.replace("/%40s3/","").replace("/@s3/","").split("/").filter(Boolean).length==1;return s.searchParams.has("policy")?new K(s,t):s.searchParams.has("cors")?new O(s,t):s.searchParams.has("acl")?c?new $(s,t):new _(s,t):s.searchParams.has("tagging")?c?new U(s,t):new D(s,t):new j(s,t)}if(n=="PutObject")return new L(s,t);if(n=="CopyObject")return new A(s,t)}return new S(s,t)};var ie=class extends i{bucket;constructor(e,t){super(t);let[s]=decodeURIComponent(e.pathname.replace("/%40s3/","").replace("/@s3/","")).split("/").filter(Boolean);this.bucket=s}exec(e){this.hasNot(this.bucket,e)||(e.statusCode=200,e.setHeader("x-amzn-requestid",this.requestId),e.end())}};var ye=R(require("path"));var ae=class extends i{filePath;bucketPath;bucket;key;versionId;partNumber;range;ifMatch;ifNoneMatch;ifModifiedSince;ifUnmodifiedSince;constructor(e,t){super(t);let s=decodeURIComponent(e.pathname.replace("/%40s3/","").replace("/@s3/","")),[n,...o]=s.split("/").filter(Boolean);if(this.bucket=n,this.key=o.join("/"),this.bucketPath=ye.default.join(i.localStoragePath,n),this.filePath=ye.default.join(this.bucketPath,...o),this.versionId=e.searchParams.get("versionId"),this.partNumber=e.searchParams.has("partNumber")?Number(e.searchParams.get("partNumber")):null,t.range){let[c]=t.range.split("bytes=").filter(Boolean),[a,u]=c.split("-");!isNaN(Number(a))&&!isNaN(Number(u))&&(this.range=[Number(a),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())}async exec(e){if(!this.hasNot(this.bucket,e)){if(!i.persistence.buckets[this.bucket].objects[this.key]){e.writeHead(404,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(f({Key:this.key,RequestId:this.requestId}));return}try{let t={ifMatch:this.ifMatch,ifModifiedSince:this.ifModifiedSince,ifNoneMatch:this.ifNoneMatch,ifUnmodifiedSince:this.ifUnmodifiedSince},s=i.persistence.buckets[this.bucket].objects[this.key],n=N(t,s);if(n==200){let o=200,c=s.size,a,u=s.type,d={};if(this.range){o=206,d.start=this.range[0],d.end=this.range[1];let m=1;d.end>s.size&&(d.end=s.size,m--),c=m+d.end-d.start,a=`bytes ${d.start}-${d.end}/${s.size}`,u="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),u&&e.setHeader("Content-Type",u),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),Object.entries(s.metadata).forEach(([m,p])=>{e.setHeader(m,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 Le=r=>{let{url:e,headers:t}=r,s=new URL(e,"http://localhost:3000");return s.pathname.replace("/%40s3/","").replace("/@s3/","").split("/").filter(Boolean).length>1?new ae(s,t):new ie(s,t)};var Me=require("fs/promises"),Ae=R(require("path")),F=class extends i{bucket;constructor(e,t){super(t);let s=decodeURIComponent(e.pathname.replace("/%40s3/","").replace("/@s3/","")),[n]=s.split("/").filter(Boolean);this.bucket=n}async exec(e,...t){if(!this.hasNot(this.bucket,e))try{let n=!(Object.keys(i.persistence.buckets[this.bucket].objects).length>0&&i.persistence.buckets[this.bucket].deletionPolicy=="Retain");await(0,Me.rm)(Ae.default.join(i.localStoragePath,this.bucket),{recursive:n,force:!0}),delete i.persistence.buckets[this.bucket],e.writeHead(204,{"x-amzn-requestid":this.requestId,Server:"AmazonS3"}).end()}catch{e.writeHead(404,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(`<?xml version="1.0" encoding="UTF-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>`)}}};var V=class extends i{bucket;key;version;constructor(e,t){super(t);let s=decodeURIComponent(e.pathname.replace("/%40s3/","").replace("/@s3/","")),[n,...o]=s.split("/").filter(Boolean);this.bucket=n,this.key=o.join("/"),this.version=e.searchParams.get("versionId")}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"),e.end();let s=t.socket.remoteAddress?.split(":")?.[3]??"127.0.0.1";await i.removeObject(this.bucket,this.key,s,this.requestId)}};var ce=class extends i{bucket;constructor(e,t){super(t);let[s]=decodeURIComponent(e.pathname.replace("/%40s3/","").replace("/@s3/","")).split("/").filter(Boolean);this.bucket=s}async exec(e){if(!this.hasNot(this.bucket,e))try{i.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 g){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(g.genericError({Code:"UnknownError",Message:t.message,RequestId:this.requestId}));return}e.end(t?.toString?.())}}};var de=class extends i{bucket;key;constructor(e,t){super(t);let[s,...n]=decodeURIComponent(e.pathname.replace("/%40s3/","").replace("/@s3/","")).split("/").filter(Boolean);this.bucket=s,this.key=n.join("/")}async exec(e){if(!this.hasNot(this.bucket,e)){if(!i.persistence.buckets[this.bucket].objects[this.key]){e.writeHead(404,{"x-amzn-requestid":this.requestId,"Content-Type":"application/xml",Server:"AmazonS3"}).end(f({Key:this.key,RequestId:this.requestId}));return}try{i.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 g){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(g.genericError({Code:"UnknownError",Message:t.message,RequestId:this.requestId}));return}e.end(t?.toString?.())}}}};var it=new Set(["rm","rb.rm","mv","delete-object"]),Pe=r=>{let{url:e,headers:t}=r,s=new URL(e,"http://localhost:3000"),n=s.pathname.replace("/%40s3/","").replace("/@s3/","").split("/").filter(Boolean).length==1;if(s.searchParams.has("tagging"))return n?new ce(s,t):new de(s,t);let o=t["user-agent"];if(o&&o.startsWith("aws-cli")){let[,c]=o.split("command/"),[,...a]=c.split("."),u=a.join(".");if(it.has(u))return new V(s,t);if(u=="rb"||u=="delete-bucket")return new F(s,t)}else{let c=s.searchParams.get("x-id");if(!c)return new F(s,t);if(c=="DeleteObject")return new V(s,t)}return new S(s,t)};var X=class r{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=e=>e.toLowerCase().split("-").map(Ne).join("-");static getMultiValueHeaders=e=>{let t={},s=e.filter((o,c)=>c%2==0).map(o=>o.toLowerCase()),n=e.filter((o,c)=>c%2!==0);return s.forEach((o,c)=>{o!="x-mock-type"&&(t[o]?t[o].push(n[c]):t[o]=[n[c]])}),t};static getIsBase64Encoded=e=>{let t=e["content-type"];return e["content-encoding"]||!t?!0:!(t.startsWith("application/json")||t.startsWith("application/xml")||t.startsWith("application/javascript")||t.startsWith("text/"))};static knownHeaders=["accept","accept-encoding","user-agent","host","via","content-length"];static getApiGV1Headers(e,t){let{rawHeaders:s}=e,n,o={"X-Forwarded-For":e.socket.remoteAddress,"X-Forwarded-Proto":"http","X-Forwarded-Port":String(r.port)};for(let d=0;d<s.length;){let m=s[d],p=m.toLowerCase();if(["connection","x-mock-type"].includes(p)){d=d+2;continue}this.knownHeaders.includes(p)&&(m=this.normalizeHeaderKey(p));let l=s[d+1];o[m]=l,p=="x-api-key"&&(n=l),d=d+2}let c={};for(let d of Object.keys(o).sort((m,p)=>m.localeCompare(p)))c[d]=o[d];let a={"X-Forwarded-For":[e.socket.remoteAddress],"X-Forwarded-Proto":["http"],"X-Forwarded-Port":[String(r.port)]};for(let d=0;d<s.length;){let m=s[d],p=m.toLowerCase();if(["connection","x-mock-type"].includes(p)){d=d+2;continue}this.knownHeaders.includes(p)&&(m=this.normalizeHeaderKey(p));let l=s[d+1];a[m]?a[m].push(l):a[m]=[l],d=d+2}let u={};for(let d of Object.keys(a).sort((m,p)=>m.localeCompare(p)))u[d]=a[d];return{headers:c,multiValueHeaders:u,apiKey:n}}static getCustomHeaders(e,t){let{headers:s}=e;return delete s["x-mock-type"],delete s.connection,{"X-Forwarded-For":e.socket.remoteAddress,"X-Forwarded-Proto":"http","X-Forwarded-Port":String(r.port),...s}}static getPathParameters(e,t){let s=e.paths[0].split("/"),n=t.pathname.split("/"),o={};return s.forEach((c,a)=>{c.startsWith("{")&&c.endsWith("}")&&!c.endsWith("+}")&&(o[c.slice(1,-1)]=n[a])}),o}static normalizeSearchParams=(e,t)=>{let s={};Array.from(e.keys()).forEach(c=>{let a=e.getAll(c).map(d=>d.toLowerCase()),u=c.toLowerCase();a?s[u]?s[u].push(...a):s[u]=a:s[u]||(s[u]=void 0)});let n="",o=t.indexOf("?");return o!=-1&&(n=t.slice(o+1)),s.toString=()=>n,s};static getMultiValueQueryStringParameters=e=>{let t={};e.delete("x_mock_type");for(let s of Array.from(new Set(e.keys())))t[s]=e.getAll(s).map(encodeURI);return t};static isEndpointTimeoutError=e=>{if(!e)return;let t=e.match(this.timeoutRegex)?.[0];if(t){let s=t.split(" ")[1];if(!isNaN(s))return Number(s)>=r.apgRequestTimeout}}};var ue=!1,at=r=>{ue=r},ct=()=>ue,G=(r,e)=>{ue&&console.log(`\x1B[${r}m${e}\x1B[0m`)},dt=r=>console.log(`\x1B[31m${r}\x1B[0m`),ut=r=>G("32",r),mt=r=>G("33",r),pt=r=>G("36",r),lt=r=>G("90",r),gt=r=>G("94",r),ht=r=>ue?console.log(r):void 0,ze={GREEN:ut,YELLOW:mt,CYAN:pt,BR_BLUE:gt,RED:dt,GREY:lt,setDebug:at,getDebug:ct,info:ht};var Be="application/vnd.awslambda.http-integration-response",be=class r{buffer;_isHttpIntegrationResponse;_metaDelimiter;_endDelimiter;_ct;_isStreamResponse=!0;#e;static codec=new TextDecoder;static splitMessage=(e,t)=>{if(!e)return;let s=Array.from(e.values()),n=null;if(t)n=t;else for(let o=0;o<s.length;o++)if(s[o]===0&&[s[o+1],s[o+2],s[o+3],s[o+4],s[o+5],s[o+6],s[o+7]].every(u=>u===0)){n=o;break}if(n)return new Uint8Array(s.slice(0,n))};constructor(e){this._isHttpIntegrationResponse=!1,this._metaDelimiter=0,this._endDelimiter=0,this.#e=e}setHeader(e,t){this._isHttpIntegrationResponse=!this.buffer&&t==Be&&(!this._ct||this._ct==Be),this._ct=t}write(e,t){!this._isHttpIntegrationResponse&&!this._metaDelimiter&&(this._metaDelimiter=e.byteLength),this.#s(e)}end(e){this.buffer&&(this._endDelimiter=this.buffer.byteLength),e&&this.#s(e)}destroy(){}#s(e){this.buffer=typeof this.buffer>"u"?e:Buffer.concat([this.buffer,e])}getParsedResponse(){if(!this.#e)return;let e=this.#e.kind;if(e=="alb")return this.#n();if(e=="url")return this.#o();if(e=="apg")return this.#r()}#n(){let e=this._isHttpIntegrationResponse?r.splitMessage(this.buffer):this.buffer,t;return e&&(t=this.#t(e)),t}#r(){if(this._isHttpIntegrationResponse)return ze.RED("awslambda.HttpResponseStream.from() is not supported with API Gateway"),{statusCode:500,headers:{"Content-Type":X.contentType.json},body:X.httpErrMsg};if(this.buffer)return this.#t(this.buffer)}#o(){let e=r.splitMessage(this.buffer,this._isHttpIntegrationResponse?void 0:this._metaDelimiter),t;return e&&(t=this.#t(e)),t}#t(e){let t=r.codec.decode(e);if(typeof t=="string")try{t=JSON.parse(t)}catch{}return t}};var je="<html><head><title>400 Request Header Or Cookie Too Large</title></head><body><center><h1>400 Bad