exlo 0.0.14 → 0.0.16
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.
- package/dist/cli/index.mjs +1 -1
- package/dist/defineConfig.mjs +1 -1
- package/dist/plugins/dynamodb/src/proxy/proxy.d.ts +6 -1
- package/dist/plugins/dynamodb/src/proxy/worker.mjs +1 -1
- package/dist/plugins/s3/actions/AbortMultipartUploadAction.d.ts +1 -1
- package/dist/plugins/s3/actions/CompleteMultipartUploadAction.d.ts +1 -1
- package/dist/plugins/s3/actions/CreateBucketAction.d.ts +2 -2
- package/dist/plugins/s3/actions/CreateMultipartUploadAction.d.ts +1 -1
- package/dist/plugins/s3/actions/DeleteBucketAction.d.ts +2 -2
- package/dist/plugins/s3/actions/DeleteBucketPolicyAction.d.ts +2 -2
- package/dist/plugins/s3/actions/DeleteBucketTaggingAction.d.ts +2 -2
- package/dist/plugins/s3/actions/DeleteObjectAction.d.ts +1 -1
- package/dist/plugins/s3/actions/DeleteObjectTaggingAction.d.ts +2 -2
- package/dist/plugins/s3/actions/GetBucketAclAction.d.ts +2 -2
- package/dist/plugins/s3/actions/GetBucketPolicy.d.ts +2 -2
- package/dist/plugins/s3/actions/GetBucketTaggingAction.d.ts +2 -2
- package/dist/plugins/s3/actions/GetObjectAclAction.d.ts +2 -2
- package/dist/plugins/s3/actions/GetObjectAction.d.ts +3 -3
- package/dist/plugins/s3/actions/GetObjectTaggingAction.d.ts +2 -2
- package/dist/plugins/s3/actions/HeadBucketAction.d.ts +2 -2
- package/dist/plugins/s3/actions/HeadObjectAction.d.ts +2 -2
- package/dist/plugins/s3/actions/ListBucketsAction.d.ts +2 -2
- package/dist/plugins/s3/actions/ListMultipartUploadsAction.d.ts +2 -2
- package/dist/plugins/s3/actions/ListObjectsAction.d.ts +4 -4
- package/dist/plugins/s3/actions/ListPartsAction.d.ts +2 -2
- package/dist/plugins/s3/actions/PutObjectAction.d.ts +2 -2
- package/dist/plugins/s3/actions/UnknownAction.d.ts +2 -2
- package/dist/plugins/s3/actions/localAction.d.ts +7 -2
- package/dist/plugins/s3/index.mjs +63 -63
- package/dist/standalone.js +1 -1
- package/dist/standalone.mjs +1 -1
- package/package.json +9 -9
package/dist/cli/index.mjs
CHANGED
|
@@ -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.
|
|
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.16";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+=`
|
package/dist/defineConfig.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var h="0.0.
|
|
1
|
+
var h="0.0.16";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};
|
|
@@ -14,6 +14,11 @@ export declare class ProxyDynamoDbServer {
|
|
|
14
14
|
private redirect;
|
|
15
15
|
private safeReturnThrownError;
|
|
16
16
|
private dynamoDbLocalEndpoint;
|
|
17
|
+
tableSchemas: {
|
|
18
|
+
TableName: string;
|
|
19
|
+
TableArn: string;
|
|
20
|
+
KeySchema: IStreamDescription["KeySchema"];
|
|
21
|
+
}[];
|
|
17
22
|
server?: Server;
|
|
18
23
|
streams: ProxyDynamoStream[];
|
|
19
24
|
itemsWithTTL: Record<string, {
|
|
@@ -50,7 +55,7 @@ export declare class ProxyDynamoDbServer {
|
|
|
50
55
|
BatchWriteItem(req: IncomingMessage, res: ServerResponse): Promise<void>;
|
|
51
56
|
TransactWriteItems(req: IncomingMessage, res: ServerResponse): Promise<void>;
|
|
52
57
|
private setDynamoDbLocalEndpoint;
|
|
53
|
-
private
|
|
58
|
+
private setupInitialTables;
|
|
54
59
|
private watchTTL;
|
|
55
60
|
init(): Promise<number>;
|
|
56
61
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{parentPort as H,workerData as b}from"node:worker_threads";import{DynamoDB as Q}from"@aws-sdk/client-dynamodb";import D,{createServer as W}from"node:http";import{isDeepStrictEqual as w}from"node:util";import{EventSourceMapping as he}from"exlo/internal/esm";import{EventSourceMapping as ae}from"exlo/internal/esm";var g=c=>Object.prototype.toString.call(c)=="[object Object]";import{randomUUID as q}from"node:crypto";var A=new TextEncoder;function O(c){if(!c)return 0;let t=0,e={};for(let a in c){if(!c.hasOwnProperty(a))continue;let n={sizeOfName:A.encode(a).length,attributeSize:_(c[a])};n.total=n.sizeOfName+n.attributeSize,t+=n.total,e[a]=n}return t}function _(c){if(!c)return 0;if(c.hasOwnProperty("B"))return atob(c.B).length;if(c.hasOwnProperty("S"))return A.encode(c.S).length;if(c.hasOwnProperty("N"))return C(c.N);if(c.hasOwnProperty("BS")){let t=0;for(let e=0;e<c.BS.length;e++)t+=atob(c.BS[e]).length;return t}if(c.hasOwnProperty("SS")){let t=0;for(let e=0;e<c.SS.length;e++)t+=A.encode(c.SS[e]).length;return t}if(c.hasOwnProperty("NS")){let t=0;for(let e=0;e<c.NS.length;e++)t+=C(c.NS[e]);return t}if(c.hasOwnProperty("BOOL")||c.hasOwnProperty("NULL"))return 1;if(c.hasOwnProperty("M")){let t=3;for(let e in c.M)c.M.hasOwnProperty(e)&&(t+=A.encode(e).length,t+=_(c.M[e]),t+=1);return t}if(c.hasOwnProperty("L")){let t=3;for(let e=0;e<c.L.length;e++)t+=_(c.L[e]),t+=1;return t}throw`unknown data type in ${JSON.stringify(c)}`}var x=class{value=0;rawValue;constructor(t){this.rawValue=t,this.value=Number(t)}toFixed(){return this.rawValue.split(".")[0]}};function C(c){let t=new x(c);if(t.value==0)return 1;let e=t.toFixed(),a=U(e.replace("-",""))+1;return e.startsWith("-")&&a++,a>21&&(a=21),a}function U(c){if(c.indexOf(".")!==-1){let t=c.split("."),e=t[0],a=t[1];return e==="0"&&(e="",a=V(a,!0)),e.length%2!==0&&(e=`Z${e}`),a.length%2!==0&&(a=`${a}Z`),U(e+a)}return c=V(c,!0,!0),Math.ceil(c.length/2)}function V(c,t,e){for(;t;){let a=c.replace(/^(0{2})/,"");if(a.length==c.length)break;c=a}for(;e;){let a=c.replace(/(0{2})$/,"");if(a.length==c.length)break;c=a}return c}var R=class{#e;constructor(t=new Date){this.#e=t}getRawValue(){return this.#e}eq(t){return this.#e==t.getRawValue()}gt(t){return this.#e>t.getRawValue()}gte(t){return this.#e>=t.getRawValue()}lt(t){return this.#e<t.getRawValue()}lte(t){return this.#e<=t.getRawValue()}toISOString(){return this.#e.toISOString()}getTime(){return this.#e.getTime()}toJSON(){return this.#e.getTime()/1e3}};var T=class c{static create(){return new c(BigInt("100000000000000000000000"))}static createFromString(t){return new c(BigInt(t))}#e;constructor(t){this.#e=t}getRawValue(){return this.#e}plusplus(){this.#e++}dup(){return new c(this.#e)}eq(t){return this.#e==t.getRawValue()}gt(t){return this.#e>t.getRawValue()}gte(t){return this.#e>=t.getRawValue()}lt(t){return this.#e<t.getRawValue()}lte(t){return this.#e<=t.getRawValue()}toJSON(){return this.#e.toString()}toString(){return this.#e.toString()}};var v=class c{constructor(t,e,a,n){this.shardId=t;this.iteratorType=e;this.position=a;this.expires=n}static fromString(t){let e=JSON.parse(Buffer.from(t,"base64").toString("utf-8")),{shardId:a,position:n,expires:i,iteratorType:r}=e;return new c(a,r,n,new Date(i))}isExpired(){return new Date>this.expires}toString(){let t=JSON.stringify({shardId:this.shardId,iteratorType:this.iteratorType,position:this.position,expires:this.expires});return Buffer.from(t,"utf-8").toString("base64")}},B=class{ParentShardId;SequenceNumberRange;ShardId;#e=[];#t;constructor(t){this.#t=t,this.ShardId=`shardId-${q()}`,this.SequenceNumberRange={}}getId(){return this.#t}setRecord(t){this.SequenceNumberRange.StartingSequenceNumber||(this.SequenceNumberRange.StartingSequenceNumber=t.dynamodb.SequenceNumber),this.#e.push(t)}get records(){return this.#e}getRecords(t,e=1e3){let a=this.#e.slice(t.position,t.position+e),n=null,i=t.position+a.length;return n=this.getIterator("LATEST"),n.iteratorType=t.iteratorType,n.position=i,this.SequenceNumberRange.EndingSequenceNumber&&!this.#e[i]&&(n=null),{Records:a,nextIterator:n}}getIterator(t,e){let a;if(t=="TRIM_HORIZON")a=0;else if(t=="LATEST")a=this.#e.length;else if(e){let n=this.#e.findIndex(i=>i.dynamodb.SequenceNumber.eq(e));n==-1?a=this.#e.length+1:t=="AT_SEQUENCE_NUMBER"?a=n:a=n+1}else throw new Error("SequenceNumber is requied for this shardIteratorType");return new v(this.ShardId,t,a,new Date)}},E=class{constructor(t,e,a,n,i="123456789012",r="us-east-1"){this.TableName=t;this.#t=n,this.#n=i,this.#a=r;let o=new R,s=o.toISOString();s=s.split("Z")[0],this.#e=T.create(),this.TableArn=`arn:aws:dynamodb:${r}:${i}:table/${t}`,this.StreamDescription={CreationRequestDateTime:o,KeySchema:a,Shards:[],StreamArn:`${this.TableArn}/stream/${s}`,StreamStatus:"ENABLED",StreamViewType:e,StreamLabel:s,TableName:t};for(let d=1;d<=n;d++)this.StreamDescription.Shards.push(new B(d))}StreamDescription;TableArn;#e;#t;#a;#n;get maxShards(){return this.#t}findShardByHashId(t){let e=this.StreamDescription.Shards.find(n=>n.getId()==t);if(e)return e;let a=new B(t);return this.StreamDescription.Shards.push(a),a}setRecord(t,e,a){let n=this.#a,i=q().replaceAll("-",""),r="1.1",o="aws:dynamodb",s;t&&e?s="MODIFY":t?s="INSERT":s="REMOVE";let d=t??e,u={},m={};for(let{AttributeName:M,KeyType:J}of this.StreamDescription.KeySchema)u[M]=d[M],J=="HASH"&&(m=u[M]);this.#e.plusplus();let h=this.#e.dup(),l=["NEW_IMAGE","NEW_AND_OLD_IMAGES"].includes(this.StreamDescription.StreamViewType)?t:void 0,f=["OLD_IMAGE","NEW_AND_OLD_IMAGES"].includes(this.StreamDescription.StreamViewType)?e:void 0,y=O(l)+O(f)+O(u),I={ApproximateCreationDateTime:new R,Keys:u,NewImage:l,OldImage:f,SequenceNumber:h,SizeBytes:y,StreamViewType:this.StreamDescription.StreamViewType},N={awsRegion:n,dynamodb:I,eventID:i,eventName:s,eventSource:o,eventVersion:r};a&&(N.userIdentity={type:"Service",principalId:"dynamodb.amazonaws.com"});let S=m.S??m.N??m.B,p=k(S,this.maxShards);this.findShardByHashId(p).setRecord(N)}getShardById(t){return this.StreamDescription.Shards.find(e=>e.ShardId==t)}};function $(c){let t=0;for(let e=0;e<c.length;e++)t=t*31+c.charCodeAt(e)>>>0;return t}function k(c,t=3){let a=$(c)%t;return a==0?1:a}var L=class c{constructor(t,e=0,a=3,n=!1,i="123456789012",r="us-east-1"){this.client=t;this.proxyPort=e;this.maxShards=a;this.inheritStreamsFromExistingTables=n;this.accountId=i;this.region=r}static async collectBuffer(t){let e=Buffer.alloc(0);return t.on("data",a=>{e=Buffer.concat([e,a])}),new Promise(a=>{t.on("end",async()=>{a(e)})})}static async collectBody(t){return(await this.collectBuffer(t)).toString("utf-8")}static async collectJsonObjectOrReturnError(t,e){try{let a=JSON.parse(await this.collectBody(t));if(!a||Array.isArray(a)||typeof a!="object")throw new Error("Invalid request");return a}catch{e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",Message:"Invalid Request Body"}));return}}redirect(t,e,a){let n=D.request(new URL(t.url,this.dynamoDbLocalEndpoint),{headers:t.headers,method:t.method},i=>{e.writeHead(i.statusCode,i.statusMessage,i.headers),i.pipe(e)});a&&n.write(a)}safeReturnThrownError(t,e,a,n){if(a?.$response?.body){let i=a.$response.body,r={};for(let d of Object.keys(a))d.startsWith("$")||(r[d]=a[d]);let o={};typeof i.headers.server=="string"&&(o.server=i.headers.server),typeof i.headers.date=="string"&&(o.date=i.headers.date),typeof i.headers["x-amzn-requestid"]=="string"&&(o["x-amzn-requestid"]=i.headers["x-amzn-requestid"]),o["content-type"]="application/x-amz-json-1.0";let s=JSON.stringify(r);o["content-length"]=Buffer.from(s).byteLength,e.writeHead(i.statusCode,i.statusMessage,o),e.end(s)}else return this.redirect(t,e,n)}dynamoDbLocalEndpoint="http://localhost:8000";server;streams=[];itemsWithTTL={};getStreamByTableName(t){return this.streams.find(e=>(e.TableName==t||e.TableArn==t)&&e.StreamDescription.StreamStatus=="ENABLED")}getTableKeySchemaAttributeNames(t){let e=this.streams.find(a=>a.TableName==t||a.TableArn==t);if(e)return e.StreamDescription.KeySchema.map(a=>a.AttributeName)}getStreamByArn(t){return this.streams.find(e=>e.StreamDescription.StreamArn==t)}trackTTLRecord(t,e){if(!e)return;let a=this.itemsWithTTL[t];if(a)try{let n={};for(let o of a.keySchema)n[o.AttributeName]=e[o.AttributeName];let i=JSON.stringify(n);if(!e[a.ttlFieldName]){a.items.delete(i);return}let r=new Date(Number(e[a.ttlFieldName].N)*1e3);a.items.set(i,{oldImage:e,ttl:r.getTime(),key:n})}catch(n){console.error(n)}}setRecord(t,e,a,n=!1){let i=this.getStreamByTableName(t);if(i&&i.setRecord(e,a,n),!n&&!e&&a){let r=this.itemsWithTTL[t];if(!r)return;let o={};for(let d of r.keySchema)o[d.AttributeName]=a[d.AttributeName];let s=JSON.stringify(o);r.items.delete(s);return}this.trackTTLRecord(t,e)}async getBodyIfJsonObject(t,e){let a=await c.collectBuffer(t),n=a.toString("utf-8"),i;try{if(i=JSON.parse(n),!i||Array.isArray(i)||typeof i!="object")throw new Error("");return{buf:a,rawBody:n,parsedBody:i}}catch{return this.redirect(t,e,a)}}static isValidStreamArn(t){if(!t||typeof t!="string")return!1;let e=t.split("/");if(e.length!=4)return!1;let[a,n,i,r]=e;if(i!="stream"||!new Date(r).getTime())return!1;let o=a.split(":");if(o.length!=6)return!1;let[s,d,u,m,h,l]=o;return!(!(s=="arn"&&u=="dynamodb"&&l=="table")||!["aws","aws-cn","aws-us-gov"].includes(d))}static isValidShardIteratorType(t){return!t||typeof t!="string"?!1:["AFTER_SEQUENCE_NUMBER","LATEST","AT_SEQUENCE_NUMBER","TRIM_HORIZON"].includes(t)}async GetRecords(t,e){let a=await c.collectJsonObjectOrReturnError(t,e);if(!a)return;let{ShardIterator:n,Limit:i}=a,r=typeof n=="string"?n:"",[o,s,d]=r.split("|"),u=this.getStreamByArn(o);if(!u){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",Message:"Invalid ShardIterator"}));return}let m;try{m=v.fromString(d)}catch{e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",Message:"Invalid ShardIterator"}));return}let h=u.getShardById(m.shardId);if(!h){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",Message:"Invalid ShardIterator"}));return}let{Records:l,nextIterator:f}=h.getRecords(m,i?Number(i):void 0),y=null;f&&(y=`${u.StreamDescription.StreamArn}|${h.getId()}|${f.toString()}`),e.end(JSON.stringify({NextShardIterator:y,Records:l}))}async GetShardIterator(t,e){let a=await c.collectJsonObjectOrReturnError(t,e);if(!a)return;let{ShardId:n,ShardIteratorType:i,StreamArn:r,SequenceNumber:o}=a;if(!c.isValidStreamArn(r)){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",Message:"Invalid StreamArn"}));return}let s=this.getStreamByArn(r);if(!s){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazonaws.dynamodb.v20120810#ResourceNotFoundException",message:`Requested resource not found: Stream: ${r} not found`}));return}if(!c.isValidShardIteratorType(i)){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",message:`1 validation error detected: Value '${i}' at 'shardIteratorType' failed to satisfy constraint: Member must satisfy enum value set: [AFTER_SEQUENCE_NUMBER, LATEST, AT_SEQUENCE_NUMBER, TRIM_HORIZON]`}));return}let d=s.getShardById(n);if(!d){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazonaws.dynamodb.v20120810#ResourceNotFoundException",message:"Requested resource not found: Shard does not exist"}));return}if(["AT_SEQUENCE_NUMBER","AFTER_SEQUENCE_NUMBER"].includes(i)){if(!o){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",Message:"One or more parameter values were invalid: SequenceNumber cannot be null"}));return}}else if(o){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",Message:"One or more parameter values were invalid: SequenceNumber should not be passed for this iterator type"}));return}let u;if(typeof o<"u")if(typeof o=="string"){let m;if(o.length<21)m=`1 validation error detected: Value '${o}' at 'sequenceNumber' failed to satisfy constraint: Member must have length greater than or equal to 21`;else try{u=T.createFromString(o)}catch{m="Invalid SequenceNumber for the shard"}if(m){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",Message:m}));return}}else{let m;if(typeof o=="object"&&o?m="Start of structure or map found where not expected":typeof o=="number"?m="NUMBER_VALUE cannot be converted to String":typeof o=="boolean"&&(m=`${String(o).toUpperCase()}_VALUE cannot be converted to String`),m){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.service#SerializationException",Message:m}));return}}if(u){if(!d.SequenceNumberRange.StartingSequenceNumber){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",Message:"Invalid SequenceNumber for the shard"}));return}if(u.lt(d.SequenceNumberRange.StartingSequenceNumber)){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",Message:"Invalid SequenceNumber for the shard"}));return}if(d.SequenceNumberRange.EndingSequenceNumber&&u.gt(T.createFromString(d.SequenceNumberRange.EndingSequenceNumber))){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",Message:"Invalid SequenceNumber for the shard"}));return}}try{let m=d.getIterator(i,u);e.end(JSON.stringify({ShardIterator:`${s.StreamDescription.StreamArn}|${d.getId()}|${m.toString()}`}))}catch(m){console.error(m),e.end()}}async ListStreams(t,e){let a=await c.collectJsonObjectOrReturnError(t,e);if(!a)return;let{ExclusiveStartStreamArn:n,Limit:i,TableName:r}=a,o=i??100,s=r?this.streams.filter(d=>d.TableName==r||d.TableArn==r):this.streams;if(n){let d=s.findIndex(u=>u.StreamDescription.StreamArn==n);d!=-1&&(s=s.slice(d+1,o-1))}e.end(JSON.stringify({Streams:s.map(({TableName:d,StreamDescription:u})=>({StreamArn:u.StreamArn,StreamLabel:u.StreamLabel,TableName:d}))}))}async DescribeStream(t,e){let a=await c.collectJsonObjectOrReturnError(t,e);if(!a)return;let{StreamArn:n,ExclusiveStartShardId:i,Limit:r}=a;if(!c.isValidStreamArn(n)){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",Message:"Invalid StreamArn"}));return}let o=this.streams.find(u=>u.StreamDescription.StreamArn==n);if(!o){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazonaws.dynamodb.v20120810#ResourceNotFoundException",message:`Requested resource not found: Stream: ${n} not found`}));return}let s=r??100,d=o.StreamDescription.Shards;if(i){let u=d.findIndex(m=>m.ShardId==i);u!=-1&&(d=d.slice(u+1,s-1))}e.end(JSON.stringify({StreamDescription:{...o.StreamDescription,Shards:d}}))}async CreateTable(t,e){t.pipe(D.request(new URL(t.url,this.dynamoDbLocalEndpoint),{headers:t.headers,method:t.method},async a=>{if(e.writeHead(a.statusCode,a.statusMessage,a.headers),a.statusCode==200){let n=await c.collectBuffer(a),i=JSON.parse(n.toString("utf-8")),{TableName:r,KeySchema:o,TableArn:s,StreamSpecification:d}=i.TableDescription;d?.StreamEnabled&&this.streams.push(new E(r,d.StreamViewType,o,this.maxShards,this.accountId,this.region)),e.end(n)}else a.pipe(e)}))}async DeleteTable(t,e){t.pipe(D.request(new URL(t.url,this.dynamoDbLocalEndpoint),{headers:t.headers,method:t.method},async a=>{if(e.writeHead(a.statusCode,a.statusMessage,a.headers),a.statusCode==200){let n=await c.collectBuffer(a),i=JSON.parse(n.toString("utf-8")),{TableName:r}=i.TableDescription,o=this.streams.findIndex(s=>s.TableName==r||s.TableArn==r);o!=-1&&this.streams.splice(o,1),delete this.itemsWithTTL[r],e.end(n)}else a.pipe(e)}))}async UpdateTable(t,e){t.pipe(D.request(new URL(t.url,this.dynamoDbLocalEndpoint),{headers:t.headers,method:t.method},async a=>{if(e.writeHead(a.statusCode,a.statusMessage,a.headers),a.statusCode!=200){a.pipe(e);return}let n=await c.collectBuffer(a),i=JSON.parse(n.toString("utf-8")),{TableName:r,StreamSpecification:o,KeySchema:s}=i.TableDescription;if(o){let d=this.getStreamByTableName(r);typeof o.StreamEnabled=="boolean"?d?d.StreamDescription.StreamStatus=o.StreamEnabled?"ENABLED":"DISABLED":o.StreamEnabled&&this.streams.push(new E(r,o.StreamViewType,s,this.maxShards)):d?d.StreamDescription.StreamViewType=o.StreamViewType:this.streams.push(new E(r,o.StreamViewType,s,this.maxShards))}else{let d=this.streams.find(u=>u.TableName==r||u.TableArn==r);d&&(d.StreamDescription.StreamStatus="DISABLED")}e.end(n)}))}async UpdateTimeToLive(t,e){let a=await this.getBodyIfJsonObject(t,e);if(!a)return;let{buf:n,parsedBody:i}=a;try{let r=await this.client.updateTimeToLive(i);r.$metadata.httpStatusCode&&(e.statusCode=r.$metadata.httpStatusCode),r.$metadata.requestId&&e.setHeader("x-amzn-RequestId",r.$metadata.requestId);let{TableName:o}=i,s=this.streams.find(d=>d.TableName==o||d.TableArn==o);if(s){let{TimeToLiveSpecification:d}=r,{AttributeName:u,Enabled:m}=d,h=m,l=u;this.itemsWithTTL[o]??={items:new Map,ttlFieldName:l,enabled:h,keySchema:s.StreamDescription.KeySchema},this.itemsWithTTL[o].enabled=h,this.itemsWithTTL[o].ttlFieldName=l}e.end(JSON.stringify(r))}catch(r){this.safeReturnThrownError(t,e,r,n)}}async PutItem(t,e){let a=await this.getBodyIfJsonObject(t,e);if(!a)return;let{buf:n,rawBody:i,parsedBody:r}=a;try{let o=["NONE","ALL_OLD"],s=r.ReturnValues,d="";s?o.includes(s)?d="ALL_OLD":d=s:d="ALL_OLD";let u={...r,ReturnValues:d},m=await this.client.putItem(u);m.$metadata.httpStatusCode&&(e.statusCode=m.$metadata.httpStatusCode),m.$metadata.requestId&&e.setHeader("x-amzn-RequestId",m.$metadata.requestId);let{TableName:h,Item:l}=r,f=l,y=m.Attributes;this.setRecord(h,f,y);let I=JSON.stringify({...m,Attributes:s=="ALL_OLD"?m.Attributes:void 0});e.end(I)}catch(o){this.safeReturnThrownError(t,e,o,n)}}async DeleteItem(t,e){let a=await this.getBodyIfJsonObject(t,e);if(!a)return;let{buf:n,parsedBody:i}=a;try{let r=["NONE","ALL_OLD"],o=i.ReturnValues,s="";o?r.includes(o)?s="ALL_OLD":s=o:s="ALL_OLD";let d={...i,ReturnValues:s},u=await this.client.deleteItem(d);u.$metadata.httpStatusCode&&(e.statusCode=u.$metadata.httpStatusCode),u.$metadata.requestId&&e.setHeader("x-amzn-RequestId",u.$metadata.requestId);let{TableName:m}=i,h=void 0,l=u.Attributes;l&&this.setRecord(m,h,l);let f=JSON.stringify({...u,Attributes:o=="ALL_OLD"?u.Attributes:void 0});e.end(f)}catch(r){this.safeReturnThrownError(t,e,r,n)}}async UpdateItem(t,e){let a=await this.getBodyIfJsonObject(t,e);if(!a)return;let{buf:n,rawBody:i,parsedBody:r}=a;try{let{TableName:o,Key:s}=r,d;try{d=(await this.client.getItem({TableName:o,Key:s,ConsistentRead:!0})).Item}catch{}let u=await this.client.updateItem(r),{Item:m}=await this.client.getItem({TableName:o,Key:s,ConsistentRead:!0});u.$metadata.httpStatusCode&&(e.statusCode=u.$metadata.httpStatusCode),u.$metadata.requestId&&e.setHeader("x-amzn-RequestId",u.$metadata.requestId),this.setRecord(o,m,d);let h=JSON.stringify(u);e.end(h)}catch(o){this.safeReturnThrownError(t,e,o,n)}}async safeBatchGetItems(t){let e={},a=t;do try{let{Responses:n,UnprocessedKeys:i}=await this.client.batchGetItem({RequestItems:a});if(n)for(let[r,o]of Object.entries(n))e[r]?e[r]=e[r].concat(o):e[r]=o;i&&Object.keys(i).length?a=i:a=void 0}catch{a=void 0}while(a);return e}async BatchWriteItem(t,e){let a=await this.getBodyIfJsonObject(t,e);if(!a)return;let{buf:n,parsedBody:i}=a;if(!g(i.RequestItems))return this.redirect(t,e,n);let r={};for(let[s,d]of Object.entries(i.RequestItems)){if(!Array.isArray(d))return this.redirect(t,e,n);let u=this.getTableKeySchemaAttributeNames(s);if(!u)return this.redirect(t,e,n);r[s]={Keys:[],ConsistentRead:!0};for(let m of d){if(!g(m))return this.redirect(t,e,n);if(g(m.DeleteRequest)){if(!g(m.DeleteRequest.Key))return this.redirect(t,e,n);let h={};for(let l of u)h[l]=m.DeleteRequest.Key[l];r[s].Keys.push(h)}else if(g(m.PutRequest)){if(!g(m.PutRequest.Item))return this.redirect(t,e,n);let h={};for(let l of u)h[l]=m.PutRequest.Item[l];r[s].Keys.push(h)}else return this.redirect(t,e,n)}}let o=await this.safeBatchGetItems(r);try{let s=await this.client.batchWriteItem(i),d=await this.safeBatchGetItems(r);for(let[u,m]of Object.entries(r))if(this.getStreamByTableName(u))for(let l of m.Keys){let f=Object.keys(l),y=o[u].find(N=>{let S={};for(let p of f)S[p]=N[p];return w(l,S)}),I=d[u].find(N=>{let S={};for(let p of f)S[p]=N[p];return w(l,S)});(I||y)&&this.setRecord(u,I,y)}s.$metadata.httpStatusCode&&(e.statusCode=s.$metadata.httpStatusCode),s.$metadata.requestId&&e.setHeader("x-amzn-RequestId",s.$metadata.requestId),e.end(JSON.stringify(s))}catch(s){this.safeReturnThrownError(t,e,s,n)}}async TransactWriteItems(t,e){let a=await this.getBodyIfJsonObject(t,e);if(!a)return;let{buf:n,parsedBody:i}=a;if(!Array.isArray(i.TransactItems))return this.redirect(t,e,n);let r={};for(let s of i.TransactItems){if(!g(s))return this.redirect(t,e,n);if(s.Delete){if(!g(s.Delete)||typeof s.Delete.TableName!="string"||!s.Delete.Key)return this.redirect(t,e,n);r[s.Delete.TableName]??={Keys:[],ConsistentRead:!0},r[s.Delete.TableName].Keys.find(u=>w(u,s.Delete.Key))||r[s.Delete.TableName].Keys.push(s.Delete.Key)}else if(s.Update){if(!g(s.Update)||typeof s.Update.TableName!="string"||!s.Update.Key)return this.redirect(t,e,n);r[s.Update.TableName]??={Keys:[],ConsistentRead:!0},r[s.Update.TableName].Keys.find(u=>w(u,s.Update.Key))||r[s.Update.TableName].Keys.push(s.Update.Key)}else if(s.Put){if(!g(s.Put)||typeof s.Put.TableName!="string"||!g(s.Put.Item))return this.redirect(t,e,n);let d=this.getTableKeySchemaAttributeNames(s.Put.TableName);if(!d)return this.redirect(t,e,n);r[s.Put.TableName]??={Keys:[],ConsistentRead:!0};let u={};for(let h of d)u[h]=s.Put.Item[h];r[s.Put.TableName].Keys.find(h=>w(h,u))||r[s.Put.TableName].Keys.push(u)}}let o=await this.safeBatchGetItems(r);try{let s=await this.client.transactWriteItems(i),d=await this.safeBatchGetItems(r);for(let[u,m]of Object.entries(r))if(this.getStreamByTableName(u))for(let l of m.Keys){let f=Object.keys(l),y=o[u].find(N=>{let S={};for(let p of f)S[p]=N[p];return w(l,S)}),I=d[u].find(N=>{let S={};for(let p of f)S[p]=N[p];return w(l,S)});(I||y)&&this.setRecord(u,I,y)}s.$metadata.httpStatusCode&&(e.statusCode=s.$metadata.httpStatusCode),s.$metadata.requestId&&e.setHeader("x-amzn-RequestId",s.$metadata.requestId),e.end(JSON.stringify(s))}catch(s){this.safeReturnThrownError(t,e,s,n)}}async setDynamoDbLocalEndpoint(){try{let t="http://localhost:8000",e=await this.client.config.endpoint?.();e&&(t=`${e.protocol}${e.hostname}`,e.port&&(t+=`:${e.port}`),e.path&&e.path!="/"&&(t+=e.path)),this.dynamoDbLocalEndpoint=t}catch{console.warn("Can not resolve DynamoDB Local endpoint. Using default http://localhost:8000")}}async inheritStreams(){let t;do{let e={ExclusiveStartTableName:t},{TableNames:a,LastEvaluatedTableName:n}=await this.client.listTables(e);for(let i of a){let{Table:r}=await this.client.describeTable({TableName:i});if(r?.StreamSpecification?.StreamEnabled&&r.StreamSpecification.StreamViewType&&r.KeySchema?.every(s=>s.AttributeName&&s.KeyType)){let s=new E(i,r.StreamSpecification.StreamViewType,r.KeySchema,this.maxShards);this.streams.push(s)}let{TimeToLiveDescription:o}=await this.client.describeTimeToLive({TableName:i});o?.TimeToLiveStatus=="ENABLED"&&(this.itemsWithTTL[i]={enabled:!0,ttlFieldName:o.AttributeName,keySchema:r.KeySchema,items:new Map})}t=n}while(t)}watchTTL(){setInterval(async()=>{for(let[t,e]of Object.entries(this.itemsWithTTL)){if(!e.enabled)continue;let a=Date.now();for(let[n,i]of e.items.entries())if(!(i.ttl>a))try{(await this.client.getItem({TableName:t,Key:i.key,ConsistentRead:!0})).Item||(e.items.delete(n),this.setRecord(t,void 0,i.oldImage,!0))}catch(r){console.error(r)}}},1e3).unref()}async init(){let t=this;await this.setDynamoDbLocalEndpoint(),this.inheritStreamsFromExistingTables&&await this.inheritStreams();let e=W(async(a,n)=>{switch(a.headers["x-amz-target"]?.split(".")[1]){case"GetRecords":return t.GetRecords(a,n);case"GetShardIterator":return t.GetShardIterator(a,n);case"ListStreams":return t.ListStreams(a,n);case"DescribeStream":return t.DescribeStream(a,n);case"CreateTable":return t.CreateTable(a,n);case"DeleteTable":return t.DeleteTable(a,n);case"UpdateTable":return t.UpdateTable(a,n);case"PutItem":return t.PutItem(a,n);case"UpdateItem":return t.UpdateItem(a,n);case"DeleteItem":return t.DeleteItem(a,n);case"BatchWriteItem":return t.BatchWriteItem(a,n);case"TransactWriteItems":return t.TransactWriteItems(a,n);case"UpdateTimeToLive":return t.UpdateTimeToLive(a,n);default:a.pipe(D.request(new URL(a.url,this.dynamoDbLocalEndpoint),{headers:a.headers,method:a.method},o=>{n.writeHead(o.statusCode,o.statusMessage,o.headers),o.pipe(n)}))}});return await new Promise(a=>{e.listen(this.proxyPort,()=>{a(void 0)})}),this.server=e,t.watchTTL(),e.address().port}};var F=3,K=!1,P="123456789012",z="us-east-1";b.maxShards&&(typeof b.maxShards=="number"&&b.maxShards>0?F=Math.round(b.maxShards):console.warn("When provided, maxShards must be a positive integer. Using default 3."));typeof b.inheritStreamsFromExistingTables=="boolean"&&(K=b.inheritStreamsFromExistingTables);typeof b.accountId=="string"&&(P=b.accountId);typeof b.region=="string"&&(z=b.region);var G=new Q(b.dynamoDbLocalClientConfig),j=new L(G,b.proxyPort,F,K,P,z),Y=await j.init();H.postMessage({proxyPort:Y});
|
|
1
|
+
import{parentPort as H,workerData as b}from"node:worker_threads";import{DynamoDB as Q}from"@aws-sdk/client-dynamodb";import D,{createServer as W}from"node:http";import{isDeepStrictEqual as w}from"node:util";import{EventSourceMapping as he}from"exlo/internal/esm";import{EventSourceMapping as ae}from"exlo/internal/esm";var g=u=>Object.prototype.toString.call(u)=="[object Object]";import{randomUUID as U}from"node:crypto";var A=new TextEncoder;function O(u){if(!u)return 0;let t=0,e={};for(let a in u){if(!u.hasOwnProperty(a))continue;let n={sizeOfName:A.encode(a).length,attributeSize:_(u[a])};n.total=n.sizeOfName+n.attributeSize,t+=n.total,e[a]=n}return t}function _(u){if(!u)return 0;if(u.hasOwnProperty("B"))return atob(u.B).length;if(u.hasOwnProperty("S"))return A.encode(u.S).length;if(u.hasOwnProperty("N"))return C(u.N);if(u.hasOwnProperty("BS")){let t=0;for(let e=0;e<u.BS.length;e++)t+=atob(u.BS[e]).length;return t}if(u.hasOwnProperty("SS")){let t=0;for(let e=0;e<u.SS.length;e++)t+=A.encode(u.SS[e]).length;return t}if(u.hasOwnProperty("NS")){let t=0;for(let e=0;e<u.NS.length;e++)t+=C(u.NS[e]);return t}if(u.hasOwnProperty("BOOL")||u.hasOwnProperty("NULL"))return 1;if(u.hasOwnProperty("M")){let t=3;for(let e in u.M)u.M.hasOwnProperty(e)&&(t+=A.encode(e).length,t+=_(u.M[e]),t+=1);return t}if(u.hasOwnProperty("L")){let t=3;for(let e=0;e<u.L.length;e++)t+=_(u.L[e]),t+=1;return t}throw`unknown data type in ${JSON.stringify(u)}`}var x=class{value=0;rawValue;constructor(t){this.rawValue=t,this.value=Number(t)}toFixed(){return this.rawValue.split(".")[0]}};function C(u){let t=new x(u);if(t.value==0)return 1;let e=t.toFixed(),a=q(e.replace("-",""))+1;return e.startsWith("-")&&a++,a>21&&(a=21),a}function q(u){if(u.indexOf(".")!==-1){let t=u.split("."),e=t[0],a=t[1];return e==="0"&&(e="",a=V(a,!0)),e.length%2!==0&&(e=`Z${e}`),a.length%2!==0&&(a=`${a}Z`),q(e+a)}return u=V(u,!0,!0),Math.ceil(u.length/2)}function V(u,t,e){for(;t;){let a=u.replace(/^(0{2})/,"");if(a.length==u.length)break;u=a}for(;e;){let a=u.replace(/(0{2})$/,"");if(a.length==u.length)break;u=a}return u}var R=class{#e;constructor(t=new Date){this.#e=t}getRawValue(){return this.#e}eq(t){return this.#e==t.getRawValue()}gt(t){return this.#e>t.getRawValue()}gte(t){return this.#e>=t.getRawValue()}lt(t){return this.#e<t.getRawValue()}lte(t){return this.#e<=t.getRawValue()}toISOString(){return this.#e.toISOString()}getTime(){return this.#e.getTime()}toJSON(){return this.#e.getTime()/1e3}};var T=class u{static create(){return new u(BigInt("100000000000000000000000"))}static createFromString(t){return new u(BigInt(t))}#e;constructor(t){this.#e=t}getRawValue(){return this.#e}plusplus(){this.#e++}dup(){return new u(this.#e)}eq(t){return this.#e==t.getRawValue()}gt(t){return this.#e>t.getRawValue()}gte(t){return this.#e>=t.getRawValue()}lt(t){return this.#e<t.getRawValue()}lte(t){return this.#e<=t.getRawValue()}toJSON(){return this.#e.toString()}toString(){return this.#e.toString()}};var v=class u{constructor(t,e,a,n){this.shardId=t;this.iteratorType=e;this.position=a;this.expires=n}static fromString(t){let e=JSON.parse(Buffer.from(t,"base64").toString("utf-8")),{shardId:a,position:n,expires:o,iteratorType:r}=e;return new u(a,r,n,new Date(o))}isExpired(){return new Date>this.expires}toString(){let t=JSON.stringify({shardId:this.shardId,iteratorType:this.iteratorType,position:this.position,expires:this.expires});return Buffer.from(t,"utf-8").toString("base64")}},B=class{ParentShardId;SequenceNumberRange;ShardId;#e=[];#t;constructor(t){this.#t=t,this.ShardId=`shardId-${U()}`,this.SequenceNumberRange={}}getId(){return this.#t}setRecord(t){this.SequenceNumberRange.StartingSequenceNumber||(this.SequenceNumberRange.StartingSequenceNumber=t.dynamodb.SequenceNumber),this.#e.push(t)}get records(){return this.#e}getRecords(t,e=1e3){let a=this.#e.slice(t.position,t.position+e),n=null,o=t.position+a.length;return n=this.getIterator("LATEST"),n.iteratorType=t.iteratorType,n.position=o,this.SequenceNumberRange.EndingSequenceNumber&&!this.#e[o]&&(n=null),{Records:a,nextIterator:n}}getIterator(t,e){let a;if(t=="TRIM_HORIZON")a=0;else if(t=="LATEST")a=this.#e.length;else if(e){let n=this.#e.findIndex(o=>o.dynamodb.SequenceNumber.eq(e));n==-1?a=this.#e.length+1:t=="AT_SEQUENCE_NUMBER"?a=n:a=n+1}else throw new Error("SequenceNumber is requied for this shardIteratorType");return new v(this.ShardId,t,a,new Date)}},E=class{constructor(t,e,a,n,o="123456789012",r="us-east-1"){this.TableName=t;this.#t=n,this.#n=o,this.#a=r;let i=new R,s=i.toISOString();s=s.split("Z")[0],this.#e=T.create(),this.TableArn=`arn:aws:dynamodb:${r}:${o}:table/${t}`,this.StreamDescription={CreationRequestDateTime:i,KeySchema:a,Shards:[],StreamArn:`${this.TableArn}/stream/${s}`,StreamStatus:"ENABLED",StreamViewType:e,StreamLabel:s,TableName:t};for(let c=1;c<=n;c++)this.StreamDescription.Shards.push(new B(c))}StreamDescription;TableArn;#e;#t;#a;#n;get maxShards(){return this.#t}findShardByHashId(t){let e=this.StreamDescription.Shards.find(n=>n.getId()==t);if(e)return e;let a=new B(t);return this.StreamDescription.Shards.push(a),a}setRecord(t,e,a){let n=this.#a,o=U().replaceAll("-",""),r="1.1",i="aws:dynamodb",s;t&&e?s="MODIFY":t?s="INSERT":s="REMOVE";let c=t??e,d={},m={};for(let{AttributeName:M,KeyType:J}of this.StreamDescription.KeySchema)d[M]=c[M],J=="HASH"&&(m=d[M]);this.#e.plusplus();let h=this.#e.dup(),l=["NEW_IMAGE","NEW_AND_OLD_IMAGES"].includes(this.StreamDescription.StreamViewType)?t:void 0,f=["OLD_IMAGE","NEW_AND_OLD_IMAGES"].includes(this.StreamDescription.StreamViewType)?e:void 0,y=O(l)+O(f)+O(d),I={ApproximateCreationDateTime:new R,Keys:d,NewImage:l,OldImage:f,SequenceNumber:h,SizeBytes:y,StreamViewType:this.StreamDescription.StreamViewType},N={awsRegion:n,dynamodb:I,eventID:o,eventName:s,eventSource:i,eventVersion:r};a&&(N.userIdentity={type:"Service",principalId:"dynamodb.amazonaws.com"});let S=m.S??m.N??m.B,p=k(S,this.maxShards);this.findShardByHashId(p).setRecord(N)}getShardById(t){return this.StreamDescription.Shards.find(e=>e.ShardId==t)}};function $(u){let t=0;for(let e=0;e<u.length;e++)t=t*31+u.charCodeAt(e)>>>0;return t}function k(u,t=3){let a=$(u)%t;return a==0?1:a}var L=class u{constructor(t,e=0,a=3,n=!1,o="123456789012",r="us-east-1"){this.client=t;this.proxyPort=e;this.maxShards=a;this.inheritStreamsFromExistingTables=n;this.accountId=o;this.region=r}static async collectBuffer(t){let e=Buffer.alloc(0);return t.on("data",a=>{e=Buffer.concat([e,a])}),new Promise(a=>{t.on("end",async()=>{a(e)})})}static async collectBody(t){return(await this.collectBuffer(t)).toString("utf-8")}static async collectJsonObjectOrReturnError(t,e){try{let a=JSON.parse(await this.collectBody(t));if(!a||Array.isArray(a)||typeof a!="object")throw new Error("Invalid request");return a}catch{e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",Message:"Invalid Request Body"}));return}}redirect(t,e,a){let n=D.request(new URL(t.url,this.dynamoDbLocalEndpoint),{headers:t.headers,method:t.method},o=>{e.writeHead(o.statusCode,o.statusMessage,o.headers),o.pipe(e)});a&&n.write(a)}safeReturnThrownError(t,e,a,n){if(a?.$response?.body){let o=a.$response.body,r={};for(let c of Object.keys(a))c.startsWith("$")||(r[c]=a[c]);let i={};typeof o.headers.server=="string"&&(i.server=o.headers.server),typeof o.headers.date=="string"&&(i.date=o.headers.date),typeof o.headers["x-amzn-requestid"]=="string"&&(i["x-amzn-requestid"]=o.headers["x-amzn-requestid"]),i["content-type"]="application/x-amz-json-1.0";let s=JSON.stringify(r);i["content-length"]=Buffer.from(s).byteLength,e.writeHead(o.statusCode,o.statusMessage,i),e.end(s)}else return this.redirect(t,e,n)}dynamoDbLocalEndpoint="http://localhost:8000";tableSchemas=[];server;streams=[];itemsWithTTL={};getStreamByTableName(t){return this.streams.find(e=>(e.TableName==t||e.TableArn==t)&&e.StreamDescription.StreamStatus=="ENABLED")}getTableKeySchemaAttributeNames(t){let e=this.streams.find(a=>a.TableName==t||a.TableArn==t);return e?e.StreamDescription.KeySchema.map(a=>a.AttributeName):this.tableSchemas.find(a=>a.TableName==t||a.TableArn==t)?.KeySchema.map(a=>a.AttributeName)}getStreamByArn(t){return this.streams.find(e=>e.StreamDescription.StreamArn==t)}trackTTLRecord(t,e){if(!e)return;let a=this.itemsWithTTL[t];if(a)try{let n={};for(let i of a.keySchema)n[i.AttributeName]=e[i.AttributeName];let o=JSON.stringify(n);if(!e[a.ttlFieldName]){a.items.delete(o);return}let r=new Date(Number(e[a.ttlFieldName].N)*1e3);a.items.set(o,{oldImage:e,ttl:r.getTime(),key:n})}catch(n){console.error(n)}}setRecord(t,e,a,n=!1){let o=this.getStreamByTableName(t);if(o&&o.setRecord(e,a,n),!n&&!e&&a){let r=this.itemsWithTTL[t];if(!r)return;let i={};for(let c of r.keySchema)i[c.AttributeName]=a[c.AttributeName];let s=JSON.stringify(i);r.items.delete(s);return}this.trackTTLRecord(t,e)}async getBodyIfJsonObject(t,e){let a=await u.collectBuffer(t),n=a.toString("utf-8"),o;try{if(o=JSON.parse(n),!o||Array.isArray(o)||typeof o!="object")throw new Error("");return{buf:a,rawBody:n,parsedBody:o}}catch{return this.redirect(t,e,a)}}static isValidStreamArn(t){if(!t||typeof t!="string")return!1;let e=t.split("/");if(e.length!=4)return!1;let[a,n,o,r]=e;if(o!="stream"||!new Date(r).getTime())return!1;let i=a.split(":");if(i.length!=6)return!1;let[s,c,d,m,h,l]=i;return!(!(s=="arn"&&d=="dynamodb"&&l=="table")||!["aws","aws-cn","aws-us-gov"].includes(c))}static isValidShardIteratorType(t){return!t||typeof t!="string"?!1:["AFTER_SEQUENCE_NUMBER","LATEST","AT_SEQUENCE_NUMBER","TRIM_HORIZON"].includes(t)}async GetRecords(t,e){let a=await u.collectJsonObjectOrReturnError(t,e);if(!a)return;let{ShardIterator:n,Limit:o}=a,r=typeof n=="string"?n:"",[i,s,c]=r.split("|"),d=this.getStreamByArn(i);if(!d){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",Message:"Invalid ShardIterator"}));return}let m;try{m=v.fromString(c)}catch{e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",Message:"Invalid ShardIterator"}));return}let h=d.getShardById(m.shardId);if(!h){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",Message:"Invalid ShardIterator"}));return}let{Records:l,nextIterator:f}=h.getRecords(m,o?Number(o):void 0),y=null;f&&(y=`${d.StreamDescription.StreamArn}|${h.getId()}|${f.toString()}`),e.end(JSON.stringify({NextShardIterator:y,Records:l}))}async GetShardIterator(t,e){let a=await u.collectJsonObjectOrReturnError(t,e);if(!a)return;let{ShardId:n,ShardIteratorType:o,StreamArn:r,SequenceNumber:i}=a;if(!u.isValidStreamArn(r)){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",Message:"Invalid StreamArn"}));return}let s=this.getStreamByArn(r);if(!s){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazonaws.dynamodb.v20120810#ResourceNotFoundException",message:`Requested resource not found: Stream: ${r} not found`}));return}if(!u.isValidShardIteratorType(o)){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",message:`1 validation error detected: Value '${o}' at 'shardIteratorType' failed to satisfy constraint: Member must satisfy enum value set: [AFTER_SEQUENCE_NUMBER, LATEST, AT_SEQUENCE_NUMBER, TRIM_HORIZON]`}));return}let c=s.getShardById(n);if(!c){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazonaws.dynamodb.v20120810#ResourceNotFoundException",message:"Requested resource not found: Shard does not exist"}));return}if(["AT_SEQUENCE_NUMBER","AFTER_SEQUENCE_NUMBER"].includes(o)){if(!i){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",Message:"One or more parameter values were invalid: SequenceNumber cannot be null"}));return}}else if(i){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",Message:"One or more parameter values were invalid: SequenceNumber should not be passed for this iterator type"}));return}let d;if(typeof i<"u")if(typeof i=="string"){let m;if(i.length<21)m=`1 validation error detected: Value '${i}' at 'sequenceNumber' failed to satisfy constraint: Member must have length greater than or equal to 21`;else try{d=T.createFromString(i)}catch{m="Invalid SequenceNumber for the shard"}if(m){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",Message:m}));return}}else{let m;if(typeof i=="object"&&i?m="Start of structure or map found where not expected":typeof i=="number"?m="NUMBER_VALUE cannot be converted to String":typeof i=="boolean"&&(m=`${String(i).toUpperCase()}_VALUE cannot be converted to String`),m){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.service#SerializationException",Message:m}));return}}if(d){if(!c.SequenceNumberRange.StartingSequenceNumber){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",Message:"Invalid SequenceNumber for the shard"}));return}if(d.lt(c.SequenceNumberRange.StartingSequenceNumber)){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",Message:"Invalid SequenceNumber for the shard"}));return}if(c.SequenceNumberRange.EndingSequenceNumber&&d.gt(T.createFromString(c.SequenceNumberRange.EndingSequenceNumber))){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",Message:"Invalid SequenceNumber for the shard"}));return}}try{let m=c.getIterator(o,d);e.end(JSON.stringify({ShardIterator:`${s.StreamDescription.StreamArn}|${c.getId()}|${m.toString()}`}))}catch(m){console.error(m),e.end()}}async ListStreams(t,e){let a=await u.collectJsonObjectOrReturnError(t,e);if(!a)return;let{ExclusiveStartStreamArn:n,Limit:o,TableName:r}=a,i=o??100,s=r?this.streams.filter(c=>c.TableName==r||c.TableArn==r):this.streams;if(n){let c=s.findIndex(d=>d.StreamDescription.StreamArn==n);c!=-1&&(s=s.slice(c+1,i-1))}e.end(JSON.stringify({Streams:s.map(({TableName:c,StreamDescription:d})=>({StreamArn:d.StreamArn,StreamLabel:d.StreamLabel,TableName:c}))}))}async DescribeStream(t,e){let a=await u.collectJsonObjectOrReturnError(t,e);if(!a)return;let{StreamArn:n,ExclusiveStartShardId:o,Limit:r}=a;if(!u.isValidStreamArn(n)){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazon.coral.validate#ValidationException",Message:"Invalid StreamArn"}));return}let i=this.streams.find(d=>d.StreamDescription.StreamArn==n);if(!i){e.statusCode=400,e.end(JSON.stringify({__type:"com.amazonaws.dynamodb.v20120810#ResourceNotFoundException",message:`Requested resource not found: Stream: ${n} not found`}));return}let s=r??100,c=i.StreamDescription.Shards;if(o){let d=c.findIndex(m=>m.ShardId==o);d!=-1&&(c=c.slice(d+1,s-1))}e.end(JSON.stringify({StreamDescription:{...i.StreamDescription,Shards:c}}))}async CreateTable(t,e){t.pipe(D.request(new URL(t.url,this.dynamoDbLocalEndpoint),{headers:t.headers,method:t.method},async a=>{if(e.writeHead(a.statusCode,a.statusMessage,a.headers),a.statusCode==200){let n=await u.collectBuffer(a),o=JSON.parse(n.toString("utf-8")),{TableName:r,KeySchema:i,TableArn:s,StreamSpecification:c}=o.TableDescription;c?.StreamEnabled?this.streams.push(new E(r,c.StreamViewType,i,this.maxShards,this.accountId,this.region)):this.tableSchemas.find(d=>d.TableName==r)||this.tableSchemas.push({TableName:r,TableArn:s,KeySchema:i}),e.end(n)}else a.pipe(e)}))}async DeleteTable(t,e){t.pipe(D.request(new URL(t.url,this.dynamoDbLocalEndpoint),{headers:t.headers,method:t.method},async a=>{if(e.writeHead(a.statusCode,a.statusMessage,a.headers),a.statusCode==200){let n=await u.collectBuffer(a),o=JSON.parse(n.toString("utf-8")),{TableName:r}=o.TableDescription,i=this.streams.findIndex(s=>s.TableName==r||s.TableArn==r);i!=-1&&this.streams.splice(i,1),delete this.itemsWithTTL[r],e.end(n)}else a.pipe(e)}))}async UpdateTable(t,e){t.pipe(D.request(new URL(t.url,this.dynamoDbLocalEndpoint),{headers:t.headers,method:t.method},async a=>{if(e.writeHead(a.statusCode,a.statusMessage,a.headers),a.statusCode!=200){a.pipe(e);return}let n=await u.collectBuffer(a),o=JSON.parse(n.toString("utf-8")),{TableName:r,StreamSpecification:i,KeySchema:s}=o.TableDescription;if(i){let c=this.getStreamByTableName(r);typeof i.StreamEnabled=="boolean"?c?c.StreamDescription.StreamStatus=i.StreamEnabled?"ENABLED":"DISABLED":i.StreamEnabled&&this.streams.push(new E(r,i.StreamViewType,s,this.maxShards)):c?c.StreamDescription.StreamViewType=i.StreamViewType:this.streams.push(new E(r,i.StreamViewType,s,this.maxShards))}else{let c=this.streams.find(d=>d.TableName==r||d.TableArn==r);c&&(c.StreamDescription.StreamStatus="DISABLED")}e.end(n)}))}async UpdateTimeToLive(t,e){let a=await this.getBodyIfJsonObject(t,e);if(!a)return;let{buf:n,parsedBody:o}=a;try{let r=await this.client.updateTimeToLive(o);r.$metadata.httpStatusCode&&(e.statusCode=r.$metadata.httpStatusCode),r.$metadata.requestId&&e.setHeader("x-amzn-RequestId",r.$metadata.requestId);let{TableName:i}=o,s=this.streams.find(c=>c.TableName==i||c.TableArn==i);if(s){let{TimeToLiveSpecification:c}=r,{AttributeName:d,Enabled:m}=c,h=m,l=d;this.itemsWithTTL[i]??={items:new Map,ttlFieldName:l,enabled:h,keySchema:s.StreamDescription.KeySchema},this.itemsWithTTL[i].enabled=h,this.itemsWithTTL[i].ttlFieldName=l}e.end(JSON.stringify(r))}catch(r){this.safeReturnThrownError(t,e,r,n)}}async PutItem(t,e){let a=await this.getBodyIfJsonObject(t,e);if(!a)return;let{buf:n,rawBody:o,parsedBody:r}=a;try{let i=["NONE","ALL_OLD"],s=r.ReturnValues,c="";s?i.includes(s)?c="ALL_OLD":c=s:c="ALL_OLD";let d={...r,ReturnValues:c},m=await this.client.putItem(d);m.$metadata.httpStatusCode&&(e.statusCode=m.$metadata.httpStatusCode),m.$metadata.requestId&&e.setHeader("x-amzn-RequestId",m.$metadata.requestId);let{TableName:h,Item:l}=r,f=l,y=m.Attributes;this.setRecord(h,f,y);let I=JSON.stringify({...m,Attributes:s=="ALL_OLD"?m.Attributes:void 0});e.end(I)}catch(i){this.safeReturnThrownError(t,e,i,n)}}async DeleteItem(t,e){let a=await this.getBodyIfJsonObject(t,e);if(!a)return;let{buf:n,parsedBody:o}=a;try{let r=["NONE","ALL_OLD"],i=o.ReturnValues,s="";i?r.includes(i)?s="ALL_OLD":s=i:s="ALL_OLD";let c={...o,ReturnValues:s},d=await this.client.deleteItem(c);d.$metadata.httpStatusCode&&(e.statusCode=d.$metadata.httpStatusCode),d.$metadata.requestId&&e.setHeader("x-amzn-RequestId",d.$metadata.requestId);let{TableName:m}=o,h=void 0,l=d.Attributes;l&&this.setRecord(m,h,l);let f=JSON.stringify({...d,Attributes:i=="ALL_OLD"?d.Attributes:void 0});e.end(f)}catch(r){this.safeReturnThrownError(t,e,r,n)}}async UpdateItem(t,e){let a=await this.getBodyIfJsonObject(t,e);if(!a)return;let{buf:n,rawBody:o,parsedBody:r}=a;try{let{TableName:i,Key:s}=r,c;try{c=(await this.client.getItem({TableName:i,Key:s,ConsistentRead:!0})).Item}catch{}let d=await this.client.updateItem(r),{Item:m}=await this.client.getItem({TableName:i,Key:s,ConsistentRead:!0});d.$metadata.httpStatusCode&&(e.statusCode=d.$metadata.httpStatusCode),d.$metadata.requestId&&e.setHeader("x-amzn-RequestId",d.$metadata.requestId),this.setRecord(i,m,c);let h=JSON.stringify(d);e.end(h)}catch(i){this.safeReturnThrownError(t,e,i,n)}}async safeBatchGetItems(t){let e={},a=t;do try{let{Responses:n,UnprocessedKeys:o}=await this.client.batchGetItem({RequestItems:a});if(n)for(let[r,i]of Object.entries(n))e[r]?e[r]=e[r].concat(i):e[r]=i;o&&Object.keys(o).length?a=o:a=void 0}catch{a=void 0}while(a);return e}async BatchWriteItem(t,e){let a=await this.getBodyIfJsonObject(t,e);if(!a)return;let{buf:n,parsedBody:o}=a;if(!g(o.RequestItems))return this.redirect(t,e,n);let r={};for(let[s,c]of Object.entries(o.RequestItems)){if(!Array.isArray(c))return this.redirect(t,e,n);let d=this.getTableKeySchemaAttributeNames(s);if(!d)return this.redirect(t,e,n);r[s]={Keys:[],ConsistentRead:!0};for(let m of c){if(!g(m))return this.redirect(t,e,n);if(g(m.DeleteRequest)){if(!g(m.DeleteRequest.Key))return this.redirect(t,e,n);let h={};for(let l of d)h[l]=m.DeleteRequest.Key[l];r[s].Keys.push(h)}else if(g(m.PutRequest)){if(!g(m.PutRequest.Item))return this.redirect(t,e,n);let h={};for(let l of d)h[l]=m.PutRequest.Item[l];r[s].Keys.push(h)}else return this.redirect(t,e,n)}}let i=await this.safeBatchGetItems(r);try{let s=await this.client.batchWriteItem(o),c=await this.safeBatchGetItems(r);for(let[d,m]of Object.entries(r))if(this.getStreamByTableName(d))for(let l of m.Keys){let f=Object.keys(l),y=i[d].find(N=>{let S={};for(let p of f)S[p]=N[p];return w(l,S)}),I=c[d].find(N=>{let S={};for(let p of f)S[p]=N[p];return w(l,S)});(I||y)&&this.setRecord(d,I,y)}s.$metadata.httpStatusCode&&(e.statusCode=s.$metadata.httpStatusCode),s.$metadata.requestId&&e.setHeader("x-amzn-RequestId",s.$metadata.requestId),e.end(JSON.stringify(s))}catch(s){this.safeReturnThrownError(t,e,s,n)}}async TransactWriteItems(t,e){let a=await this.getBodyIfJsonObject(t,e);if(!a)return;let{buf:n,parsedBody:o}=a;if(!Array.isArray(o.TransactItems))return this.redirect(t,e,n);let r={};for(let s of o.TransactItems){if(!g(s))return this.redirect(t,e,n);if(s.Delete){if(!g(s.Delete)||typeof s.Delete.TableName!="string"||!s.Delete.Key)return this.redirect(t,e,n);r[s.Delete.TableName]??={Keys:[],ConsistentRead:!0},r[s.Delete.TableName].Keys.find(d=>w(d,s.Delete.Key))||r[s.Delete.TableName].Keys.push(s.Delete.Key)}else if(s.Update){if(!g(s.Update)||typeof s.Update.TableName!="string"||!s.Update.Key)return this.redirect(t,e,n);r[s.Update.TableName]??={Keys:[],ConsistentRead:!0},r[s.Update.TableName].Keys.find(d=>w(d,s.Update.Key))||r[s.Update.TableName].Keys.push(s.Update.Key)}else if(s.Put){if(!g(s.Put)||typeof s.Put.TableName!="string"||!g(s.Put.Item))return this.redirect(t,e,n);let c=this.getTableKeySchemaAttributeNames(s.Put.TableName);if(!c)return this.redirect(t,e,n);r[s.Put.TableName]??={Keys:[],ConsistentRead:!0};let d={};for(let h of c)d[h]=s.Put.Item[h];r[s.Put.TableName].Keys.find(h=>w(h,d))||r[s.Put.TableName].Keys.push(d)}}let i=await this.safeBatchGetItems(r);try{let s=await this.client.transactWriteItems(o),c=await this.safeBatchGetItems(r);for(let[d,m]of Object.entries(r))if(this.getStreamByTableName(d))for(let l of m.Keys){let f=Object.keys(l),y=i[d].find(N=>{let S={};for(let p of f)S[p]=N[p];return w(l,S)}),I=c[d].find(N=>{let S={};for(let p of f)S[p]=N[p];return w(l,S)});(I||y)&&this.setRecord(d,I,y)}s.$metadata.httpStatusCode&&(e.statusCode=s.$metadata.httpStatusCode),s.$metadata.requestId&&e.setHeader("x-amzn-RequestId",s.$metadata.requestId),e.end(JSON.stringify(s))}catch(s){this.safeReturnThrownError(t,e,s,n)}}async setDynamoDbLocalEndpoint(){try{let t="http://localhost:8000",e=await this.client.config.endpoint?.();e&&(t=`${e.protocol}${e.hostname}`,e.port&&(t+=`:${e.port}`),e.path&&e.path!="/"&&(t+=e.path)),this.dynamoDbLocalEndpoint=t}catch{console.warn("Can not resolve DynamoDB Local endpoint. Using default http://localhost:8000")}}async setupInitialTables(){let t;do{let e={ExclusiveStartTableName:t},{TableNames:a,LastEvaluatedTableName:n}=await this.client.listTables(e);if(!a)return;for(let o of a){let{Table:r}=await this.client.describeTable({TableName:o});if(r?.KeySchema?.every(s=>s.AttributeName&&s.KeyType)){let s=r.KeySchema;if(this.inheritStreamsFromExistingTables&&r.StreamSpecification?.StreamEnabled&&r.StreamSpecification.StreamViewType){let c=new E(o,r.StreamSpecification.StreamViewType,s,this.maxShards);this.streams.push(c)}else{let{TableName:c,TableArn:d}=r;this.tableSchemas.push({TableName:c,TableArn:d,KeySchema:s})}}let{TimeToLiveDescription:i}=await this.client.describeTimeToLive({TableName:o});i?.TimeToLiveStatus=="ENABLED"&&(this.itemsWithTTL[o]={enabled:!0,ttlFieldName:i.AttributeName,keySchema:r.KeySchema,items:new Map})}t=n}while(t)}watchTTL(){setInterval(async()=>{for(let[t,e]of Object.entries(this.itemsWithTTL)){if(!e.enabled)continue;let a=Date.now();for(let[n,o]of e.items.entries())if(!(o.ttl>a))try{(await this.client.getItem({TableName:t,Key:o.key,ConsistentRead:!0})).Item||(e.items.delete(n),this.setRecord(t,void 0,o.oldImage,!0))}catch(r){console.error(r)}}},1e3).unref()}async init(){let t=this;await this.setDynamoDbLocalEndpoint(),await this.setupInitialTables();let e=W(async(a,n)=>{switch(a.headers["x-amz-target"]?.split(".")[1]){case"GetRecords":return t.GetRecords(a,n);case"GetShardIterator":return t.GetShardIterator(a,n);case"ListStreams":return t.ListStreams(a,n);case"DescribeStream":return t.DescribeStream(a,n);case"CreateTable":return t.CreateTable(a,n);case"DeleteTable":return t.DeleteTable(a,n);case"UpdateTable":return t.UpdateTable(a,n);case"PutItem":return t.PutItem(a,n);case"UpdateItem":return t.UpdateItem(a,n);case"DeleteItem":return t.DeleteItem(a,n);case"BatchWriteItem":return t.BatchWriteItem(a,n);case"TransactWriteItems":return t.TransactWriteItems(a,n);case"UpdateTimeToLive":return t.UpdateTimeToLive(a,n);default:a.pipe(D.request(new URL(a.url,this.dynamoDbLocalEndpoint),{headers:a.headers,method:a.method},i=>{n.writeHead(i.statusCode,i.statusMessage,i.headers),i.pipe(n)}))}});return await new Promise(a=>{e.listen(this.proxyPort,()=>{a(void 0)})}),this.server=e,t.watchTTL(),e.address().port}};var K=3,F=!1,P="123456789012",z="us-east-1";b.maxShards&&(typeof b.maxShards=="number"&&b.maxShards>0?K=Math.round(b.maxShards):console.warn("When provided, maxShards must be a positive integer. Using default 3."));typeof b.inheritStreamsFromExistingTables=="boolean"&&(F=b.inheritStreamsFromExistingTables);typeof b.accountId=="string"&&(P=b.accountId);typeof b.region=="string"&&(z=b.region);var G=new Q(b.dynamoDbLocalClientConfig),j=new L(G,b.proxyPort,K,F,P,z),Y=await j.init();H.postMessage({proxyPort:Y});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S3GenericAction, type S3LocalService } from "./localAction";
|
|
2
1
|
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
import { S3GenericAction, type S3LocalService } from "./localAction";
|
|
3
3
|
export declare class AbortMultipartUploadAction extends S3GenericAction {
|
|
4
4
|
localService: S3LocalService;
|
|
5
5
|
bucket: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S3GenericAction, S3LocalService } from "./localAction";
|
|
2
1
|
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "http";
|
|
2
|
+
import { S3GenericAction, S3LocalService } from "./localAction";
|
|
3
3
|
export declare class CompleteMultipartUploadAction extends S3GenericAction {
|
|
4
4
|
localService: S3LocalService;
|
|
5
5
|
bucket: string;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { IncomingHttpHeaders, ServerResponse } from "node:http";
|
|
1
|
+
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "node:http";
|
|
2
2
|
import { S3GenericAction, S3LocalService } from "./localAction";
|
|
3
3
|
export declare class CreateBucketAction extends S3GenericAction {
|
|
4
4
|
localService: S3LocalService;
|
|
5
5
|
bucket: string;
|
|
6
6
|
constructor(url: URL, headers: IncomingHttpHeaders, localService: S3LocalService);
|
|
7
|
-
exec(res: ServerResponse): Promise<void>;
|
|
7
|
+
exec(res: ServerResponse, req: IncomingMessage): Promise<void>;
|
|
8
8
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S3GenericAction, S3LocalService } from "./localAction";
|
|
2
1
|
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "http";
|
|
2
|
+
import { S3GenericAction, S3LocalService } from "./localAction";
|
|
3
3
|
export declare class CreateMultipartUploadAction extends S3GenericAction {
|
|
4
4
|
private url;
|
|
5
5
|
private headers;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { IncomingHttpHeaders, ServerResponse } from "node:http";
|
|
1
|
+
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "node:http";
|
|
2
2
|
import { S3GenericAction, type S3LocalService } from "./localAction";
|
|
3
3
|
export declare class DeleteBucketAction extends S3GenericAction {
|
|
4
4
|
localService: S3LocalService;
|
|
5
5
|
bucket: string;
|
|
6
6
|
constructor(url: URL, headers: IncomingHttpHeaders, localService: S3LocalService);
|
|
7
|
-
exec(res: ServerResponse): Promise<void>;
|
|
7
|
+
exec(res: ServerResponse, req: IncomingMessage): Promise<void>;
|
|
8
8
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "http";
|
|
1
2
|
import { S3GenericAction, S3LocalService } from "./localAction";
|
|
2
|
-
import type { IncomingHttpHeaders, ServerResponse } from "http";
|
|
3
3
|
export declare class DeleteBucketPolicyAction extends S3GenericAction {
|
|
4
4
|
localService: S3LocalService;
|
|
5
5
|
bucket: string;
|
|
6
6
|
constructor(url: URL, headers: IncomingHttpHeaders, localService: S3LocalService);
|
|
7
|
-
exec(res: ServerResponse): Promise<void>;
|
|
7
|
+
exec(res: ServerResponse, req: IncomingMessage): Promise<void>;
|
|
8
8
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "http";
|
|
1
2
|
import { S3GenericAction, S3LocalService } from "./localAction";
|
|
2
|
-
import type { IncomingHttpHeaders, ServerResponse } from "http";
|
|
3
3
|
export declare class DeleteBucketTaggingAction extends S3GenericAction {
|
|
4
4
|
localService: S3LocalService;
|
|
5
5
|
bucket: string;
|
|
6
6
|
constructor(url: URL, headers: IncomingHttpHeaders, localService: S3LocalService);
|
|
7
|
-
exec(res: ServerResponse): Promise<void>;
|
|
7
|
+
exec(res: ServerResponse, req: IncomingMessage): Promise<void>;
|
|
8
8
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S3GenericAction, S3LocalService } from "./localAction";
|
|
2
1
|
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "http";
|
|
2
|
+
import { S3GenericAction, S3LocalService } from "./localAction";
|
|
3
3
|
export declare class DeleteObjectAction extends S3GenericAction {
|
|
4
4
|
localService: S3LocalService;
|
|
5
5
|
bucket: string;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { IncomingHttpHeaders, ServerResponse } from "node:http";
|
|
1
|
+
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "node:http";
|
|
2
2
|
import { S3GenericAction, type S3LocalService } from "./localAction";
|
|
3
3
|
export declare class DeleteObjectTaggingAction extends S3GenericAction {
|
|
4
4
|
localService: S3LocalService;
|
|
5
5
|
bucket: string;
|
|
6
6
|
key: string;
|
|
7
7
|
constructor(url: URL, headers: IncomingHttpHeaders, localService: S3LocalService);
|
|
8
|
-
exec(res: ServerResponse): Promise<void>;
|
|
8
|
+
exec(res: ServerResponse, req: IncomingMessage): Promise<void>;
|
|
9
9
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { IncomingHttpHeaders, ServerResponse } from "node:http";
|
|
1
|
+
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "node:http";
|
|
2
2
|
import { S3GenericAction, type S3LocalService } from "./localAction";
|
|
3
3
|
export declare class GetBucketAclAction extends S3GenericAction {
|
|
4
4
|
localService: S3LocalService;
|
|
5
5
|
bucket: string;
|
|
6
6
|
constructor(url: URL, headers: IncomingHttpHeaders, localService: S3LocalService);
|
|
7
|
-
exec(res: ServerResponse): Promise<void>;
|
|
7
|
+
exec(res: ServerResponse, req: IncomingMessage): Promise<void>;
|
|
8
8
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { IncomingHttpHeaders, ServerResponse } from "node:http";
|
|
1
|
+
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "node:http";
|
|
2
2
|
import { S3GenericAction, type S3LocalService } from "./localAction";
|
|
3
3
|
export declare class GetBucketPolicyAction extends S3GenericAction {
|
|
4
4
|
localService: S3LocalService;
|
|
5
5
|
bucket: string;
|
|
6
6
|
constructor(url: URL, headers: IncomingHttpHeaders, localService: S3LocalService);
|
|
7
|
-
exec(res: ServerResponse): Promise<void>;
|
|
7
|
+
exec(res: ServerResponse, req: IncomingMessage): Promise<void>;
|
|
8
8
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { IncomingHttpHeaders, ServerResponse } from "node:http";
|
|
1
|
+
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "node:http";
|
|
2
2
|
import { S3GenericAction, S3LocalService } from "./localAction";
|
|
3
3
|
export declare class GetBucketTaggingAction extends S3GenericAction {
|
|
4
4
|
localService: S3LocalService;
|
|
5
5
|
bucket: string;
|
|
6
6
|
constructor(url: URL, headers: IncomingHttpHeaders, localService: S3LocalService);
|
|
7
|
-
exec(res: ServerResponse): Promise<void>;
|
|
7
|
+
exec(res: ServerResponse, req: IncomingMessage): Promise<void>;
|
|
8
8
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { IncomingHttpHeaders, ServerResponse } from "node:http";
|
|
1
|
+
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "node:http";
|
|
2
2
|
import { S3GenericAction, type S3LocalService } from "./localAction";
|
|
3
3
|
export declare class GetObjectAclAction extends S3GenericAction {
|
|
4
4
|
localService: S3LocalService;
|
|
5
5
|
bucket: string;
|
|
6
6
|
constructor(url: URL, headers: IncomingHttpHeaders, localService: S3LocalService);
|
|
7
|
-
exec(res: ServerResponse): Promise<void>;
|
|
7
|
+
exec(res: ServerResponse, req: IncomingMessage): Promise<void>;
|
|
8
8
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { IncomingHttpHeaders, ServerResponse } from "node:http";
|
|
1
|
+
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "node:http";
|
|
3
2
|
import type { LocalS3Object, S3LocalService } from "./localAction";
|
|
3
|
+
import { S3GenericAction } from "./localAction";
|
|
4
4
|
export declare const checkS3Conditions: ({ ifMatch, ifNoneMatch, ifModifiedSince, ifUnmodifiedSince, }: {
|
|
5
5
|
ifMatch?: string;
|
|
6
6
|
ifNoneMatch?: string;
|
|
@@ -26,5 +26,5 @@ export declare class GetObjectAction extends S3GenericAction {
|
|
|
26
26
|
ifModifiedSince?: number;
|
|
27
27
|
ifUnmodifiedSince?: number;
|
|
28
28
|
constructor(url: URL, headers: IncomingHttpHeaders, localService: S3LocalService);
|
|
29
|
-
exec(res: ServerResponse): Promise<void>;
|
|
29
|
+
exec(res: ServerResponse, req: IncomingMessage): Promise<void>;
|
|
30
30
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { IncomingHttpHeaders, ServerResponse } from "node:http";
|
|
1
|
+
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "node:http";
|
|
2
2
|
import { S3GenericAction, S3LocalService } from "./localAction";
|
|
3
3
|
export declare class GetObjectTaggingAction extends S3GenericAction {
|
|
4
4
|
localService: S3LocalService;
|
|
@@ -6,5 +6,5 @@ export declare class GetObjectTaggingAction extends S3GenericAction {
|
|
|
6
6
|
key: string;
|
|
7
7
|
versionId: string | null;
|
|
8
8
|
constructor(url: URL, headers: IncomingHttpHeaders, localService: S3LocalService);
|
|
9
|
-
exec(res: ServerResponse): Promise<void>;
|
|
9
|
+
exec(res: ServerResponse, req: IncomingMessage): Promise<void>;
|
|
10
10
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { IncomingHttpHeaders, ServerResponse } from "node:http";
|
|
1
|
+
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "node:http";
|
|
2
2
|
import { S3GenericAction, type S3LocalService } from "./localAction";
|
|
3
3
|
export declare class HeadBucketAction extends S3GenericAction {
|
|
4
4
|
localService: S3LocalService;
|
|
5
5
|
bucket: string;
|
|
6
6
|
constructor(url: URL, headers: IncomingHttpHeaders, localService: S3LocalService);
|
|
7
|
-
exec(res: ServerResponse): void;
|
|
7
|
+
exec(res: ServerResponse, req: IncomingMessage): void;
|
|
8
8
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { IncomingHttpHeaders, ServerResponse } from "node:http";
|
|
1
|
+
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "node:http";
|
|
2
2
|
import { S3GenericAction, type S3LocalService } from "./localAction";
|
|
3
3
|
export declare class HeadObjectAction extends S3GenericAction {
|
|
4
4
|
localService: S3LocalService;
|
|
@@ -14,5 +14,5 @@ export declare class HeadObjectAction extends S3GenericAction {
|
|
|
14
14
|
ifModifiedSince?: number;
|
|
15
15
|
ifUnmodifiedSince?: number;
|
|
16
16
|
constructor(url: URL, headers: IncomingHttpHeaders, localService: S3LocalService);
|
|
17
|
-
exec(res: ServerResponse): Promise<void>;
|
|
17
|
+
exec(res: ServerResponse, req: IncomingMessage): Promise<void>;
|
|
18
18
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { IncomingHttpHeaders, ServerResponse } from "node:http";
|
|
1
|
+
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "node:http";
|
|
2
2
|
import { S3GenericAction, type S3LocalService } from "./localAction";
|
|
3
3
|
export declare class ListBucketsAction extends S3GenericAction {
|
|
4
4
|
localService: S3LocalService;
|
|
@@ -11,5 +11,5 @@ export declare class ListBucketsAction extends S3GenericAction {
|
|
|
11
11
|
private isValidRequest;
|
|
12
12
|
private createContinuationToken;
|
|
13
13
|
private getBucketNames;
|
|
14
|
-
exec(res: ServerResponse): Promise<void>;
|
|
14
|
+
exec(res: ServerResponse, req: IncomingMessage): Promise<void>;
|
|
15
15
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { IncomingHttpHeaders, ServerResponse } from "node:http";
|
|
1
|
+
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "node:http";
|
|
2
2
|
import { S3GenericAction, type S3LocalService } from "./localAction";
|
|
3
3
|
export declare class ListMultipartUploadsAction extends S3GenericAction {
|
|
4
4
|
localService: S3LocalService;
|
|
@@ -15,5 +15,5 @@ export declare class ListMultipartUploadsAction extends S3GenericAction {
|
|
|
15
15
|
private validateRequest;
|
|
16
16
|
private collectUploads;
|
|
17
17
|
private getUploads;
|
|
18
|
-
exec(res: ServerResponse): Promise<void>;
|
|
18
|
+
exec(res: ServerResponse, req: IncomingMessage): Promise<void>;
|
|
19
19
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { IncomingHttpHeaders, ServerResponse } from "node:http";
|
|
1
|
+
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "node:http";
|
|
2
2
|
import { S3GenericAction, type S3LocalService } from "./localAction";
|
|
3
3
|
declare abstract class ListObjectsAction extends S3GenericAction {
|
|
4
4
|
localService: S3LocalService;
|
|
@@ -12,13 +12,13 @@ declare abstract class ListObjectsAction extends S3GenericAction {
|
|
|
12
12
|
requestPayer: string | null;
|
|
13
13
|
constructor(url: URL, headers: IncomingHttpHeaders, localService: S3LocalService);
|
|
14
14
|
getKeys(): string[];
|
|
15
|
-
isInvalidMaxKeys(res: ServerResponse): true | undefined;
|
|
15
|
+
isInvalidMaxKeys(res: ServerResponse, req: IncomingMessage): true | undefined;
|
|
16
16
|
}
|
|
17
17
|
export declare class ListObjectsV1Action extends ListObjectsAction {
|
|
18
18
|
localService: S3LocalService;
|
|
19
19
|
marker: string | null;
|
|
20
20
|
constructor(url: URL, headers: IncomingHttpHeaders, localService: S3LocalService);
|
|
21
|
-
exec(res: ServerResponse): void;
|
|
21
|
+
exec(res: ServerResponse, req: IncomingMessage): void;
|
|
22
22
|
}
|
|
23
23
|
export declare class ListObjectsV2Action extends ListObjectsAction {
|
|
24
24
|
localService: S3LocalService;
|
|
@@ -26,6 +26,6 @@ export declare class ListObjectsV2Action extends ListObjectsAction {
|
|
|
26
26
|
fetchOwner: string | null;
|
|
27
27
|
startAfter: string | null;
|
|
28
28
|
constructor(url: URL, headers: IncomingHttpHeaders, localService: S3LocalService);
|
|
29
|
-
exec(res: ServerResponse): void;
|
|
29
|
+
exec(res: ServerResponse, req: IncomingMessage): void;
|
|
30
30
|
}
|
|
31
31
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { IncomingHttpHeaders, ServerResponse } from "node:http";
|
|
1
|
+
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "node:http";
|
|
2
2
|
import { S3GenericAction, type S3LocalService } from "./localAction";
|
|
3
3
|
export declare class ListPartsAction extends S3GenericAction {
|
|
4
4
|
localService: S3LocalService;
|
|
@@ -10,5 +10,5 @@ export declare class ListPartsAction extends S3GenericAction {
|
|
|
10
10
|
maxParts: string;
|
|
11
11
|
constructor(url: URL, headers: IncomingHttpHeaders, localService: S3LocalService);
|
|
12
12
|
private validateRequest;
|
|
13
|
-
exec(res: ServerResponse): Promise<void>;
|
|
13
|
+
exec(res: ServerResponse, req: IncomingMessage): Promise<void>;
|
|
14
14
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type LocalS3Object, S3GenericAction, S3LocalService } from "./localAction";
|
|
2
1
|
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
import { type LocalS3Object, S3GenericAction, S3LocalService } from "./localAction";
|
|
3
3
|
export declare class PutObjectAction extends S3GenericAction {
|
|
4
4
|
localService: S3LocalService;
|
|
5
5
|
bucket: string;
|
|
@@ -14,7 +14,7 @@ export declare class PutObjectAction extends S3GenericAction {
|
|
|
14
14
|
storageClass: LocalS3Object["StorageClass"];
|
|
15
15
|
tagging?: string;
|
|
16
16
|
constructor(url: URL, headers: IncomingHttpHeaders, localService: S3LocalService);
|
|
17
|
-
validateRequest(res: ServerResponse): {
|
|
17
|
+
validateRequest(res: ServerResponse, req: IncomingMessage): {
|
|
18
18
|
tagsLen: number;
|
|
19
19
|
Tags: Record<string, string>;
|
|
20
20
|
} | undefined;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { IncomingHttpHeaders, ServerResponse } from "node:http";
|
|
1
|
+
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "node:http";
|
|
2
2
|
import { S3GenericAction, type S3LocalService } from "./localAction";
|
|
3
3
|
export declare class UnknownAction extends S3GenericAction {
|
|
4
4
|
localService: S3LocalService;
|
|
5
5
|
constructor(url: URL, headers: IncomingHttpHeaders, localService: S3LocalService);
|
|
6
|
-
exec(res: ServerResponse): void;
|
|
6
|
+
exec(res: ServerResponse, req: IncomingMessage): void;
|
|
7
7
|
}
|
|
@@ -79,14 +79,19 @@ export declare class S3LocalService {
|
|
|
79
79
|
saveState(): void;
|
|
80
80
|
static isValidBucketName(bucket: string): boolean;
|
|
81
81
|
removeObject(bucket: string, key: string, sourceIPAddress: string, requestId: string): Promise<void>;
|
|
82
|
+
setCorsHeaders(req: IncomingMessage, res: ServerResponse): void;
|
|
83
|
+
getCorsHeaders(req: IncomingMessage, array?: boolean): string[] | {
|
|
84
|
+
"access-control-allow-origin": string;
|
|
85
|
+
"access-control-allow-credentials": string;
|
|
86
|
+
} | undefined;
|
|
82
87
|
}
|
|
83
88
|
export declare abstract class S3GenericAction {
|
|
84
89
|
localService: S3LocalService;
|
|
85
90
|
requestId: string;
|
|
86
91
|
metadata: Record<string, any>;
|
|
87
92
|
constructor(headers: IncomingHttpHeaders, localService: S3LocalService);
|
|
88
|
-
isValidStorageClass(storage: any, res: ServerResponse): boolean;
|
|
89
|
-
hasNot(bucket: string, res: ServerResponse): true | undefined;
|
|
93
|
+
isValidStorageClass(storage: any, res: ServerResponse, req: IncomingMessage): boolean;
|
|
94
|
+
hasNot(bucket: string, res: ServerResponse, req: IncomingMessage): true | undefined;
|
|
90
95
|
abstract exec(res: ServerResponse, ...rest: any): Promise<void> | void;
|
|
91
96
|
}
|
|
92
97
|
export {};
|