s3db.js 8.1.0 → 8.1.1
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/PLUGINS.md +95 -34
- package/dist/s3db.cjs.js +123 -53
- package/dist/s3db.cjs.min.js +1 -1
- package/dist/s3db.es.js +123 -53
- package/dist/s3db.es.min.js +1 -1
- package/dist/s3db.iife.js +123 -53
- package/dist/s3db.iife.min.js +1 -1
- package/package.json +2 -2
- package/src/behaviors/body-overflow.js +0 -1
- package/src/behaviors/enforce-limits.js +3 -1
- package/src/behaviors/truncate-data.js +2 -1
- package/src/behaviors/user-managed.js +24 -3
- package/src/plugins/audit.plugin.js +61 -10
- package/src/plugins/cache/partition-aware-filesystem-cache.class.js +28 -0
- package/src/plugins/cache/s3-cache.class.js +1 -1
- package/src/resource.class.js +38 -38
package/dist/s3db.es.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{customAlphabet as e,urlAlphabet as t}from"nanoid";import r from"node:zlib";import{PromisePool as i}from"@supercharge/promise-pool";import{ReadableStream as s}from"node:stream/web";import{mkdir as n,writeFile as o,readFile as a,stat as c,unlink as u,readdir as l,rm as h}from"fs/promises";import{createHash as f}from"crypto";import{chunk as d,merge as p,isString as m,isEmpty as g,invert as y,uniq as b,cloneDeep as w,get as v,set as k,isObject as _,isFunction as S}from"lodash-es";import O from"json-stable-stringify";import{NodeHttpHandler as R}from"@smithy/node-http-handler";import{S3Client as j,PutObjectCommand as x,GetObjectCommand as E,HeadObjectCommand as A,CopyObjectCommand as D,DeleteObjectCommand as $,DeleteObjectsCommand as C,ListObjectsV2Command as N}from"@aws-sdk/client-s3";import{flatten as I,unflatten as P}from"flat";import T from"fastest-validator";const M="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",L=Object.fromEntries([...M].map((e,t)=>[e,t])),U=e=>{if("number"!=typeof e||isNaN(e))return"undefined";if(!isFinite(e))return"undefined";if(0===e)return M[0];if(e<0)return"-"+U(-Math.floor(e));e=Math.floor(e);let t="";for(;e;)t=M[e%62]+t,e=Math.floor(e/62);return t},F=e=>{if("string"!=typeof e)return NaN;if(""===e)return 0;let t=!1;"-"===e[0]&&(t=!0,e=e.slice(1));let r=0;for(let t=0;t<e.length;t++){const i=L[e[t]];if(void 0===i)return NaN;r=62*r+i}return t?-r:r},q=e=>{if("number"!=typeof e||isNaN(e))return"undefined";if(!isFinite(e))return"undefined";const t=e<0;e=Math.abs(e);const[r,i]=e.toString().split("."),s=U(Number(r));return i?(t?"-":"")+s+"."+i:(t?"-":"")+s},B=e=>{if("string"!=typeof e)return NaN;let t=!1;"-"===e[0]&&(t=!0,e=e.slice(1));const[r,i]=e.split("."),s=F(r);if(isNaN(s))return NaN;const n=i?Number(s+"."+i):s;return t?-n:n};function z(e){"string"!=typeof e&&(e=String(e));let t=0;for(let r=0;r<e.length;r++){const i=e.codePointAt(r);i<=127?t+=1:i<=2047?t+=2:i<=65535?t+=3:i<=1114111&&(t+=4,i>65535&&r++)}return t}function H(e){let t=0;for(const r of Object.keys(e))t+=z(r);return t}function V(e){return null==e?"":"boolean"==typeof e?e?"1":"0":"number"==typeof e?String(e):"string"==typeof e?e:Array.isArray(e)?0===e.length?"[]":e.map(e=>String(e)).join("|"):"object"==typeof e?JSON.stringify(e):String(e)}function K(e){const t={};for(const[r,i]of Object.entries(e)){const e=z(V(i));t[r]=e}return t}function W(e){const t=K(e);return Object.values(t).reduce((e,t)=>e+t,0)+H(e)}function J(e){const t=K(e),r=H(e),i=Object.values(t).reduce((e,t)=>e+t,0),s=i+r,n=Object.entries(t).sort(([,e],[,t])=>t-e).map(([e,t])=>({attribute:e,size:t,percentage:(t/s*100).toFixed(2)+"%"}));return{total:s,valueSizes:t,namesSize:r,valueTotal:i,breakdown:n,detailedBreakdown:{values:i,names:r,total:s}}}function G(e={}){const{version:t="1",timestamps:r=!1,id:i=""}=e,s={_v:String(t)};r&&(s.createdAt="2024-01-01T00:00:00.000Z",s.updatedAt="2024-01-01T00:00:00.000Z"),i&&(s.id=i);const n={};for(const[e,t]of Object.entries(s))n[e]=t;return W(n)}function Y(e={}){const{s3Limit:t=2048,systemConfig:r={}}=e;return t-G(r)}class Q extends Error{constructor({verbose:e,bucket:t,key:r,message:i,code:s,statusCode:n,requestId:o,awsMessage:a,original:c,commandName:u,commandInput:l,metadata:h,suggestion:f,...d}){e&&(i+=`\n\nVerbose:\n\n${JSON.stringify(d,null,2)}`),super(i),"function"==typeof Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error(i).stack,super.name=this.constructor.name,this.name=this.constructor.name,this.bucket=t,this.key=r,this.thrownAt=new Date,this.code=s,this.statusCode=n,this.requestId=o,this.awsMessage=a,this.original=c,this.commandName=u,this.commandInput=l,this.metadata=h,this.suggestion=f,this.data={bucket:t,key:r,...d,verbose:e,message:i}}toJson(){return{name:this.name,message:this.message,code:this.code,statusCode:this.statusCode,requestId:this.requestId,awsMessage:this.awsMessage,bucket:this.bucket,key:this.key,thrownAt:this.thrownAt,commandName:this.commandName,commandInput:this.commandInput,metadata:this.metadata,suggestion:this.suggestion,data:this.data,original:this.original,stack:this.stack}}toString(){return`${this.name} | ${this.message}`}}class Z extends Q{constructor(e,t={}){let r,i,s,n,o,a;t.original&&(o=t.original,r=o.code||o.Code||o.name,i=o.statusCode||o.$metadata&&o.$metadata.httpStatusCode,s=o.requestId||o.$metadata&&o.$metadata.requestId,n=o.message,a=o.$metadata?{...o.$metadata}:void 0),super({message:e,...t,code:r,statusCode:i,requestId:s,awsMessage:n,original:o,metadata:a})}}class X extends Z{constructor(e,t={}){super(e,t),Object.assign(this,t)}}class ee extends Z{constructor(e,t={}){super(e,t),Object.assign(this,t)}}class te extends Z{constructor(e,t={}){super(e,t),Object.assign(this,t)}}class re extends Z{constructor(e,t={}){super(e,t),Object.assign(this,t)}}class ie extends Z{constructor(e,t={}){super(e,t),Object.assign(this,t)}}class se extends Z{constructor({bucket:e,resourceName:t,id:r,original:i,...s}){if("string"!=typeof r)throw new Error("id must be a string");if("string"!=typeof e)throw new Error("bucket must be a string");if("string"!=typeof t)throw new Error("resourceName must be a string");super(`Resource not found: ${t}/${r} [bucket:${e}]`,{bucket:e,resourceName:t,id:r,original:i,...s})}}class ne extends Z{constructor({bucket:e,original:t,...r}){if("string"!=typeof e)throw new Error("bucket must be a string");super(`Bucket does not exists [bucket:${e}]`,{bucket:e,original:t,...r})}}class oe extends Z{constructor({bucket:e,key:t,resourceName:r,id:i,original:s,...n}){if("string"!=typeof t)throw new Error("key must be a string");if("string"!=typeof e)throw new Error("bucket must be a string");if(void 0!==i&&"string"!=typeof i)throw new Error("id must be a string");super(`No such key: ${t} [bucket:${e}]`,{bucket:e,key:t,resourceName:r,id:i,original:s,...n}),this.resourceName=r,this.id=i}}class ae extends Z{constructor({bucket:e,key:t,resourceName:r,id:i,original:s,...n}){if("string"!=typeof t)throw new Error("key must be a string");if("string"!=typeof e)throw new Error("bucket must be a string");super(`Not found: ${t} [bucket:${e}]`,{bucket:e,key:t,resourceName:r,id:i,original:s,...n}),this.resourceName=r,this.id=i}}class ce extends Z{constructor({bucket:e,original:t,...r}){if("string"!=typeof e)throw new Error("bucket must be a string");super(`Missing metadata for bucket [bucket:${e}]`,{bucket:e,original:t,...r})}}class ue extends Z{constructor({bucket:e,resourceName:t,attributes:r,validation:i,message:s,original:n,...o}){if("string"!=typeof e)throw new Error("bucket must be a string");if("string"!=typeof t)throw new Error("resourceName must be a string");super(s||`Validation error: This item is not valid. Resource=${t} [bucket:${e}].\n${JSON.stringify(i,null,2)}`,{bucket:e,resourceName:t,attributes:r,validation:i,original:n,...o})}}class le extends Z{}const he={NotFound:ae,NoSuchKey:oe,UnknownError:le,NoSuchBucket:ne,MissingMetadata:ce,InvalidResourceItem:ue};function fe(e,t={}){const r=e.code||e.Code||e.name,i=e.$metadata?{...e.$metadata}:void 0,s=t.commandName,n=t.commandInput;let o;return"NoSuchKey"===r||"NotFound"===r?(o="Check if the key exists in the specified bucket and if your credentials have permission.",new oe({...t,original:e,metadata:i,commandName:s,commandInput:n,suggestion:o})):"NoSuchBucket"===r?(o="Check if the bucket exists and if your credentials have permission.",new ne({...t,original:e,metadata:i,commandName:s,commandInput:n,suggestion:o})):"AccessDenied"===r||403===e.statusCode||"Forbidden"===r?(o="Check your credentials and bucket policy.",new re("Access denied",{...t,original:e,metadata:i,commandName:s,commandInput:n,suggestion:o})):"ValidationError"===r||400===e.statusCode?(o="Check the request parameters and payload.",new ee("Validation error",{...t,original:e,metadata:i,commandName:s,commandInput:n,suggestion:o})):"MissingMetadata"===r?(o="Check if the object metadata is present and valid.",new ce({...t,original:e,metadata:i,commandName:s,commandInput:n,suggestion:o})):(o="Check the error details and AWS documentation.",new le("Unknown error",{...t,original:e,metadata:i,commandName:s,commandInput:n,suggestion:o}))}class de extends Z{constructor(e,t={}){super(e,{...t,suggestion:"Check the connection string format and credentials."})}}class pe extends Z{constructor(e,t={}){super(e,{...t,suggestion:"Check if the crypto library is available and input is valid."})}}class me extends Z{constructor(e,t={}){super(e,{...t,suggestion:"Check schema definition and input data."})}}class ge extends Z{constructor(e,t={}){super(e,{...t,suggestion:t.suggestion||"Check resource configuration, attributes, and operation context."}),Object.assign(this,t)}}class ye extends Z{constructor(e,t={}){super(e,{...t,suggestion:t.suggestion||"Check partition definition, fields, and input values."})}}function be(e){if(null==e){const e=new Error("fnOrPromise cannot be null or undefined");return e.stack=(new Error).stack,[!1,e,void 0]}if("function"==typeof e)try{const t=e();return null==t?[!0,null,t]:"function"==typeof t.then?t.then(e=>[!0,null,e]).catch(e=>{if(e instanceof Error&&Object.isExtensible(e)){const t=Object.getOwnPropertyDescriptor(e,"stack");if(t&&t.writable&&t.configurable&&e.hasOwnProperty("stack"))try{e.stack=(new Error).stack}catch(e){}}return[!1,e,void 0]}):[!0,null,t]}catch(e){if(e instanceof Error&&Object.isExtensible(e)){const t=Object.getOwnPropertyDescriptor(e,"stack");if(t&&t.writable&&t.configurable&&e.hasOwnProperty("stack"))try{e.stack=(new Error).stack}catch(e){}}return[!1,e,void 0]}return"function"==typeof e.then?Promise.resolve(e).then(e=>[!0,null,e]).catch(e=>{if(e instanceof Error&&Object.isExtensible(e)){const t=Object.getOwnPropertyDescriptor(e,"stack");if(t&&t.writable&&t.configurable&&e.hasOwnProperty("stack"))try{e.stack=(new Error).stack}catch(e){}}return[!1,e,void 0]}):[!0,null,e]}function we(e){try{return[!0,null,e()]}catch(e){return[!1,e,null]}}var ve=be;async function ke(){let e;if("undefined"!=typeof process){const[t,r,i]=await ve(async()=>{const{webcrypto:e}=await import("crypto");return e});if(!t)throw new pe("Crypto API not available",{original:r,context:"dynamicCrypto"});e=i}else"undefined"!=typeof window&&(e=window.crypto);if(!e)throw new pe("Could not load any crypto library",{context:"dynamicCrypto"});return e}async function _e(e){const[t,r,i]=await ve(ke);if(!t)throw new pe("Crypto API not available",{original:r});const s=(new TextEncoder).encode(e),[n,o,a]=await ve(()=>i.subtle.digest("SHA-256",s));if(!n)throw new pe("SHA-256 digest failed",{original:o,input:e});return Array.from(new Uint8Array(a)).map(e=>e.toString(16).padStart(2,"0")).join("")}async function Se(e,t){const[r,i,s]=await ve(ke);if(!r)throw new pe("Crypto API not available",{original:i});const n=s.getRandomValues(new Uint8Array(16)),[o,a,c]=await ve(()=>je(t,n));if(!o)throw new pe("Key derivation failed",{original:a,passphrase:t,salt:n});const u=s.getRandomValues(new Uint8Array(12)),l=(new TextEncoder).encode(e),[h,f,d]=await ve(()=>s.subtle.encrypt({name:"AES-GCM",iv:u},c,l));if(!h)throw new pe("Encryption failed",{original:f,content:e});const p=new Uint8Array(n.length+u.length+d.byteLength);return p.set(n),p.set(u,n.length),p.set(new Uint8Array(d),n.length+u.length),function(e){if("undefined"!=typeof process)return Buffer.from(e).toString("base64");{const[t,r,i]=we(()=>String.fromCharCode.apply(null,new Uint8Array(e)));if(!t)throw new pe("Failed to convert ArrayBuffer to base64 (browser)",{original:r});return window.btoa(i)}}(p)}async function Oe(e,t){const[r,i,s]=await ve(ke);if(!r)throw new pe("Crypto API not available",{original:i});const n=function(e){if("undefined"!=typeof process)return new Uint8Array(Buffer.from(e,"base64"));{const[t,r,i]=we(()=>window.atob(e));if(!t)throw new pe("Failed to decode base64 (browser)",{original:r});const s=i.length,n=new Uint8Array(s);for(let e=0;e<s;e++)n[e]=i.charCodeAt(e);return n}}(e),o=n.slice(0,16),a=n.slice(16,28),c=n.slice(28),[u,l,h]=await ve(()=>je(t,o));if(!u)throw new pe("Key derivation failed (decrypt)",{original:l,passphrase:t,salt:o});const[f,d,p]=await ve(()=>s.subtle.decrypt({name:"AES-GCM",iv:a},h,c));if(!f)throw new pe("Decryption failed",{original:d,encryptedBase64:e});return(new TextDecoder).decode(p)}async function Re(e){if("undefined"==typeof process)throw new pe("MD5 hashing is only available in Node.js environment",{context:"md5"});const[t,r,i]=await ve(async()=>{const{createHash:t}=await import("crypto");return t("md5").update(e).digest("base64")});if(!t)throw new pe("MD5 hashing failed",{original:r,data:e});return i}async function je(e,t){const[r,i,s]=await ve(ke);if(!r)throw new pe("Crypto API not available",{original:i});const n=(new TextEncoder).encode(e),[o,a,c]=await ve(()=>s.subtle.importKey("raw",n,{name:"PBKDF2"},!1,["deriveKey"]));if(!o)throw new pe("importKey failed",{original:a,passphrase:e});const[u,l,h]=await ve(()=>s.subtle.deriveKey({name:"PBKDF2",salt:t,iterations:1e5,hash:"SHA-256"},c,{name:"AES-GCM",length:256},!0,["encrypt","decrypt"]));if(!u)throw new pe("deriveKey failed",{original:l,passphrase:e,salt:t});return h}const xe=e(t,22),Ee=e("ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789",16);var Ae;function De(){}function $e(){$e.init.call(this)}function Ce(e){return void 0===e._maxListeners?$e.defaultMaxListeners:e._maxListeners}function Ne(e,t,r,i){var s,n,o,a;if("function"!=typeof r)throw new TypeError('"listener" argument must be a function');if((n=e._events)?(n.newListener&&(e.emit("newListener",t,r.listener?r.listener:r),n=e._events),o=n[t]):(n=e._events=new De,e._eventsCount=0),o){if("function"==typeof o?o=n[t]=i?[r,o]:[o,r]:i?o.unshift(r):o.push(r),!o.warned&&(s=Ce(e))&&s>0&&o.length>s){o.warned=!0;var c=new Error("Possible EventEmitter memory leak detected. "+o.length+" "+t+" listeners added. Use emitter.setMaxListeners() to increase limit");c.name="MaxListenersExceededWarning",c.emitter=e,c.type=t,c.count=o.length,a=c,"function"==typeof console.warn?console.warn(a):console.log(a)}}else o=n[t]=r,++e._eventsCount;return e}function Ie(e,t,r){var i=!1;function s(){e.removeListener(t,s),i||(i=!0,r.apply(e,arguments))}return s.listener=r,s}function Pe(e){var t=this._events;if(t){var r=t[e];if("function"==typeof r)return 1;if(r)return r.length}return 0}function Te(e,t){for(var r=new Array(t);t--;)r[t]=e[t];return r}De.prototype=Object.create(null),$e.EventEmitter=$e,$e.usingDomains=!1,$e.prototype.domain=void 0,$e.prototype._events=void 0,$e.prototype._maxListeners=void 0,$e.defaultMaxListeners=10,$e.init=function(){this.domain=null,$e.usingDomains&&(!Ae.active||this instanceof Ae.Domain||(this.domain=Ae.active)),this._events&&this._events!==Object.getPrototypeOf(this)._events||(this._events=new De,this._eventsCount=0),this._maxListeners=this._maxListeners||void 0},$e.prototype.setMaxListeners=function(e){if("number"!=typeof e||e<0||isNaN(e))throw new TypeError('"n" argument must be a positive number');return this._maxListeners=e,this},$e.prototype.getMaxListeners=function(){return Ce(this)},$e.prototype.emit=function(e){var t,r,i,s,n,o,a,c="error"===e;if(o=this._events)c=c&&null==o.error;else if(!c)return!1;if(a=this.domain,c){if(t=arguments[1],!a){if(t instanceof Error)throw t;var u=new Error('Uncaught, unspecified "error" event. ('+t+")");throw u.context=t,u}return t||(t=new Error('Uncaught, unspecified "error" event')),t.domainEmitter=this,t.domain=a,t.domainThrown=!1,a.emit("error",t),!1}if(!(r=o[e]))return!1;var l="function"==typeof r;switch(i=arguments.length){case 1:!function(e,t,r){if(t)e.call(r);else for(var i=e.length,s=Te(e,i),n=0;n<i;++n)s[n].call(r)}(r,l,this);break;case 2:!function(e,t,r,i){if(t)e.call(r,i);else for(var s=e.length,n=Te(e,s),o=0;o<s;++o)n[o].call(r,i)}(r,l,this,arguments[1]);break;case 3:!function(e,t,r,i,s){if(t)e.call(r,i,s);else for(var n=e.length,o=Te(e,n),a=0;a<n;++a)o[a].call(r,i,s)}(r,l,this,arguments[1],arguments[2]);break;case 4:!function(e,t,r,i,s,n){if(t)e.call(r,i,s,n);else for(var o=e.length,a=Te(e,o),c=0;c<o;++c)a[c].call(r,i,s,n)}(r,l,this,arguments[1],arguments[2],arguments[3]);break;default:for(s=new Array(i-1),n=1;n<i;n++)s[n-1]=arguments[n];!function(e,t,r,i){if(t)e.apply(r,i);else for(var s=e.length,n=Te(e,s),o=0;o<s;++o)n[o].apply(r,i)}(r,l,this,s)}return!0},$e.prototype.addListener=function(e,t){return Ne(this,e,t,!1)},$e.prototype.on=$e.prototype.addListener,$e.prototype.prependListener=function(e,t){return Ne(this,e,t,!0)},$e.prototype.once=function(e,t){if("function"!=typeof t)throw new TypeError('"listener" argument must be a function');return this.on(e,Ie(this,e,t)),this},$e.prototype.prependOnceListener=function(e,t){if("function"!=typeof t)throw new TypeError('"listener" argument must be a function');return this.prependListener(e,Ie(this,e,t)),this},$e.prototype.removeListener=function(e,t){var r,i,s,n,o;if("function"!=typeof t)throw new TypeError('"listener" argument must be a function');if(!(i=this._events))return this;if(!(r=i[e]))return this;if(r===t||r.listener&&r.listener===t)0===--this._eventsCount?this._events=new De:(delete i[e],i.removeListener&&this.emit("removeListener",e,r.listener||t));else if("function"!=typeof r){for(s=-1,n=r.length;n-- >0;)if(r[n]===t||r[n].listener&&r[n].listener===t){o=r[n].listener,s=n;break}if(s<0)return this;if(1===r.length){if(r[0]=void 0,0===--this._eventsCount)return this._events=new De,this;delete i[e]}else!function(e,t){for(var r=t,i=r+1,s=e.length;i<s;r+=1,i+=1)e[r]=e[i];e.pop()}(r,s);i.removeListener&&this.emit("removeListener",e,o||t)}return this},$e.prototype.off=function(e,t){return this.removeListener(e,t)},$e.prototype.removeAllListeners=function(e){var t,r;if(!(r=this._events))return this;if(!r.removeListener)return 0===arguments.length?(this._events=new De,this._eventsCount=0):r[e]&&(0===--this._eventsCount?this._events=new De:delete r[e]),this;if(0===arguments.length){for(var i,s=Object.keys(r),n=0;n<s.length;++n)"removeListener"!==(i=s[n])&&this.removeAllListeners(i);return this.removeAllListeners("removeListener"),this._events=new De,this._eventsCount=0,this}if("function"==typeof(t=r[e]))this.removeListener(e,t);else if(t)do{this.removeListener(e,t[t.length-1])}while(t[0]);return this},$e.prototype.listeners=function(e){var t,r=this._events;return r&&(t=r[e])?"function"==typeof t?[t.listener||t]:function(e){for(var t=new Array(e.length),r=0;r<t.length;++r)t[r]=e[r].listener||e[r];return t}(t):[]},$e.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):Pe.call(e,t)},$e.prototype.listenerCount=Pe,$e.prototype.eventNames=function(){return this._eventsCount>0?Reflect.ownKeys(this._events):[]};var Me=class extends $e{constructor(e={}){super(),this.name=this.constructor.name,this.options=e,this.hooks=new Map}async setup(e){this.database=e,this.beforeSetup(),await this.onSetup(),this.afterSetup()}async start(){this.beforeStart(),await this.onStart(),this.afterStart()}async stop(){this.beforeStop(),await this.onStop(),this.afterStop()}async onSetup(){}async onStart(){}async onStop(){}addHook(e,t,r){this.hooks.has(e)||this.hooks.set(e,new Map);const i=this.hooks.get(e);i.has(t)||i.set(t,[]),i.get(t).push(r)}removeHook(e,t,r){const i=this.hooks.get(e);if(i&&i.has(t)){const e=i.get(t),s=e.indexOf(r);s>-1&&e.splice(s,1)}}wrapResourceMethod(e,t,r){const i=e[t];if(e._pluginWrappers||(e._pluginWrappers=new Map),e._pluginWrappers.has(t)||e._pluginWrappers.set(t,[]),e._pluginWrappers.get(t).push(r),!e[`_wrapped_${t}`]){e[`_wrapped_${t}`]=i;const r=i&&i._isMockFunction;e[t]=async function(...r){let i=await e[`_wrapped_${t}`](...r);for(const s of e._pluginWrappers.get(t))i=await s.call(this,i,r,t);return i},r&&(Object.setPrototypeOf(e[t],Object.getPrototypeOf(i)),Object.assign(e[t],i))}}addMiddleware(e,t,r){if(e._pluginMiddlewares||(e._pluginMiddlewares={}),!e._pluginMiddlewares[t]){e._pluginMiddlewares[t]=[];const r=e[t].bind(e);e[t]=async function(...i){let s=-1;const n=async(...i)=>(s++,s<e._pluginMiddlewares[t].length?await e._pluginMiddlewares[t][s].call(this,n,...i):await r(...i));return await n(...i)}}e._pluginMiddlewares[t].push(r)}getPartitionValues(e,t){if(!t.config?.partitions)return{};const r={};for(const[i,s]of Object.entries(t.config.partitions))if(s.fields){r[i]={};for(const[n,o]of Object.entries(s.fields)){const s=this.getNestedFieldValue(e,n);null!=s&&(r[i][n]=t.applyPartitionRule(s,o))}}else r[i]={};return r}getNestedFieldValue(e,t){if(!t.includes("."))return e[t]??null;const r=t.split(".");let i=e;for(const e of r){if(!i||"object"!=typeof i||!(e in i))return null;i=i[e]}return i??null}beforeSetup(){this.emit("plugin.beforeSetup",new Date)}afterSetup(){this.emit("plugin.afterSetup",new Date)}beforeStart(){this.emit("plugin.beforeStart",new Date)}afterStart(){this.emit("plugin.afterStart",new Date)}beforeStop(){this.emit("plugin.beforeStop",new Date)}afterStop(){this.emit("plugin.afterStop",new Date)}};const Le={setup(e){},start(){},stop(){}};class Ue extends Me{constructor(e={}){super(e),this.auditResource=null,this.config={includeData:!1!==e.includeData,includePartitions:!1!==e.includePartitions,maxDataSize:e.maxDataSize||1e4,...e}}async onSetup(){const[e,t,r]=await ve(()=>this.database.createResource({name:"audits",attributes:{id:"string|required",resourceName:"string|required",operation:"string|required",recordId:"string|required",userId:"string|optional",timestamp:"string|required",oldData:"string|optional",newData:"string|optional",partition:"string|optional",partitionValues:"string|optional",metadata:"string|optional"},behavior:"body-overflow"}));if(this.auditResource=e?r:this.database.resources.audits||null,e||this.auditResource){this.database.addHook("afterCreateResource",e=>{"audits"!==e.resource.name&&this.setupResourceAuditing(e.resource)});for(const e of Object.values(this.database.resources))"audits"!==e.name&&this.setupResourceAuditing(e)}}async onStart(){}async onStop(){}setupResourceAuditing(e){e.on("insert",async t=>{await this.logAudit({resourceName:e.name,operation:"insert",recordId:t.id||"auto-generated",oldData:null,newData:this.config.includeData?JSON.stringify(this.truncateData(t)):null,partition:this.config.includePartitions&&this.getPartitionValues(t,e)?this.getPrimaryPartition(this.getPartitionValues(t,e)):null,partitionValues:this.config.includePartitions&&this.getPartitionValues(t,e)?JSON.stringify(this.getPartitionValues(t,e)):null})}),e.on("update",async t=>{let r=t.$before;if(this.config.includeData&&!r){const[i,s,n]=await ve(()=>e.get(t.id));i&&(r=n)}await this.logAudit({resourceName:e.name,operation:"update",recordId:t.id,oldData:r&&this.config.includeData?JSON.stringify(this.truncateData(r)):null,newData:this.config.includeData?JSON.stringify(this.truncateData(t)):null,partition:this.config.includePartitions&&this.getPartitionValues(t,e)?this.getPrimaryPartition(this.getPartitionValues(t,e)):null,partitionValues:this.config.includePartitions&&this.getPartitionValues(t,e)?JSON.stringify(this.getPartitionValues(t,e)):null})}),e.on("delete",async t=>{let r=t;if(this.config.includeData&&!r){const[i,s,n]=await ve(()=>e.get(t.id));i&&(r=n)}await this.logAudit({resourceName:e.name,operation:"delete",recordId:t.id,oldData:r&&this.config.includeData?JSON.stringify(this.truncateData(r)):null,newData:null,partition:r&&this.config.includePartitions&&this.getPartitionValues(r,e)?this.getPrimaryPartition(this.getPartitionValues(r,e)):null,partitionValues:r&&this.config.includePartitions&&this.getPartitionValues(r,e)?JSON.stringify(this.getPartitionValues(r,e)):null})})}installEventListenersForResource(e){return this.setupResourceAuditing(e)}async logAudit(e){if(!this.auditResource)return;const t={id:`audit-${Date.now()}-${Math.random().toString(36).substring(2,11)}`,userId:this.getCurrentUserId?.()||"system",timestamp:(new Date).toISOString(),metadata:JSON.stringify({source:"audit-plugin",version:"2.0"}),resourceName:e.resourceName,operation:e.operation,recordId:e.recordId};null!==e.oldData&&(t.oldData=e.oldData),null!==e.newData&&(t.newData=e.newData),null!==e.partition&&(t.partition=e.partition),null!==e.partitionValues&&(t.partitionValues=e.partitionValues);try{await this.auditResource.insert(t)}catch(e){console.warn("Audit logging failed:",e.message)}}getPartitionValues(e,t){if(!this.config.includePartitions||!t.partitions)return null;const r={};for(const[i,s]of Object.entries(t.partitions)){const t={};for(const r of Object.keys(s.fields))t[r]=this.getNestedFieldValue(e,r);Object.values(t).some(e=>null!=e)&&(r[i]=t)}return Object.keys(r).length>0?r:null}getNestedFieldValue(e,t){const r=t.split(".");let i=e;for(const e of r){if(!i||"object"!=typeof i||!(e in i))return;i=i[e]}return i}getPrimaryPartition(e){if(!e)return null;const t=Object.keys(e);return t.length>0?t[0]:null}truncateData(e){if(!this.config.includeData)return null;const t=JSON.stringify(e);return t.length<=this.config.maxDataSize?e:{...e,_truncated:!0,_originalSize:t.length,_truncatedAt:(new Date).toISOString()}}async getAuditLogs(e={}){if(!this.auditResource)return[];const{resourceName:t,operation:r,recordId:i,partition:s,startDate:n,endDate:o,limit:a=100}=e;let c={};t&&(c.resourceName=t),r&&(c.operation=r),i&&(c.recordId=i),s&&(c.partition=s),(n||o)&&(c.timestamp={},n&&(c.timestamp.$gte=n),o&&(c.timestamp.$lte=o));return(await this.auditResource.page({query:c,limit:a})).items||[]}async getRecordHistory(e,t){return await this.getAuditLogs({resourceName:e,recordId:t})}async getPartitionHistory(e,t,r){return await this.getAuditLogs({resourceName:e,partition:t,partitionValues:JSON.stringify(r)})}async getAuditStats(e={}){const t=await this.getAuditLogs(e),r={total:t.length,byOperation:{},byResource:{},byPartition:{},byUser:{},timeline:{}};for(const e of t){r.byOperation[e.operation]=(r.byOperation[e.operation]||0)+1,r.byResource[e.resourceName]=(r.byResource[e.resourceName]||0)+1,e.partition&&(r.byPartition[e.partition]=(r.byPartition[e.partition]||0)+1),r.byUser[e.userId]=(r.byUser[e.userId]||0)+1;const t=e.timestamp.split("T")[0];r.timeline[t]=(r.timeline[t]||0)+1}return r}}function Fe(e,t){for(var r=0,i=e.length-1;i>=0;i--){var s=e[i];"."===s?e.splice(i,1):".."===s?(e.splice(i,1),r++):r&&(e.splice(i,1),r--)}if(t)for(;r--;r)e.unshift("..");return e}var qe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/,Be=function(e){return qe.exec(e).slice(1)};function ze(){for(var e="",t=!1,r=arguments.length-1;r>=-1&&!t;r--){var i=r>=0?arguments[r]:"/";if("string"!=typeof i)throw new TypeError("Arguments to path.resolve must be strings");i&&(e=i+"/"+e,t="/"===i.charAt(0))}return(t?"/":"")+(e=Fe(Je(e.split("/"),function(e){return!!e}),!t).join("/"))||"."}function He(e){var t=Ve(e),r="/"===Ge(e,-1);return(e=Fe(Je(e.split("/"),function(e){return!!e}),!t).join("/"))||t||(e="."),e&&r&&(e+="/"),(t?"/":"")+e}function Ve(e){return"/"===e.charAt(0)}function Ke(){return He(Je(Array.prototype.slice.call(arguments,0),function(e,t){if("string"!=typeof e)throw new TypeError("Arguments to path.join must be strings");return e}).join("/"))}var We={extname:function(e){return Be(e)[3]},basename:function(e,t){var r=Be(e)[2];return t&&r.substr(-1*t.length)===t&&(r=r.substr(0,r.length-t.length)),r},dirname:function(e){var t=Be(e),r=t[0],i=t[1];return r||i?(i&&(i=i.substr(0,i.length-1)),r+i):"."},sep:"/",delimiter:":",relative:function(e,t){function r(e){for(var t=0;t<e.length&&""===e[t];t++);for(var r=e.length-1;r>=0&&""===e[r];r--);return t>r?[]:e.slice(t,r-t+1)}e=ze(e).substr(1),t=ze(t).substr(1);for(var i=r(e.split("/")),s=r(t.split("/")),n=Math.min(i.length,s.length),o=n,a=0;a<n;a++)if(i[a]!==s[a]){o=a;break}var c=[];for(a=o;a<i.length;a++)c.push("..");return(c=c.concat(s.slice(o))).join("/")},join:Ke,isAbsolute:Ve,normalize:He,resolve:ze};function Je(e,t){if(e.filter)return e.filter(t);for(var r=[],i=0;i<e.length;i++)t(e[i],i,e)&&r.push(e[i]);return r}var Ge="b"==="ab".substr(-1)?function(e,t,r){return e.substr(t,r)}:function(e,t,r){return t<0&&(t=e.length+t),e.substr(t,r)};class Ye extends $e{constructor(e={}){super(),this.config=e}async _set(e,t){}async _get(e){}async _del(e){}async _clear(e){}validateKey(e){if(null==e||"string"!=typeof e||!e)throw new Error("Invalid key")}async set(e,t){return this.validateKey(e),await this._set(e,t),this.emit("set",t),t}async get(e){this.validateKey(e);const t=await this._get(e);return this.emit("get",t),t}async del(e){this.validateKey(e);const t=await this._del(e);return this.emit("delete",t),t}async delete(e){return this.del(e)}async clear(e){const t=await this._clear(e);return this.emit("clear",t),t}}function Qe(){throw new Error("setTimeout has not been defined")}function Ze(){throw new Error("clearTimeout has not been defined")}var Xe=Qe,et=Ze;function tt(e){if(Xe===setTimeout)return setTimeout(e,0);if((Xe===Qe||!Xe)&&setTimeout)return Xe=setTimeout,setTimeout(e,0);try{return Xe(e,0)}catch(t){try{return Xe.call(null,e,0)}catch(t){return Xe.call(this,e,0)}}}"function"==typeof global.setTimeout&&(Xe=setTimeout),"function"==typeof global.clearTimeout&&(et=clearTimeout);var rt,it=[],st=!1,nt=-1;function ot(){st&&rt&&(st=!1,rt.length?it=rt.concat(it):nt=-1,it.length&&at())}function at(){if(!st){var e=tt(ot);st=!0;for(var t=it.length;t;){for(rt=it,it=[];++nt<t;)rt&&rt[nt].run();nt=-1,t=it.length}rt=null,st=!1,function(e){if(et===clearTimeout)return clearTimeout(e);if((et===Ze||!et)&&clearTimeout)return et=clearTimeout,clearTimeout(e);try{return et(e)}catch(t){try{return et.call(null,e)}catch(t){return et.call(this,e)}}}(e)}}function ct(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var r=1;r<arguments.length;r++)t[r-1]=arguments[r];it.push(new ut(e,t)),1!==it.length||st||tt(at)}function ut(e,t){this.fun=e,this.array=t}ut.prototype.run=function(){this.fun.apply(null,this.array)};var lt,ht={env:{}};lt="function"==typeof Object.create?function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:function(e,t){e.super_=t;var r=function(){};r.prototype=t.prototype,e.prototype=new r,e.prototype.constructor=e};var ft=/%[sdj%]/g;function dt(e){if(!Rt(e)){for(var t=[],r=0;r<arguments.length;r++)t.push(yt(arguments[r]));return t.join(" ")}r=1;for(var i=arguments,s=i.length,n=String(e).replace(ft,function(e){if("%%"===e)return"%";if(r>=s)return e;switch(e){case"%s":return String(i[r++]);case"%d":return Number(i[r++]);case"%j":try{return JSON.stringify(i[r++])}catch(e){return"[Circular]"}default:return e}}),o=i[r];r<s;o=i[++r])Ot(o)||!Et(o)?n+=" "+o:n+=" "+yt(o);return n}function pt(e,t){if(jt(global.process))return function(){return pt(e,t).apply(this,arguments)};if(!0===ht.noDeprecation)return e;var r=!1;return function(){if(!r){if(ht.throwDeprecation)throw new Error(t);ht.traceDeprecation?console.trace(t):console.error(t),r=!0}return e.apply(this,arguments)}}var mt,gt={};function yt(e,t){var r={seen:[],stylize:wt};return arguments.length>=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),St(t)?r.showHidden=t:t&&function(e,t){if(!t||!Et(t))return e;var r=Object.keys(t),i=r.length;for(;i--;)e[r[i]]=t[r[i]]}(r,t),jt(r.showHidden)&&(r.showHidden=!1),jt(r.depth)&&(r.depth=2),jt(r.colors)&&(r.colors=!1),jt(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=bt),vt(r,e,r.depth)}function bt(e,t){var r=yt.styles[t];return r?"["+yt.colors[r][0]+"m"+e+"["+yt.colors[r][1]+"m":e}function wt(e,t){return e}function vt(e,t,r){if(e.customInspect&&t&&$t(t.inspect)&&t.inspect!==yt&&(!t.constructor||t.constructor.prototype!==t)){var i=t.inspect(r,e);return Rt(i)||(i=vt(e,i,r)),i}var s=function(e,t){if(jt(t))return e.stylize("undefined","undefined");if(Rt(t)){var r="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(r,"string")}if(i=t,"number"==typeof i)return e.stylize(""+t,"number");var i;if(St(t))return e.stylize(""+t,"boolean");if(Ot(t))return e.stylize("null","null")}(e,t);if(s)return s;var n=Object.keys(t),o=function(e){var t={};return e.forEach(function(e,r){t[e]=!0}),t}(n);if(e.showHidden&&(n=Object.getOwnPropertyNames(t)),Dt(t)&&(n.indexOf("message")>=0||n.indexOf("description")>=0))return kt(t);if(0===n.length){if($t(t)){var a=t.name?": "+t.name:"";return e.stylize("[Function"+a+"]","special")}if(xt(t))return e.stylize(RegExp.prototype.toString.call(t),"regexp");if(At(t))return e.stylize(Date.prototype.toString.call(t),"date");if(Dt(t))return kt(t)}var c,u,l="",h=!1,f=["{","}"];(c=t,Array.isArray(c)&&(h=!0,f=["[","]"]),$t(t))&&(l=" [Function"+(t.name?": "+t.name:"")+"]");return xt(t)&&(l=" "+RegExp.prototype.toString.call(t)),At(t)&&(l=" "+Date.prototype.toUTCString.call(t)),Dt(t)&&(l=" "+kt(t)),0!==n.length||h&&0!=t.length?r<0?xt(t)?e.stylize(RegExp.prototype.toString.call(t),"regexp"):e.stylize("[Object]","special"):(e.seen.push(t),u=h?function(e,t,r,i,s){for(var n=[],o=0,a=t.length;o<a;++o)Nt(t,String(o))?n.push(_t(e,t,r,i,String(o),!0)):n.push("");return s.forEach(function(s){s.match(/^\d+$/)||n.push(_t(e,t,r,i,s,!0))}),n}(e,t,r,o,n):n.map(function(i){return _t(e,t,r,o,i,h)}),e.seen.pop(),function(e,t,r){var i=e.reduce(function(e,t){return t.indexOf("\n"),e+t.replace(/\u001b\[\d\d?m/g,"").length+1},0);if(i>60)return r[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+r[1];return r[0]+t+" "+e.join(", ")+" "+r[1]}(u,l,f)):f[0]+l+f[1]}function kt(e){return"["+Error.prototype.toString.call(e)+"]"}function _t(e,t,r,i,s,n){var o,a,c;if((c=Object.getOwnPropertyDescriptor(t,s)||{value:t[s]}).get?a=c.set?e.stylize("[Getter/Setter]","special"):e.stylize("[Getter]","special"):c.set&&(a=e.stylize("[Setter]","special")),Nt(i,s)||(o="["+s+"]"),a||(e.seen.indexOf(c.value)<0?(a=Ot(r)?vt(e,c.value,null):vt(e,c.value,r-1)).indexOf("\n")>-1&&(a=n?a.split("\n").map(function(e){return" "+e}).join("\n").substr(2):"\n"+a.split("\n").map(function(e){return" "+e}).join("\n")):a=e.stylize("[Circular]","special")),jt(o)){if(n&&s.match(/^\d+$/))return a;(o=JSON.stringify(""+s)).match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(o=o.substr(1,o.length-2),o=e.stylize(o,"name")):(o=o.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),o=e.stylize(o,"string"))}return o+": "+a}function St(e){return"boolean"==typeof e}function Ot(e){return null===e}function Rt(e){return"string"==typeof e}function jt(e){return void 0===e}function xt(e){return Et(e)&&"[object RegExp]"===Ct(e)}function Et(e){return"object"==typeof e&&null!==e}function At(e){return Et(e)&&"[object Date]"===Ct(e)}function Dt(e){return Et(e)&&("[object Error]"===Ct(e)||e instanceof Error)}function $t(e){return"function"==typeof e}function Ct(e){return Object.prototype.toString.call(e)}function Nt(e,t){return Object.prototype.hasOwnProperty.call(e,t)}yt.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},yt.styles={special:"cyan",number:"yellow",boolean:"yellow",undefined:"grey",null:"bold",string:"green",date:"magenta",regexp:"red"};var It=[],Pt=[],Tt="undefined"!=typeof Uint8Array?Uint8Array:Array,Mt=!1;function Lt(){Mt=!0;for(var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",t=0;t<64;++t)It[t]=e[t],Pt[e.charCodeAt(t)]=t;Pt["-".charCodeAt(0)]=62,Pt["_".charCodeAt(0)]=63}function Ut(e){return It[e>>18&63]+It[e>>12&63]+It[e>>6&63]+It[63&e]}function Ft(e,t,r){for(var i,s=[],n=t;n<r;n+=3)i=(e[n]<<16)+(e[n+1]<<8)+e[n+2],s.push(Ut(i));return s.join("")}function qt(e){var t;Mt||Lt();for(var r=e.length,i=r%3,s="",n=[],o=16383,a=0,c=r-i;a<c;a+=o)n.push(Ft(e,a,a+o>c?c:a+o));return 1===i?(t=e[r-1],s+=It[t>>2],s+=It[t<<4&63],s+="=="):2===i&&(t=(e[r-2]<<8)+e[r-1],s+=It[t>>10],s+=It[t>>4&63],s+=It[t<<2&63],s+="="),n.push(s),n.join("")}function Bt(e,t,r,i,s){var n,o,a=8*s-i-1,c=(1<<a)-1,u=c>>1,l=-7,h=r?s-1:0,f=r?-1:1,d=e[t+h];for(h+=f,n=d&(1<<-l)-1,d>>=-l,l+=a;l>0;n=256*n+e[t+h],h+=f,l-=8);for(o=n&(1<<-l)-1,n>>=-l,l+=i;l>0;o=256*o+e[t+h],h+=f,l-=8);if(0===n)n=1-u;else{if(n===c)return o?NaN:1/0*(d?-1:1);o+=Math.pow(2,i),n-=u}return(d?-1:1)*o*Math.pow(2,n-i)}function zt(e,t,r,i,s,n){var o,a,c,u=8*n-s-1,l=(1<<u)-1,h=l>>1,f=23===s?Math.pow(2,-24)-Math.pow(2,-77):0,d=i?0:n-1,p=i?1:-1,m=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,o=l):(o=Math.floor(Math.log(t)/Math.LN2),t*(c=Math.pow(2,-o))<1&&(o--,c*=2),(t+=o+h>=1?f/c:f*Math.pow(2,1-h))*c>=2&&(o++,c/=2),o+h>=l?(a=0,o=l):o+h>=1?(a=(t*c-1)*Math.pow(2,s),o+=h):(a=t*Math.pow(2,h-1)*Math.pow(2,s),o=0));s>=8;e[r+d]=255&a,d+=p,a/=256,s-=8);for(o=o<<s|a,u+=s;u>0;e[r+d]=255&o,d+=p,o/=256,u-=8);e[r+d-p]|=128*m}var Ht={}.toString,Vt=Array.isArray||function(e){return"[object Array]"==Ht.call(e)};function Kt(){return Jt.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function Wt(e,t){if(Kt()<t)throw new RangeError("Invalid typed array length");return Jt.TYPED_ARRAY_SUPPORT?(e=new Uint8Array(t)).__proto__=Jt.prototype:(null===e&&(e=new Jt(t)),e.length=t),e}function Jt(e,t,r){if(!(Jt.TYPED_ARRAY_SUPPORT||this instanceof Jt))return new Jt(e,t,r);if("number"==typeof e){if("string"==typeof t)throw new Error("If encoding is specified then the first argument must be a string");return Qt(this,e)}return Gt(this,e,t,r)}function Gt(e,t,r,i){if("number"==typeof t)throw new TypeError('"value" argument must not be a number');return"undefined"!=typeof ArrayBuffer&&t instanceof ArrayBuffer?function(e,t,r,i){if(t.byteLength,r<0||t.byteLength<r)throw new RangeError("'offset' is out of bounds");if(t.byteLength<r+(i||0))throw new RangeError("'length' is out of bounds");t=void 0===r&&void 0===i?new Uint8Array(t):void 0===i?new Uint8Array(t,r):new Uint8Array(t,r,i);Jt.TYPED_ARRAY_SUPPORT?(e=t).__proto__=Jt.prototype:e=Zt(e,t);return e}(e,t,r,i):"string"==typeof t?function(e,t,r){"string"==typeof r&&""!==r||(r="utf8");if(!Jt.isEncoding(r))throw new TypeError('"encoding" must be a valid string encoding');var i=0|tr(t,r);e=Wt(e,i);var s=e.write(t,r);s!==i&&(e=e.slice(0,s));return e}(e,t,r):function(e,t){if(er(t)){var r=0|Xt(t.length);return 0===(e=Wt(e,r)).length||t.copy(e,0,0,r),e}if(t){if("undefined"!=typeof ArrayBuffer&&t.buffer instanceof ArrayBuffer||"length"in t)return"number"!=typeof t.length||(i=t.length)!=i?Wt(e,0):Zt(e,t);if("Buffer"===t.type&&Vt(t.data))return Zt(e,t.data)}var i;throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.")}(e,t)}function Yt(e){if("number"!=typeof e)throw new TypeError('"size" argument must be a number');if(e<0)throw new RangeError('"size" argument must not be negative')}function Qt(e,t){if(Yt(t),e=Wt(e,t<0?0:0|Xt(t)),!Jt.TYPED_ARRAY_SUPPORT)for(var r=0;r<t;++r)e[r]=0;return e}function Zt(e,t){var r=t.length<0?0:0|Xt(t.length);e=Wt(e,r);for(var i=0;i<r;i+=1)e[i]=255&t[i];return e}function Xt(e){if(e>=Kt())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+Kt().toString(16)+" bytes");return 0|e}function er(e){return!(null==e||!e._isBuffer)}function tr(e,t){if(er(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var r=e.length;if(0===r)return 0;for(var i=!1;;)switch(t){case"ascii":case"latin1":case"binary":return r;case"utf8":case"utf-8":case void 0:return Er(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*r;case"hex":return r>>>1;case"base64":return Ar(e).length;default:if(i)return Er(e).length;t=(""+t).toLowerCase(),i=!0}}function rr(e,t,r){var i=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return"";if((r>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return yr(this,t,r);case"utf8":case"utf-8":return dr(this,t,r);case"ascii":return mr(this,t,r);case"latin1":case"binary":return gr(this,t,r);case"base64":return fr(this,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return br(this,t,r);default:if(i)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),i=!0}}function ir(e,t,r){var i=e[t];e[t]=e[r],e[r]=i}function sr(e,t,r,i,s){if(0===e.length)return-1;if("string"==typeof r?(i=r,r=0):r>2147483647?r=2147483647:r<-2147483648&&(r=-2147483648),r=+r,isNaN(r)&&(r=s?0:e.length-1),r<0&&(r=e.length+r),r>=e.length){if(s)return-1;r=e.length-1}else if(r<0){if(!s)return-1;r=0}if("string"==typeof t&&(t=Jt.from(t,i)),er(t))return 0===t.length?-1:nr(e,t,r,i,s);if("number"==typeof t)return t&=255,Jt.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?s?Uint8Array.prototype.indexOf.call(e,t,r):Uint8Array.prototype.lastIndexOf.call(e,t,r):nr(e,[t],r,i,s);throw new TypeError("val must be string, number or Buffer")}function nr(e,t,r,i,s){var n,o=1,a=e.length,c=t.length;if(void 0!==i&&("ucs2"===(i=String(i).toLowerCase())||"ucs-2"===i||"utf16le"===i||"utf-16le"===i)){if(e.length<2||t.length<2)return-1;o=2,a/=2,c/=2,r/=2}function u(e,t){return 1===o?e[t]:e.readUInt16BE(t*o)}if(s){var l=-1;for(n=r;n<a;n++)if(u(e,n)===u(t,-1===l?0:n-l)){if(-1===l&&(l=n),n-l+1===c)return l*o}else-1!==l&&(n-=n-l),l=-1}else for(r+c>a&&(r=a-c),n=r;n>=0;n--){for(var h=!0,f=0;f<c;f++)if(u(e,n+f)!==u(t,f)){h=!1;break}if(h)return n}return-1}function or(e,t,r,i){r=Number(r)||0;var s=e.length-r;i?(i=Number(i))>s&&(i=s):i=s;var n=t.length;if(n%2!=0)throw new TypeError("Invalid hex string");i>n/2&&(i=n/2);for(var o=0;o<i;++o){var a=parseInt(t.substr(2*o,2),16);if(isNaN(a))return o;e[r+o]=a}return o}function ar(e,t,r,i){return Dr(Er(t,e.length-r),e,r,i)}function cr(e,t,r,i){return Dr(function(e){for(var t=[],r=0;r<e.length;++r)t.push(255&e.charCodeAt(r));return t}(t),e,r,i)}function ur(e,t,r,i){return cr(e,t,r,i)}function lr(e,t,r,i){return Dr(Ar(t),e,r,i)}function hr(e,t,r,i){return Dr(function(e,t){for(var r,i,s,n=[],o=0;o<e.length&&!((t-=2)<0);++o)i=(r=e.charCodeAt(o))>>8,s=r%256,n.push(s),n.push(i);return n}(t,e.length-r),e,r,i)}function fr(e,t,r){return 0===t&&r===e.length?qt(e):qt(e.slice(t,r))}function dr(e,t,r){r=Math.min(e.length,r);for(var i=[],s=t;s<r;){var n,o,a,c,u=e[s],l=null,h=u>239?4:u>223?3:u>191?2:1;if(s+h<=r)switch(h){case 1:u<128&&(l=u);break;case 2:128==(192&(n=e[s+1]))&&(c=(31&u)<<6|63&n)>127&&(l=c);break;case 3:n=e[s+1],o=e[s+2],128==(192&n)&&128==(192&o)&&(c=(15&u)<<12|(63&n)<<6|63&o)>2047&&(c<55296||c>57343)&&(l=c);break;case 4:n=e[s+1],o=e[s+2],a=e[s+3],128==(192&n)&&128==(192&o)&&128==(192&a)&&(c=(15&u)<<18|(63&n)<<12|(63&o)<<6|63&a)>65535&&c<1114112&&(l=c)}null===l?(l=65533,h=1):l>65535&&(l-=65536,i.push(l>>>10&1023|55296),l=56320|1023&l),i.push(l),s+=h}return function(e){var t=e.length;if(t<=pr)return String.fromCharCode.apply(String,e);var r="",i=0;for(;i<t;)r+=String.fromCharCode.apply(String,e.slice(i,i+=pr));return r}(i)}Jt.TYPED_ARRAY_SUPPORT=void 0===global.TYPED_ARRAY_SUPPORT||global.TYPED_ARRAY_SUPPORT,Kt(),Jt.poolSize=8192,Jt._augment=function(e){return e.__proto__=Jt.prototype,e},Jt.from=function(e,t,r){return Gt(null,e,t,r)},Jt.TYPED_ARRAY_SUPPORT&&(Jt.prototype.__proto__=Uint8Array.prototype,Jt.__proto__=Uint8Array,"undefined"!=typeof Symbol&&Symbol.species&&Jt[Symbol.species]),Jt.alloc=function(e,t,r){return function(e,t,r,i){return Yt(t),t<=0?Wt(e,t):void 0!==r?"string"==typeof i?Wt(e,t).fill(r,i):Wt(e,t).fill(r):Wt(e,t)}(null,e,t,r)},Jt.allocUnsafe=function(e){return Qt(null,e)},Jt.allocUnsafeSlow=function(e){return Qt(null,e)},Jt.isBuffer=function(e){return null!=e&&(!!e._isBuffer||$r(e)||function(e){return"function"==typeof e.readFloatLE&&"function"==typeof e.slice&&$r(e.slice(0,0))}(e))},Jt.compare=function(e,t){if(!er(e)||!er(t))throw new TypeError("Arguments must be Buffers");if(e===t)return 0;for(var r=e.length,i=t.length,s=0,n=Math.min(r,i);s<n;++s)if(e[s]!==t[s]){r=e[s],i=t[s];break}return r<i?-1:i<r?1:0},Jt.isEncoding=function(e){switch(String(e).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"latin1":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return!0;default:return!1}},Jt.concat=function(e,t){if(!Vt(e))throw new TypeError('"list" argument must be an Array of Buffers');if(0===e.length)return Jt.alloc(0);var r;if(void 0===t)for(t=0,r=0;r<e.length;++r)t+=e[r].length;var i=Jt.allocUnsafe(t),s=0;for(r=0;r<e.length;++r){var n=e[r];if(!er(n))throw new TypeError('"list" argument must be an Array of Buffers');n.copy(i,s),s+=n.length}return i},Jt.byteLength=tr,Jt.prototype._isBuffer=!0,Jt.prototype.swap16=function(){var e=this.length;if(e%2!=0)throw new RangeError("Buffer size must be a multiple of 16-bits");for(var t=0;t<e;t+=2)ir(this,t,t+1);return this},Jt.prototype.swap32=function(){var e=this.length;if(e%4!=0)throw new RangeError("Buffer size must be a multiple of 32-bits");for(var t=0;t<e;t+=4)ir(this,t,t+3),ir(this,t+1,t+2);return this},Jt.prototype.swap64=function(){var e=this.length;if(e%8!=0)throw new RangeError("Buffer size must be a multiple of 64-bits");for(var t=0;t<e;t+=8)ir(this,t,t+7),ir(this,t+1,t+6),ir(this,t+2,t+5),ir(this,t+3,t+4);return this},Jt.prototype.toString=function(){var e=0|this.length;return 0===e?"":0===arguments.length?dr(this,0,e):rr.apply(this,arguments)},Jt.prototype.equals=function(e){if(!er(e))throw new TypeError("Argument must be a Buffer");return this===e||0===Jt.compare(this,e)},Jt.prototype.inspect=function(){var e="";return this.length>0&&(e=this.toString("hex",0,50).match(/.{2}/g).join(" "),this.length>50&&(e+=" ... ")),"<Buffer "+e+">"},Jt.prototype.compare=function(e,t,r,i,s){if(!er(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===r&&(r=e?e.length:0),void 0===i&&(i=0),void 0===s&&(s=this.length),t<0||r>e.length||i<0||s>this.length)throw new RangeError("out of range index");if(i>=s&&t>=r)return 0;if(i>=s)return-1;if(t>=r)return 1;if(this===e)return 0;for(var n=(s>>>=0)-(i>>>=0),o=(r>>>=0)-(t>>>=0),a=Math.min(n,o),c=this.slice(i,s),u=e.slice(t,r),l=0;l<a;++l)if(c[l]!==u[l]){n=c[l],o=u[l];break}return n<o?-1:o<n?1:0},Jt.prototype.includes=function(e,t,r){return-1!==this.indexOf(e,t,r)},Jt.prototype.indexOf=function(e,t,r){return sr(this,e,t,r,!0)},Jt.prototype.lastIndexOf=function(e,t,r){return sr(this,e,t,r,!1)},Jt.prototype.write=function(e,t,r,i){if(void 0===t)i="utf8",r=this.length,t=0;else if(void 0===r&&"string"==typeof t)i=t,r=this.length,t=0;else{if(!isFinite(t))throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported");t|=0,isFinite(r)?(r|=0,void 0===i&&(i="utf8")):(i=r,r=void 0)}var s=this.length-t;if((void 0===r||r>s)&&(r=s),e.length>0&&(r<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");i||(i="utf8");for(var n=!1;;)switch(i){case"hex":return or(this,e,t,r);case"utf8":case"utf-8":return ar(this,e,t,r);case"ascii":return cr(this,e,t,r);case"latin1":case"binary":return ur(this,e,t,r);case"base64":return lr(this,e,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return hr(this,e,t,r);default:if(n)throw new TypeError("Unknown encoding: "+i);i=(""+i).toLowerCase(),n=!0}},Jt.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var pr=4096;function mr(e,t,r){var i="";r=Math.min(e.length,r);for(var s=t;s<r;++s)i+=String.fromCharCode(127&e[s]);return i}function gr(e,t,r){var i="";r=Math.min(e.length,r);for(var s=t;s<r;++s)i+=String.fromCharCode(e[s]);return i}function yr(e,t,r){var i=e.length;(!t||t<0)&&(t=0),(!r||r<0||r>i)&&(r=i);for(var s="",n=t;n<r;++n)s+=xr(e[n]);return s}function br(e,t,r){for(var i=e.slice(t,r),s="",n=0;n<i.length;n+=2)s+=String.fromCharCode(i[n]+256*i[n+1]);return s}function wr(e,t,r){if(e%1!=0||e<0)throw new RangeError("offset is not uint");if(e+t>r)throw new RangeError("Trying to access beyond buffer length")}function vr(e,t,r,i,s,n){if(!er(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>s||t<n)throw new RangeError('"value" argument is out of bounds');if(r+i>e.length)throw new RangeError("Index out of range")}function kr(e,t,r,i){t<0&&(t=65535+t+1);for(var s=0,n=Math.min(e.length-r,2);s<n;++s)e[r+s]=(t&255<<8*(i?s:1-s))>>>8*(i?s:1-s)}function _r(e,t,r,i){t<0&&(t=4294967295+t+1);for(var s=0,n=Math.min(e.length-r,4);s<n;++s)e[r+s]=t>>>8*(i?s:3-s)&255}function Sr(e,t,r,i,s,n){if(r+i>e.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("Index out of range")}function Or(e,t,r,i,s){return s||Sr(e,0,r,4),zt(e,t,r,i,23,4),r+4}function Rr(e,t,r,i,s){return s||Sr(e,0,r,8),zt(e,t,r,i,52,8),r+8}Jt.prototype.slice=function(e,t){var r,i=this.length;if((e=~~e)<0?(e+=i)<0&&(e=0):e>i&&(e=i),(t=void 0===t?i:~~t)<0?(t+=i)<0&&(t=0):t>i&&(t=i),t<e&&(t=e),Jt.TYPED_ARRAY_SUPPORT)(r=this.subarray(e,t)).__proto__=Jt.prototype;else{var s=t-e;r=new Jt(s,void 0);for(var n=0;n<s;++n)r[n]=this[n+e]}return r},Jt.prototype.readUIntLE=function(e,t,r){e|=0,t|=0,r||wr(e,t,this.length);for(var i=this[e],s=1,n=0;++n<t&&(s*=256);)i+=this[e+n]*s;return i},Jt.prototype.readUIntBE=function(e,t,r){e|=0,t|=0,r||wr(e,t,this.length);for(var i=this[e+--t],s=1;t>0&&(s*=256);)i+=this[e+--t]*s;return i},Jt.prototype.readUInt8=function(e,t){return t||wr(e,1,this.length),this[e]},Jt.prototype.readUInt16LE=function(e,t){return t||wr(e,2,this.length),this[e]|this[e+1]<<8},Jt.prototype.readUInt16BE=function(e,t){return t||wr(e,2,this.length),this[e]<<8|this[e+1]},Jt.prototype.readUInt32LE=function(e,t){return t||wr(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},Jt.prototype.readUInt32BE=function(e,t){return t||wr(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},Jt.prototype.readIntLE=function(e,t,r){e|=0,t|=0,r||wr(e,t,this.length);for(var i=this[e],s=1,n=0;++n<t&&(s*=256);)i+=this[e+n]*s;return i>=(s*=128)&&(i-=Math.pow(2,8*t)),i},Jt.prototype.readIntBE=function(e,t,r){e|=0,t|=0,r||wr(e,t,this.length);for(var i=t,s=1,n=this[e+--i];i>0&&(s*=256);)n+=this[e+--i]*s;return n>=(s*=128)&&(n-=Math.pow(2,8*t)),n},Jt.prototype.readInt8=function(e,t){return t||wr(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},Jt.prototype.readInt16LE=function(e,t){t||wr(e,2,this.length);var r=this[e]|this[e+1]<<8;return 32768&r?4294901760|r:r},Jt.prototype.readInt16BE=function(e,t){t||wr(e,2,this.length);var r=this[e+1]|this[e]<<8;return 32768&r?4294901760|r:r},Jt.prototype.readInt32LE=function(e,t){return t||wr(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},Jt.prototype.readInt32BE=function(e,t){return t||wr(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},Jt.prototype.readFloatLE=function(e,t){return t||wr(e,4,this.length),Bt(this,e,!0,23,4)},Jt.prototype.readFloatBE=function(e,t){return t||wr(e,4,this.length),Bt(this,e,!1,23,4)},Jt.prototype.readDoubleLE=function(e,t){return t||wr(e,8,this.length),Bt(this,e,!0,52,8)},Jt.prototype.readDoubleBE=function(e,t){return t||wr(e,8,this.length),Bt(this,e,!1,52,8)},Jt.prototype.writeUIntLE=function(e,t,r,i){(e=+e,t|=0,r|=0,i)||vr(this,e,t,r,Math.pow(2,8*r)-1,0);var s=1,n=0;for(this[t]=255&e;++n<r&&(s*=256);)this[t+n]=e/s&255;return t+r},Jt.prototype.writeUIntBE=function(e,t,r,i){(e=+e,t|=0,r|=0,i)||vr(this,e,t,r,Math.pow(2,8*r)-1,0);var s=r-1,n=1;for(this[t+s]=255&e;--s>=0&&(n*=256);)this[t+s]=e/n&255;return t+r},Jt.prototype.writeUInt8=function(e,t,r){return e=+e,t|=0,r||vr(this,e,t,1,255,0),Jt.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},Jt.prototype.writeUInt16LE=function(e,t,r){return e=+e,t|=0,r||vr(this,e,t,2,65535,0),Jt.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):kr(this,e,t,!0),t+2},Jt.prototype.writeUInt16BE=function(e,t,r){return e=+e,t|=0,r||vr(this,e,t,2,65535,0),Jt.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):kr(this,e,t,!1),t+2},Jt.prototype.writeUInt32LE=function(e,t,r){return e=+e,t|=0,r||vr(this,e,t,4,4294967295,0),Jt.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):_r(this,e,t,!0),t+4},Jt.prototype.writeUInt32BE=function(e,t,r){return e=+e,t|=0,r||vr(this,e,t,4,4294967295,0),Jt.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):_r(this,e,t,!1),t+4},Jt.prototype.writeIntLE=function(e,t,r,i){if(e=+e,t|=0,!i){var s=Math.pow(2,8*r-1);vr(this,e,t,r,s-1,-s)}var n=0,o=1,a=0;for(this[t]=255&e;++n<r&&(o*=256);)e<0&&0===a&&0!==this[t+n-1]&&(a=1),this[t+n]=(e/o|0)-a&255;return t+r},Jt.prototype.writeIntBE=function(e,t,r,i){if(e=+e,t|=0,!i){var s=Math.pow(2,8*r-1);vr(this,e,t,r,s-1,-s)}var n=r-1,o=1,a=0;for(this[t+n]=255&e;--n>=0&&(o*=256);)e<0&&0===a&&0!==this[t+n+1]&&(a=1),this[t+n]=(e/o|0)-a&255;return t+r},Jt.prototype.writeInt8=function(e,t,r){return e=+e,t|=0,r||vr(this,e,t,1,127,-128),Jt.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},Jt.prototype.writeInt16LE=function(e,t,r){return e=+e,t|=0,r||vr(this,e,t,2,32767,-32768),Jt.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):kr(this,e,t,!0),t+2},Jt.prototype.writeInt16BE=function(e,t,r){return e=+e,t|=0,r||vr(this,e,t,2,32767,-32768),Jt.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):kr(this,e,t,!1),t+2},Jt.prototype.writeInt32LE=function(e,t,r){return e=+e,t|=0,r||vr(this,e,t,4,2147483647,-2147483648),Jt.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):_r(this,e,t,!0),t+4},Jt.prototype.writeInt32BE=function(e,t,r){return e=+e,t|=0,r||vr(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),Jt.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):_r(this,e,t,!1),t+4},Jt.prototype.writeFloatLE=function(e,t,r){return Or(this,e,t,!0,r)},Jt.prototype.writeFloatBE=function(e,t,r){return Or(this,e,t,!1,r)},Jt.prototype.writeDoubleLE=function(e,t,r){return Rr(this,e,t,!0,r)},Jt.prototype.writeDoubleBE=function(e,t,r){return Rr(this,e,t,!1,r)},Jt.prototype.copy=function(e,t,r,i){if(r||(r=0),i||0===i||(i=this.length),t>=e.length&&(t=e.length),t||(t=0),i>0&&i<r&&(i=r),i===r)return 0;if(0===e.length||0===this.length)return 0;if(t<0)throw new RangeError("targetStart out of bounds");if(r<0||r>=this.length)throw new RangeError("sourceStart out of bounds");if(i<0)throw new RangeError("sourceEnd out of bounds");i>this.length&&(i=this.length),e.length-t<i-r&&(i=e.length-t+r);var s,n=i-r;if(this===e&&r<t&&t<i)for(s=n-1;s>=0;--s)e[s+t]=this[s+r];else if(n<1e3||!Jt.TYPED_ARRAY_SUPPORT)for(s=0;s<n;++s)e[s+t]=this[s+r];else Uint8Array.prototype.set.call(e,this.subarray(r,r+n),t);return n},Jt.prototype.fill=function(e,t,r,i){if("string"==typeof e){if("string"==typeof t?(i=t,t=0,r=this.length):"string"==typeof r&&(i=r,r=this.length),1===e.length){var s=e.charCodeAt(0);s<256&&(e=s)}if(void 0!==i&&"string"!=typeof i)throw new TypeError("encoding must be a string");if("string"==typeof i&&!Jt.isEncoding(i))throw new TypeError("Unknown encoding: "+i)}else"number"==typeof e&&(e&=255);if(t<0||this.length<t||this.length<r)throw new RangeError("Out of range index");if(r<=t)return this;var n;if(t>>>=0,r=void 0===r?this.length:r>>>0,e||(e=0),"number"==typeof e)for(n=t;n<r;++n)this[n]=e;else{var o=er(e)?e:Er(new Jt(e,i).toString()),a=o.length;for(n=0;n<r-t;++n)this[n+t]=o[n%a]}return this};var jr=/[^+\/0-9A-Za-z-_]/g;function xr(e){return e<16?"0"+e.toString(16):e.toString(16)}function Er(e,t){var r;t=t||1/0;for(var i=e.length,s=null,n=[],o=0;o<i;++o){if((r=e.charCodeAt(o))>55295&&r<57344){if(!s){if(r>56319){(t-=3)>-1&&n.push(239,191,189);continue}if(o+1===i){(t-=3)>-1&&n.push(239,191,189);continue}s=r;continue}if(r<56320){(t-=3)>-1&&n.push(239,191,189),s=r;continue}r=65536+(s-55296<<10|r-56320)}else s&&(t-=3)>-1&&n.push(239,191,189);if(s=null,r<128){if((t-=1)<0)break;n.push(r)}else if(r<2048){if((t-=2)<0)break;n.push(r>>6|192,63&r|128)}else if(r<65536){if((t-=3)<0)break;n.push(r>>12|224,r>>6&63|128,63&r|128)}else{if(!(r<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;n.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128)}}return n}function Ar(e){return function(e){var t,r,i,s,n,o;Mt||Lt();var a=e.length;if(a%4>0)throw new Error("Invalid string. Length must be a multiple of 4");n="="===e[a-2]?2:"="===e[a-1]?1:0,o=new Tt(3*a/4-n),i=n>0?a-4:a;var c=0;for(t=0,r=0;t<i;t+=4,r+=3)s=Pt[e.charCodeAt(t)]<<18|Pt[e.charCodeAt(t+1)]<<12|Pt[e.charCodeAt(t+2)]<<6|Pt[e.charCodeAt(t+3)],o[c++]=s>>16&255,o[c++]=s>>8&255,o[c++]=255&s;return 2===n?(s=Pt[e.charCodeAt(t)]<<2|Pt[e.charCodeAt(t+1)]>>4,o[c++]=255&s):1===n&&(s=Pt[e.charCodeAt(t)]<<10|Pt[e.charCodeAt(t+1)]<<4|Pt[e.charCodeAt(t+2)]>>2,o[c++]=s>>8&255,o[c++]=255&s),o}(function(e){if((e=function(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}(e).replace(jr,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function Dr(e,t,r,i){for(var s=0;s<i&&!(s+r>=t.length||s>=e.length);++s)t[s+r]=e[s];return s}function $r(e){return!!e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}function Cr(){this.head=null,this.tail=null,this.length=0}Cr.prototype.push=function(e){var t={data:e,next:null};this.length>0?this.tail.next=t:this.head=t,this.tail=t,++this.length},Cr.prototype.unshift=function(e){var t={data:e,next:this.head};0===this.length&&(this.tail=t),this.head=t,++this.length},Cr.prototype.shift=function(){if(0!==this.length){var e=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,e}},Cr.prototype.clear=function(){this.head=this.tail=null,this.length=0},Cr.prototype.join=function(e){if(0===this.length)return"";for(var t=this.head,r=""+t.data;t=t.next;)r+=e+t.data;return r},Cr.prototype.concat=function(e){if(0===this.length)return Jt.alloc(0);if(1===this.length)return this.head.data;for(var t=Jt.allocUnsafe(e>>>0),r=this.head,i=0;r;)r.data.copy(t,i),i+=r.data.length,r=r.next;return t};var Nr=Jt.isEncoding||function(e){switch(e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function Ir(e){switch(this.encoding=(e||"utf8").toLowerCase().replace(/[-_]/,""),function(e){if(e&&!Nr(e))throw new Error("Unknown encoding: "+e)}(e),this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2,this.detectIncompleteChar=Tr;break;case"base64":this.surrogateSize=3,this.detectIncompleteChar=Mr;break;default:return void(this.write=Pr)}this.charBuffer=new Jt(6),this.charReceived=0,this.charLength=0}function Pr(e){return e.toString(this.encoding)}function Tr(e){this.charReceived=e.length%2,this.charLength=this.charReceived?2:0}function Mr(e){this.charReceived=e.length%3,this.charLength=this.charReceived?3:0}Ir.prototype.write=function(e){for(var t="";this.charLength;){var r=e.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:e.length;if(e.copy(this.charBuffer,this.charReceived,0,r),this.charReceived+=r,this.charReceived<this.charLength)return"";if(e=e.slice(r,e.length),!((s=(t=this.charBuffer.slice(0,this.charLength).toString(this.encoding)).charCodeAt(t.length-1))>=55296&&s<=56319)){if(this.charReceived=this.charLength=0,0===e.length)return t;break}this.charLength+=this.surrogateSize,t=""}this.detectIncompleteChar(e);var i=e.length;this.charLength&&(e.copy(this.charBuffer,0,e.length-this.charReceived,i),i-=this.charReceived);var s;i=(t+=e.toString(this.encoding,0,i)).length-1;if((s=t.charCodeAt(i))>=55296&&s<=56319){var n=this.surrogateSize;return this.charLength+=n,this.charReceived+=n,this.charBuffer.copy(this.charBuffer,n,0,n),e.copy(this.charBuffer,0,0,n),t.substring(0,i)}return t},Ir.prototype.detectIncompleteChar=function(e){for(var t=e.length>=3?3:e.length;t>0;t--){var r=e[e.length-t];if(1==t&&r>>5==6){this.charLength=2;break}if(t<=2&&r>>4==14){this.charLength=3;break}if(t<=3&&r>>3==30){this.charLength=4;break}}this.charReceived=t},Ir.prototype.end=function(e){var t="";if(e&&e.length&&(t=this.write(e)),this.charReceived){var r=this.charReceived,i=this.charBuffer,s=this.encoding;t+=i.slice(0,r).toString(s)}return t},Fr.ReadableState=Ur;var Lr=function(e){if(jt(mt)&&(mt=ht.env.NODE_DEBUG||""),e=e.toUpperCase(),!gt[e])if(new RegExp("\\b"+e+"\\b","i").test(mt)){gt[e]=function(){var t=dt.apply(null,arguments);console.error("%s %d: %s",e,0,t)}}else gt[e]=function(){};return gt[e]}("stream");function Ur(e,t){e=e||{},this.objectMode=!!e.objectMode,t instanceof pi&&(this.objectMode=this.objectMode||!!e.readableObjectMode);var r=e.highWaterMark,i=this.objectMode?16:16384;this.highWaterMark=r||0===r?r:i,this.highWaterMark=~~this.highWaterMark,this.buffer=new Cr,this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.resumeScheduled=!1,this.defaultEncoding=e.defaultEncoding||"utf8",this.ranOut=!1,this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,e.encoding&&(this.decoder=new Ir(e.encoding),this.encoding=e.encoding)}function Fr(e){if(!(this instanceof Fr))return new Fr(e);this._readableState=new Ur(e,this),this.readable=!0,e&&"function"==typeof e.read&&(this._read=e.read),$e.call(this)}function qr(e,t,r,i,s){var n=function(e,t){var r=null;Buffer.isBuffer(t)||"string"==typeof t||null==t||e.objectMode||(r=new TypeError("Invalid non-string/buffer chunk"));return r}(t,r);if(n)e.emit("error",n);else if(null===r)t.reading=!1,function(e,t){if(t.ended)return;if(t.decoder){var r=t.decoder.end();r&&r.length&&(t.buffer.push(r),t.length+=t.objectMode?1:r.length)}t.ended=!0,Hr(e)}(e,t);else if(t.objectMode||r&&r.length>0)if(t.ended&&!s){var o=new Error("stream.push() after EOF");e.emit("error",o)}else if(t.endEmitted&&s){var a=new Error("stream.unshift() after end event");e.emit("error",a)}else{var c;!t.decoder||s||i||(r=t.decoder.write(r),c=!t.objectMode&&0===r.length),s||(t.reading=!1),c||(t.flowing&&0===t.length&&!t.sync?(e.emit("data",r),e.read(0)):(t.length+=t.objectMode?1:r.length,s?t.buffer.unshift(r):t.buffer.push(r),t.needReadable&&Hr(e))),function(e,t){t.readingMore||(t.readingMore=!0,ct(Kr,e,t))}(e,t)}else s||(t.reading=!1);return function(e){return!e.ended&&(e.needReadable||e.length<e.highWaterMark||0===e.length)}(t)}lt(Fr,$e),Fr.prototype.push=function(e,t){var r=this._readableState;return r.objectMode||"string"!=typeof e||(t=t||r.defaultEncoding)!==r.encoding&&(e=Buffer.from(e,t),t=""),qr(this,r,e,t,!1)},Fr.prototype.unshift=function(e){return qr(this,this._readableState,e,"",!0)},Fr.prototype.isPaused=function(){return!1===this._readableState.flowing},Fr.prototype.setEncoding=function(e){return this._readableState.decoder=new Ir(e),this._readableState.encoding=e,this};var Br=8388608;function zr(e,t){return e<=0||0===t.length&&t.ended?0:t.objectMode?1:e!=e?t.flowing&&t.length?t.buffer.head.data.length:t.length:(e>t.highWaterMark&&(t.highWaterMark=function(e){return e>=Br?e=Br:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function Hr(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(Lr("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?ct(Vr,e):Vr(e))}function Vr(e){Lr("emit readable"),e.emit("readable"),Gr(e)}function Kr(e,t){for(var r=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length<t.highWaterMark&&(Lr("maybeReadMore read 0"),e.read(0),r!==t.length);)r=t.length;t.readingMore=!1}function Wr(e){Lr("readable nexttick read 0"),e.read(0)}function Jr(e,t){t.reading||(Lr("resume read 0"),e.read(0)),t.resumeScheduled=!1,t.awaitDrain=0,e.emit("resume"),Gr(e),t.flowing&&!t.reading&&e.read(0)}function Gr(e){var t=e._readableState;for(Lr("flow",t.flowing);t.flowing&&null!==e.read(););}function Yr(e,t){return 0===t.length?null:(t.objectMode?r=t.buffer.shift():!e||e>=t.length?(r=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.head.data:t.buffer.concat(t.length),t.buffer.clear()):r=function(e,t,r){var i;e<t.head.data.length?(i=t.head.data.slice(0,e),t.head.data=t.head.data.slice(e)):i=e===t.head.data.length?t.shift():r?function(e,t){var r=t.head,i=1,s=r.data;e-=s.length;for(;r=r.next;){var n=r.data,o=e>n.length?n.length:e;if(o===n.length?s+=n:s+=n.slice(0,e),0===(e-=o)){o===n.length?(++i,r.next?t.head=r.next:t.head=t.tail=null):(t.head=r,r.data=n.slice(o));break}++i}return t.length-=i,s}(e,t):function(e,t){var r=Buffer.allocUnsafe(e),i=t.head,s=1;i.data.copy(r),e-=i.data.length;for(;i=i.next;){var n=i.data,o=e>n.length?n.length:e;if(n.copy(r,r.length-e,0,o),0===(e-=o)){o===n.length?(++s,i.next?t.head=i.next:t.head=t.tail=null):(t.head=i,i.data=n.slice(o));break}++s}return t.length-=s,r}(e,t);return i}(e,t.buffer,t.decoder),r);var r}function Qr(e){var t=e._readableState;if(t.length>0)throw new Error('"endReadable()" called on non-empty stream');t.endEmitted||(t.ended=!0,ct(Zr,t,e))}function Zr(e,t){e.endEmitted||0!==e.length||(e.endEmitted=!0,t.readable=!1,t.emit("end"))}function Xr(e,t){for(var r=0,i=e.length;r<i;r++)if(e[r]===t)return r;return-1}function ei(){}function ti(e,t,r){this.chunk=e,this.encoding=t,this.callback=r,this.next=null}function ri(e,t){Object.defineProperty(this,"buffer",{get:pt(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.")}),e=e||{},this.objectMode=!!e.objectMode,t instanceof pi&&(this.objectMode=this.objectMode||!!e.writableObjectMode);var r=e.highWaterMark,i=this.objectMode?16:16384;this.highWaterMark=r||0===r?r:i,this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var s=!1===e.decodeStrings;this.decodeStrings=!s,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var r=e._writableState,i=r.sync,s=r.writecb;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(r),t)!function(e,t,r,i,s){--t.pendingcb,r?ct(s,i):s(i);e._writableState.errorEmitted=!0,e.emit("error",i)}(e,r,i,t,s);else{var n=ai(r);n||r.corked||r.bufferProcessing||!r.bufferedRequest||oi(e,r),i?ct(ni,e,r,n,s):ni(e,r,n,s)}}(t,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.bufferedRequestCount=0,this.corkedRequestsFree=new li(this)}function ii(e){if(!(this instanceof ii||this instanceof pi))return new ii(e);this._writableState=new ri(e,this),this.writable=!0,e&&("function"==typeof e.write&&(this._write=e.write),"function"==typeof e.writev&&(this._writev=e.writev)),$e.call(this)}function si(e,t,r,i,s,n,o){t.writelen=i,t.writecb=o,t.writing=!0,t.sync=!0,r?e._writev(s,t.onwrite):e._write(s,n,t.onwrite),t.sync=!1}function ni(e,t,r,i){r||function(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}(e,t),t.pendingcb--,i(),ui(e,t)}function oi(e,t){t.bufferProcessing=!0;var r=t.bufferedRequest;if(e._writev&&r&&r.next){var i=t.bufferedRequestCount,s=new Array(i),n=t.corkedRequestsFree;n.entry=r;for(var o=0;r;)s[o]=r,r=r.next,o+=1;si(e,t,!0,t.length,s,"",n.finish),t.pendingcb++,t.lastBufferedRequest=null,n.next?(t.corkedRequestsFree=n.next,n.next=null):t.corkedRequestsFree=new li(t)}else{for(;r;){var a=r.chunk,c=r.encoding,u=r.callback;if(si(e,t,!1,t.objectMode?1:a.length,a,c,u),r=r.next,t.writing)break}null===r&&(t.lastBufferedRequest=null)}t.bufferedRequestCount=0,t.bufferedRequest=r,t.bufferProcessing=!1}function ai(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function ci(e,t){t.prefinished||(t.prefinished=!0,e.emit("prefinish"))}function ui(e,t){var r=ai(t);return r&&(0===t.pendingcb?(ci(e,t),t.finished=!0,e.emit("finish")):ci(e,t)),r}function li(e){var t=this;this.next=null,this.entry=null,this.finish=function(r){var i=t.entry;for(t.entry=null;i;){var s=i.callback;e.pendingcb--,s(r),i=i.next}e.corkedRequestsFree?e.corkedRequestsFree.next=t:e.corkedRequestsFree=t}}Fr.prototype.read=function(e){Lr("read",e),e=parseInt(e,10);var t=this._readableState,r=e;if(0!==e&&(t.emittedReadable=!1),0===e&&t.needReadable&&(t.length>=t.highWaterMark||t.ended))return Lr("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?Qr(this):Hr(this),null;if(0===(e=zr(e,t))&&t.ended)return 0===t.length&&Qr(this),null;var i,s=t.needReadable;return Lr("need readable",s),(0===t.length||t.length-e<t.highWaterMark)&&Lr("length less than watermark",s=!0),t.ended||t.reading?Lr("reading or ended",s=!1):s&&(Lr("do read"),t.reading=!0,t.sync=!0,0===t.length&&(t.needReadable=!0),this._read(t.highWaterMark),t.sync=!1,t.reading||(e=zr(r,t))),null===(i=e>0?Yr(e,t):null)?(t.needReadable=!0,e=0):t.length-=e,0===t.length&&(t.ended||(t.needReadable=!0),r!==e&&t.ended&&Qr(this)),null!==i&&this.emit("data",i),i},Fr.prototype._read=function(e){this.emit("error",new Error("not implemented"))},Fr.prototype.pipe=function(e,t){var r=this,i=this._readableState;switch(i.pipesCount){case 0:i.pipes=e;break;case 1:i.pipes=[i.pipes,e];break;default:i.pipes.push(e)}i.pipesCount+=1,Lr("pipe count=%d opts=%j",i.pipesCount,t);var s=!t||!1!==t.end?o:u;function n(e){Lr("onunpipe"),e===r&&u()}function o(){Lr("onend"),e.end()}i.endEmitted?ct(s):r.once("end",s),e.on("unpipe",n);var a=function(e){return function(){var t=e._readableState;Lr("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&e.listeners("data").length&&(t.flowing=!0,Gr(e))}}(r);e.on("drain",a);var c=!1;function u(){Lr("cleanup"),e.removeListener("close",d),e.removeListener("finish",p),e.removeListener("drain",a),e.removeListener("error",f),e.removeListener("unpipe",n),r.removeListener("end",o),r.removeListener("end",u),r.removeListener("data",h),c=!0,!i.awaitDrain||e._writableState&&!e._writableState.needDrain||a()}var l=!1;function h(t){Lr("ondata"),l=!1,!1!==e.write(t)||l||((1===i.pipesCount&&i.pipes===e||i.pipesCount>1&&-1!==Xr(i.pipes,e))&&!c&&(Lr("false write response, pause",r._readableState.awaitDrain),r._readableState.awaitDrain++,l=!0),r.pause())}function f(t){var r;Lr("onerror",t),m(),e.removeListener("error",f),0===(r="error",e.listeners(r).length)&&e.emit("error",t)}function d(){e.removeListener("finish",p),m()}function p(){Lr("onfinish"),e.removeListener("close",d),m()}function m(){Lr("unpipe"),r.unpipe(e)}return r.on("data",h),function(e,t,r){if("function"==typeof e.prependListener)return e.prependListener(t,r);e._events&&e._events[t]?Array.isArray(e._events[t])?e._events[t].unshift(r):e._events[t]=[r,e._events[t]]:e.on(t,r)}(e,"error",f),e.once("close",d),e.once("finish",p),e.emit("pipe",r),i.flowing||(Lr("pipe resume"),r.resume()),e},Fr.prototype.unpipe=function(e){var t=this._readableState;if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes||(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this)),this;if(!e){var r=t.pipes,i=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var s=0;s<i;s++)r[s].emit("unpipe",this);return this}var n=Xr(t.pipes,e);return-1===n||(t.pipes.splice(n,1),t.pipesCount-=1,1===t.pipesCount&&(t.pipes=t.pipes[0]),e.emit("unpipe",this)),this},Fr.prototype.on=function(e,t){var r=$e.prototype.on.call(this,e,t);if("data"===e)!1!==this._readableState.flowing&&this.resume();else if("readable"===e){var i=this._readableState;i.endEmitted||i.readableListening||(i.readableListening=i.needReadable=!0,i.emittedReadable=!1,i.reading?i.length&&Hr(this):ct(Wr,this))}return r},Fr.prototype.addListener=Fr.prototype.on,Fr.prototype.resume=function(){var e=this._readableState;return e.flowing||(Lr("resume"),e.flowing=!0,function(e,t){t.resumeScheduled||(t.resumeScheduled=!0,ct(Jr,e,t))}(this,e)),this},Fr.prototype.pause=function(){return Lr("call pause flowing=%j",this._readableState.flowing),!1!==this._readableState.flowing&&(Lr("pause"),this._readableState.flowing=!1,this.emit("pause")),this},Fr.prototype.wrap=function(e){var t=this._readableState,r=!1,i=this;for(var s in e.on("end",function(){if(Lr("wrapped end"),t.decoder&&!t.ended){var e=t.decoder.end();e&&e.length&&i.push(e)}i.push(null)}),e.on("data",function(s){(Lr("wrapped data"),t.decoder&&(s=t.decoder.write(s)),t.objectMode&&null==s)||(t.objectMode||s&&s.length)&&(i.push(s)||(r=!0,e.pause()))}),e)void 0===this[s]&&"function"==typeof e[s]&&(this[s]=function(t){return function(){return e[t].apply(e,arguments)}}(s));return function(e,t){for(var r=0,i=e.length;r<i;r++)t(e[r],r)}(["error","close","destroy","pause","resume"],function(t){e.on(t,i.emit.bind(i,t))}),i._read=function(t){Lr("wrapped _read",t),r&&(r=!1,e.resume())},i},Fr._fromList=Yr,ii.WritableState=ri,lt(ii,$e),ri.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},ii.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))},ii.prototype.write=function(e,t,r){var i=this._writableState,s=!1;return"function"==typeof t&&(r=t,t=null),Jt.isBuffer(e)?t="buffer":t||(t=i.defaultEncoding),"function"!=typeof r&&(r=ei),i.ended?function(e,t){var r=new Error("write after end");e.emit("error",r),ct(t,r)}(this,r):function(e,t,r,i){var s=!0,n=!1;return null===r?n=new TypeError("May not write null values to stream"):Jt.isBuffer(r)||"string"==typeof r||void 0===r||t.objectMode||(n=new TypeError("Invalid non-string/buffer chunk")),n&&(e.emit("error",n),ct(i,n),s=!1),s}(this,i,e,r)&&(i.pendingcb++,s=function(e,t,r,i,s){r=function(e,t,r){e.objectMode||!1===e.decodeStrings||"string"!=typeof t||(t=Jt.from(t,r));return t}(t,r,i),Jt.isBuffer(r)&&(i="buffer");var n=t.objectMode?1:r.length;t.length+=n;var o=t.length<t.highWaterMark;o||(t.needDrain=!0);if(t.writing||t.corked){var a=t.lastBufferedRequest;t.lastBufferedRequest=new ti(r,i,s),a?a.next=t.lastBufferedRequest:t.bufferedRequest=t.lastBufferedRequest,t.bufferedRequestCount+=1}else si(e,t,!1,n,r,i,s);return o}(this,i,e,t,r)),s},ii.prototype.cork=function(){this._writableState.corked++},ii.prototype.uncork=function(){var e=this._writableState;e.corked&&(e.corked--,e.writing||e.corked||e.finished||e.bufferProcessing||!e.bufferedRequest||oi(this,e))},ii.prototype.setDefaultEncoding=function(e){if("string"==typeof e&&(e=e.toLowerCase()),!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((e+"").toLowerCase())>-1))throw new TypeError("Unknown encoding: "+e);return this._writableState.defaultEncoding=e,this},ii.prototype._write=function(e,t,r){r(new Error("not implemented"))},ii.prototype._writev=null,ii.prototype.end=function(e,t,r){var i=this._writableState;"function"==typeof e?(r=e,e=null,t=null):"function"==typeof t&&(r=t,t=null),null!=e&&this.write(e,t),i.corked&&(i.corked=1,this.uncork()),i.ending||i.finished||function(e,t,r){t.ending=!0,ui(e,t),r&&(t.finished?ct(r):e.once("finish",r));t.ended=!0,e.writable=!1}(this,i,r)},lt(pi,Fr);for(var hi=Object.keys(ii.prototype),fi=0;fi<hi.length;fi++){var di=hi[fi];pi.prototype[di]||(pi.prototype[di]=ii.prototype[di])}function pi(e){if(!(this instanceof pi))return new pi(e);Fr.call(this,e),ii.call(this,e),e&&!1===e.readable&&(this.readable=!1),e&&!1===e.writable&&(this.writable=!1),this.allowHalfOpen=!0,e&&!1===e.allowHalfOpen&&(this.allowHalfOpen=!1),this.once("end",mi)}function mi(){this.allowHalfOpen||this._writableState.ended||ct(gi,this)}function gi(e){e.end()}function yi(e){this.afterTransform=function(t,r){return function(e,t,r){var i=e._transformState;i.transforming=!1;var s=i.writecb;if(!s)return e.emit("error",new Error("no writecb in Transform class"));i.writechunk=null,i.writecb=null,null!=r&&e.push(r);s(t);var n=e._readableState;n.reading=!1,(n.needReadable||n.length<n.highWaterMark)&&e._read(n.highWaterMark)}(e,t,r)},this.needTransform=!1,this.transforming=!1,this.writecb=null,this.writechunk=null,this.writeencoding=null}function bi(e){if(!(this instanceof bi))return new bi(e);pi.call(this,e),this._transformState=new yi(this);var t=this;this._readableState.needReadable=!0,this._readableState.sync=!1,e&&("function"==typeof e.transform&&(this._transform=e.transform),"function"==typeof e.flush&&(this._flush=e.flush)),this.once("prefinish",function(){"function"==typeof this._flush?this._flush(function(e){wi(t,e)}):wi(t)})}function wi(e,t){if(t)return e.emit("error",t);var r=e._writableState,i=e._transformState;if(r.length)throw new Error("Calling transform done when ws.length != 0");if(i.transforming)throw new Error("Calling transform done when still transforming");return e.push(null)}function vi(e){if(!(this instanceof vi))return new vi(e);bi.call(this,e)}function ki(){$e.call(this)}lt(bi,pi),bi.prototype.push=function(e,t){return this._transformState.needTransform=!1,pi.prototype.push.call(this,e,t)},bi.prototype._transform=function(e,t,r){throw new Error("Not implemented")},bi.prototype._write=function(e,t,r){var i=this._transformState;if(i.writecb=r,i.writechunk=e,i.writeencoding=t,!i.transforming){var s=this._readableState;(i.needTransform||s.needReadable||s.length<s.highWaterMark)&&this._read(s.highWaterMark)}},bi.prototype._read=function(e){var t=this._transformState;null!==t.writechunk&&t.writecb&&!t.transforming?(t.transforming=!0,this._transform(t.writechunk,t.writeencoding,t.afterTransform)):t.needTransform=!0},lt(vi,bi),vi.prototype._transform=function(e,t,r){r(null,e)},lt(ki,$e),ki.Readable=Fr,ki.Writable=ii,ki.Duplex=pi,ki.Transform=bi,ki.PassThrough=vi,ki.Stream=ki,ki.prototype.pipe=function(e,t){var r=this;function i(t){e.writable&&!1===e.write(t)&&r.pause&&r.pause()}function s(){r.readable&&r.resume&&r.resume()}r.on("data",i),e.on("drain",s),e._isStdio||t&&!1===t.end||(r.on("end",o),r.on("close",a));var n=!1;function o(){n||(n=!0,e.end())}function a(){n||(n=!0,"function"==typeof e.destroy&&e.destroy())}function c(e){if(u(),0===$e.listenerCount(this,"error"))throw e}function u(){r.removeListener("data",i),e.removeListener("drain",s),r.removeListener("end",o),r.removeListener("close",a),r.removeListener("error",c),e.removeListener("error",c),r.removeListener("end",u),r.removeListener("close",u),e.removeListener("close",u)}return r.on("error",c),e.on("error",c),r.on("end",u),r.on("close",u),e.on("close",u),e.emit("pipe",r),e};class _i extends $e{constructor({resource:e}){super(),this.resource=e,this.client=e.client,this.stream=new s({highWaterMark:3*this.client.parallelism,start:this._start.bind(this),pull:this._pull.bind(this),cancel:this._cancel.bind(this)})}build(){return this.stream.getReader()}async _start(e){this.controller=e,this.continuationToken=null,this.closeNextIteration=!1}async _pull(e){if(this.closeNextIteration)return void e.close();const t=await this.client.listObjects({prefix:`resource=${this.resource.name}`,continuationToken:this.continuationToken}),r=t?.Contents.map(e=>e.Key).map(e=>e.replace(this.client.config.keyPrefix,"")).map(e=>e.startsWith("/")?e.replace("/",""):e).map(e=>e.replace(`resource=${this.resource.name}/id=`,""));this.continuationToken=t.NextContinuationToken,this.enqueue(r),t.IsTruncated||(this.closeNextIteration=!0)}enqueue(e){e.forEach(e=>{this.controller.enqueue(e),this.emit("id",e)})}_cancel(e){}}var Si=_i;class Oi extends Si{enqueue(e){this.controller.enqueue(e),this.emit("page",e)}}class Ri extends $e{constructor({resource:e,batchSize:t=10,concurrency:r=5}){if(super(),!e)throw new Error("Resource is required for ResourceReader");this.resource=e,this.client=e.client,this.batchSize=t,this.concurrency=r,this.input=new Oi({resource:this.resource}),this.transform=new bi({objectMode:!0,transform:this._transform.bind(this)}),this.input.on("data",e=>{this.transform.write(e)}),this.input.on("end",()=>{this.transform.end()}),this.input.on("error",e=>{this.emit("error",e)}),this.transform.on("data",e=>{this.emit("data",e)}),this.transform.on("end",()=>{this.emit("end")}),this.transform.on("error",e=>{this.emit("error",e)})}build(){return this}async _transform(e,t,r){const[s,n]=await ve(async()=>{await i.for(e).withConcurrency(this.concurrency).handleError(async(e,t)=>{this.emit("error",e,t)}).process(async e=>{const t=await this.resource.get(e);return this.push(t),t})});r(n)}resume(){this.input.resume()}}class ji extends $e{constructor({resource:e,batchSize:t=10,concurrency:r=5}){super(),this.resource=e,this.client=e.client,this.batchSize=t,this.concurrency=r,this.buffer=[],this.writing=!1,this.writable=new ii({objectMode:!0,write:this._write.bind(this)}),this.writable.on("finish",()=>{this.emit("finish")}),this.writable.on("error",e=>{this.emit("error",e)})}build(){return this}write(e){return this.buffer.push(e),this._maybeWrite().catch(e=>{this.emit("error",e)}),!0}end(){this.ended=!0,this._maybeWrite().catch(e=>{this.emit("error",e)})}async _maybeWrite(){if(!this.writing&&(0!==this.buffer.length||this.ended)){for(this.writing=!0;this.buffer.length>0;){const e=this.buffer.splice(0,this.batchSize),[t,r]=await ve(async()=>{await i.for(e).withConcurrency(this.concurrency).handleError(async(e,t)=>{this.emit("error",e,t)}).process(async e=>{const[t,r,i]=await ve(async()=>await this.resource.insert(e));return t?i:(this.emit("error",r,e),null)})});t||this.emit("error",r)}this.writing=!1,this.ended&&this.writable.emit("finish")}}async _write(e,t,r){r()}}function xi(e){return new Promise((t,r)=>{if(!e)return r(new Error("streamToString: stream is undefined"));const i=[];e.on("data",e=>i.push(e)),e.on("error",r),e.on("end",()=>t(Buffer.concat(i).toString("utf-8")))})}var Ei=class extends Ye{constructor({client:e,keyPrefix:t="cache",ttl:r=0,prefix:i}){super({client:e,keyPrefix:t,ttl:r,prefix:i}),this.client=e,this.keyPrefix=t,this.config.ttl=r,this.config.client=e,this.config.prefix=void 0!==i?i:t+(t.endsWith("/")?"":"/")}async _set(e,t){let i=JSON.stringify(t);const s=i.length;return i=r.gzipSync(i).toString("base64"),this.client.putObject({key:Ke(this.keyPrefix,e),body:i,contentEncoding:"gzip",contentType:"application/gzip",metadata:{compressor:"zlib",compressed:"true","client-id":this.client.id,"length-serialized":String(s),"length-compressed":String(i.length),"compression-gain":(i.length/s).toFixed(2)}})}async _get(e){const[t,i,s]=await ve(async()=>{const{Body:t}=await this.client.getObject(Ke(this.keyPrefix,e));let i=await xi(t);return i=Buffer.from(i,"base64"),i=r.unzipSync(i).toString(),JSON.parse(i)});if(t)return s;if("NoSuchKey"===i.name||"NotFound"===i.name)return null;throw i}async _del(e){return await this.client.deleteObject(Ke(this.keyPrefix,e)),!0}async _clear(){const e=await this.client.getAllKeys({prefix:this.keyPrefix});await this.client.deleteObjects(e)}async size(){return(await this.keys()).length}async keys(){const e=await this.client.getAllKeys({prefix:this.keyPrefix}),t=this.keyPrefix.endsWith("/")?this.keyPrefix:this.keyPrefix+"/";return e.map(e=>e.startsWith(t)?e.slice(t.length):e)}};var Ai=class extends Ye{constructor(e={}){super(e),this.cache={},this.meta={},this.maxSize=void 0!==e.maxSize?e.maxSize:1e3,this.ttl=void 0!==e.ttl?e.ttl:3e5}async _set(e,t){if(this.maxSize>0&&Object.keys(this.cache).length>=this.maxSize){const e=Object.entries(this.meta).sort((e,t)=>e[1].ts-t[1].ts)[0]?.[0];e&&(delete this.cache[e],delete this.meta[e])}return this.cache[e]=t,this.meta[e]={ts:Date.now()},t}async _get(e){if(!Object.prototype.hasOwnProperty.call(this.cache,e))return null;if(this.ttl>0){const t=Date.now(),r=this.meta[e];if(r&&t-r.ts>1e3*this.ttl)return delete this.cache[e],delete this.meta[e],null}return this.cache[e]}async _del(e){return delete this.cache[e],delete this.meta[e],!0}async _clear(e){if(!e)return this.cache={},this.meta={},!0;for(const t of Object.keys(this.cache))t.startsWith(e)&&(delete this.cache[t],delete this.meta[t]);return!0}async size(){return Object.keys(this.cache).length}async keys(){return Object.keys(this.cache)}},Di={};class $i extends Ye{constructor({directory:e,prefix:t="cache",ttl:r=36e5,enableCompression:i=!0,compressionThreshold:s=1024,createDirectory:n=!0,fileExtension:o=".cache",enableMetadata:a=!0,maxFileSize:c=10485760,enableStats:u=!1,enableCleanup:l=!0,cleanupInterval:h=3e5,encoding:f="utf8",fileMode:d=420,enableBackup:p=!1,backupSuffix:m=".bak",enableLocking:g=!1,lockTimeout:y=5e3,enableJournal:b=!1,journalFile:w="cache.journal",...v}){if(super(v),!e)throw new Error("FilesystemCache: directory parameter is required");this.directory=We.resolve(e),this.prefix=t,this.ttl=r,this.enableCompression=i,this.compressionThreshold=s,this.createDirectory=n,this.fileExtension=o,this.enableMetadata=a,this.maxFileSize=c,this.enableStats=u,this.enableCleanup=l,this.cleanupInterval=h,this.encoding=f,this.fileMode=d,this.enableBackup=p,this.backupSuffix=m,this.enableLocking=g,this.lockTimeout=y,this.enableJournal=b,this.journalFile=We.join(this.directory,w),this.stats={hits:0,misses:0,sets:0,deletes:0,clears:0,errors:0},this.locks=new Map,this.cleanupTimer=null,this._init()}async _init(){this.createDirectory&&await this._ensureDirectory(this.directory),this.enableCleanup&&this.cleanupInterval>0&&(this.cleanupTimer=setInterval(()=>{this._cleanup().catch(e=>{console.warn("FilesystemCache cleanup error:",e.message)})},this.cleanupInterval))}async _ensureDirectory(e){const[t,r]=await ve(async()=>{await n(e,{recursive:!0})});if(!t&&"EEXIST"!==r.code)throw new Error(`Failed to create cache directory: ${r.message}`)}_getFilePath(e){const t=e.replace(/[<>:"/\\|?*]/g,"_"),r=`${this.prefix}_${t}${this.fileExtension}`;return We.join(this.directory,r)}_getMetadataPath(e){return e+".meta"}async _set(e,t){const i=this._getFilePath(e);try{let s=JSON.stringify(t);const n=Buffer.byteLength(s,this.encoding);if(n>this.maxFileSize)throw new Error(`Cache data exceeds maximum file size: ${n} > ${this.maxFileSize}`);let a=!1,c=s;if(this.enableCompression&&n>=this.compressionThreshold){c=r.gzipSync(Buffer.from(s,this.encoding)).toString("base64"),a=!0}if(this.enableBackup&&await this._fileExists(i)){const e=i+this.backupSuffix;await this._copyFile(i,e)}this.enableLocking&&await this._acquireLock(i);try{if(await o(i,c,{encoding:a?"utf8":this.encoding,mode:this.fileMode}),this.enableMetadata){const t={key:e,timestamp:Date.now(),ttl:this.ttl,compressed:a,originalSize:n,compressedSize:a?Buffer.byteLength(c,"utf8"):n,compressionRatio:a?(Buffer.byteLength(c,"utf8")/n).toFixed(2):1};await o(this._getMetadataPath(i),JSON.stringify(t),{encoding:this.encoding,mode:this.fileMode})}this.enableStats&&this.stats.sets++,this.enableJournal&&await this._journalOperation("set",e,{size:n,compressed:a})}finally{this.enableLocking&&this._releaseLock(i)}return t}catch(t){throw this.enableStats&&this.stats.errors++,new Error(`Failed to set cache key '${e}': ${t.message}`)}}async _get(e){const t=this._getFilePath(e);try{if(!await this._fileExists(t))return this.enableStats&&this.stats.misses++,null;let i=!1;if(this.enableMetadata){const e=this._getMetadataPath(t);if(await this._fileExists(e)){const[t,r,s]=await ve(async()=>{const t=await a(e,this.encoding);return JSON.parse(t)});if(t&&s.ttl>0){i=Date.now()-s.timestamp>s.ttl}}}else if(this.ttl>0){const e=await c(t);i=Date.now()-e.mtime.getTime()>this.ttl}if(i)return await this._del(e),this.enableStats&&this.stats.misses++,null;this.enableLocking&&await this._acquireLock(t);try{const e=await a(t,this.encoding);let i=!1;if(this.enableMetadata){const e=this._getMetadataPath(t);if(await this._fileExists(e)){const[t,r,s]=await ve(async()=>{const t=await a(e,this.encoding);return JSON.parse(t)});t&&(i=s.compressed)}}let s=e;if(i||this.enableCompression&&e.match(/^[A-Za-z0-9+/=]+$/))try{const t=Buffer.from(e,"base64");s=r.gunzipSync(t).toString(this.encoding)}catch(t){s=e}const n=JSON.parse(s);return this.enableStats&&this.stats.hits++,n}finally{this.enableLocking&&this._releaseLock(t)}}catch(t){return this.enableStats&&this.stats.errors++,await this._del(e),null}}async _del(e){const t=this._getFilePath(e);try{if(await this._fileExists(t)&&await u(t),this.enableMetadata){const e=this._getMetadataPath(t);await this._fileExists(e)&&await u(e)}if(this.enableBackup){const e=t+this.backupSuffix;await this._fileExists(e)&&await u(e)}return this.enableStats&&this.stats.deletes++,this.enableJournal&&await this._journalOperation("delete",e),!0}catch(t){throw this.enableStats&&this.stats.errors++,new Error(`Failed to delete cache key '${e}': ${t.message}`)}}async _clear(e){try{if(!await this._fileExists(this.directory))return this.enableStats&&this.stats.clears++,!0;const t=(await l(this.directory)).filter(t=>{if(!t.startsWith(this.prefix))return!1;if(!t.endsWith(this.fileExtension))return!1;if(e){return t.slice(this.prefix.length+1,-this.fileExtension.length).startsWith(e)}return!0});for(const e of t){const t=We.join(this.directory,e);try{await this._fileExists(t)&&await u(t)}catch(e){if("ENOENT"!==e.code)throw e}if(this.enableMetadata)try{const e=this._getMetadataPath(t);await this._fileExists(e)&&await u(e)}catch(e){if("ENOENT"!==e.code)throw e}if(this.enableBackup)try{const e=t+this.backupSuffix;await this._fileExists(e)&&await u(e)}catch(e){if("ENOENT"!==e.code)throw e}}return this.enableStats&&this.stats.clears++,this.enableJournal&&await this._journalOperation("clear",e||"all",{count:t.length}),!0}catch(e){if("ENOENT"===e.code)return this.enableStats&&this.stats.clears++,!0;throw this.enableStats&&this.stats.errors++,new Error(`Failed to clear cache: ${e.message}`)}}async size(){return(await this.keys()).length}async keys(){try{const e=(await l(this.directory)).filter(e=>e.startsWith(this.prefix)&&e.endsWith(this.fileExtension));return e.map(e=>e.slice(this.prefix.length+1,-this.fileExtension.length))}catch(e){return console.warn("FilesystemCache: Failed to list keys:",e.message),[]}}async _fileExists(e){const[t]=await ve(async()=>{await c(e)});return t}async _copyFile(e,t){const[r,i]=await ve(async()=>{const r=await a(e);await o(t,r)});r||console.warn("FilesystemCache: Failed to create backup:",i.message)}async _cleanup(){if(this.ttl&&!(this.ttl<=0))try{const e=await l(this.directory),t=Date.now();for(const r of e){if(!r.startsWith(this.prefix)||!r.endsWith(this.fileExtension))continue;const e=We.join(this.directory,r);let i=!1;if(this.enableMetadata){const r=this._getMetadataPath(e);if(await this._fileExists(r)){const[e,s,n]=await ve(async()=>{const e=await a(r,this.encoding);return JSON.parse(e)});if(e&&n.ttl>0){i=t-n.timestamp>n.ttl}}}else{const[r,s,n]=await ve(async()=>await c(e));if(r){i=t-n.mtime.getTime()>this.ttl}}if(i){const e=r.slice(this.prefix.length+1,-this.fileExtension.length);await this._del(e)}}}catch(e){console.warn("FilesystemCache cleanup error:",e.message)}}async _acquireLock(e){if(!this.enableLocking)return;const t=e,r=Date.now();for(;this.locks.has(t);){if(Date.now()-r>this.lockTimeout)throw new Error(`Lock timeout for file: ${e}`);await new Promise(e=>setTimeout(e,10))}this.locks.set(t,Date.now())}_releaseLock(e){this.enableLocking&&this.locks.delete(e)}async _journalOperation(e,t,r={}){if(!this.enableJournal)return;const i={timestamp:(new Date).toISOString(),operation:e,key:t,metadata:r},[s,n]=await ve(async()=>{const e=JSON.stringify(i)+"\n";await Di.promises.appendFile(this.journalFile,e,this.encoding)});s||console.warn("FilesystemCache journal error:",n.message)}destroy(){this.cleanupTimer&&(clearInterval(this.cleanupTimer),this.cleanupTimer=null)}getStats(){return{...this.stats,directory:this.directory,ttl:this.ttl,compression:this.enableCompression,metadata:this.enableMetadata,cleanup:this.enableCleanup,locking:this.enableLocking,journal:this.enableJournal}}}class Ci extends $i{constructor({partitionStrategy:e="hierarchical",trackUsage:t=!0,preloadRelated:r=!1,preloadThreshold:i=10,maxCacheSize:s=null,usageStatsFile:n="partition-usage.json",...o}){super(o),this.partitionStrategy=e,this.trackUsage=t,this.preloadRelated=r,this.preloadThreshold=i,this.maxCacheSize=s,this.usageStatsFile=We.join(this.directory,n),this.partitionUsage=new Map,this.loadUsageStats()}_getPartitionCacheKey(e,t,r,i={},s={}){const n=[`resource=${e}`,`action=${t}`];if(r&&Object.keys(i).length>0){n.push(`partition=${r}`);const e=Object.entries(i).sort(([e],[t])=>e.localeCompare(t));for(const[t,r]of e)null!=r&&n.push(`${t}=${r}`)}if(Object.keys(s).length>0){const e=Object.entries(s).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${e}=${t}`).join("|");n.push(`params=${Buffer.from(e).toString("base64")}`)}return n.join("/")+this.fileExtension}_getPartitionDirectory(e,t,r={}){const i=We.join(this.directory,`resource=${e}`);if(!t)return i;if("flat"===this.partitionStrategy)return We.join(i,"partitions");if("temporal"===this.partitionStrategy&&this._isTemporalPartition(t,r))return this._getTemporalDirectory(i,t,r);const s=[i,`partition=${t}`],n=Object.entries(r).sort(([e],[t])=>e.localeCompare(t));for(const[e,t]of n)null!=t&&s.push(`${e}=${this._sanitizePathValue(t)}`);return We.join(...s)}async _set(e,t,r={}){const{resource:i,action:s,partition:n,partitionValues:o,params:a}=r;if(i&&n){const e=this._getPartitionCacheKey(i,s,n,o,a),r=this._getPartitionDirectory(i,n,o);await this._ensureDirectory(r);const c=We.join(r,this._sanitizeFileName(e));this.trackUsage&&await this._trackPartitionUsage(i,n,o);const u={data:t,metadata:{resource:i,partition:n,partitionValues:o,timestamp:Date.now(),ttl:this.ttl}};return this._writeFileWithMetadata(c,u)}return super._set(e,t)}async _get(e,t={}){const{resource:r,action:i,partition:s,partitionValues:n,params:o}=t;if(r&&s){const e=this._getPartitionCacheKey(r,i,s,n,o),t=this._getPartitionDirectory(r,s,n),a=We.join(t,this._sanitizeFileName(e));if(!await this._fileExists(a))return this.preloadRelated&&await this._preloadRelatedPartitions(r,s,n),null;const c=await this._readFileWithMetadata(a);return c&&this.trackUsage&&await this._trackPartitionUsage(r,s,n),c?.data||null}return super._get(e)}async clearPartition(e,t,r={}){const i=this._getPartitionDirectory(e,t,r),[s,n]=await ve(async()=>{await this._fileExists(i)&&await h(i,{recursive:!0})});s||console.warn(`Failed to clear partition cache: ${n.message}`);const o=this._getUsageKey(e,t,r);return this.partitionUsage.delete(o),await this._saveUsageStats(),s}async clearResourcePartitions(e){const t=We.join(this.directory,`resource=${e}`),[r,i]=await ve(async()=>{await this._fileExists(t)&&await h(t,{recursive:!0})});for(const[t]of this.partitionUsage.entries())t.startsWith(`${e}/`)&&this.partitionUsage.delete(t);return await this._saveUsageStats(),r}async getPartitionStats(e,t=null){const r={totalFiles:0,totalSize:0,partitions:{},usage:{}},i=We.join(this.directory,`resource=${e}`);if(!await this._fileExists(i))return r;await this._calculateDirectoryStats(i,r);for(const[i,s]of this.partitionUsage.entries())if(i.startsWith(`${e}/`)){const e=i.split("/")[1];t&&e!==t||(r.usage[e]=s)}return r}async getCacheRecommendations(e){const t=[],r=Date.now();for(const[i,s]of this.partitionUsage.entries())if(i.startsWith(`${e}/`)){const[,e]=i.split("/"),n=(r-s.lastAccess)/864e5,o=s.count/Math.max(1,n);let a="keep",c=s.count;n>30?(a="archive",c=0):o<.1?(a="reduce_ttl",c=1):o>10&&(a="preload",c=100),t.push({partition:e,recommendation:a,priority:c,usage:o,lastAccess:new Date(s.lastAccess).toISOString()})}return t.sort((e,t)=>t.priority-e.priority)}async warmPartitionCache(e,t={}){const{partitions:r=[],maxFiles:i=1e3}=t;let s=0;for(const t of r){const r=`${e}/${t}`,n=this.partitionUsage.get(r);if(n&&n.count>=this.preloadThreshold&&(console.log(`🔥 Warming cache for ${e}/${t} (${n.count} accesses)`),s++),s>=i)break}return s}async _trackPartitionUsage(e,t,r){const i=this._getUsageKey(e,t,r),s=this.partitionUsage.get(i)||{count:0,firstAccess:Date.now(),lastAccess:Date.now()};s.count++,s.lastAccess=Date.now(),this.partitionUsage.set(i,s),s.count%10==0&&await this._saveUsageStats()}_getUsageKey(e,t,r){const i=Object.entries(r).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${e}=${t}`).join("|");return`${e}/${t}/${i}`}async _preloadRelatedPartitions(e,t,r){console.log(`🎯 Preloading related partitions for ${e}/${t}`),r.timestamp||r.date}_isTemporalPartition(e,t){const r=["date","timestamp","createdAt","updatedAt"];return Object.keys(t).some(e=>r.some(t=>e.toLowerCase().includes(t)))}_getTemporalDirectory(e,t,r){const i=Object.values(r)[0];if("string"==typeof i&&i.match(/^\d{4}-\d{2}-\d{2}/)){const[t,r,s]=i.split("-");return We.join(e,"temporal",t,r,s)}return We.join(e,`partition=${t}`)}_sanitizePathValue(e){return String(e).replace(/[<>:"/\\|?*]/g,"_")}_sanitizeFileName(e){return e.replace(/[<>:"/\\|?*]/g,"_")}async _calculateDirectoryStats(e,t){const[r,i,s]=await ve(()=>l(e));if(r)for(const r of s){const i=We.join(e,r),[s,n,o]=await ve(()=>c(i));s&&(o.isDirectory()?await this._calculateDirectoryStats(i,t):(t.totalFiles++,t.totalSize+=o.size))}}async loadUsageStats(){const[e,t,r]=await ve(async()=>{const e=await a(this.usageStatsFile,"utf8");return JSON.parse(e)});e&&r&&(this.partitionUsage=new Map(Object.entries(r)))}async _saveUsageStats(){const e=Object.fromEntries(this.partitionUsage);await ve(async()=>{await o(this.usageStatsFile,JSON.stringify(e,null,2),"utf8")})}async _writeFileWithMetadata(e,t){const r=JSON.stringify(t),[i,s]=await ve(async()=>{await o(e,r,{encoding:this.encoding,mode:this.fileMode})});if(!i)throw new Error(`Failed to write cache file: ${s.message}`);return!0}async _readFileWithMetadata(e){const[t,r,i]=await ve(async()=>await a(e,this.encoding));if(!t||!i)return null;try{return JSON.parse(i)}catch(e){return{data:i}}}}class Ni extends Me{constructor(e={}){super(e),this.driverName=e.driver||"s3",this.ttl=e.ttl,this.maxSize=e.maxSize,this.config=e.config||{},this.includePartitions=!1!==e.includePartitions,this.partitionStrategy=e.partitionStrategy||"hierarchical",this.partitionAware=!1!==e.partitionAware,this.trackUsage=!1!==e.trackUsage,this.preloadRelated=!1!==e.preloadRelated,this.legacyConfig={memoryOptions:e.memoryOptions,filesystemOptions:e.filesystemOptions,s3Options:e.s3Options,driver:e.driver}}async setup(e){await super.setup(e)}async onSetup(){if(this.driverName&&"object"==typeof this.driverName)this.driver=this.driverName;else if("memory"===this.driverName){const e={...this.legacyConfig.memoryOptions,...this.config};void 0!==this.ttl&&(e.ttl=this.ttl),void 0!==this.maxSize&&(e.maxSize=this.maxSize),this.driver=new Ai(e)}else if("filesystem"===this.driverName){const e={...this.legacyConfig.filesystemOptions,...this.config};void 0!==this.ttl&&(e.ttl=this.ttl),void 0!==this.maxSize&&(e.maxSize=this.maxSize),this.partitionAware?this.driver=new Ci({partitionStrategy:this.partitionStrategy,trackUsage:this.trackUsage,preloadRelated:this.preloadRelated,...e}):this.driver=new $i(e)}else{const e={client:this.database.client,...this.legacyConfig.s3Options,...this.config};void 0!==this.ttl&&(e.ttl=this.ttl),void 0!==this.maxSize&&(e.maxSize=this.maxSize),this.driver=new Ei(e)}this.installDatabaseHooks(),this.installResourceHooks()}installDatabaseHooks(){this.database.addHook("afterCreateResource",async({resource:e})=>{this.installResourceHooksForResource(e)})}async onStart(){}async onStop(){}installResourceHooks(){for(const e of Object.values(this.database.resources))this.installResourceHooksForResource(e)}installResourceHooksForResource(e){if(!this.driver)return;Object.defineProperty(e,"cache",{value:this.driver,writable:!0,configurable:!0,enumerable:!1}),e.cacheKeyFor=async(t={})=>{const{action:r,params:i={},partition:s,partitionValues:n}=t;return this.generateCacheKey(e,r,i,s,n)},this.driver instanceof Ci&&(e.clearPartitionCache=async(t,r={})=>await this.driver.clearPartition(e.name,t,r),e.getPartitionCacheStats=async(t=null)=>await this.driver.getPartitionStats(e.name,t),e.getCacheRecommendations=async()=>await this.driver.getCacheRecommendations(e.name),e.warmPartitionCache=async(t=[],r={})=>await this.driver.warmPartitionCache(e.name,{partitions:t,...r}));const t=["count","listIds","getMany","getAll","page","list","get","exists","content","hasContent","query","getFromPartition"];for(const r of t)e.useMiddleware(r,async(t,i)=>{let s;if("getMany"===r)s=await e.cacheKeyFor({action:r,params:{ids:t.args[0]}});else if("page"===r){const{offset:i,size:n,partition:o,partitionValues:a}=t.args[0]||{};s=await e.cacheKeyFor({action:r,params:{offset:i,size:n},partition:o,partitionValues:a})}else if("list"===r||"listIds"===r||"count"===r){const{partition:i,partitionValues:n}=t.args[0]||{};s=await e.cacheKeyFor({action:r,partition:i,partitionValues:n})}else if("query"===r){const i=t.args[0]||{},n=t.args[1]||{};s=await e.cacheKeyFor({action:r,params:{filter:i,options:{limit:n.limit,offset:n.offset}},partition:n.partition,partitionValues:n.partitionValues})}else if("getFromPartition"===r){const{id:i,partitionName:n,partitionValues:o}=t.args[0]||{};s=await e.cacheKeyFor({action:r,params:{id:i,partitionName:n},partition:n,partitionValues:o})}else"getAll"===r?s=await e.cacheKeyFor({action:r}):["get","exists","content","hasContent"].includes(r)&&(s=await e.cacheKeyFor({action:r,params:{id:t.args[0]}}));if(this.driver instanceof Ci){let n,o;if("list"===r||"listIds"===r||"count"===r||"page"===r){const e=t.args[0]||{};n=e.partition,o=e.partitionValues}else if("query"===r){const e=t.args[1]||{};n=e.partition,o=e.partitionValues}else if("getFromPartition"===r){const{partitionName:e,partitionValues:r}=t.args[0]||{};n=e,o=r}const[a,c,u]=await ve(()=>e.cache._get(s,{resource:e.name,action:r,partition:n,partitionValues:o}));if(a&&null!=u)return u;if(!a&&"NoSuchKey"!==c.name)throw c;const l=await i();return await e.cache._set(s,l,{resource:e.name,action:r,partition:n,partitionValues:o}),l}{const[t,r,n]=await ve(()=>e.cache.get(s));if(t&&null!=n)return n;if(!t&&"NoSuchKey"!==r.name)throw r;const o=await i();return await e.cache.set(s,o),o}});const r=["insert","update","delete","deleteMany","setContent","deleteContent","replace"];for(const t of r)e.useMiddleware(t,async(r,i)=>{const s=await i();if("insert"===t)await this.clearCacheForResource(e,r.args[0]);else if("update"===t)await this.clearCacheForResource(e,{id:r.args[0],...r.args[1]});else if("delete"===t){let t={id:r.args[0]};if("function"==typeof e.get){const[i,s,n]=await ve(()=>e.get(r.args[0]));i&&n&&(t=n)}await this.clearCacheForResource(e,t)}else if("setContent"===t||"deleteContent"===t){const t=r.args[0]?.id||r.args[0];await this.clearCacheForResource(e,{id:t})}else if("replace"===t){const t=r.args[0];await this.clearCacheForResource(e,{id:t,...r.args[1]})}else"deleteMany"===t&&await this.clearCacheForResource(e);return s})}async clearCacheForResource(e,t){if(!e.cache)return;const r=`resource=${e.name}`;if(t&&t.id){const i=["get","exists","content","hasContent"];for(const r of i)try{const i=await this.generateCacheKey(e,r,{id:t.id});await e.cache.clear(i.replace(".json.gz",""))}catch(e){}if(!0===this.config.includePartitions&&e.config?.partitions&&Object.keys(e.config.partitions).length>0){const i=this.getPartitionValues(t,e);for(const[t,s]of Object.entries(i))if(s&&Object.keys(s).length>0&&Object.values(s).some(e=>null!=e))try{const i=Ke(r,`partition=${t}`);await e.cache.clear(i)}catch(e){}}}try{await e.cache.clear(r)}catch(t){const i=["count","list","listIds","getAll","page","query"];for(const t of i)try{await e.cache.clear(`${r}/action=${t}`),await e.cache.clear(`resource=${e.name}/action=${t}`)}catch(e){}}}async generateCacheKey(e,t,r={},i=null,s=null){const n=[`resource=${e.name}`,`action=${t}`];if(i&&s&&Object.keys(s).length>0){n.push(`partition:${i}`);for(const[e,t]of Object.entries(s))null!=t&&n.push(`${e}:${t}`)}if(Object.keys(r).length>0){const e=await this.hashParams(r);n.push(e)}return Ke(...n)+".json.gz"}async hashParams(e){const t=Object.keys(e).sort().map(t=>`${t}:${JSON.stringify(e[t])}`).join("|")||"empty";return await _e(t)}async getCacheStats(){return this.driver?{size:await this.driver.size(),keys:await this.driver.keys(),driver:this.driver.constructor.name}:null}async clearAllCache(){if(this.driver)for(const e of Object.values(this.database.resources))if(e.cache){const t=`resource=${e.name}`;await e.cache.clear(t)}}async warmCache(e,t={}){const r=this.database.resources[e];if(!r)throw new Error(`Resource '${e}' not found`);const{includePartitions:i=!0}=t;if(this.driver instanceof Ci&&r.warmPartitionCache){const e=r.config.partitions?Object.keys(r.config.partitions):[];return await r.warmPartitionCache(e,t)}if(await r.getAll(),i&&r.config.partitions)for(const[e,t]of Object.entries(r.config.partitions))if(t.fields){const t=await r.getAll(),i=Array.isArray(t)?t:[],s=new Set;for(const t of i.slice(0,10)){const i=this.getPartitionValues(t,r);i[e]&&s.add(JSON.stringify(i[e]))}for(const t of s){const i=JSON.parse(t);await r.list({partition:e,partitionValues:i})}}}async getPartitionCacheStats(e,t=null){if(!(this.driver instanceof Ci))throw new Error("Partition cache statistics are only available with PartitionAwareFilesystemCache");return await this.driver.getPartitionStats(e,t)}async getCacheRecommendations(e){if(!(this.driver instanceof Ci))throw new Error("Cache recommendations are only available with PartitionAwareFilesystemCache");return await this.driver.getCacheRecommendations(e)}async clearPartitionCache(e,t,r={}){if(!(this.driver instanceof Ci))throw new Error("Partition cache clearing is only available with PartitionAwareFilesystemCache");return await this.driver.clearPartition(e,t,r)}async analyzeCacheUsage(){if(!(this.driver instanceof Ci))return{message:"Cache usage analysis is only available with PartitionAwareFilesystemCache"};const e={totalResources:Object.keys(this.database.resources).length,resourceStats:{},recommendations:{},summary:{mostUsedPartitions:[],leastUsedPartitions:[],suggestedOptimizations:[]}};for(const[t,r]of Object.entries(this.database.resources))try{e.resourceStats[t]=await this.driver.getPartitionStats(t),e.recommendations[t]=await this.driver.getCacheRecommendations(t)}catch(r){e.resourceStats[t]={error:r.message}}const t=Object.values(e.recommendations).flat();return e.summary.mostUsedPartitions=t.filter(e=>"preload"===e.recommendation).sort((e,t)=>t.priority-e.priority).slice(0,5),e.summary.leastUsedPartitions=t.filter(e=>"archive"===e.recommendation).slice(0,5),e.summary.suggestedOptimizations=[`Consider preloading ${e.summary.mostUsedPartitions.length} high-usage partitions`,`Archive ${e.summary.leastUsedPartitions.length} unused partitions`,"Monitor cache hit rates for partition efficiency"],e}}const Ii={async setup(e){e&&e.client&&(this.client=e.client,this.map={PutObjectCommand:"put",GetObjectCommand:"get",HeadObjectCommand:"head",DeleteObjectCommand:"delete",DeleteObjectsCommand:"delete",ListObjectsV2Command:"list"},this.costs={total:0,prices:{put:5e-6,copy:5e-6,list:5e-6,post:5e-6,get:4e-4/1e3,select:4e-4/1e3,delete:4e-4/1e3,head:4e-4/1e3},requests:{total:0,put:0,post:0,copy:0,list:0,get:0,select:0,delete:0,head:0},events:{total:0,PutObjectCommand:0,GetObjectCommand:0,HeadObjectCommand:0,DeleteObjectCommand:0,DeleteObjectsCommand:0,ListObjectsV2Command:0}},this.client.costs=JSON.parse(JSON.stringify(this.costs)))},async start(){this.client&&(this.client.on("command.response",e=>this.addRequest(e,this.map[e])),this.client.on("command.error",e=>this.addRequest(e,this.map[e])))},addRequest(e,t){t&&(this.costs.events[e]++,this.costs.events.total++,this.costs.requests.total++,this.costs.requests[t]++,this.costs.total+=this.costs.prices[t],this.client&&this.client.costs&&(this.client.costs.events[e]++,this.client.costs.events.total++,this.client.costs.requests.total++,this.client.costs.requests[t]++,this.client.costs.total+=this.client.costs.prices[t]))}};class Pi extends Me{constructor(e={}){super(),this.indexResource=null,this.config={minWordLength:e.minWordLength||3,maxResults:e.maxResults||100,...e},this.indexes=new Map}async setup(e){this.database=e;const[t,r,i]=await ve(()=>e.createResource({name:"fulltext_indexes",attributes:{id:"string|required",resourceName:"string|required",fieldName:"string|required",word:"string|required",recordIds:"json|required",count:"number|required",lastUpdated:"string|required"}}));this.indexResource=t?i:e.resources.fulltext_indexes,await this.loadIndexes(),this.installDatabaseHooks(),this.installIndexingHooks()}async start(){}async stop(){await this.saveIndexes(),this.removeDatabaseHooks()}async loadIndexes(){if(!this.indexResource)return;const[e,t,r]=await ve(()=>this.indexResource.getAll());if(e)for(const e of r){const t=`${e.resourceName}:${e.fieldName}:${e.word}`;this.indexes.set(t,{recordIds:e.recordIds||[],count:e.count||0})}}async saveIndexes(){if(!this.indexResource)return;const[e,t]=await ve(async()=>{const e=await this.indexResource.getAll();for(const t of e)await this.indexResource.delete(t.id);for(const[e,t]of this.indexes.entries()){const[r,i,s]=e.split(":");await this.indexResource.insert({id:`index-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,resourceName:r,fieldName:i,word:s,recordIds:t.recordIds,count:t.count,lastUpdated:(new Date).toISOString()})}})}installDatabaseHooks(){this.database.addHook("afterCreateResource",e=>{"fulltext_indexes"!==e.name&&this.installResourceHooks(e)})}removeDatabaseHooks(){this.database.removeHook("afterCreateResource",this.installResourceHooks.bind(this))}installIndexingHooks(){this.database.plugins||(this.database.plugins={}),this.database.plugins.fulltext=this;for(const e of Object.values(this.database.resources))"fulltext_indexes"!==e.name&&this.installResourceHooks(e);this.database._fulltextProxyInstalled||(this.database._previousCreateResourceForFullText=this.database.createResource,this.database.createResource=async function(...e){const t=await this._previousCreateResourceForFullText(...e);return this.plugins?.fulltext&&"fulltext_indexes"!==t.name&&this.plugins.fulltext.installResourceHooks(t),t},this.database._fulltextProxyInstalled=!0);for(const e of Object.values(this.database.resources))"fulltext_indexes"!==e.name&&this.installResourceHooks(e)}installResourceHooks(e){e._insert=e.insert,e._update=e.update,e._delete=e.delete,e._deleteMany=e.deleteMany,this.wrapResourceMethod(e,"insert",async(t,r,i)=>{const[s]=r;return this.indexRecord(e.name,t.id,s).catch(()=>{}),t}),this.wrapResourceMethod(e,"update",async(t,r,i)=>{const[s,n]=r;return this.removeRecordFromIndex(e.name,s).catch(()=>{}),this.indexRecord(e.name,s,t).catch(()=>{}),t}),this.wrapResourceMethod(e,"delete",async(t,r,i)=>{const[s]=r;return this.removeRecordFromIndex(e.name,s).catch(()=>{}),t}),this.wrapResourceMethod(e,"deleteMany",async(t,r,i)=>{const[s]=r;for(const t of s)this.removeRecordFromIndex(e.name,t).catch(()=>{});return t})}async indexRecord(e,t,r){const i=this.getIndexedFields(e);if(i&&0!==i.length)for(const s of i){const i=this.getFieldValue(r,s);if(!i)continue;const n=this.tokenize(i);for(const r of n){if(r.length<this.config.minWordLength)continue;const i=`${e}:${s}:${r.toLowerCase()}`,n=this.indexes.get(i)||{recordIds:[],count:0};n.recordIds.includes(t)||(n.recordIds.push(t),n.count=n.recordIds.length),this.indexes.set(i,n)}}}async removeRecordFromIndex(e,t){for(const[r,i]of this.indexes.entries())if(r.startsWith(`${e}:`)){const e=i.recordIds.indexOf(t);e>-1&&(i.recordIds.splice(e,1),i.count=i.recordIds.length,0===i.recordIds.length?this.indexes.delete(r):this.indexes.set(r,i))}}getFieldValue(e,t){if(!t.includes("."))return e&&void 0!==e[t]?e[t]:null;const r=t.split(".");let i=e;for(const e of r){if(!i||"object"!=typeof i||!(e in i))return null;i=i[e]}return i}tokenize(e){if(!e)return[];return String(e).toLowerCase().replace(/[^\w\s\u00C0-\u017F]/g," ").split(/\s+/).filter(e=>e.length>0)}getIndexedFields(e){if(this.config.fields)return this.config.fields;return{users:["name","email"],products:["name","description"],articles:["title","content"]}[e]||[]}async search(e,t,r={}){const{fields:i=null,limit:s=this.config.maxResults,offset:n=0,exactMatch:o=!1}=r;if(!t||0===t.trim().length)return[];const a=this.tokenize(t),c=new Map,u=i||this.getIndexedFields(e);if(0===u.length)return[];for(const t of a)if(!(t.length<this.config.minWordLength))for(const r of u)if(o){const i=`${e}:${r}:${t.toLowerCase()}`,s=this.indexes.get(i);if(s)for(const e of s.recordIds){const t=c.get(e)||0;c.set(e,t+1)}}else for(const[i,s]of this.indexes.entries())if(i.startsWith(`${e}:${r}:${t.toLowerCase()}`))for(const e of s.recordIds){const t=c.get(e)||0;c.set(e,t+1)}return Array.from(c.entries()).map(([e,t])=>({recordId:e,score:t})).sort((e,t)=>t.score-e.score).slice(n,n+s)}async searchRecords(e,t,r={}){const i=await this.search(e,t,r);if(0===i.length)return[];const s=this.database.resources[e];if(!s)throw new Error(`Resource '${e}' not found`);const n=i.map(e=>e.recordId);return(await s.getMany(n)).filter(e=>e&&"object"==typeof e).map(e=>{const t=i.find(t=>t.recordId===e.id);return{...e,_searchScore:t?t.score:0}}).sort((e,t)=>t._searchScore-e._searchScore)}async rebuildIndex(e){const t=this.database.resources[e];if(!t)throw new Error(`Resource '${e}' not found`);for(const[t]of this.indexes.entries())t.startsWith(`${e}:`)&&this.indexes.delete(t);const r=await t.getAll();for(let t=0;t<r.length;t+=100){const i=r.slice(t,t+100);for(const t of i){const[r,i]=await ve(()=>this.indexRecord(e,t.id,t))}}await this.saveIndexes()}async getIndexStats(){const e={totalIndexes:this.indexes.size,resources:{},totalWords:0};for(const[t,r]of this.indexes.entries()){const[i,s]=t.split(":");e.resources[i]||(e.resources[i]={fields:{},totalRecords:new Set,totalWords:0}),e.resources[i].fields[s]||(e.resources[i].fields[s]={words:0,totalOccurrences:0}),e.resources[i].fields[s].words++,e.resources[i].fields[s].totalOccurrences+=r.count,e.resources[i].totalWords++;for(const t of r.recordIds)e.resources[i].totalRecords.add(t);e.totalWords++}for(const t in e.resources)e.resources[t].totalRecords=e.resources[t].totalRecords.size;return e}async rebuildAllIndexes({timeout:e}={}){return e?Promise.race([this._rebuildAllIndexesInternal(),new Promise((t,r)=>setTimeout(()=>r(new Error("Timeout")),e))]):this._rebuildAllIndexesInternal()}async _rebuildAllIndexesInternal(){const e=Object.keys(this.database.resources).filter(e=>"fulltext_indexes"!==e);for(const t of e){const[e,r]=await ve(()=>this.rebuildIndex(t))}}async clearIndex(e){for(const[t]of this.indexes.entries())t.startsWith(`${e}:`)&&this.indexes.delete(t);await this.saveIndexes()}async clearAllIndexes(){this.indexes.clear(),await this.saveIndexes()}}class Ti extends Me{constructor(e={}){super(),this.config={collectPerformance:!1!==e.collectPerformance,collectErrors:!1!==e.collectErrors,collectUsage:!1!==e.collectUsage,retentionDays:e.retentionDays||30,flushInterval:e.flushInterval||6e4,...e},this.metrics={operations:{insert:{count:0,totalTime:0,errors:0},update:{count:0,totalTime:0,errors:0},delete:{count:0,totalTime:0,errors:0},get:{count:0,totalTime:0,errors:0},list:{count:0,totalTime:0,errors:0},count:{count:0,totalTime:0,errors:0}},resources:{},errors:[],performance:[],startTime:(new Date).toISOString()},this.flushTimer=null}async setup(e){if(this.database=e,"undefined"!=typeof process&&"test"===process.env.NODE_ENV)return;const[t,r]=await ve(async()=>{const[t,r,i]=await ve(()=>e.createResource({name:"metrics",attributes:{id:"string|required",type:"string|required",resourceName:"string",operation:"string",count:"number|required",totalTime:"number|required",errors:"number|required",avgTime:"number|required",timestamp:"string|required",metadata:"json"}}));this.metricsResource=t?i:e.resources.metrics;const[s,n,o]=await ve(()=>e.createResource({name:"error_logs",attributes:{id:"string|required",resourceName:"string|required",operation:"string|required",error:"string|required",timestamp:"string|required",metadata:"json"}}));this.errorsResource=s?o:e.resources.error_logs;const[a,c,u]=await ve(()=>e.createResource({name:"performance_logs",attributes:{id:"string|required",resourceName:"string|required",operation:"string|required",duration:"number|required",timestamp:"string|required",metadata:"json"}}));this.performanceResource=a?u:e.resources.performance_logs});t||(this.metricsResource=e.resources.metrics,this.errorsResource=e.resources.error_logs,this.performanceResource=e.resources.performance_logs),this.installDatabaseHooks(),this.installMetricsHooks(),"undefined"!=typeof process&&"test"!==process.env.NODE_ENV&&this.startFlushTimer()}async start(){}async stop(){this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.removeDatabaseHooks()}installDatabaseHooks(){this.database.addHook("afterCreateResource",e=>{"metrics"!==e.name&&"error_logs"!==e.name&&"performance_logs"!==e.name&&this.installResourceHooks(e)})}removeDatabaseHooks(){this.database.removeHook("afterCreateResource",this.installResourceHooks.bind(this))}installMetricsHooks(){for(const e of Object.values(this.database.resources))["metrics","error_logs","performance_logs"].includes(e.name)||this.installResourceHooks(e);this.database._createResource=this.database.createResource,this.database.createResource=async function(...e){const t=await this._createResource(...e);return this.plugins?.metrics&&!["metrics","error_logs","performance_logs"].includes(t.name)&&this.plugins.metrics.installResourceHooks(t),t}}installResourceHooks(e){e._insert=e.insert,e._update=e.update,e._delete=e.delete,e._deleteMany=e.deleteMany,e._get=e.get,e._getMany=e.getMany,e._getAll=e.getAll,e._list=e.list,e._listIds=e.listIds,e._count=e.count,e._page=e.page,e.insert=async function(...t){const r=Date.now(),[i,s,n]=await ve(()=>e._insert(...t));if(this.recordOperation(e.name,"insert",Date.now()-r,!i),i||this.recordError(e.name,"insert",s),!i)throw s;return n}.bind(this),e.update=async function(...t){const r=Date.now(),[i,s,n]=await ve(()=>e._update(...t));if(this.recordOperation(e.name,"update",Date.now()-r,!i),i||this.recordError(e.name,"update",s),!i)throw s;return n}.bind(this),e.delete=async function(...t){const r=Date.now(),[i,s,n]=await ve(()=>e._delete(...t));if(this.recordOperation(e.name,"delete",Date.now()-r,!i),i||this.recordError(e.name,"delete",s),!i)throw s;return n}.bind(this),e.deleteMany=async function(...t){const r=Date.now(),[i,s,n]=await ve(()=>e._deleteMany(...t));if(this.recordOperation(e.name,"delete",Date.now()-r,!i),i||this.recordError(e.name,"delete",s),!i)throw s;return n}.bind(this),e.get=async function(...t){const r=Date.now(),[i,s,n]=await ve(()=>e._get(...t));if(this.recordOperation(e.name,"get",Date.now()-r,!i),i||this.recordError(e.name,"get",s),!i)throw s;return n}.bind(this),e.getMany=async function(...t){const r=Date.now(),[i,s,n]=await ve(()=>e._getMany(...t));if(this.recordOperation(e.name,"get",Date.now()-r,!i),i||this.recordError(e.name,"get",s),!i)throw s;return n}.bind(this),e.getAll=async function(...t){const r=Date.now(),[i,s,n]=await ve(()=>e._getAll(...t));if(this.recordOperation(e.name,"list",Date.now()-r,!i),i||this.recordError(e.name,"list",s),!i)throw s;return n}.bind(this),e.list=async function(...t){const r=Date.now(),[i,s,n]=await ve(()=>e._list(...t));if(this.recordOperation(e.name,"list",Date.now()-r,!i),i||this.recordError(e.name,"list",s),!i)throw s;return n}.bind(this),e.listIds=async function(...t){const r=Date.now(),[i,s,n]=await ve(()=>e._listIds(...t));if(this.recordOperation(e.name,"list",Date.now()-r,!i),i||this.recordError(e.name,"list",s),!i)throw s;return n}.bind(this),e.count=async function(...t){const r=Date.now(),[i,s,n]=await ve(()=>e._count(...t));if(this.recordOperation(e.name,"count",Date.now()-r,!i),i||this.recordError(e.name,"count",s),!i)throw s;return n}.bind(this),e.page=async function(...t){const r=Date.now(),[i,s,n]=await ve(()=>e._page(...t));if(this.recordOperation(e.name,"list",Date.now()-r,!i),i||this.recordError(e.name,"list",s),!i)throw s;return n}.bind(this)}recordOperation(e,t,r,i){this.metrics.operations[t]&&(this.metrics.operations[t].count++,this.metrics.operations[t].totalTime+=r,i&&this.metrics.operations[t].errors++),this.metrics.resources[e]||(this.metrics.resources[e]={insert:{count:0,totalTime:0,errors:0},update:{count:0,totalTime:0,errors:0},delete:{count:0,totalTime:0,errors:0},get:{count:0,totalTime:0,errors:0},list:{count:0,totalTime:0,errors:0},count:{count:0,totalTime:0,errors:0}}),this.metrics.resources[e][t]&&(this.metrics.resources[e][t].count++,this.metrics.resources[e][t].totalTime+=r,i&&this.metrics.resources[e][t].errors++),this.config.collectPerformance&&this.metrics.performance.push({resourceName:e,operation:t,duration:r,timestamp:(new Date).toISOString()})}recordError(e,t,r){this.config.collectErrors&&this.metrics.errors.push({resourceName:e,operation:t,error:r.message,stack:r.stack,timestamp:(new Date).toISOString()})}startFlushTimer(){this.flushTimer&&clearInterval(this.flushTimer),this.config.flushInterval>0&&(this.flushTimer=setInterval(()=>{this.flushMetrics().catch(()=>{})},this.config.flushInterval))}async flushMetrics(){if(!this.metricsResource)return;const[e,t]=await ve(async()=>{let e,t,r,i;"undefined"!=typeof process&&"test"===process.env.NODE_ENV?(e={},t={},r={},i={}):(e={global:"true"},t={perf:"true"},r={error:"true"},i={resource:"true"});for(const[t,r]of Object.entries(this.metrics.operations))r.count>0&&await this.metricsResource.insert({id:`metrics-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,type:"operation",resourceName:"global",operation:t,count:r.count,totalTime:r.totalTime,errors:r.errors,avgTime:r.count>0?r.totalTime/r.count:0,timestamp:(new Date).toISOString(),metadata:e});for(const[e,t]of Object.entries(this.metrics.resources))for(const[r,s]of Object.entries(t))s.count>0&&await this.metricsResource.insert({id:`metrics-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,type:"operation",resourceName:e,operation:r,count:s.count,totalTime:s.totalTime,errors:s.errors,avgTime:s.count>0?s.totalTime/s.count:0,timestamp:(new Date).toISOString(),metadata:i});if(this.config.collectPerformance&&this.metrics.performance.length>0)for(const e of this.metrics.performance)await this.performanceResource.insert({id:`perf-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,resourceName:e.resourceName,operation:e.operation,duration:e.duration,timestamp:e.timestamp,metadata:t});if(this.config.collectErrors&&this.metrics.errors.length>0)for(const e of this.metrics.errors)await this.errorsResource.insert({id:`error-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,resourceName:e.resourceName,operation:e.operation,error:e.error,stack:e.stack,timestamp:e.timestamp,metadata:r});this.resetMetrics()})}resetMetrics(){for(const e of Object.keys(this.metrics.operations))this.metrics.operations[e]={count:0,totalTime:0,errors:0};for(const e of Object.keys(this.metrics.resources))for(const t of Object.keys(this.metrics.resources[e]))this.metrics.resources[e][t]={count:0,totalTime:0,errors:0};this.metrics.performance=[],this.metrics.errors=[]}async getMetrics(e={}){const{type:t="operation",resourceName:r,operation:i,startDate:s,endDate:n,limit:o=100,offset:a=0}=e;if(!this.metricsResource)return[];let c=(await this.metricsResource.getAll()).filter(e=>(!t||e.type===t)&&((!r||e.resourceName===r)&&((!i||e.operation===i)&&(!(s&&new Date(e.timestamp)<new Date(s))&&!(n&&new Date(e.timestamp)>new Date(n))))));return c.sort((e,t)=>new Date(t.timestamp)-new Date(e.timestamp)),c.slice(a,a+o)}async getErrorLogs(e={}){if(!this.errorsResource)return[];const{resourceName:t,operation:r,startDate:i,endDate:s,limit:n=100,offset:o=0}=e;let a=(await this.errorsResource.getAll()).filter(e=>(!t||e.resourceName===t)&&((!r||e.operation===r)&&(!(i&&new Date(e.timestamp)<new Date(i))&&!(s&&new Date(e.timestamp)>new Date(s)))));return a.sort((e,t)=>new Date(t.timestamp)-new Date(e.timestamp)),a.slice(o,o+n)}async getPerformanceLogs(e={}){if(!this.performanceResource)return[];const{resourceName:t,operation:r,startDate:i,endDate:s,limit:n=100,offset:o=0}=e;let a=(await this.performanceResource.getAll()).filter(e=>(!t||e.resourceName===t)&&((!r||e.operation===r)&&(!(i&&new Date(e.timestamp)<new Date(i))&&!(s&&new Date(e.timestamp)>new Date(s)))));return a.sort((e,t)=>new Date(t.timestamp)-new Date(e.timestamp)),a.slice(o,o+n)}async getStats(){const e=new Date,t=new Date(e.getTime()-864e5),[r,i,s]=await Promise.all([this.getMetrics({startDate:t.toISOString()}),this.getErrorLogs({startDate:t.toISOString()}),this.getPerformanceLogs({startDate:t.toISOString()})]),n={period:"24h",totalOperations:0,totalErrors:i.length,avgResponseTime:0,operationsByType:{},resources:{},uptime:{startTime:this.metrics.startTime,duration:e.getTime()-new Date(this.metrics.startTime).getTime()}};for(const e of r)if("operation"===e.type){n.totalOperations+=e.count,n.operationsByType[e.operation]||(n.operationsByType[e.operation]={count:0,errors:0,avgTime:0}),n.operationsByType[e.operation].count+=e.count,n.operationsByType[e.operation].errors+=e.errors;const t=n.operationsByType[e.operation],r=t.count,i=(t.avgTime*(r-e.count)+e.totalTime)/r;t.avgTime=i}const o=r.reduce((e,t)=>e+t.totalTime,0),a=r.reduce((e,t)=>e+t.count,0);return n.avgResponseTime=a>0?o/a:0,n}async cleanupOldData(){const e=new Date;if(e.setDate(e.getDate()-this.config.retentionDays),this.metricsResource){const t=await this.getMetrics({endDate:e.toISOString()});for(const e of t)await this.metricsResource.delete(e.id)}if(this.errorsResource){const t=await this.getErrorLogs({endDate:e.toISOString()});for(const e of t)await this.errorsResource.delete(e.id)}if(this.performanceResource){const t=await this.getPerformanceLogs({endDate:e.toISOString()});for(const e of t)await this.performanceResource.delete(e.id)}}}var Mi=class extends $e{constructor(e={}){super(),this.config=e,this.name=this.constructor.name,this.enabled=!1!==e.enabled}async initialize(e){this.database=e,this.emit("initialized",{replicator:this.name})}async replicate(e,t,r,i){throw new Error(`replicate() method must be implemented by ${this.name}`)}async replicateBatch(e,t){throw new Error(`replicateBatch() method must be implemented by ${this.name}`)}async testConnection(){throw new Error(`testConnection() method must be implemented by ${this.name}`)}async getStatus(){return{name:this.name,config:this.config,connected:!1}}async cleanup(){this.emit("cleanup",{replicator:this.name})}validateConfig(){return{isValid:!0,errors:[]}}};var Li=class extends Mi{constructor(e={},t={}){super(e),this.projectId=e.projectId,this.datasetId=e.datasetId,this.bigqueryClient=null,this.credentials=e.credentials,this.location=e.location||"US",this.logTable=e.logTable,this.resources=this.parseResourcesConfig(t)}parseResourcesConfig(e){const t={};for(const[r,i]of Object.entries(e))"string"==typeof i?t[r]=[{table:i,actions:["insert"],transform:null}]:Array.isArray(i)?t[r]=i.map(e=>"string"==typeof e?{table:e,actions:["insert"],transform:null}:{table:e.table,actions:e.actions||["insert"],transform:e.transform||null}):"object"==typeof i&&(t[r]=[{table:i.table,actions:i.actions||["insert"],transform:i.transform||null}]);return t}validateConfig(){const e=[];this.projectId||e.push("projectId is required"),this.datasetId||e.push("datasetId is required"),0===Object.keys(this.resources).length&&e.push("At least one resource must be configured");for(const[t,r]of Object.entries(this.resources))for(const i of r){i.table||e.push(`Table name is required for resource '${t}'`),Array.isArray(i.actions)&&0!==i.actions.length||e.push(`Actions array is required for resource '${t}'`);const r=["insert","update","delete"],s=i.actions.filter(e=>!r.includes(e));s.length>0&&e.push(`Invalid actions for resource '${t}': ${s.join(", ")}. Valid actions: ${r.join(", ")}`),i.transform&&"function"!=typeof i.transform&&e.push(`Transform must be a function for resource '${t}'`)}return{isValid:0===e.length,errors:e}}async initialize(e){await super.initialize(e);const[t,r,i]=await ve(()=>import("@google-cloud/bigquery"));if(!t)throw this.config.verbose&&console.warn(`[BigqueryReplicator] Failed to import BigQuery SDK: ${r.message}`),this.emit("initialization_error",{replicator:this.name,error:r.message}),r;const{BigQuery:s}=i;this.bigqueryClient=new s({projectId:this.projectId,credentials:this.credentials,location:this.location}),this.emit("initialized",{replicator:this.name,projectId:this.projectId,datasetId:this.datasetId,resources:Object.keys(this.resources)})}shouldReplicateResource(e){return this.resources.hasOwnProperty(e)}shouldReplicateAction(e,t){return!!this.resources[e]&&this.resources[e].some(e=>e.actions.includes(t))}getTablesForResource(e,t){return this.resources[e]?this.resources[e].filter(e=>e.actions.includes(t)).map(e=>({table:e.table,transform:e.transform})):[]}applyTransform(e,t){let r=this._cleanInternalFields(e);return t?t(JSON.parse(JSON.stringify(r))):r}_cleanInternalFields(e){if(!e||"object"!=typeof e)return e;const t={...e};return Object.keys(t).forEach(e=>{(e.startsWith("$")||e.startsWith("_"))&&delete t[e]}),t}async replicate(e,t,r,i,s=null){if(!this.enabled||!this.shouldReplicateResource(e))return{skipped:!0,reason:"resource_not_included"};if(!this.shouldReplicateAction(e,t))return{skipped:!0,reason:"action_not_included"};const n=this.getTablesForResource(e,t);if(0===n.length)return{skipped:!0,reason:"no_tables_for_action"};const o=[],a=[],[c,u,l]=await ve(async()=>{const s=this.bigqueryClient.dataset(this.datasetId);for(const e of n){const[n,c]=await ve(async()=>{const n=s.table(e.table);let a;if("insert"===t){const t=this.applyTransform(r,e.transform);try{a=await n.insert([t])}catch(e){const{errors:t,response:r}=e;throw this.config.verbose&&(console.error("[BigqueryReplicator] BigQuery insert error details:"),t&&console.error(JSON.stringify(t,null,2)),r&&console.error(JSON.stringify(r,null,2))),e}}else if("update"===t){const t=this.applyTransform(r,e.transform),s=Object.keys(t).filter(e=>"id"!==e).map(e=>`${e} = @${e}`).join(", "),n={id:i,...t},o=`UPDATE \`${this.projectId}.${this.datasetId}.${e.table}\` SET ${s} WHERE id = @id`,c=2;let u=null;for(let e=1;e<=c;e++){const[t,r]=await ve(async()=>{const[e]=await this.bigqueryClient.createQueryJob({query:o,params:n,location:this.location});return await e.getQueryResults(),[e]});if(t){a=t;break}if(u=r,this.config.verbose&&(console.warn(`[BigqueryReplicator] Update attempt ${e} failed: ${r.message}`),r.errors&&(console.error("[BigqueryReplicator] BigQuery update error details:"),console.error("Errors:",JSON.stringify(r.errors,null,2)))),r?.message?.includes("streaming buffer")&&e<c){const e=30;this.config.verbose&&console.warn(`[BigqueryReplicator] Retrying in ${e} seconds due to streaming buffer issue`),await new Promise(t=>setTimeout(t,1e3*e));continue}throw r}if(!a)throw u}else{if("delete"!==t)throw new Error(`Unsupported operation: ${t}`);{const t=`DELETE FROM \`${this.projectId}.${this.datasetId}.${e.table}\` WHERE id = @id`;try{const[e]=await this.bigqueryClient.createQueryJob({query:t,params:{id:i},location:this.location});await e.getQueryResults(),a=[e]}catch(e){throw this.config.verbose&&(console.error("[BigqueryReplicator] BigQuery delete error details:"),console.error("Query:",t),e.errors&&console.error("Errors:",JSON.stringify(e.errors,null,2)),e.response&&console.error("Response:",JSON.stringify(e.response,null,2))),e}}}o.push({table:e.table,success:!0,jobId:a[0]?.id})});n||a.push({table:e.table,error:c.message})}if(this.logTable){const[n,o]=await ve(async()=>{const n=s.table(this.logTable);await n.insert([{resource_name:e,operation:t,record_id:i,data:JSON.stringify(r),timestamp:(new Date).toISOString(),source:"s3db-replicator"}])})}const c=0===a.length;return a.length>0&&console.warn(`[BigqueryReplicator] Replication completed with errors for ${e}:`,a),this.emit("replicated",{replicator:this.name,resourceName:e,operation:t,id:i,tables:n.map(e=>e.table),results:o,errors:a,success:c}),{success:c,results:o,errors:a,tables:n.map(e=>e.table)}});return c?l:(this.config.verbose&&console.warn(`[BigqueryReplicator] Replication failed for ${e}: ${u.message}`),this.emit("replicator_error",{replicator:this.name,resourceName:e,operation:t,id:i,error:u.message}),{success:!1,error:u.message})}async replicateBatch(e,t){const r=[],i=[];for(const s of t){const[t,n,o]=await ve(()=>this.replicate(e,s.operation,s.data,s.id,s.beforeData));t?r.push(o):(this.config.verbose&&console.warn(`[BigqueryReplicator] Batch replication failed for record ${s.id}: ${n.message}`),i.push({id:s.id,error:n.message}))}return i.length>0&&console.warn(`[BigqueryReplicator] Batch replication completed with ${i.length} error(s) for ${e}:`,i),{success:0===i.length,results:r,errors:i}}async testConnection(){const[e,t]=await ve(async()=>{this.bigqueryClient||await this.initialize();const e=this.bigqueryClient.dataset(this.datasetId);return await e.getMetadata(),!0});return!!e||(this.config.verbose&&console.warn(`[BigqueryReplicator] Connection test failed: ${t.message}`),this.emit("connection_error",{replicator:this.name,error:t.message}),!1)}async cleanup(){}getStatus(){return{...super.getStatus(),projectId:this.projectId,datasetId:this.datasetId,resources:this.resources,logTable:this.logTable}}};var Ui=class extends Mi{constructor(e={},t={}){super(e),this.connectionString=e.connectionString,this.host=e.host,this.port=e.port||5432,this.database=e.database,this.user=e.user,this.password=e.password,this.client=null,this.ssl=e.ssl,this.logTable=e.logTable,this.resources=this.parseResourcesConfig(t)}parseResourcesConfig(e){const t={};for(const[r,i]of Object.entries(e))"string"==typeof i?t[r]=[{table:i,actions:["insert"]}]:Array.isArray(i)?t[r]=i.map(e=>"string"==typeof e?{table:e,actions:["insert"]}:{table:e.table,actions:e.actions||["insert"]}):"object"==typeof i&&(t[r]=[{table:i.table,actions:i.actions||["insert"]}]);return t}validateConfig(){const e=[];this.connectionString||this.host&&this.database||e.push("Either connectionString or host+database must be provided"),0===Object.keys(this.resources).length&&e.push("At least one resource must be configured");for(const[t,r]of Object.entries(this.resources))for(const i of r){i.table||e.push(`Table name is required for resource '${t}'`),Array.isArray(i.actions)&&0!==i.actions.length||e.push(`Actions array is required for resource '${t}'`);const r=["insert","update","delete"],s=i.actions.filter(e=>!r.includes(e));s.length>0&&e.push(`Invalid actions for resource '${t}': ${s.join(", ")}. Valid actions: ${r.join(", ")}`)}return{isValid:0===e.length,errors:e}}async initialize(e){await super.initialize(e);const[t,r,i]=await ve(()=>import("pg"));if(!t)throw this.config.verbose&&console.warn(`[PostgresReplicator] Failed to import pg SDK: ${r.message}`),this.emit("initialization_error",{replicator:this.name,error:r.message}),r;const{Client:s}=i,n=this.connectionString?{connectionString:this.connectionString,ssl:this.ssl}:{host:this.host,port:this.port,database:this.database,user:this.user,password:this.password,ssl:this.ssl};this.client=new s(n),await this.client.connect(),this.logTable&&await this.createLogTableIfNotExists(),this.emit("initialized",{replicator:this.name,database:this.database||"postgres",resources:Object.keys(this.resources)})}async createLogTableIfNotExists(){const e=`\n CREATE TABLE IF NOT EXISTS ${this.logTable} (\n id SERIAL PRIMARY KEY,\n resource_name VARCHAR(255) NOT NULL,\n operation VARCHAR(50) NOT NULL,\n record_id VARCHAR(255) NOT NULL,\n data JSONB,\n timestamp TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n source VARCHAR(100) DEFAULT 's3db-replicator',\n created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()\n );\n CREATE INDEX IF NOT EXISTS idx_${this.logTable}_resource_name ON ${this.logTable}(resource_name);\n CREATE INDEX IF NOT EXISTS idx_${this.logTable}_operation ON ${this.logTable}(operation);\n CREATE INDEX IF NOT EXISTS idx_${this.logTable}_record_id ON ${this.logTable}(record_id);\n CREATE INDEX IF NOT EXISTS idx_${this.logTable}_timestamp ON ${this.logTable}(timestamp);\n `;await this.client.query(e)}shouldReplicateResource(e){return this.resources.hasOwnProperty(e)}shouldReplicateAction(e,t){return!!this.resources[e]&&this.resources[e].some(e=>e.actions.includes(t))}getTablesForResource(e,t){return this.resources[e]?this.resources[e].filter(e=>e.actions.includes(t)).map(e=>e.table):[]}async replicate(e,t,r,i,s=null){if(!this.enabled||!this.shouldReplicateResource(e))return{skipped:!0,reason:"resource_not_included"};if(!this.shouldReplicateAction(e,t))return{skipped:!0,reason:"action_not_included"};const n=this.getTablesForResource(e,t);if(0===n.length)return{skipped:!0,reason:"no_tables_for_action"};const o=[],a=[],[c,u,l]=await ve(async()=>{for(const e of n){const[s,n]=await ve(async()=>{let s;if("insert"===t){const t=this._cleanInternalFields(r),i=Object.keys(t),n=i.map(e=>t[e]),o=i.map(e=>`"${e}"`).join(", "),a=i.map((e,t)=>`$${t+1}`).join(", "),c=`INSERT INTO ${e} (${o}) VALUES (${a}) ON CONFLICT (id) DO NOTHING RETURNING *`;s=await this.client.query(c,n)}else if("update"===t){const t=this._cleanInternalFields(r),n=Object.keys(t).filter(e=>"id"!==e),o=n.map((e,t)=>`"${e}"=$${t+1}`).join(", "),a=n.map(e=>t[e]);a.push(i);const c=`UPDATE ${e} SET ${o} WHERE id=$${n.length+1} RETURNING *`;s=await this.client.query(c,a)}else{if("delete"!==t)throw new Error(`Unsupported operation: ${t}`);{const t=`DELETE FROM ${e} WHERE id=$1 RETURNING *`;s=await this.client.query(t,[i])}}o.push({table:e,success:!0,rows:s.rows,rowCount:s.rowCount})});s||a.push({table:e,error:n.message})}if(this.logTable){const[s,n]=await ve(async()=>{await this.client.query(`INSERT INTO ${this.logTable} (resource_name, operation, record_id, data, timestamp, source) VALUES ($1, $2, $3, $4, $5, $6)`,[e,t,i,JSON.stringify(r),(new Date).toISOString(),"s3db-replicator"])})}const s=0===a.length;return a.length>0&&console.warn(`[PostgresReplicator] Replication completed with errors for ${e}:`,a),this.emit("replicated",{replicator:this.name,resourceName:e,operation:t,id:i,tables:n,results:o,errors:a,success:s}),{success:s,results:o,errors:a,tables:n}});return c?l:(this.config.verbose&&console.warn(`[PostgresReplicator] Replication failed for ${e}: ${u.message}`),this.emit("replicator_error",{replicator:this.name,resourceName:e,operation:t,id:i,error:u.message}),{success:!1,error:u.message})}async replicateBatch(e,t){const r=[],i=[];for(const s of t){const[t,n,o]=await ve(()=>this.replicate(e,s.operation,s.data,s.id,s.beforeData));t?r.push(o):(this.config.verbose&&console.warn(`[PostgresReplicator] Batch replication failed for record ${s.id}: ${n.message}`),i.push({id:s.id,error:n.message}))}return i.length>0&&console.warn(`[PostgresReplicator] Batch replication completed with ${i.length} error(s) for ${e}:`,i),{success:0===i.length,results:r,errors:i}}async testConnection(){const[e,t]=await ve(async()=>(this.client||await this.initialize(),await this.client.query("SELECT 1"),!0));return!!e||(this.config.verbose&&console.warn(`[PostgresReplicator] Connection test failed: ${t.message}`),this.emit("connection_error",{replicator:this.name,error:t.message}),!1)}_cleanInternalFields(e){if(!e||"object"!=typeof e)return e;const t={...e};return Object.keys(t).forEach(e=>{(e.startsWith("$")||e.startsWith("_"))&&delete t[e]}),t}async cleanup(){this.client&&await this.client.end()}getStatus(){return{...super.getStatus(),database:this.database||"postgres",resources:this.resources,logTable:this.logTable}}};function Fi(){}function qi(){}Fi.defaultMaxSockets=4,qi.defaultMaxSockets=4;class Bi{constructor(e){let t;const[r,i,s]=ve(()=>new URL(e));if(!r)throw new de("Invalid connection string: "+e,{original:i,input:e});t=s,this.region="us-east-1","s3:"===t.protocol?this.defineFromS3(t):this.defineFromCustomUri(t);for(const[e,r]of t.searchParams.entries())this[e]=r}defineFromS3(e){const[t,r,i]=we(()=>decodeURIComponent(e.hostname));if(!t)throw new de("Invalid bucket in connection string",{original:r,input:e.hostname});this.bucket=i||"s3db";const[s,n,o]=we(()=>decodeURIComponent(e.username));if(!s)throw new de("Invalid accessKeyId in connection string",{original:n,input:e.username});this.accessKeyId=o;const[a,c,u]=we(()=>decodeURIComponent(e.password));if(!a)throw new de("Invalid secretAccessKey in connection string",{original:c,input:e.password});if(this.secretAccessKey=u,this.endpoint="https://s3.us-east-1.amazonaws.com",["/","",null].includes(e.pathname))this.keyPrefix="";else{let[,...t]=e.pathname.split("/");this.keyPrefix=[...t||[]].join("/")}}defineFromCustomUri(e){this.forcePathStyle=!0,this.endpoint=e.origin;const[t,r,i]=we(()=>decodeURIComponent(e.username));if(!t)throw new de("Invalid accessKeyId in connection string",{original:r,input:e.username});this.accessKeyId=i;const[s,n,o]=we(()=>decodeURIComponent(e.password));if(!s)throw new de("Invalid secretAccessKey in connection string",{original:n,input:e.password});if(this.secretAccessKey=o,["/","",null].includes(e.pathname))this.bucket="s3db",this.keyPrefix="";else{let[,t,...r]=e.pathname.split("/");if(t){const[e,r,i]=we(()=>decodeURIComponent(t));if(!e)throw new de("Invalid bucket in connection string",{original:r,input:t});this.bucket=i}else this.bucket="s3db";this.keyPrefix=[...r||[]].join("/")}}}class zi extends $e{constructor({verbose:e=!1,id:t=null,AwsS3Client:r,connectionString:i,parallelism:s=10,httpClientOptions:n={}}){super(),this.verbose=e,this.id=t??xe(77),this.parallelism=s,this.config=new Bi(i),this.httpClientOptions={keepAlive:!0,keepAliveMsecs:1e3,maxSockets:50,maxFreeSockets:10,timeout:6e4,...n},this.client=r||this.createClient()}createClient(){const e=new Fi(this.httpClientOptions),t=new qi(this.httpClientOptions),r=new R({httpAgent:e,httpsAgent:t});let i={region:this.config.region,endpoint:this.config.endpoint,requestHandler:r};this.config.forcePathStyle&&(i.forcePathStyle=!0),this.config.accessKeyId&&(i.credentials={accessKeyId:this.config.accessKeyId,secretAccessKey:this.config.secretAccessKey});const s=new j(i);return s.middlewareStack.add((e,t)=>async r=>{if("DeleteObjectsCommand"===t.commandName){const e=r.request.body;if(e&&"string"==typeof e){const t=await Re(e);r.request.headers["Content-MD5"]=t}}return e(r)},{step:"build",name:"addContentMd5ForDeleteObjects",priority:"high"}),s}async sendCommand(e){this.emit("command.request",e.constructor.name,e.input);const[t,r,i]=await ve(()=>this.client.send(e));if(!t){throw fe(r,{bucket:this.config.bucket,key:e.input&&e.input.Key,commandName:e.constructor.name,commandInput:e.input})}return this.emit("command.response",e.constructor.name,i,e.input),i}async putObject({key:e,metadata:t,contentType:r,body:i,contentEncoding:s,contentLength:n}){const o="string"==typeof this.config.keyPrefix?this.config.keyPrefix:"";o&&We.join(o,e);const a={};if(t)for(const[e,r]of Object.entries(t)){const t=String(e).replace(/[^a-zA-Z0-9\-_]/g,"_"),i=String(r),s=/[^\x00-\x7F]/.test(i);a[t]=s?Buffer.from(i,"utf8").toString("base64"):i}const c={Bucket:this.config.bucket,Key:o?We.join(o,e):e,Metadata:a,Body:i||Buffer.alloc(0)};let u,l;void 0!==r&&(c.ContentType=r),void 0!==s&&(c.ContentEncoding=s),void 0!==n&&(c.ContentLength=n);try{return u=await this.sendCommand(new x(c)),u}catch(t){throw l=t,fe(t,{bucket:this.config.bucket,key:e,commandName:"PutObjectCommand",commandInput:c})}finally{this.emit("putObject",l||u,{key:e,metadata:t,contentType:r,body:i,contentEncoding:s,contentLength:n})}}async getObject(e){const t="string"==typeof this.config.keyPrefix?this.config.keyPrefix:"",r={Bucket:this.config.bucket,Key:t?We.join(t,e):e};let i,s;try{if(i=await this.sendCommand(new E(r)),i.Metadata){const e={};for(const[t,r]of Object.entries(i.Metadata))if("string"==typeof r)try{const i=Buffer.from(r,"base64").toString("utf8"),s=/[^\x00-\x7F]/.test(i),n=Buffer.from(i,"utf8").toString("base64")===r;e[t]=n&&s&&i!==r?i:r}catch(i){e[t]=r}else e[t]=r;i.Metadata=e}return i}catch(t){throw s=t,fe(t,{bucket:this.config.bucket,key:e,commandName:"GetObjectCommand",commandInput:r})}finally{this.emit("getObject",s||i,{key:e})}}async headObject(e){const t="string"==typeof this.config.keyPrefix?this.config.keyPrefix:"",r={Bucket:this.config.bucket,Key:t?We.join(t,e):e};let i,s;try{return i=await this.sendCommand(new A(r)),i}catch(t){throw s=t,fe(t,{bucket:this.config.bucket,key:e,commandName:"HeadObjectCommand",commandInput:r})}finally{this.emit("headObject",s||i,{key:e})}}async copyObject({from:e,to:t}){const r={Bucket:this.config.bucket,Key:this.config.keyPrefix?We.join(this.config.keyPrefix,t):t,CopySource:We.join(this.config.bucket,this.config.keyPrefix?We.join(this.config.keyPrefix,e):e)};let i,s;try{return i=await this.sendCommand(new D(r)),i}catch(e){throw s=e,fe(e,{bucket:this.config.bucket,key:t,commandName:"CopyObjectCommand",commandInput:r})}finally{this.emit("copyObject",s||i,{from:e,to:t})}}async exists(e){const[t,r]=await ve(()=>this.headObject(e));if(t)return!0;if("NoSuchKey"===r.name||"NotFound"===r.name)return!1;throw r}async deleteObject(e){const t="string"==typeof this.config.keyPrefix?this.config.keyPrefix:"";t&&We.join(t,e);const r={Bucket:this.config.bucket,Key:t?We.join(t,e):e};let i,s;try{return i=await this.sendCommand(new $(r)),i}catch(t){throw s=t,fe(t,{bucket:this.config.bucket,key:e,commandName:"DeleteObjectCommand",commandInput:r})}finally{this.emit("deleteObject",s||i,{key:e})}}async deleteObjects(e){const t="string"==typeof this.config.keyPrefix?this.config.keyPrefix:"",r=d(e,1e3),{results:s,errors:n}=await i.for(r).withConcurrency(this.parallelism).process(async e=>{for(const r of e)t&&We.join(t,r),this.config.bucket,await this.exists(r);const r={Bucket:this.config.bucket,Delete:{Objects:e.map(e=>({Key:t?We.join(t,e):e}))}};let i;const[s,n,o]=await ve(()=>this.sendCommand(new C(r)));if(!s)throw n;return i=o,i&&i.Errors&&i.Errors.length,i&&i.Deleted&&(i.Deleted.length,e.length),i}),o={deleted:s,notFound:n};return this.emit("deleteObjects",o,e),o}async deleteAll({prefix:e}={}){const t="string"==typeof this.config.keyPrefix?this.config.keyPrefix:"";let r,i=0;do{const s=new N({Bucket:this.config.bucket,Prefix:t?We.join(t,e||""):e||"",ContinuationToken:r}),n=await this.client.send(s);if(n.Contents&&n.Contents.length>0){const t=new C({Bucket:this.config.bucket,Delete:{Objects:n.Contents.map(e=>({Key:e.Key}))}}),r=await this.client.send(t),s=r.Deleted?r.Deleted.length:0;i+=s,this.emit("deleteAll",{prefix:e,batch:s,total:i})}r=n.IsTruncated?n.NextContinuationToken:void 0}while(r);return this.emit("deleteAllComplete",{prefix:e,totalDeleted:i}),i}async moveObject({from:e,to:t}){const[r,i]=await ve(async()=>{await this.copyObject({from:e,to:t}),await this.deleteObject(e)});if(!r)throw new le("Unknown error in moveObject",{bucket:this.config.bucket,from:e,to:t,original:i});return!0}async listObjects({prefix:e,maxKeys:t=1e3,continuationToken:r}={}){const i={Bucket:this.config.bucket,MaxKeys:t,ContinuationToken:r,Prefix:this.config.keyPrefix?We.join(this.config.keyPrefix,e||""):e||""},[s,n,o]=await ve(()=>this.sendCommand(new N(i)));if(!s)throw new le("Unknown error in listObjects",{prefix:e,bucket:this.config.bucket,original:n});return this.emit("listObjects",o,i),o}async count({prefix:e}={}){let t,r=0,i=!0;for(;i;){const s={prefix:e,continuationToken:t},n=await this.listObjects(s);r+=n.KeyCount||0,i=n.IsTruncated||!1,t=n.NextContinuationToken}return this.emit("count",r,{prefix:e}),r}async getAllKeys({prefix:e}={}){let t,r=[],i=!0;for(;i;){const s={prefix:e,continuationToken:t},n=await this.listObjects(s);n.Contents&&(r=r.concat(n.Contents.map(e=>e.Key))),i=n.IsTruncated||!1,t=n.NextContinuationToken}return this.config.keyPrefix&&(r=r.map(e=>e.replace(this.config.keyPrefix,"")).map(e=>e.startsWith("/")?e.replace("/",""):e)),this.emit("getAllKeys",r,{prefix:e}),r}async getContinuationTokenAfterOffset(e={}){const{prefix:t,offset:r=1e3}=e;if(0===r)return null;let i,s=!0,n=0;for(;s;){const e={prefix:t,maxKeys:r<1e3?r:r-n>1e3?1e3:r-n,continuationToken:i},o=await this.listObjects(e);if(o.Contents&&(n+=o.Contents.length),s=o.IsTruncated||!1,i=o.NextContinuationToken,n>=r)break}return this.emit("getContinuationTokenAfterOffset",i||null,e),i||null}async getKeysPage(e={}){const{prefix:t,offset:r=0,amount:i=100}=e;let s,n=[],o=!0;if(r>0&&(s=await this.getContinuationTokenAfterOffset({prefix:t,offset:r}),!s))return this.emit("getKeysPage",[],e),[];for(;o;){const e={prefix:t,continuationToken:s},r=await this.listObjects(e);if(r.Contents&&(n=n.concat(r.Contents.map(e=>e.Key))),o=r.IsTruncated||!1,s=r.NextContinuationToken,n.length>=i){n=n.slice(0,i);break}}return this.config.keyPrefix&&(n=n.map(e=>e.replace(this.config.keyPrefix,"")).map(e=>e.startsWith("/")?e.replace("/",""):e)),this.emit("getKeysPage",n,e),n}async moveAllObjects({prefixFrom:e,prefixTo:t}){const r=await this.getAllKeys({prefix:e}),{results:s,errors:n}=await i.for(r).withConcurrency(this.parallelism).process(async r=>{const i=r.replace(e,t),[s,n]=await ve(async()=>{await this.moveObject({from:r,to:i})});if(!s)throw new le("Unknown error in moveAllObjects",{bucket:this.config.bucket,from:r,to:i,original:n});return i});if(this.emit("moveAllObjects",{results:s,errors:n},{prefixFrom:e,prefixTo:t}),n.length>0)throw new Error("Some objects could not be moved");return s}}var Hi=zi;async function Vi(e,t,r){if(!this.passphrase)return t.push(new ee("Missing configuration for secrets encryption.",{actual:e,type:"encryptionKeyMissing",suggestion:"Provide a passphrase for secret encryption."})),e;const[i,s,n]=await ve(()=>Se(String(e),this.passphrase));return i?n:(t.push(new ee("Problem encrypting secret.",{actual:e,type:"encryptionProblem",error:s,suggestion:"Check the passphrase and input value."})),e)}async function Ki(e,t,r){if(m(e))return e;const[i,s,n]=we(()=>JSON.stringify(e));if(!i)throw new ee("Failed to stringify JSON",{original:s,input:e});return n}class Wi extends T{constructor({options:e,passphrase:t,autoEncrypt:r=!0}={}){super(p({},{useNewCustomCheckerFunction:!0,messages:{encryptionKeyMissing:"Missing configuration for secrets encryption.",encryptionProblem:"Problem encrypting secret. Actual: {actual}. Error: {error}"},defaults:{string:{trim:!0},object:{strict:"remove"},number:{convert:!0}}},e)),this.passphrase=t,this.autoEncrypt=r,this.alias("secret",{type:"string",custom:this.autoEncrypt?Vi:void 0,messages:{string:"The '{field}' field must be a string.",stringMin:"This secret '{field}' field length must be at least {expected} long."}}),this.alias("secretAny",{type:"any",custom:this.autoEncrypt?Vi:void 0}),this.alias("secretNumber",{type:"number",custom:this.autoEncrypt?Vi:void 0}),this.alias("json",{type:"any",custom:this.autoEncrypt?Ki:void 0})}}const Ji=new Proxy(Wi,{instance:null,construct(e,t){return this.instance||(this.instance=new e(...t)),this.instance}});const Gi={trim:e=>null==e?e:e.trim(),encrypt:async(e,{passphrase:t})=>{if(null==e)return e;const[r,i,s]=await be(()=>Se(e,t));return r?s:e},decrypt:async(e,{passphrase:t})=>{if(null==e)return e;const[r,i,s]=await be(()=>Oe(e,t));return r?"null"===s?null:"undefined"!==s?s:void 0:e},toString:e=>null==e?e:String(e),fromArray:(e,{separator:t})=>{if(null==e||!Array.isArray(e))return e;if(0===e.length)return"";return e.map(e=>"string"==typeof e?e.replace(/\\/g,"\\\\").replace(new RegExp(`\\${t}`,"g"),`\\${t}`):String(e)).join(t)},toArray:(e,{separator:t})=>{if(Array.isArray(e))return e;if(null==e)return e;if(""===e)return[];const r=[];let i="",s=0;const n=String(e);for(;s<n.length;)"\\"===n[s]&&s+1<n.length?(i+=n[s+1],s+=2):n[s]===t?(r.push(i),i="",s++):(i+=n[s],s++);return r.push(i),r},toJSON:e=>{if(null===e)return null;if(void 0===e)return;if("string"==typeof e){const[t,r,i]=we(()=>JSON.parse(e));return e}const[t,r,i]=we(()=>JSON.stringify(e));return t?i:e},fromJSON:e=>{if(null===e)return null;if(void 0===e)return;if("string"!=typeof e)return e;if(""===e)return"";const[t,r,i]=we(()=>JSON.parse(e));return t?i:e},toNumber:e=>m(e)?e.includes(".")?parseFloat(e):parseInt(e):e,toBool:e=>[!0,1,"true","1","yes","y"].includes(e),fromBool:e=>[!0,1,"true","1","yes","y"].includes(e)?"1":"0",fromBase62:e=>{if(null==e||""===e)return e;if("number"==typeof e)return e;if("string"==typeof e){const t=F(e);return isNaN(t)?void 0:t}},toBase62:e=>{if(null==e||""===e)return e;if("number"==typeof e)return U(e);if("string"==typeof e){const t=Number(e);return isNaN(t)?e:U(t)}return e},fromBase62Decimal:e=>{if(null==e||""===e)return e;if("number"==typeof e)return e;if("string"==typeof e){const t=B(e);return isNaN(t)?void 0:t}},toBase62Decimal:e=>{if(null==e||""===e)return e;if("number"==typeof e)return q(e);if("string"==typeof e){const t=Number(e);return isNaN(t)?e:q(t)}return e},fromArrayOfNumbers:(e,{separator:t})=>{if(null==e||!Array.isArray(e))return e;if(0===e.length)return"";return e.map(e=>{if("number"==typeof e&&!isNaN(e))return U(e);const t=Number(e);return isNaN(t)?"":U(t)}).join(t)},toArrayOfNumbers:(e,{separator:t})=>{if(Array.isArray(e))return e.map(e=>"number"==typeof e?e:F(e));if(null==e)return e;if(""===e)return[];const r=String(e),i=[];let s="",n=0;for(;n<r.length;)"\\"===r[n]&&n+1<r.length?(s+=r[n+1],n+=2):r[n]===t?(i.push(s),s="",n++):(s+=r[n],n++);return i.push(s),i.map(e=>{if("number"==typeof e)return e;if("string"==typeof e&&""!==e){const t=F(e);return isNaN(t)?NaN:t}return NaN})},fromArrayOfDecimals:(e,{separator:t})=>{if(null==e||!Array.isArray(e))return e;if(0===e.length)return"";return e.map(e=>{if("number"==typeof e&&!isNaN(e))return q(e);const t=Number(e);return isNaN(t)?"":q(t)}).join(t)},toArrayOfDecimals:(e,{separator:t})=>{if(Array.isArray(e))return e.map(e=>"number"==typeof e?e:B(e));if(null==e)return e;if(""===e)return[];const r=String(e),i=[];let s="",n=0;for(;n<r.length;)"\\"===r[n]&&n+1<r.length?(s+=r[n+1],n+=2):r[n]===t?(i.push(s),s="",n++):(s+=r[n],n++);return i.push(s),i.map(e=>{if("number"==typeof e)return e;if("string"==typeof e&&""!==e){const t=B(e);return isNaN(t)?NaN:t}return NaN})}};class Yi{constructor(e){const{map:t,name:r,attributes:i,passphrase:s,version:n=1,options:o={}}=e;this.name=r,this.version=n,this.attributes=i||{},this.passphrase=s??"secret",this.options=p({},this.defaultOptions(),o),this.allNestedObjectsOptional=this.options.allNestedObjectsOptional??!1;const a=this.preprocessAttributesForValidation(this.attributes);if(this.validator=new Ji({autoEncrypt:!1}).compile(p({$$async:!0},a)),this.options.generateAutoHooks&&this.generateAutoHooks(),g(t)){const e=I(this.attributes,{safe:!0}),t=Object.keys(e).filter(e=>!e.includes("$$")),r=this.extractObjectKeys(this.attributes),i=[...new Set([...t,...r])],{mapping:s,reversedMapping:n}=function(e){const t={},r={};return e.forEach((e,i)=>{const s=U(i);t[e]=s,r[s]=e}),{mapping:t,reversedMapping:r}}(i);this.map=s,this.reversedMap=n}else this.map=t,this.reversedMap=y(t)}defaultOptions(){return{autoEncrypt:!0,autoDecrypt:!0,arraySeparator:"|",generateAutoHooks:!0,hooks:{beforeMap:{},afterMap:{},beforeUnmap:{},afterUnmap:{}}}}addHook(e,t,r){this.options.hooks[e][t]||(this.options.hooks[e][t]=[]),this.options.hooks[e][t]=b([...this.options.hooks[e][t],r])}extractObjectKeys(e,t=""){const r=[];for(const[i,s]of Object.entries(e)){if(i.startsWith("$$"))continue;const e=t?`${t}.${i}`:i;"object"!=typeof s||null===s||Array.isArray(s)||(r.push(e),"object"===s.$$type&&r.push(...this.extractObjectKeys(s,e)))}return r}generateAutoHooks(){const e=I(w(this.attributes),{safe:!0});for(const[t,r]of Object.entries(e))if(r.includes("array")){if(r.includes("items:string"))this.addHook("beforeMap",t,"fromArray"),this.addHook("afterUnmap",t,"toArray");else if(r.includes("items:number")){r.includes("integer:true")||r.includes("|integer:")||r.includes("|integer")?(this.addHook("beforeMap",t,"fromArrayOfNumbers"),this.addHook("afterUnmap",t,"toArrayOfNumbers")):(this.addHook("beforeMap",t,"fromArrayOfDecimals"),this.addHook("afterUnmap",t,"toArrayOfDecimals"))}}else if(r.includes("secret"))this.options.autoEncrypt&&this.addHook("beforeMap",t,"encrypt"),this.options.autoDecrypt&&this.addHook("afterUnmap",t,"decrypt");else{if(r.includes("number")){r.includes("integer:true")||r.includes("|integer:")||r.includes("|integer")?(this.addHook("beforeMap",t,"toBase62"),this.addHook("afterUnmap",t,"fromBase62")):(this.addHook("beforeMap",t,"toBase62Decimal"),this.addHook("afterUnmap",t,"fromBase62Decimal"));continue}r.includes("boolean")?(this.addHook("beforeMap",t,"fromBool"),this.addHook("afterUnmap",t,"toBool")):(r.includes("json")||"object"===r||r.includes("object"))&&(this.addHook("beforeMap",t,"toJSON"),this.addHook("afterUnmap",t,"fromJSON"))}}static import(e){let{map:t,name:r,options:i,version:s,attributes:n}=m(e)?JSON.parse(e):e;const[o,a,c]=we(()=>Yi._importAttributes(n));if(!o)throw new me("Failed to import schema attributes",{original:a,input:n});n=c;return new Yi({map:t,name:r,options:i,version:s,attributes:n})}static _importAttributes(e){if("string"==typeof e){const[t,r,i]=we(()=>JSON.parse(e));if(t&&"object"==typeof i&&null!==i){const[t,r,s]=we(()=>Yi._importAttributes(i));if(!t)throw new me("Failed to parse nested schema attribute",{original:r,input:e});return s}return e}if(Array.isArray(e)){const[t,r,i]=we(()=>e.map(e=>Yi._importAttributes(e)));if(!t)throw new me("Failed to import array schema attributes",{original:r,input:e});return i}if("object"==typeof e&&null!==e){const t={};for(const[r,i]of Object.entries(e)){const[e,s,n]=we(()=>Yi._importAttributes(i));if(!e)throw new me("Failed to import object schema attribute",{original:s,key:r,input:i});t[r]=n}return t}return e}export(){return{version:this.version,name:this.name,options:this.options,attributes:this._exportAttributes(this.attributes),map:this.map}}_exportAttributes(e){if("string"==typeof e)return e;if(Array.isArray(e))return e.map(e=>this._exportAttributes(e));if("object"==typeof e&&null!==e){const t={};for(const[r,i]of Object.entries(e))t[r]=this._exportAttributes(i);return t}return e}async applyHooksActions(e,t){const r=w(e);for(const[e,i]of Object.entries(this.options.hooks[t]))for(const t of i){const i=v(r,e);void 0!==i&&"function"==typeof Gi[t]&&k(r,e,await Gi[t](i,{passphrase:this.passphrase,separator:this.options.arraySeparator}))}return r}async validate(e,{mutateOriginal:t=!1}={}){let r=t?e:w(e);return await this.validator(r)}async mapper(e){let t=w(e);t=await this.applyHooksActions(t,"beforeMap");const r=I(t,{safe:!0}),i={_v:this.version+""};for(const[e,t]of Object.entries(r)){const r=this.map[e]||e,s=this.getAttributeDefinition(e);"number"==typeof t&&"string"==typeof s&&s.includes("number")?i[r]=U(t):"string"==typeof t?"[object Object]"===t?i[r]="{}":(t.startsWith("{")||t.startsWith("["),i[r]=t):Array.isArray(t)||"object"==typeof t&&null!==t?i[r]=JSON.stringify(t):i[r]=t}return await this.applyHooksActions(i,"afterMap"),i}async unmapper(e,t){let r=w(e);delete r._v,r=await this.applyHooksActions(r,"beforeUnmap");const i=t?y(t):this.reversedMap,s={};for(const[e,t]of Object.entries(r)){const r=i&&i[e]?i[e]:e;let n=t;const o=this.getAttributeDefinition(r);if("string"!=typeof o||!o.includes("number")||o.includes("array")||o.includes("decimal")){if("string"==typeof t)if("[object Object]"===t)n={};else if(t.startsWith("{")||t.startsWith("[")){const[e,r,i]=we(()=>JSON.parse(t));e&&(n=i)}}else"string"==typeof n&&""!==n?n=F(n):"number"==typeof n||(n=void 0);if(this.attributes&&"string"==typeof o&&o.includes("array"))if(Array.isArray(n));else if("string"==typeof n&&n.trim().startsWith("[")){const[e,t,r]=we(()=>JSON.parse(n));e&&Array.isArray(r)&&(n=r)}else n=Gi.toArray(n,{separator:this.options.arraySeparator});if(this.options.hooks&&this.options.hooks.afterUnmap&&this.options.hooks.afterUnmap[r])for(const e of this.options.hooks.afterUnmap[r])"function"==typeof Gi[e]&&(n=await Gi[e](n,{passphrase:this.passphrase,separator:this.options.arraySeparator}));s[r]=n}await this.applyHooksActions(s,"afterUnmap");const n=P(s);for(const[t,r]of Object.entries(e))t.startsWith("$")&&(n[t]=r);return n}getAttributeDefinition(e){const t=e.split(".");let r=this.attributes;for(const e of t){if(!r)return;r=r[e]}return r}preprocessAttributesForValidation(e){const t={};for(const[r,i]of Object.entries(e))if("object"!=typeof i||null===i||Array.isArray(i))t[r]=i;else{const e=i.$$type&&i.$$type.includes("required"),s=i.$$type&&i.$$type.includes("optional"),n={type:"object",properties:this.preprocessAttributesForValidation(i),strict:!1};e||(s||this.allNestedObjectsOptional)&&(n.optional=!0),t[r]=n}return t}}var Qi=Yi;const Zi=2047;var Xi=Object.freeze({__proto__:null,S3_METADATA_LIMIT_BYTES:Zi,handleGet:async function({resource:e,metadata:t,body:r}){return{metadata:t,body:r}},handleInsert:async function({resource:e,data:t,mappedData:r,originalData:i}){const s=W(r),n=Y({s3Limit:Zi,systemConfig:{version:e.version,timestamps:e.config.timestamps,id:t.id}});if(s>n)throw new Error(`S3 metadata size exceeds 2KB limit. Current size: ${s} bytes, effective limit: ${n} bytes, absolute limit: 2047 bytes`);return{mappedData:r,body:JSON.stringify(r)}},handleUpdate:async function({resource:e,id:t,data:r,mappedData:i,originalData:s}){const n=W(i),o=Y({s3Limit:Zi,systemConfig:{version:e.version,timestamps:e.config.timestamps,id:t}});if(n>o)throw new Error(`S3 metadata size exceeds 2KB limit. Current size: ${n} bytes, effective limit: ${o} bytes, absolute limit: 2047 bytes`);return{mappedData:i,body:JSON.stringify(i)}},handleUpsert:async function({resource:e,id:t,data:r,mappedData:i}){const s=W(i),n=Y({s3Limit:Zi,systemConfig:{version:e.version,timestamps:e.config.timestamps,id:t}});if(s>n)throw new Error(`S3 metadata size exceeds 2KB limit. Current size: ${s} bytes, effective limit: ${n} bytes, absolute limit: 2047 bytes`);return{mappedData:i,body:""}}});var es=Object.freeze({__proto__:null,handleGet:async function({resource:e,metadata:t,body:r}){return{metadata:t,body:r}},handleInsert:async function({resource:e,data:t,mappedData:r,originalData:i}){const s=W(r);return s>Y({s3Limit:Zi,systemConfig:{version:e.version,timestamps:e.config.timestamps,id:t.id}})&&e.emit("exceedsLimit",{operation:"insert",totalSize:s,limit:2047,excess:s-2047,data:i||t}),{mappedData:r,body:JSON.stringify(t)}},handleUpdate:async function({resource:e,id:t,data:r,mappedData:i,originalData:s}){const n=W(i);return n>Y({s3Limit:Zi,systemConfig:{version:e.version,timestamps:e.config.timestamps,id:t}})&&e.emit("exceedsLimit",{operation:"update",id:t,totalSize:n,limit:2047,excess:n-2047,data:s||r}),{mappedData:i,body:JSON.stringify(r)}},handleUpsert:async function({resource:e,id:t,data:r,mappedData:i,originalData:s}){const n=W(i);return n>Y({s3Limit:Zi,systemConfig:{version:e.version,timestamps:e.config.timestamps,id:t}})&&e.emit("exceedsLimit",{operation:"upsert",id:t,totalSize:n,limit:2047,excess:n-2047,data:s||r}),{mappedData:i,body:JSON.stringify(r)}}});const ts="$truncated",rs="true",is=z(ts)+z(rs);async function ss({resource:e,data:t,mappedData:r,originalData:i}){const s=Y({s3Limit:Zi,systemConfig:{version:e.version,timestamps:e.config.timestamps,id:t.id}}),n=K(r),o=Object.entries(n).sort(([,e],[,t])=>e-t),a={};let c=0,u=!1;r._v&&(a._v=r._v,c+=n._v);for(const[e,t]of o){if("_v"===e)continue;const i=r[e];if(!(c+(t+(u?0:is))<=s)){const t=s-c-(u?0:is);if(t>0){const r=ns(i,t);a[e]=r,u=!0,c+=z(r)}else a[e]="",u=!0;break}a[e]=i,c+=t}let l=W(a)+(u?is:0);for(;l>s;){const e=Object.keys(a).filter(e=>"_v"!==e&&"$truncated"!==e);if(0===e.length)break;a[e[e.length-1]]="",l=W(a)+is,u=!0}return u&&(a[ts]=rs),{mappedData:a,body:JSON.stringify(r)}}function ns(e,t){if("string"==typeof e)return os(e,t);if("object"==typeof e&&null!==e){return os(JSON.stringify(e),t)}return os(String(e),t)}function os(e,t){const r=new TextEncoder;let i=r.encode(e);if(i.length<=t)return e;let s=e.length;for(;s>0;){const n=e.substring(0,s);if(i=r.encode(n),i.length<=t)return n;s--}return""}var as=Object.freeze({__proto__:null,handleGet:async function({resource:e,metadata:t,body:r}){return{metadata:t,body:r}},handleInsert:ss,handleUpdate:async function({resource:e,id:t,data:r,mappedData:i,originalData:s}){return ss({resource:e,data:r,mappedData:i,originalData:s})},handleUpsert:async function({resource:e,id:t,data:r,mappedData:i}){return ss({resource:e,data:r,mappedData:i})}});const cs="$overflow",us="true",ls=z(cs)+z(us);async function hs({resource:e,data:t,mappedData:r,originalData:i}){const s=Y({s3Limit:Zi,systemConfig:{version:e.version,timestamps:e.config.timestamps,id:t.id}}),n=K(r),o=Object.entries(n).sort(([,e],[,t])=>e-t),a={},c={};let u=0,l=!1;r._v&&(a._v=r._v,u+=n._v);let h=s;for(const[e,t]of o)"_v"!==e&&(!l&&u+t>s&&(h-=ls,l=!0),!l&&u+t<=h?(a[e]=r[e],u+=t):(c[e]=r[e],l=!0));l&&(a[cs]=us);const f=Object.keys(c).length>0;let d=f?JSON.stringify(c):"";return f||(d="{}"),{mappedData:a,body:d}}async function fs({resource:e,data:t,mappedData:r}){const i={_v:r._v||String(e.version)};i._map=JSON.stringify(e.schema.map);return{mappedData:i,body:JSON.stringify(r)}}const ds={"user-managed":es,"enforce-limits":Xi,"truncate-data":as,"body-overflow":Object.freeze({__proto__:null,handleGet:async function({resource:e,metadata:t,body:r}){let i={};if(r&&""!==r.trim()){const[e,t,s]=we(()=>JSON.parse(r));i=e?s:{}}const s={...i,...t};return delete s.$overflow,{metadata:s,body:r}},handleInsert:hs,handleUpdate:async function({resource:e,id:t,data:r,mappedData:i,originalData:s}){return hs({resource:e,data:r,mappedData:i,originalData:s})},handleUpsert:async function({resource:e,id:t,data:r,mappedData:i}){return hs({resource:e,data:r,mappedData:i})}}),"body-only":Object.freeze({__proto__:null,handleGet:async function({resource:e,metadata:t,body:r}){let i={};if(r&&""!==r.trim()){const[e,t,s]=we(()=>JSON.parse(r));i=e?s:{}}return{metadata:{...i,...t},body:r}},handleInsert:fs,handleUpdate:async function({resource:e,id:t,data:r,mappedData:i}){const s={_v:i._v||String(e.version)};return s._map=JSON.stringify(e.schema.map),{mappedData:s,body:JSON.stringify(i)}},handleUpsert:async function({resource:e,id:t,data:r,mappedData:i}){return fs({resource:e,data:r,mappedData:i})}})};function ps(e){const t=ds[e];if(!t)throw new Error(`Unknown behavior: ${e}. Available behaviors: ${Object.keys(ds).join(", ")}`);return t}const ms=Object.keys(ds),gs="user-managed";class ys extends $e{constructor(e={}){super(),this._instanceId=xe(7);const t=function(e){const t=[];e.name?"string"!=typeof e.name?t.push("Resource 'name' must be a string"):""===e.name.trim()&&t.push("Resource 'name' cannot be empty"):t.push("Resource 'name' is required");e.client||t.push("S3 'client' is required");e.attributes?"object"!=typeof e.attributes||Array.isArray(e.attributes)?t.push("Resource 'attributes' must be an object"):0===Object.keys(e.attributes).length&&t.push("Resource 'attributes' cannot be empty"):t.push("Resource 'attributes' are required");void 0!==e.version&&"string"!=typeof e.version&&t.push("Resource 'version' must be a string");void 0!==e.behavior&&"string"!=typeof e.behavior&&t.push("Resource 'behavior' must be a string");void 0!==e.passphrase&&"string"!=typeof e.passphrase&&t.push("Resource 'passphrase' must be a string");void 0!==e.parallelism&&("number"==typeof e.parallelism&&Number.isInteger(e.parallelism)?e.parallelism<1&&t.push("Resource 'parallelism' must be greater than 0"):t.push("Resource 'parallelism' must be an integer"));void 0===e.observers||Array.isArray(e.observers)||t.push("Resource 'observers' must be an array");const r=["cache","autoDecrypt","timestamps","paranoid","allNestedObjectsOptional"];for(const i of r)void 0!==e[i]&&"boolean"!=typeof e[i]&&t.push(`Resource '${i}' must be a boolean`);void 0!==e.idGenerator&&("function"!=typeof e.idGenerator&&"number"!=typeof e.idGenerator?t.push("Resource 'idGenerator' must be a function or a number (size)"):"number"==typeof e.idGenerator&&e.idGenerator<=0&&t.push("Resource 'idGenerator' size must be greater than 0"));void 0!==e.idSize&&("number"==typeof e.idSize&&Number.isInteger(e.idSize)?e.idSize<=0&&t.push("Resource 'idSize' must be greater than 0"):t.push("Resource 'idSize' must be an integer"));if(void 0!==e.partitions)if("object"!=typeof e.partitions||Array.isArray(e.partitions))t.push("Resource 'partitions' must be an object");else for(const[r,i]of Object.entries(e.partitions))if("object"!=typeof i||Array.isArray(i))t.push(`Partition '${r}' must be an object`);else if(i.fields)if("object"!=typeof i.fields||Array.isArray(i.fields))t.push(`Partition '${r}.fields' must be an object`);else for(const[e,s]of Object.entries(i.fields))"string"!=typeof s&&t.push(`Partition '${r}.fields.${e}' must be a string`);else t.push(`Partition '${r}' must have a 'fields' property`);if(void 0!==e.hooks)if("object"!=typeof e.hooks||Array.isArray(e.hooks))t.push("Resource 'hooks' must be an object");else{const r=["beforeInsert","afterInsert","beforeUpdate","afterUpdate","beforeDelete","afterDelete"];for(const[i,s]of Object.entries(e.hooks))if(r.includes(i))if(Array.isArray(s))for(let e=0;e<s.length;e++){const t=s[e];if("function"==typeof t);else if("string"==typeof t)continue}else t.push(`Resource 'hooks.${i}' must be an array`);else t.push(`Invalid hook event '${i}'. Valid events: ${r.join(", ")}`)}if(void 0!==e.events)if("object"!=typeof e.events||Array.isArray(e.events))t.push("Resource 'events' must be an object");else for(const[r,i]of Object.entries(e.events))if(Array.isArray(i))for(let e=0;e<i.length;e++){"function"!=typeof i[e]&&t.push(`Resource 'events.${r}[${e}]' must be a function`)}else"function"!=typeof i&&t.push(`Resource 'events.${r}' must be a function or array of functions`);return{isValid:0===t.length,errors:t}}(e);if(!t.isValid){const r=t.errors.map(e=>` • ${e}`).join("\n");throw new ge(`Invalid Resource ${e.name||"[unnamed]"} configuration:\n${r}`,{resourceName:e.name,validation:t.errors})}const{name:r,client:i,version:s="1",attributes:n={},behavior:o=gs,passphrase:a="secret",parallelism:c=10,observers:u=[],cache:l=!1,autoDecrypt:h=!0,timestamps:f=!1,partitions:d={},paranoid:p=!0,allNestedObjectsOptional:m=!0,hooks:g={},idGenerator:y,idSize:b=22,versioningEnabled:w=!1,events:v={}}=e;if(this.name=r,this.client=i,this.version=s,this.behavior=o,this.observers=u,this.parallelism=c,this.passphrase=a??"secret",this.versioningEnabled=w,this.idGenerator=this.configureIdGenerator(y,b),this.idSize="number"==typeof y&&y>0?y:"number"==typeof b&&b>0?b:22,this.idGeneratorType=this.getIdGeneratorType(y,this.idSize),this.config={cache:l,hooks:g,paranoid:p,timestamps:f,partitions:d,autoDecrypt:h,allNestedObjectsOptional:m},this.hooks={beforeInsert:[],afterInsert:[],beforeUpdate:[],afterUpdate:[],beforeDelete:[],afterDelete:[]},this.attributes=n||{},this.map=e.map,this.applyConfiguration({map:this.map}),g)for(const[e,t]of Object.entries(g))if(Array.isArray(t)&&this.hooks[e])for(const r of t)"function"==typeof r&&this.hooks[e].push(r.bind(this));if(v&&Object.keys(v).length>0)for(const[e,t]of Object.entries(v))if(Array.isArray(t))for(const r of t)"function"==typeof r&&this.on(e,r);else"function"==typeof t&&this.on(e,t);this._initMiddleware()}configureIdGenerator(r,i){return"function"==typeof r?()=>String(r()):"number"==typeof r&&r>0?e(t,r):"number"==typeof i&&i>0&&22!==i?e(t,i):xe}getIdGeneratorType(e,t){return"function"==typeof e?"custom_function":t}get options(){return{timestamps:this.config.timestamps,partitions:this.config.partitions||{},cache:this.config.cache,autoDecrypt:this.config.autoDecrypt,paranoid:this.config.paranoid,allNestedObjectsOptional:this.config.allNestedObjectsOptional}}export(){const e=this.schema.export();return e.behavior=this.behavior,e.timestamps=this.config.timestamps,e.partitions=this.config.partitions||{},e.paranoid=this.config.paranoid,e.allNestedObjectsOptional=this.config.allNestedObjectsOptional,e.autoDecrypt=this.config.autoDecrypt,e.cache=this.config.cache,e.hooks=this.hooks,e.map=this.map,e}applyConfiguration({map:e}={}){this.config.timestamps&&(this.attributes.createdAt||(this.attributes.createdAt="string|optional"),this.attributes.updatedAt||(this.attributes.updatedAt="string|optional"),this.config.partitions||(this.config.partitions={}),this.config.partitions.byCreatedDate||(this.config.partitions.byCreatedDate={fields:{createdAt:"date|maxlength:10"}}),this.config.partitions.byUpdatedDate||(this.config.partitions.byUpdatedDate={fields:{updatedAt:"date|maxlength:10"}})),this.setupPartitionHooks(),this.versioningEnabled&&(this.config.partitions.byVersion||(this.config.partitions.byVersion={fields:{_v:"string"}})),this.schema=new Qi({name:this.name,attributes:this.attributes,passphrase:this.passphrase,version:this.version,options:{autoDecrypt:this.config.autoDecrypt,allNestedObjectsOptional:this.config.allNestedObjectsOptional},map:e||this.map}),this.validatePartitions()}updateAttributes(e){const t=this.attributes;return this.attributes=e,this.applyConfiguration({map:this.schema?.map}),{oldAttributes:t,newAttributes:e}}addHook(e,t){this.hooks[e]&&this.hooks[e].push(t.bind(this))}async executeHooks(e,t){if(!this.hooks[e])return t;let r=t;for(const t of this.hooks[e])r=await t(r);return r}setupPartitionHooks(){if(!this.config.partitions)return;const e=this.config.partitions;0!==Object.keys(e).length&&(this.hooks.afterInsert||(this.hooks.afterInsert=[]),this.hooks.afterInsert.push(async e=>(await this.createPartitionReferences(e),e)),this.hooks.afterDelete||(this.hooks.afterDelete=[]),this.hooks.afterDelete.push(async e=>(await this.deletePartitionReferences(e),e)))}async validate(e){const t={original:w(e),isValid:!1,errors:[]},r=await this.schema.validate(e,{mutateOriginal:!1});return!0===r?t.isValid=!0:t.errors=r,t.data=e,t}validatePartitions(){if(!this.config.partitions)return;const e=this.config.partitions;if(0===Object.keys(e).length)return;const t=Object.keys(this.attributes||{});for(const[r,i]of Object.entries(e))if(i.fields)for(const e of Object.keys(i.fields))if(!this.fieldExistsInAttributes(e))throw new ye(`Partition '${r}' uses field '${e}' which does not exist in resource attributes. Available fields: ${t.join(", ")}.`,{resourceName:this.name,partitionName:r,fieldName:e,availableFields:t,operation:"validatePartitions"})}fieldExistsInAttributes(e){if(e.startsWith("_"))return!0;if(!e.includes("."))return Object.keys(this.attributes||{}).includes(e);const t=e.split(".");let r=this.attributes||{};for(const e of t){if(!r||"object"!=typeof r||!(e in r))return!1;r=r[e]}return!0}applyPartitionRule(e,t){if(null==e)return e;let r=e;if("string"==typeof t&&t.includes("maxlength:")){const e=t.match(/maxlength:(\d+)/);if(e){const t=parseInt(e[1]);"string"==typeof r&&r.length>t&&(r=r.substring(0,t))}}if(t.includes("date"))if(r instanceof Date)r=r.toISOString().split("T")[0];else if("string"==typeof r)if(r.includes("T")&&r.includes("Z"))r=r.split("T")[0];else{const e=new Date(r);isNaN(e.getTime())||(r=e.toISOString().split("T")[0])}return r}getResourceKey(e){return Ke("resource="+this.name,"data",`id=${e}`)}getPartitionKey({partitionName:e,id:t,data:r}){if(!this.config.partitions||!this.config.partitions[e])throw new ye(`Partition '${e}' not found`,{resourceName:this.name,partitionName:e,operation:"getPartitionKey"});const i=this.config.partitions[e],s=[],n=Object.entries(i.fields).sort(([e],[t])=>e.localeCompare(t));for(const[e,t]of n){const i=this.getNestedFieldValue(r,e),n=this.applyPartitionRule(i,t);if(null==n)return null;s.push(`${e}=${n}`)}if(0===s.length)return null;const o=t||r?.id;return o?Ke(`resource=${this.name}`,`partition=${e}`,...s,`id=${o}`):null}getNestedFieldValue(e,t){if(!t.includes("."))return e[t];const r=t.split(".");let i=e;for(const e of r){if(!i||"object"!=typeof i||!(e in i))return;i=i[e]}return i}calculateContentLength(e){return e?Buffer.isBuffer(e)?e.length:"string"==typeof e?Buffer.byteLength(e,"utf8"):"object"==typeof e?Buffer.byteLength(JSON.stringify(e),"utf8"):Buffer.byteLength(String(e),"utf8"):0}async insert({id:e,...t}){if(await this.exists(e))throw new Error(`Resource with id '${e}' already exists`);this.getResourceKey(e||"(auto)"),this.options.timestamps&&(t.createdAt=(new Date).toISOString(),t.updatedAt=(new Date).toISOString());const r={id:e,...this.applyDefaults(t)},i=await this.executeHooks("beforeInsert",r),s=Object.keys(i).filter(e=>!(e in r)||i[e]!==r[e]),n={};for(const e of s)n[e]=i[e];const{errors:o,isValid:a,data:c}=await this.validate(i);if(!a){const e=o&&o.length&&o[0].message?o[0].message:"Insert failed";throw new ue({bucket:this.client.config.bucket,resourceName:this.name,attributes:i,validation:o,message:e})}const{id:u,...l}=c;Object.assign(l,n);const h=u||e||this.idGenerator(),f=await this.schema.mapper(l);f._v=String(this.version);const d=ps(this.behavior),{mappedData:p,body:m}=await d.handleInsert({resource:this,data:l,mappedData:f,originalData:r}),g=p,y=this.getResourceKey(h);let b;if(m&&""!==m){const[e,t]=await ve(()=>Promise.resolve(JSON.parse(m)));e&&(b="application/json")}if("body-only"===this.behavior&&(!m||""===m))throw new Error(`[Resource.insert] Attempt to save object without body! Data: id=${h}, resource=${this.name}`);const[w,v,k]=await ve(()=>this.client.putObject({key:y,body:m,contentType:b,metadata:g}));if(!w){const e=v&&v.message?v.message:"";if(e.includes("metadata headers exceed")||e.includes("Insert failed")){const e=W(g),t=Y({s3Limit:2047,systemConfig:{version:this.version,timestamps:this.config.timestamps,id:h}}),r=e-t;throw v.totalSize=e,v.limit=2047,v.effectiveLimit=t,v.excess=r,new ge("metadata headers exceed",{resourceName:this.name,operation:"insert",id:h,totalSize:e,effectiveLimit:t,excess:r,suggestion:"Reduce metadata size or number of fields."})}throw fe(v,{bucket:this.client.config.bucket,key:y,resourceName:this.name,operation:"insert",id:h})}let _=await this.composeFullObjectFromWrite({id:h,metadata:g,body:m,behavior:this.behavior});const S=await this.executeHooks("afterInsert",_);return this.emit("insert",{..._,$before:{...r},$after:{...S}}),S}async get(e){if(_(e))throw new Error("id cannot be an object");if(g(e))throw new Error("id cannot be empty");const t=this.getResourceKey(e),[r,i,s]=await ve(()=>this.client.getObject(t));if(!r)throw fe(i,{bucket:this.client.config.bucket,key:t,resourceName:this.name,operation:"get",id:e});if(0===s.ContentLength){const r=new Error(`No such key: ${t} [bucket:${this.client.config.bucket}]`);throw r.name="NoSuchKey",fe(r,{bucket:this.client.config.bucket,key:t,resourceName:this.name,operation:"get",id:e})}const n=s.Metadata?._v||this.version,o="string"==typeof n&&n.startsWith("v")?n.slice(1):n,a=await this.getSchemaForVersion(o);let c=await a.unmapper(s.Metadata);const u=ps(this.behavior);let l="";if(s.ContentLength>0){const[e,r,i]=await ve(()=>this.client.getObject(t));l=e?await xi(i.Body):""}const{metadata:h}=await u.handleGet({resource:this,metadata:c,body:l});let f=await this.composeFullObjectFromWrite({id:e,metadata:h,body:l,behavior:this.behavior});f._contentLength=s.ContentLength,f._lastModified=s.LastModified,f._hasContent=s.ContentLength>0,f._mimeType=s.ContentType||null,f._v=o,s.VersionId&&(f._versionId=s.VersionId),s.Expiration&&(f._expiresAt=s.Expiration),f._definitionHash=this.getDefinitionHash(),o!==this.version&&(f=await this.applyVersionMapping(f,o,this.version)),this.emit("get",f);return f}async exists(e){const t=this.getResourceKey(e),[r,i]=await ve(()=>this.client.headObject(t));return r}async update(e,t){if(g(e))throw new Error("id cannot be empty");if(!await this.exists(e))throw new Error(`Resource with id '${e}' does not exist`);const r=await this.get(e),i=w(t);let s=w(r);for(const[e,t]of Object.entries(i))if(e.includes(".")){let r=s;const i=e.split(".");for(let e=0;e<i.length-1;e++)"object"==typeof r[i[e]]&&null!==r[i[e]]||(r[i[e]]={}),r=r[i[e]];r[i[i.length-1]]=w(t)}else"object"!=typeof t||null===t||Array.isArray(t)?s[e]=w(t):s[e]=p({},s[e],t);if(this.config.timestamps){const e=(new Date).toISOString();s.updatedAt=e,s.metadata||(s.metadata={}),s.metadata.updatedAt=e}const n=await this.executeHooks("beforeUpdate",w(s)),o={...r,...n,id:e},{isValid:a,errors:c,data:u}=await this.validate(w(o));if(!a)throw new ue({bucket:this.client.config.bucket,resourceName:this.name,attributes:n,validation:c,message:"validation: "+(c&&c.length?JSON.stringify(c):"unknown")});await this.schema.mapper(u);const l=ps(this.behavior),h=await this.schema.mapper({...r,...n});h._v=String(this.version),await l.handleUpdate({resource:this,id:e,data:{...r,...n},mappedData:h,originalData:{...i,id:e}});const{id:f,...d}=u,m={...r,id:e},y={...d,id:e};await this.handlePartitionReferenceUpdates(m,y);const b=await this.schema.mapper(d);b._v=String(this.version);const v=ps(this.behavior),{mappedData:k,body:_}=await v.handleUpdate({resource:this,id:e,data:d,mappedData:b,originalData:{...i,id:e}}),S=k,O=this.getResourceKey(e);let R,j=_;if(""===_&&"body-overflow"!==this.behavior){const[e,t,r]=await ve(()=>this.client.getObject(O));if(e&&r.ContentLength>0){const e=Buffer.from(await r.Body.transformToByteArray()),t=e.toString(),[i,s]=await ve(()=>Promise.resolve(JSON.parse(t)));i||(j=e,R=r.ContentType)}}let x=R;if(j&&""!==j&&!x){const[e,t]=await ve(()=>Promise.resolve(JSON.parse(j)));e&&(x="application/json")}this.versioningEnabled&&r._v!==this.version&&await this.createHistoricalVersion(e,r);const[E,A]=await ve(()=>this.client.putObject({key:O,body:j,contentType:x,metadata:S}));if(!E&&A&&A.message&&A.message.includes("metadata headers exceed")){const t=W(S),r=Y({s3Limit:2047,systemConfig:{version:this.version,timestamps:this.config.timestamps,id:e}}),i=t-r;throw A.totalSize=t,A.limit=2047,A.effectiveLimit=r,A.excess=i,this.emit("exceedsLimit",{operation:"update",totalSize:t,limit:2047,effectiveLimit:r,excess:i,data:d}),new ge("metadata headers exceed",{resourceName:this.name,operation:"update",id:e,totalSize:t,effectiveLimit:r,excess:i,suggestion:"Reduce metadata size or number of fields."})}if(!E)throw fe(A,{bucket:this.client.config.bucket,key:O,resourceName:this.name,operation:"update",id:e});const D=await this.composeFullObjectFromWrite({id:e,metadata:S,body:j,behavior:this.behavior}),$=await this.executeHooks("afterUpdate",D);return this.emit("update",{...D,$before:{...r},$after:{...$}}),$}async delete(e){if(g(e))throw new Error("id cannot be empty");let t,r=null;const[i,s,n]=await ve(()=>this.get(e));i?t=n:(t={id:e},r=s),await this.executeHooks("beforeDelete",t);const o=this.getResourceKey(e),[a,c,u]=await ve(()=>this.client.deleteObject(o));if(this.emit("delete",{...t,$before:{...t},$after:null}),r)throw fe(r,{bucket:this.client.config.bucket,key:o,resourceName:this.name,operation:"delete",id:e});if(!a)throw fe(c,{key:o,resourceName:this.name,operation:"delete",id:e});return await this.executeHooks("afterDelete",t),u}async upsert({id:e,...t}){return await this.exists(e)?this.update(e,t):this.insert({id:e,...t})}async count({partition:e=null,partitionValues:t={}}={}){let r;if(e&&Object.keys(t).length>0){const i=this.config.partitions[e];if(!i)throw new ye(`Partition '${e}' not found`,{resourceName:this.name,partitionName:e,operation:"count"});const s=[],n=Object.entries(i.fields).sort(([e],[t])=>e.localeCompare(t));for(const[e,r]of n){const i=t[e];if(null!=i){const t=this.applyPartitionRule(i,r);s.push(`${e}=${t}`)}}r=s.length>0?`resource=${this.name}/partition=${e}/${s.join("/")}`:`resource=${this.name}/partition=${e}`}else r=`resource=${this.name}/data`;const i=await this.client.count({prefix:r});return this.emit("count",i),i}async insertMany(e){const{results:t}=await i.for(e).withConcurrency(this.parallelism).handleError(async(e,t)=>{this.emit("error",e,t),this.observers.map(r=>r.emit("error",this.name,e,t))}).process(async e=>await this.insert(e));return this.emit("insertMany",e.length),t}async deleteMany(e){const t=d(e.map(e=>this.getResourceKey(e)),1e3);e.map(e=>this.getResourceKey(e));const{results:r}=await i.for(t).withConcurrency(this.parallelism).handleError(async(e,t)=>{this.emit("error",e,t),this.observers.map(r=>r.emit("error",this.name,e,t))}).process(async e=>{const t=await this.client.deleteObjects(e);return e.forEach(e=>{const t=e.split("/").find(e=>e.startsWith("id=")),r=t?t.replace("id=",""):null;r&&(this.emit("deleted",r),this.observers.map(e=>e.emit("deleted",this.name,r)))}),t});return this.emit("deleteMany",e.length),r}async deleteAll(){if(!1!==this.config.paranoid)throw new ge("deleteAll() is a dangerous operation and requires paranoid: false option.",{resourceName:this.name,operation:"deleteAll",paranoid:this.config.paranoid,suggestion:"Set paranoid: false to allow deleteAll."});const e=`resource=${this.name}/data`,t=await this.client.deleteAll({prefix:e});return this.emit("deleteAll",{version:this.version,prefix:e,deletedCount:t}),{deletedCount:t,version:this.version}}async deleteAllData(){if(!1!==this.config.paranoid)throw new ge("deleteAllData() is a dangerous operation and requires paranoid: false option.",{resourceName:this.name,operation:"deleteAllData",paranoid:this.config.paranoid,suggestion:"Set paranoid: false to allow deleteAllData."});const e=`resource=${this.name}`,t=await this.client.deleteAll({prefix:e});return this.emit("deleteAllData",{resource:this.name,prefix:e,deletedCount:t}),{deletedCount:t,resource:this.name}}async listIds({partition:e=null,partitionValues:t={},limit:r,offset:i=0}={}){let s;if(e&&Object.keys(t).length>0){if(!this.config.partitions||!this.config.partitions[e])throw new ye(`Partition '${e}' not found`,{resourceName:this.name,partitionName:e,operation:"listIds"});const r=this.config.partitions[e],i=[],n=Object.entries(r.fields).sort(([e],[t])=>e.localeCompare(t));for(const[e,r]of n){const s=t[e];if(null!=s){const t=this.applyPartitionRule(s,r);i.push(`${e}=${t}`)}}s=i.length>0?`resource=${this.name}/partition=${e}/${i.join("/")}`:`resource=${this.name}/partition=${e}`}else s=`resource=${this.name}/data`;const n=(await this.client.getKeysPage({prefix:s,offset:i,amount:r||1e3})).map(e=>{const t=e.split("/").find(e=>e.startsWith("id="));return t?t.replace("id=",""):null}).filter(Boolean);return this.emit("listIds",n.length),n}async list({partition:e=null,partitionValues:t={},limit:r,offset:i=0}={}){const[s,n,o]=await ve(async()=>e?await this.listPartition({partition:e,partitionValues:t,limit:r,offset:i}):await this.listMain({limit:r,offset:i}));return s?o:this.handleListError(n,{partition:e,partitionValues:t})}async listMain({limit:e,offset:t=0}){const[r,i,s]=await ve(()=>this.listIds({limit:e,offset:t}));if(!r)throw i;const n=await this.processListResults(s,"main");return this.emit("list",{count:n.length,errors:0}),n}async listPartition({partition:e,partitionValues:t,limit:r,offset:i=0}){if(!this.config.partitions?.[e])return this.emit("list",{partition:e,partitionValues:t,count:0,errors:0}),[];const s=this.config.partitions[e],n=this.buildPartitionPrefix(e,s,t),[o,a,c]=await ve(()=>this.client.getAllKeys({prefix:n}));if(!o)throw a;const u=this.extractIdsFromKeys(c).slice(i),l=r?u.slice(0,r):u,h=await this.processPartitionResults(l,e,s,c);return this.emit("list",{partition:e,partitionValues:t,count:h.length,errors:0}),h}buildPartitionPrefix(e,t,r){const i=[],s=Object.entries(t.fields).sort(([e],[t])=>e.localeCompare(t));for(const[e,t]of s){const s=r[e];if(null!=s){const r=this.applyPartitionRule(s,t);i.push(`${e}=${r}`)}}return i.length>0?`resource=${this.name}/partition=${e}/${i.join("/")}`:`resource=${this.name}/partition=${e}`}extractIdsFromKeys(e){return e.map(e=>{const t=e.split("/").find(e=>e.startsWith("id="));return t?t.replace("id=",""):null}).filter(Boolean)}async processListResults(e,t="main"){const{results:r,errors:s}=await i.for(e).withConcurrency(this.parallelism).handleError(async(e,t)=>{this.emit("error",e,content),this.observers.map(t=>t.emit("error",this.name,e,content))}).process(async e=>{const[r,i,s]=await ve(()=>this.get(e));return r?s:this.handleResourceError(i,e,t)});return this.emit("list",{count:r.length,errors:0}),r}async processPartitionResults(e,t,r,s){const n=Object.entries(r.fields).sort(([e],[t])=>e.localeCompare(t)),{results:o,errors:a}=await i.for(e).withConcurrency(this.parallelism).handleError(async(e,t)=>{this.emit("error",e,content),this.observers.map(t=>t.emit("error",this.name,e,content))}).process(async e=>{const[r,i,o]=await ve(async()=>{const r=this.extractPartitionValuesFromKey(e,s,n);return await this.getFromPartition({id:e,partitionName:t,partitionValues:r})});return r?o:this.handleResourceError(i,e,"partition")});return o.filter(e=>null!==e)}extractPartitionValuesFromKey(e,t,r){const i=t.find(t=>t.includes(`id=${e}`));if(!i)throw new ye(`Partition key not found for ID ${e}`,{resourceName:this.name,id:e,operation:"extractPartitionValuesFromKey"});const s=i.split("/"),n={};for(const[e]of r){const t=s.find(t=>t.startsWith(`${e}=`));if(t){const r=t.replace(`${e}=`,"");n[e]=r}}return n}handleResourceError(e,t,r){if(e.message.includes("Cipher job failed")||e.message.includes("OperationError"))return{id:t,_decryptionFailed:!0,_error:e.message,..."partition"===r&&{_partition:r}};throw e}handleListError(e,{partition:t,partitionValues:r}){return e.message.includes("Partition '")&&e.message.includes("' not found"),this.emit("list",{partition:t,partitionValues:r,count:0,errors:1}),[]}async getMany(e){const{results:t,errors:r}=await i.for(e).withConcurrency(this.client.parallelism).handleError(async(e,t)=>(this.emit("error",e,content),this.observers.map(t=>t.emit("error",this.name,e,content)),{id:t,_error:e.message,_decryptionFailed:e.message.includes("Cipher job failed")||e.message.includes("OperationError")})).process(async e=>{const[t,r,i]=await ve(()=>this.get(e));if(t)return i;if(r.message.includes("Cipher job failed")||r.message.includes("OperationError"))return{id:e,_decryptionFailed:!0,_error:r.message};throw r});return this.emit("getMany",e.length),t}async getAll(){const[e,t,r]=await ve(()=>this.listIds());if(!e)throw t;const i=[];for(const e of r){const[t,r,s]=await ve(()=>this.get(e));t&&i.push(s)}return i}async page({offset:e=0,size:t=100,partition:r=null,partitionValues:i={},skipCount:s=!1}={}){const[n,o,a]=await ve(async()=>{let n=null,o=null;if(!s){const[e,s,a]=await ve(()=>this.count({partition:r,partitionValues:i}));e?(n=a,o=Math.ceil(n/t)):(n=null,o=null)}const a=Math.floor(e/t);let c=[];if(t<=0)c=[];else{const[s,n,o]=await ve(()=>this.list({partition:r,partitionValues:i,limit:t,offset:e}));c=s?o:[]}const u={items:c,totalItems:n,page:a,pageSize:t,totalPages:o,hasMore:c.length===t&&e+t<(n||1/0),_debug:{requestedSize:t,requestedOffset:e,actualItemsReturned:c.length,skipCount:s,hasTotalItems:null!==n}};return this.emit("page",u),u});return n?a:{items:[],totalItems:null,page:Math.floor(e/t),pageSize:t,totalPages:null,_debug:{requestedSize:t,requestedOffset:e,actualItemsReturned:0,skipCount:s,hasTotalItems:!1,error:o.message}}}readable(){return new Ri({resource:this}).build()}writable(){return new ji({resource:this}).build()}async setContent({id:e,buffer:t,contentType:r="application/octet-stream"}){const[i,s,n]=await ve(()=>this.get(e));if(!i||!n)throw new ge(`Resource with id '${e}' not found`,{resourceName:this.name,id:e,operation:"setContent"});const o={...n,_hasContent:!0,_contentLength:t.length,_mimeType:r},a=await this.schema.mapper(o),[c,u]=await ve(()=>this.client.putObject({key:this.getResourceKey(e),metadata:a,body:t,contentType:r}));if(!c)throw u;return this.emit("setContent",{id:e,contentType:r,contentLength:t.length}),o}async content(e){const t=this.getResourceKey(e),[r,i,s]=await ve(()=>this.client.getObject(t));if(!r){if("NoSuchKey"===i.name)return{buffer:null,contentType:null};throw i}const n=Buffer.from(await s.Body.transformToByteArray()),o=s.ContentType||null;return this.emit("content",e,n.length,o),{buffer:n,contentType:o}}async hasContent(e){const t=this.getResourceKey(e),[r,i,s]=await ve(()=>this.client.headObject(t));return!!r&&s.ContentLength>0}async deleteContent(e){const t=this.getResourceKey(e),[r,i,s]=await ve(()=>this.client.headObject(t));if(!r)throw i;const n=s.Metadata||{},[o,a,c]=await ve(()=>this.client.putObject({key:t,body:"",metadata:n}));if(!o)throw a;return this.emit("deleteContent",e),c}getDefinitionHash(){const e={attributes:this.attributes,behavior:this.behavior},t=O(e);return`sha256:${f("sha256").update(t).digest("hex")}`}extractVersionFromKey(e){const t=e.split("/").find(e=>e.startsWith("v="));return t?t.replace("v=",""):null}async getSchemaForVersion(e){if(e===this.version)return this.schema;const[t,r,i]=await ve(()=>Promise.resolve(new Qi({name:this.name,attributes:this.attributes,passphrase:this.passphrase,version:e,options:{...this.config,autoDecrypt:!0,autoEncrypt:!0}})));return t?i:this.schema}async createPartitionReferences(e){const t=this.config.partitions;if(t&&0!==Object.keys(t).length)for(const[r,i]of Object.entries(t)){const t=this.getPartitionKey({partitionName:r,id:e.id,data:e});if(t){const e={_v:String(this.version)};await this.client.putObject({key:t,metadata:e,body:"",contentType:void 0})}}}async deletePartitionReferences(e){const t=this.config.partitions;if(!t||0===Object.keys(t).length)return;const r=[];for(const[i,s]of Object.entries(t)){const t=this.getPartitionKey({partitionName:i,id:e.id,data:e});t&&r.push(t)}if(r.length>0){const[e,t]=await ve(()=>this.client.deleteObjects(r))}}async query(e={},{limit:t=100,offset:r=0,partition:i=null,partitionValues:s={}}={}){if(0===Object.keys(e).length)return await this.list({partition:i,partitionValues:s,limit:t,offset:r});const n=[];let o=r;const a=Math.min(t,50);for(;n.length<t;){const t=await this.list({partition:i,partitionValues:s,limit:a,offset:o});if(0===t.length)break;const r=t.filter(t=>Object.entries(e).every(([e,r])=>t[e]===r));if(n.push(...r),o+=a,t.length<a)break}return n.slice(0,t)}async handlePartitionReferenceUpdates(e,t){const r=this.config.partitions;if(!r||0===Object.keys(r).length)return;for(const[i,s]of Object.entries(r)){const[r,n]=await ve(()=>this.handlePartitionReferenceUpdate(i,s,e,t))}const i=t.id||e.id;for(const[e,s]of Object.entries(r)){const r=`resource=${this.name}/partition=${e}`;let s=[];const[n,o,a]=await ve(()=>this.client.getAllKeys({prefix:r}));if(!n)continue;s=a;const c=this.getPartitionKey({partitionName:e,id:i,data:t});for(const e of s)if(e.endsWith(`/id=${i}`)&&e!==c){const[t,r]=await ve(()=>this.client.deleteObject(e))}}}async handlePartitionReferenceUpdate(e,t,r,i){const s=i.id||r.id,n=this.getPartitionKey({partitionName:e,id:s,data:r}),o=this.getPartitionKey({partitionName:e,id:s,data:i});if(n!==o){if(n){const[e,t]=await ve(async()=>{await this.client.deleteObject(n)})}if(o){const[e,t]=await ve(async()=>{const e={_v:String(this.version)};await this.client.putObject({key:o,metadata:e,body:"",contentType:void 0})})}}else if(o){const[e,t]=await ve(async()=>{const e={_v:String(this.version)};await this.client.putObject({key:o,metadata:e,body:"",contentType:void 0})})}}async updatePartitionReferences(e){const t=this.config.partitions;if(t&&0!==Object.keys(t).length)for(const[r,i]of Object.entries(t)){if(!i||!i.fields||"object"!=typeof i.fields)continue;const t=this.getPartitionKey({partitionName:r,id:e.id,data:e});if(t){const e={_v:String(this.version)},[r,i]=await ve(async()=>{await this.client.putObject({key:t,metadata:e,body:"",contentType:void 0})})}}}async getFromPartition({id:e,partitionName:t,partitionValues:r={}}){if(!this.config.partitions||!this.config.partitions[t])throw new ye(`Partition '${t}' not found`,{resourceName:this.name,partitionName:t,operation:"getFromPartition"});const i=this.config.partitions[t],s=[],n=Object.entries(i.fields).sort(([e],[t])=>e.localeCompare(t));for(const[e,t]of n){const i=r[e];if(null!=i){const r=this.applyPartitionRule(i,t);s.push(`${e}=${r}`)}}if(0===s.length)throw new ye(`No partition values provided for partition '${t}'`,{resourceName:this.name,partitionName:t,operation:"getFromPartition"});const o=Ke(`resource=${this.name}`,`partition=${t}`,...s,`id=${e}`),[a,c]=await ve(async()=>{await this.client.headObject(o)});if(!a)throw new ge(`Resource with id '${e}' not found in partition '${t}'`,{resourceName:this.name,id:e,partitionName:t,operation:"getFromPartition"});const u=await this.get(e);return u._partition=t,u._partitionValues=r,this.emit("getFromPartition",u),u}async createHistoricalVersion(e,t){const r=Ke(`resource=${this.name}`,"historical",`id=${e}`),i={...t,_v:t._v||this.version,_historicalTimestamp:(new Date).toISOString()},s=await this.schema.mapper(i),n=ps(this.behavior),{mappedData:o,body:a}=await n.handleInsert({resource:this,data:i,mappedData:s}),c={...o,_v:t._v||this.version,_historicalTimestamp:i._historicalTimestamp};let u;if(a&&""!==a){const[e,t]=await ve(()=>Promise.resolve(JSON.parse(a)));e&&(u="application/json")}await this.client.putObject({key:r,metadata:c,body:a,contentType:u})}async applyVersionMapping(e,t,r){if(t===r)return e;return{...e,_v:r,_originalVersion:t,_versionMapped:!0}}async composeFullObjectFromWrite({id:e,metadata:t,body:r,behavior:i}){const s={};t&&"true"===t.$truncated&&(s.$truncated="true"),t&&"true"===t.$overflow&&(s.$overflow="true");let n={};const[o,a,c]=await ve(()=>this.schema.unmapper(t));n=o?c:t;const u=e=>{if(!e||"object"!=typeof e)return e;const t={};for(const[r,i]of Object.entries(e))r.startsWith("_")||(t[r]=i);return t},l=e=>{if("object"==typeof e&&null!==e)return e;if("string"==typeof e){if("[object Object]"===e)return{};if(e.startsWith("{")||e.startsWith("[")){const[t,r,i]=we(()=>JSON.parse(e));return t?i:e}return e}return e};if("body-overflow"===i){const i=t&&"true"===t.$overflow;let s={};if(i&&r){const[e,t,i]=await ve(()=>Promise.resolve(JSON.parse(r)));if(e){const[e,t,r]=await ve(()=>this.schema.unmapper(i));s=e?r:{}}}const o={...n,...s,id:e};Object.keys(o).forEach(e=>{o[e]=l(o[e])});const a=u(o);return i&&(a.$overflow="true"),a}if("body-only"===i){const[i,s,n]=await ve(()=>Promise.resolve(r?JSON.parse(r):{}));let o=this.schema.map;if(t&&t._map){const[e,r,i]=await ve(()=>Promise.resolve("string"==typeof t._map?JSON.parse(t._map):t._map));o=e?i:this.schema.map}const[a,c,u]=await ve(()=>this.schema.unmapper(n,o)),h=a?{...u,id:e}:{id:e};return Object.keys(h).forEach(e=>{h[e]=l(h[e])}),h}const h={...n,id:e};Object.keys(h).forEach(e=>{h[e]=l(h[e])});const f=u(h);return s.$truncated&&(f.$truncated=s.$truncated),s.$overflow&&(f.$overflow=s.$overflow),f}emit(e,...t){return super.emit(e,...t)}async replace(e,t){await this.delete(e),await new Promise(e=>setTimeout(e,100));const r=Date.now();for(;Date.now()-r<5e3;){if(!await this.exists(e))break;await new Promise(e=>setTimeout(e,50))}try{return await this.insert({...t,id:e})}catch(r){if(r&&r.message&&r.message.includes("already exists")){return await this.update(e,t)}throw r}}_initMiddleware(){this._middlewares=new Map,this._middlewareMethods=["get","list","listIds","getAll","count","page","insert","update","delete","deleteMany","exists","getMany","content","hasContent","query","getFromPartition","setContent","deleteContent","replace"];for(const e of this._middlewareMethods)this._middlewares.set(e,[]),this[`_original_${e}`]||(this[`_original_${e}`]=this[e].bind(this),this[e]=async(...t)=>{const r={resource:this,args:t,method:e};let i=-1;const s=this._middlewares.get(e),n=async t=>{if(t<=i)throw new Error("next() called multiple times");return i=t,t<s.length?await s[t](r,()=>n(t+1)):await this[`_original_${e}`](...r.args)};return await n(0)})}useMiddleware(e,t){if(this._middlewares||this._initMiddleware(),!this._middlewares.has(e))throw new ge(`No such method for middleware: ${e}`,{operation:"useMiddleware",method:e});this._middlewares.get(e).push(t)}applyDefaults(e){const t={...e};for(const[e,r]of Object.entries(this.attributes))if(void 0===t[e]&&"string"==typeof r&&r.includes("default:")){const i=r.match(/default:([^|]+)/);if(i){let s=i[1];r.includes("boolean")?s="true"===s:r.includes("number")&&(s=Number(s)),t[e]=s}}return t}}var bs=ys;class ws extends $e{constructor(e){super(),this.id=xe(7),this.version="1",this.s3dbVersion=(()=>{const[e,t,r]=ve(()=>"8.1.0");return e?r:"latest"})(),this.resources={},this.savedMetadata=null,this.options=e,this.verbose=e.verbose||!1,this.parallelism=parseInt(e.parallelism+"")||10,this.plugins=e.plugins||[],this.pluginList=e.plugins||[],this.cache=e.cache,this.passphrase=e.passphrase||"secret",this.versioningEnabled=e.versioningEnabled||!1,this.persistHooks=e.persistHooks||!1,this._initHooks();let t=e.connectionString;if(!t&&(e.bucket||e.accessKeyId||e.secretAccessKey)){const{bucket:r,region:i,accessKeyId:s,secretAccessKey:n,endpoint:o,forcePathStyle:a}=e;if(o){const e=new URL(o);s&&(e.username=encodeURIComponent(s)),n&&(e.password=encodeURIComponent(n)),e.pathname=`/${r||"s3db"}`,a&&e.searchParams.set("forcePathStyle","true"),t=e.toString()}else if(s&&n){const e=new URLSearchParams;e.set("region",i||"us-east-1"),a&&e.set("forcePathStyle","true"),t=`s3://${encodeURIComponent(s)}:${encodeURIComponent(n)}@${r||"s3db"}?${e.toString()}`}}this.client=e.client||new Hi({verbose:this.verbose,parallelism:this.parallelism,connectionString:t}),this.bucket=this.client.bucket,this.keyPrefix=this.client.keyPrefix,this._exitListenerRegistered||(this._exitListenerRegistered=!0,"undefined"!=typeof process&&process.on("exit",async()=>{if(this.isConnected())try{await this.disconnect()}catch(e){}}))}async connect(){await this.startPlugins();let e=null,t=!1,r=[];if(await this.client.exists("s3db.json"))try{const i=await this.client.getObject("s3db.json"),s=await xi(i?.Body);try{e=JSON.parse(s)}catch(i){r.push("JSON parsing failed - attempting recovery"),t=!0,e=await this._attemptJsonRecovery(s,r),e||(await this._createCorruptedBackup(s),r.push("Created backup of corrupted file - starting with blank metadata"),e=this.blankMetadataStructure())}const n=await this._validateAndHealMetadata(e,r);n!==e&&(e=n,t=!0)}catch(i){r.push(`Critical error reading s3db.json: ${i.message}`),await this._createCorruptedBackup(),e=this.blankMetadataStructure(),t=!0}else e=this.blankMetadataStructure(),await this.uploadMetadataFile();t&&await this._uploadHealedMetadata(e,r),this.savedMetadata=e;const i=this.detectDefinitionChanges(e);for(const[t,r]of Object.entries(e.resources||{})){const e=r.currentVersion||"v0",i=r.versions?.[e];if(i){let s,n;void 0!==i.idGenerator?"custom_function"===i.idGenerator?(s=void 0,n=i.idSize||22):"number"==typeof i.idGenerator&&(s=i.idGenerator,n=i.idSize||i.idGenerator):n=i.idSize||22,this.resources[t]=new bs({name:t,client:this.client,database:this,version:e,attributes:i.attributes,behavior:i.behavior||"user-managed",parallelism:this.parallelism,passphrase:this.passphrase,observers:[this],cache:this.cache,timestamps:void 0!==i.timestamps&&i.timestamps,partitions:r.partitions||i.partitions||{},paranoid:void 0===i.paranoid||i.paranoid,allNestedObjectsOptional:void 0===i.allNestedObjectsOptional||i.allNestedObjectsOptional,autoDecrypt:void 0===i.autoDecrypt||i.autoDecrypt,hooks:this.persistHooks?this._deserializeHooks(i.hooks||{}):i.hooks||{},versioningEnabled:this.versioningEnabled,map:i.map,idGenerator:s,idSize:n})}}i.length>0&&this.emit("resourceDefinitionsChanged",{changes:i,metadata:this.savedMetadata}),this.emit("connected",new Date)}detectDefinitionChanges(e){const t=[];for(const[r,i]of Object.entries(this.resources)){const s=this.generateDefinitionHash(i.export()),n=e.resources?.[r];if(n){const e=n.currentVersion||"v0",i=n.versions?.[e],o=i?.hash;o!==s&&t.push({type:"changed",resourceName:r,currentHash:s,savedHash:o,fromVersion:e,toVersion:this.getNextVersion(n.versions)})}else t.push({type:"new",resourceName:r,currentHash:s,savedHash:null})}for(const[r,i]of Object.entries(e.resources||{}))if(!this.resources[r]){const e=i.currentVersion||"v0",s=i.versions?.[e];t.push({type:"deleted",resourceName:r,currentHash:null,savedHash:s?.hash,deletedVersion:e})}return t}generateDefinitionHash(e,t=void 0){const r={...e.attributes};e.timestamps&&(delete r.createdAt,delete r.updatedAt);const i={attributes:r,behavior:t||e.behavior||"user-managed",partitions:e.partitions||{}},s=O(i);return`sha256:${f("sha256").update(s).digest("hex")}`}getNextVersion(e={}){const t=Object.keys(e).filter(e=>e.startsWith("v")).map(e=>parseInt(e.substring(1))).filter(e=>!isNaN(e));return`v${(t.length>0?Math.max(...t):-1)+1}`}_serializeHooks(e){if(!e||"object"!=typeof e)return e;const t={};for(const[r,i]of Object.entries(e))Array.isArray(i)?t[r]=i.map(e=>{if("function"==typeof e)try{return{__s3db_serialized_function:!0,code:e.toString(),name:e.name||"anonymous"}}catch(e){return this.verbose&&console.warn(`Failed to serialize hook for event '${r}':`,e.message),null}return e}):t[r]=i;return t}_deserializeHooks(e){if(!e||"object"!=typeof e)return e;const t={};for(const[r,i]of Object.entries(e))Array.isArray(i)?t[r]=i.map(e=>{if(e&&"object"==typeof e&&e.__s3db_serialized_function){try{const t=new Function("return "+e.code)();if("function"==typeof t)return t}catch(t){this.verbose&&console.warn(`Failed to deserialize hook '${e.name}' for event '${r}':`,t.message)}return null}return e}).filter(e=>null!==e):t[r]=i;return t}async startPlugins(){const e=this;if(!g(this.pluginList)){const t=this.pluginList.map(e=>S(e)?new e(this):e),r=t.map(async t=>{t.beforeSetup&&await t.beforeSetup(),await t.setup(e),t.afterSetup&&await t.afterSetup()});await Promise.all(r);const i=t.map(async e=>{e.beforeStart&&await e.beforeStart(),await e.start(),e.afterStart&&await e.afterStart()});await Promise.all(i)}}async usePlugin(e,t=null){const r=t||e.constructor.name.replace("Plugin","").toLowerCase();return this.plugins[r]=e,this.isConnected()&&(await e.setup(this),await e.start()),e}async uploadMetadataFile(){const e={version:this.version,s3dbVersion:this.s3dbVersion,lastUpdated:(new Date).toISOString(),resources:{}};Object.entries(this.resources).forEach(([t,r])=>{const i=r.export(),s=this.generateDefinitionHash(i),n=this.savedMetadata?.resources?.[t],o=n?.currentVersion||"v0",a=n?.versions?.[o];let c,u;a&&a.hash===s?(c=o,u=!1):(c=this.getNextVersion(n?.versions),u=!0),e.resources[t]={currentVersion:c,partitions:r.config.partitions||{},versions:{...n?.versions,[c]:{hash:s,attributes:i.attributes,behavior:i.behavior||"user-managed",timestamps:r.config.timestamps,partitions:r.config.partitions,paranoid:r.config.paranoid,allNestedObjectsOptional:r.config.allNestedObjectsOptional,autoDecrypt:r.config.autoDecrypt,cache:r.config.cache,hooks:this.persistHooks?this._serializeHooks(r.config.hooks):r.config.hooks,idSize:r.idSize,idGenerator:r.idGeneratorType,createdAt:u?(new Date).toISOString():a?.createdAt}}},r.version!==c&&(r.version=c,r.emit("versionUpdated",{oldVersion:o,newVersion:c}))}),await this.client.putObject({key:"s3db.json",body:JSON.stringify(e,null,2),contentType:"application/json"}),this.savedMetadata=e,this.emit("metadataUploaded",e)}blankMetadataStructure(){return{version:"1",s3dbVersion:this.s3dbVersion,lastUpdated:(new Date).toISOString(),resources:{}}}async _attemptJsonRecovery(e,t){if(!e||"string"!=typeof e)return t.push("Content is empty or not a string"),null;const r=[()=>e.replace(/,(\s*[}\]])/g,"$1"),()=>e.replace(/([{,]\s*)([a-zA-Z_$][a-zA-Z0-9_$]*)\s*:/g,'$1"$2":'),()=>{let t=0,r=0,i=!1,s=!1;for(let n=0;n<e.length;n++){const o=e[n];s?s=!1:"\\"!==o?'"'!==o?i||("{"===o?t++:"}"===o?t--:"["===o?r++:"]"===o&&r--):i=!i:s=!0}let n=e;for(;r>0;)n+="]",r--;for(;t>0;)n+="}",t--;return n}];for(const[e,i]of r.entries())try{const r=i(),s=JSON.parse(r);return t.push(`JSON recovery successful using fix #${e+1}`),s}catch(e){}return t.push("All JSON recovery attempts failed"),null}async _validateAndHealMetadata(e,t){if(!e||"object"!=typeof e)return t.push("Metadata is not an object - using blank structure"),this.blankMetadataStructure();let r={...e},i=!1;r.version&&"string"==typeof r.version||(r.version&&"number"==typeof r.version?(r.version=String(r.version),t.push("Converted version from number to string"),i=!0):(r.version="1",t.push("Added missing or invalid version field"),i=!0)),r.s3dbVersion&&"string"==typeof r.s3dbVersion||(r.s3dbVersion&&"string"!=typeof r.s3dbVersion?(r.s3dbVersion=String(r.s3dbVersion),t.push("Converted s3dbVersion to string"),i=!0):(r.s3dbVersion=this.s3dbVersion,t.push("Added missing s3dbVersion field"),i=!0)),r.resources&&"object"==typeof r.resources&&!Array.isArray(r.resources)||(r.resources={},t.push("Fixed invalid resources field"),i=!0),r.lastUpdated||(r.lastUpdated=(new Date).toISOString(),t.push("Added missing lastUpdated field"),i=!0);const s={};for(const[e,n]of Object.entries(r.resources)){const r=this._healResourceStructure(e,n,t);r?(s[e]=r,r!==n&&(i=!0)):(t.push(`Removed invalid resource: ${e}`),i=!0)}return r.resources=s,i?r:e}_healResourceStructure(e,t,r){if(!t||"object"!=typeof t)return r.push(`Resource ${e}: invalid structure`),null;let i={...t},s=!1;i.currentVersion||(i.currentVersion="v0",r.push(`Resource ${e}: added missing currentVersion`),s=!0),i.versions&&"object"==typeof i.versions&&!Array.isArray(i.versions)||(i.versions={},r.push(`Resource ${e}: fixed invalid versions object`),s=!0),i.partitions&&"object"==typeof i.partitions&&!Array.isArray(i.partitions)||(i.partitions={},r.push(`Resource ${e}: fixed invalid partitions object`),s=!0);const n=i.currentVersion;if(!i.versions[n]){const t=Object.keys(i.versions);if(!(t.length>0))return r.push(`Resource ${e}: no valid versions found - removing resource`),null;i.currentVersion=t[0],r.push(`Resource ${e}: changed currentVersion from ${n} to ${i.currentVersion}`),s=!0}const o=i.versions[i.currentVersion];if(!o||"object"!=typeof o)return r.push(`Resource ${e}: invalid version data - removing resource`),null;if(!o.attributes||"object"!=typeof o.attributes)return r.push(`Resource ${e}: missing or invalid attributes - removing resource`),null;if(o.hooks){const t=this._healHooksStructure(o.hooks,e,r);t!==o.hooks&&(i.versions[i.currentVersion].hooks=t,s=!0)}return s?i:t}_healHooksStructure(e,t,r){if(!e||"object"!=typeof e)return r.push(`Resource ${t}: invalid hooks structure - using empty hooks`),{};const i={};let s=!1;for(const[n,o]of Object.entries(e))if(Array.isArray(o)){const e=o.filter(e=>null!=e&&""!==e);i[n]=e,e.length!==o.length&&(r.push(`Resource ${t}: cleaned invalid hooks for event ${n}`),s=!0)}else r.push(`Resource ${t}: hooks for event ${n} is not an array - removing`),s=!0;return s?i:e}async _createCorruptedBackup(e=null){try{const t=`s3db.json.corrupted.${(new Date).toISOString().replace(/[:.]/g,"-")}.backup`;if(!e)try{const t=await this.client.getObject("s3db.json");e=await xi(t?.Body)}catch(t){e="Unable to read corrupted file content"}await this.client.putObject({key:t,body:e,contentType:"application/json"}),this.verbose&&console.warn(`S3DB: Created backup of corrupted s3db.json as ${t}`)}catch(e){this.verbose&&console.warn(`S3DB: Failed to create backup: ${e.message}`)}}async _uploadHealedMetadata(e,t){try{this.verbose&&t.length>0&&(console.warn("S3DB Self-Healing Operations:"),t.forEach(e=>console.warn(` - ${e}`))),e.lastUpdated=(new Date).toISOString(),await this.client.putObject({key:"s3db.json",body:JSON.stringify(e,null,2),contentType:"application/json"}),this.emit("metadataHealed",{healingLog:t,metadata:e}),this.verbose&&console.warn("S3DB: Successfully uploaded healed metadata")}catch(e){throw this.verbose&&console.error(`S3DB: Failed to upload healed metadata: ${e.message}`),e}}resourceExists(e){return!!this.resources[e]}resourceExistsWithSameHash({name:e,attributes:t,behavior:r="user-managed",partitions:i={},options:s={}}){if(!this.resources[e])return{exists:!1,sameHash:!1,hash:null};const n=this.resources[e],o=this.generateDefinitionHash(n.export()),a=new bs({name:e,attributes:t,behavior:r,partitions:i,client:this.client,version:n.version,passphrase:this.passphrase,versioningEnabled:this.versioningEnabled,...s}),c=this.generateDefinitionHash(a.export());return{exists:!0,sameHash:o===c,hash:c,existingHash:o}}async createResource({name:e,attributes:t,behavior:r="user-managed",hooks:i,...s}){if(this.resources[e]){const n=this.resources[e];if(Object.assign(n.config,{cache:this.cache,...s}),r&&(n.behavior=r),n.versioningEnabled=this.versioningEnabled,n.updateAttributes(t),i)for(const[e,t]of Object.entries(i))if(Array.isArray(t)&&n.hooks[e])for(const r of t)"function"==typeof r&&n.hooks[e].push(r.bind(n));const o=this.generateDefinitionHash(n.export(),n.behavior),a=this.savedMetadata?.resources?.[e],c=a?.currentVersion||"v0",u=a?.versions?.[c];return u&&u.hash===o||await this.uploadMetadataFile(),this.emit("s3db.resourceUpdated",e),n}const n=this.savedMetadata?.resources?.[e],o=n?.currentVersion||"v0",a=new bs({name:e,client:this.client,version:void 0!==s.version?s.version:o,attributes:t,behavior:r,parallelism:this.parallelism,passphrase:void 0!==s.passphrase?s.passphrase:this.passphrase,observers:[this],cache:void 0!==s.cache?s.cache:this.cache,timestamps:void 0!==s.timestamps&&s.timestamps,partitions:s.partitions||{},paranoid:void 0===s.paranoid||s.paranoid,allNestedObjectsOptional:void 0===s.allNestedObjectsOptional||s.allNestedObjectsOptional,autoDecrypt:void 0===s.autoDecrypt||s.autoDecrypt,hooks:i||{},versioningEnabled:this.versioningEnabled,map:s.map,idGenerator:s.idGenerator,idSize:s.idSize,events:s.events||{}});return a.database=this,this.resources[e]=a,await this.uploadMetadataFile(),this.emit("s3db.resourceCreated",e),a}resource(e){return this.resources[e]?this.resources[e]:Promise.reject(`resource ${e} does not exist`)}async listResources(){return Object.keys(this.resources).map(e=>({name:e}))}async getResource(e){if(!this.resources[e])throw new se({bucket:this.client.config.bucket,resourceName:e,id:e});return this.resources[e]}get config(){return{version:this.version,s3dbVersion:this.s3dbVersion,bucket:this.bucket,keyPrefix:this.keyPrefix,parallelism:this.parallelism,verbose:this.verbose}}isConnected(){return!!this.savedMetadata}async disconnect(){try{if(this.pluginList&&this.pluginList.length>0){for(const e of this.pluginList)e&&"function"==typeof e.removeAllListeners&&e.removeAllListeners();const e=this.pluginList.map(async e=>{try{e&&"function"==typeof e.stop&&await e.stop()}catch(e){}});await Promise.all(e)}if(this.resources&&Object.keys(this.resources).length>0){for(const[e,t]of Object.entries(this.resources))try{t&&"function"==typeof t.removeAllListeners&&t.removeAllListeners(),t._pluginWrappers&&t._pluginWrappers.clear(),t._pluginMiddlewares&&(t._pluginMiddlewares={}),t.observers&&Array.isArray(t.observers)&&(t.observers=[])}catch(e){}Object.keys(this.resources).forEach(e=>delete this.resources[e])}this.client&&"function"==typeof this.client.removeAllListeners&&this.client.removeAllListeners(),this.removeAllListeners(),this.savedMetadata=null,this.plugins={},this.pluginList=[],this.emit("disconnected",new Date)}catch(e){}}_initHooks(){this._hooks=new Map,this._hookEvents=["beforeConnect","afterConnect","beforeCreateResource","afterCreateResource","beforeUploadMetadata","afterUploadMetadata","beforeDisconnect","afterDisconnect","resourceCreated","resourceUpdated"];for(const e of this._hookEvents)this._hooks.set(e,[]);this._wrapHookableMethods()}_wrapHookableMethods(){this._hooksInstalled||(this._originalConnect=this.connect.bind(this),this._originalCreateResource=this.createResource.bind(this),this._originalUploadMetadataFile=this.uploadMetadataFile.bind(this),this._originalDisconnect=this.disconnect.bind(this),this.connect=async(...e)=>{await this._executeHooks("beforeConnect",{args:e});const t=await this._originalConnect(...e);return await this._executeHooks("afterConnect",{result:t,args:e}),t},this.createResource=async e=>{await this._executeHooks("beforeCreateResource",{config:e});const t=await this._originalCreateResource(e);return await this._executeHooks("afterCreateResource",{resource:t,config:e}),t},this.uploadMetadataFile=async(...e)=>{await this._executeHooks("beforeUploadMetadata",{args:e});const t=await this._originalUploadMetadataFile(...e);return await this._executeHooks("afterUploadMetadata",{result:t,args:e}),t},this.disconnect=async(...e)=>{await this._executeHooks("beforeDisconnect",{args:e});const t=await this._originalDisconnect(...e);return await this._executeHooks("afterDisconnect",{result:t,args:e}),t},this._hooksInstalled=!0)}addHook(e,t){if(this._hooks||this._initHooks(),!this._hooks.has(e))throw new Error(`Unknown hook event: ${e}. Available events: ${this._hookEvents.join(", ")}`);if("function"!=typeof t)throw new Error("Hook function must be a function");this._hooks.get(e).push(t)}async _executeHooks(e,t={}){if(!this._hooks||!this._hooks.has(e))return;const r=this._hooks.get(e);for(const i of r)try{await i({database:this,...t})}catch(r){this.emit("hookError",{event:e,error:r,context:t})}}removeHook(e,t){if(!this._hooks||!this._hooks.has(e))return;const r=this._hooks.get(e),i=r.indexOf(t);i>-1&&r.splice(i,1)}getHooks(e){return this._hooks&&this._hooks.has(e)?[...this._hooks.get(e)]:[]}clearHooks(e){this._hooks&&this._hooks.has(e)&&(this._hooks.get(e).length=0)}}class vs extends ws{}function ks(e){return"string"==typeof e?e.trim().toLowerCase():e}var _s=class extends Mi{constructor(e={},t=[],r=null){super(e),this.instanceId=Math.random().toString(36).slice(2,10),this.client=r,this.connectionString=e.connectionString;let i=t;if(t)if(Array.isArray(t)){i={};for(const e of t)"string"==typeof e&&(i[ks(e)]=e)}else"string"==typeof t&&(i[ks(t)]=t);else i={};this.resourcesMap=this._normalizeResources(i)}_normalizeResources(e){if(!e)return{};if(Array.isArray(e)){const t={};for(const r of e)"string"==typeof r?t[ks(r)]=r:"object"==typeof r&&r.resource&&(t[ks(r.resource)]=r);return t}if("object"==typeof e){const t={};for(const[r,i]of Object.entries(e)){const e=ks(r);"string"==typeof i?t[e]=i:Array.isArray(i)?t[e]=i.map(e=>("string"==typeof e||"object"==typeof e&&e.resource,e)):("function"==typeof i||"object"==typeof i&&i.resource)&&(t[e]=i)}return t}return"function"==typeof e?e:{}}validateConfig(){const e=[];return this.client||this.connectionString||e.push("You must provide a client or a connectionString"),(!this.resourcesMap||"object"==typeof this.resourcesMap&&0===Object.keys(this.resourcesMap).length)&&e.push("You must provide a resources map or array"),{isValid:0===e.length,errors:e}}async initialize(e){await super.initialize(e);const[t,r]=await ve(async()=>{if(this.client)this.targetDatabase=this.client;else{if(!this.connectionString)throw new Error("S3dbReplicator: No client or connectionString provided");{const e={connectionString:this.connectionString,region:this.region,keyPrefix:this.keyPrefix,verbose:this.config.verbose||!1};this.targetDatabase=new vs(e),await this.targetDatabase.connect()}}this.emit("connected",{replicator:this.name,target:this.connectionString||"client-provided"})});if(!t)throw this.config.verbose&&console.warn(`[S3dbReplicator] Initialization failed: ${r.message}`),r}async replicate(e,t,r,i,s){let n,o,a,c;"object"==typeof e&&e.resource?(n=e.resource,o=e.operation,a=e.data,c=e.id):(n=e,o=t,a=r,c=i);const u=ks(n),l=this.resourcesMap[u];if(!l)throw new Error(`[S3dbReplicator] Resource not configured: ${n}`);if(Array.isArray(l)){const e=[];for(const t of l){const[r,i,s]=await ve(async()=>await this._replicateToSingleDestination(t,u,o,a,c));if(!r)throw this.config&&this.config.verbose&&console.warn(`[S3dbReplicator] Failed to replicate to destination ${JSON.stringify(t)}: ${i.message}`),i;e.push(s)}return e}{const[e,t,r]=await ve(async()=>await this._replicateToSingleDestination(l,u,o,a,c));if(!e)throw this.config&&this.config.verbose&&console.warn(`[S3dbReplicator] Failed to replicate to destination ${JSON.stringify(l)}: ${t.message}`),t;return r}}async _replicateToSingleDestination(e,t,r,i,s){let n;if(n="string"==typeof e?e:"object"==typeof e&&e.resource?e.resource:t,"object"==typeof e&&e.actions&&Array.isArray(e.actions)&&!e.actions.includes(r))return{skipped:!0,reason:"action_not_supported",action:r,destination:n};const o=this._getDestResourceObj(n);let a,c;if("object"==typeof e&&e.transform&&"function"==typeof e.transform?(a=e.transform(i),a&&i&&i.id&&!a.id&&(a.id=i.id)):"object"==typeof e&&e.transformer&&"function"==typeof e.transformer?(a=e.transformer(i),a&&i&&i.id&&!a.id&&(a.id=i.id)):a=i,!a&&i&&(a=i),"insert"===r)c=await o.insert(a);else if("update"===r)c=await o.update(s,a);else{if("delete"!==r)throw new Error(`Invalid operation: ${r}. Supported operations are: insert, update, delete`);c=await o.delete(s)}return c}_applyTransformer(e,t){let r=this._cleanInternalFields(t);const i=ks(e),s=this.resourcesMap[i];let n;if(!s)return r;if(Array.isArray(s)){for(const e of s){if("object"==typeof e&&e.transform&&"function"==typeof e.transform){n=e.transform(r);break}if("object"==typeof e&&e.transformer&&"function"==typeof e.transformer){n=e.transformer(r);break}}n||(n=r)}else"object"==typeof s?"function"==typeof s.transform?n=s.transform(r):"function"==typeof s.transformer&&(n=s.transformer(r)):n="function"==typeof s?s(r):r;return n&&r&&r.id&&!n.id&&(n.id=r.id),!n&&r&&(n=r),n}_cleanInternalFields(e){if(!e||"object"!=typeof e)return e;const t={...e};return Object.keys(t).forEach(e=>{(e.startsWith("$")||e.startsWith("_"))&&delete t[e]}),t}_resolveDestResource(e,t){const r=ks(e),i=this.resourcesMap[r];if(!i)return e;if(Array.isArray(i)){for(const e of i){if("string"==typeof e)return e;if("object"==typeof e&&e.resource)return e.resource}return e}return"string"==typeof i?i:"function"==typeof i?e:"object"==typeof i&&i.resource?i.resource:e}_getDestResourceObj(e){const t=Object.keys(this.client.resources||{}),r=ks(e),i=t.find(e=>ks(e)===r);if(!i)throw new Error(`[S3dbReplicator] Destination resource not found: ${e}. Available: ${t.join(", ")}`);return this.client.resources[i]}async replicateBatch(e,t){if(!this.enabled||!this.shouldReplicateResource(e))return{skipped:!0,reason:"resource_not_included"};const r=[],i=[];for(const s of t){const[t,n,o]=await ve(()=>this.replicate({resource:e,operation:s.operation,id:s.id,data:s.data,beforeData:s.beforeData}));t?r.push(o):(this.config.verbose&&console.warn(`[S3dbReplicator] Batch replication failed for record ${s.id}: ${n.message}`),i.push({id:s.id,error:n.message}))}return i.length>0&&console.warn(`[S3dbReplicator] Batch replication completed with ${i.length} error(s) for ${e}:`,i),this.emit("batch_replicated",{replicator:this.name,resourceName:e,total:t.length,successful:r.length,errors:i.length}),{success:0===i.length,results:r,errors:i,total:t.length}}async testConnection(){const[e,t]=await ve(async()=>{if(!this.targetDatabase)throw new Error("No target database configured");return"function"==typeof this.targetDatabase.connect&&await this.targetDatabase.connect(),!0});return!!e||(this.config.verbose&&console.warn(`[S3dbReplicator] Connection test failed: ${t.message}`),this.emit("connection_error",{replicator:this.name,error:t.message}),!1)}async getStatus(){return{...await super.getStatus(),connected:!!this.targetDatabase,targetDatabase:this.connectionString||"client-provided",resources:Object.keys(this.resourcesMap||{}),totalreplicators:this.listenerCount("replicated"),totalErrors:this.listenerCount("replicator_error")}}async cleanup(){this.targetDatabase&&this.targetDatabase.removeAllListeners(),await super.cleanup()}shouldReplicateResource(e,t){const r=ks(e),i=this.resourcesMap[r];if(!i)return!1;if(!t)return!0;if(Array.isArray(i)){for(const e of i)if("object"==typeof e&&e.resource){if(!e.actions||!Array.isArray(e.actions))return!0;if(e.actions.includes(t))return!0}else if("string"==typeof e)return!0;return!1}return"object"==typeof i&&i.resource?!i.actions||!Array.isArray(i.actions)||i.actions.includes(t):"string"==typeof i||"function"==typeof i}};const Ss={s3db:_s,sqs:class extends Mi{constructor(e={},t=[],r=null){if(super(e),this.client=r,this.queueUrl=e.queueUrl,this.queues=e.queues||{},this.defaultQueue=e.defaultQueue||e.defaultQueueUrl||e.queueUrlDefault,this.region=e.region||"us-east-1",this.sqsClient=r||null,this.messageGroupId=e.messageGroupId,this.deduplicationId=e.deduplicationId,Array.isArray(t)){this.resources={};for(const e of t)"string"==typeof e?this.resources[e]=!0:"object"==typeof e&&e.name&&(this.resources[e.name]=e)}else if("object"==typeof t){this.resources=t;for(const[e,r]of Object.entries(t))r&&r.queueUrl&&(this.queues[e]=r.queueUrl)}else this.resources={}}validateConfig(){const e=[];return this.queueUrl||0!==Object.keys(this.queues).length||this.defaultQueue||this.resourceQueueMap||e.push("Either queueUrl, queues object, defaultQueue, or resourceQueueMap must be provided"),{isValid:0===e.length,errors:e}}getQueueUrlsForResource(e){if(this.resourceQueueMap&&this.resourceQueueMap[e])return this.resourceQueueMap[e];if(this.queues[e])return[this.queues[e]];if(this.queueUrl)return[this.queueUrl];if(this.defaultQueue)return[this.defaultQueue];throw new Error(`No queue URL found for resource '${e}'`)}_applyTransformer(e,t){let r=this._cleanInternalFields(t);const i=this.resources[e];let s=r;return i?("function"==typeof i.transform?s=i.transform(r):"function"==typeof i.transformer&&(s=i.transformer(r)),s||r):r}_cleanInternalFields(e){if(!e||"object"!=typeof e)return e;const t={...e};return Object.keys(t).forEach(e=>{(e.startsWith("$")||e.startsWith("_"))&&delete t[e]}),t}createMessage(e,t,r,i,s=null){const n={resource:e,action:t,timestamp:(new Date).toISOString(),source:"s3db-replicator"};switch(t){case"insert":case"delete":default:return{...n,data:r};case"update":return{...n,before:s,data:r}}}async initialize(e,t){if(await super.initialize(e),!this.sqsClient){const[e,r,i]=await ve(()=>import("@aws-sdk/client-sqs"));if(!e)throw this.config.verbose&&console.warn(`[SqsReplicator] Failed to import SQS SDK: ${r.message}`),this.emit("initialization_error",{replicator:this.name,error:r.message}),r;const{SQSClient:s}=i;this.sqsClient=t||new s({region:this.region,credentials:this.config.credentials}),this.emit("initialized",{replicator:this.name,queueUrl:this.queueUrl,queues:this.queues,defaultQueue:this.defaultQueue})}}async replicate(e,t,r,i,s=null){if(!this.enabled||!this.shouldReplicateResource(e))return{skipped:!0,reason:"resource_not_included"};const[n,o,a]=await ve(async()=>{const{SendMessageCommand:n}=await import("@aws-sdk/client-sqs"),o=this.getQueueUrlsForResource(e),a=this._applyTransformer(e,r),c=this.createMessage(e,t,a,i,s),u=[];for(const r of o){const s=new n({QueueUrl:r,MessageBody:JSON.stringify(c),MessageGroupId:this.messageGroupId,MessageDeduplicationId:this.deduplicationId?`${e}:${t}:${i}`:void 0}),o=await this.sqsClient.send(s);u.push({queueUrl:r,messageId:o.MessageId}),this.emit("replicated",{replicator:this.name,resource:e,operation:t,id:i,queueUrl:r,messageId:o.MessageId,success:!0})}return{success:!0,results:u}});return n?a:(this.config.verbose&&console.warn(`[SqsReplicator] Replication failed for ${e}: ${o.message}`),this.emit("replicator_error",{replicator:this.name,resource:e,operation:t,id:i,error:o.message}),{success:!1,error:o.message})}async replicateBatch(e,t){if(!this.enabled||!this.shouldReplicateResource(e))return{skipped:!0,reason:"resource_not_included"};const[r,i,s]=await ve(async()=>{const{SendMessageBatchCommand:r}=await import("@aws-sdk/client-sqs"),i=this.getQueueUrlsForResource(e),s=[];for(let e=0;e<t.length;e+=10)s.push(t.slice(e,e+10));const n=[],o=[];for(const t of s){const[s,a]=await ve(async()=>{const s=t.map((t,r)=>({Id:`${t.id}-${r}`,MessageBody:JSON.stringify(this.createMessage(e,t.operation,t.data,t.id,t.beforeData)),MessageGroupId:this.messageGroupId,MessageDeduplicationId:this.deduplicationId?`${e}:${t.operation}:${t.id}`:void 0})),o=new r({QueueUrl:i[0],Entries:s}),a=await this.sqsClient.send(o);n.push(a)});if(!s&&(o.push({batch:t.length,error:a.message}),a.message&&(a.message.includes("Batch error")||a.message.includes("Connection")||a.message.includes("Network"))))throw a}return o.length>0&&console.warn(`[SqsReplicator] Batch replication completed with ${o.length} error(s) for ${e}:`,o),this.emit("batch_replicated",{replicator:this.name,resource:e,queueUrl:i[0],total:t.length,successful:n.length,errors:o.length}),{success:0===o.length,results:n,errors:o,total:t.length,queueUrl:i[0]}});if(r)return s;const n=i?.message||i||"Unknown error";return this.config.verbose&&console.warn(`[SqsReplicator] Batch replication failed for ${e}: ${n}`),this.emit("batch_replicator_error",{replicator:this.name,resource:e,error:n}),{success:!1,error:n}}async testConnection(){const[e,t]=await ve(async()=>{this.sqsClient||await this.initialize(this.database);const{GetQueueAttributesCommand:e}=await import("@aws-sdk/client-sqs"),t=new e({QueueUrl:this.queueUrl,AttributeNames:["QueueArn"]});return await this.sqsClient.send(t),!0});return!!e||(this.config.verbose&&console.warn(`[SqsReplicator] Connection test failed: ${t.message}`),this.emit("connection_error",{replicator:this.name,error:t.message}),!1)}async getStatus(){return{...await super.getStatus(),connected:!!this.sqsClient,queueUrl:this.queueUrl,region:this.region,resources:Object.keys(this.resources||{}),totalreplicators:this.listenerCount("replicated"),totalErrors:this.listenerCount("replicator_error")}}async cleanup(){this.sqsClient&&this.sqsClient.destroy(),await super.cleanup()}shouldReplicateResource(e){return this.resourceQueueMap&&Object.keys(this.resourceQueueMap).includes(e)||this.queues&&Object.keys(this.queues).includes(e)||!(!this.defaultQueue&&!this.queueUrl)||this.resources&&Object.keys(this.resources).includes(e)||!1}},bigquery:Li,postgres:Ui};function Os(e){return"string"==typeof e?e.trim().toLowerCase():e}class Rs extends Me{constructor(e={}){if(super(),!e.replicators||!Array.isArray(e.replicators))throw new Error("ReplicatorPlugin: replicators array is required");for(const t of e.replicators){if(!t.driver)throw new Error("ReplicatorPlugin: each replicator must have a driver");if(!t.resources||"object"!=typeof t.resources)throw new Error("ReplicatorPlugin: each replicator must have resources config");if(0===Object.keys(t.resources).length)throw new Error("ReplicatorPlugin: each replicator must have at least one resource configured")}this.config={replicators:e.replicators||[],logErrors:!1!==e.logErrors,replicatorLogResource:e.replicatorLogResource||"replicator_log",enabled:!1!==e.enabled,batchSize:e.batchSize||100,maxRetries:e.maxRetries||3,timeout:e.timeout||3e4,verbose:e.verbose||!1,...e},this.replicators=[],this.database=null,this.eventListenersInstalled=new Set}async decompressData(e){return e}filterInternalFields(e){if(!e||"object"!=typeof e)return e;const t={};for(const[r,i]of Object.entries(e))r.startsWith("_")||"$overflow"===r||"$before"===r||"$after"===r||(t[r]=i);return t}async getCompleteData(e,t){const[r,i,s]=await ve(()=>e.get(t.id));return r?s:t}installEventListeners(e,t,r){e&&!this.eventListenersInstalled.has(e.name)&&e.name!==this.config.replicatorLogResource&&(e.on("insert",async t=>{const[i,s]=await ve(async()=>{const i={...t,createdAt:(new Date).toISOString()};await r.processReplicatorEvent("insert",e.name,i.id,i)});i||(this.config.verbose&&console.warn(`[ReplicatorPlugin] Insert event failed for resource ${e.name}: ${s.message}`),this.emit("error",{operation:"insert",error:s.message,resource:e.name}))}),e.on("update",async(t,i)=>{const[s,n]=await ve(async()=>{const s=await r.getCompleteData(e,t),n={...s,updatedAt:(new Date).toISOString()};await r.processReplicatorEvent("update",e.name,s.id,n,i)});s||(this.config.verbose&&console.warn(`[ReplicatorPlugin] Update event failed for resource ${e.name}: ${n.message}`),this.emit("error",{operation:"update",error:n.message,resource:e.name}))}),e.on("delete",async t=>{const[i,s]=await ve(async()=>{await r.processReplicatorEvent("delete",e.name,t.id,t)});i||(this.config.verbose&&console.warn(`[ReplicatorPlugin] Delete event failed for resource ${e.name}: ${s.message}`),this.emit("error",{operation:"delete",error:s.message,resource:e.name}))}),this.eventListenersInstalled.add(e.name))}async setup(e){if(this.database=e,this.config.persistReplicatorLog){const[t,r,i]=await ve(()=>e.createResource({name:this.config.replicatorLogResource||"replicator_logs",attributes:{id:"string|required",resource:"string|required",action:"string|required",data:"json",timestamp:"number|required",createdAt:"string|required"},behavior:"truncate-data"}));this.replicatorLogResource=t?i:e.resources[this.config.replicatorLogResource||"replicator_logs"]}await this.initializeReplicators(e),this.installDatabaseHooks();for(const t of Object.values(e.resources))t.name!==(this.config.replicatorLogResource||"replicator_logs")&&this.installEventListeners(t,e,this)}async start(){}async stop(){for(const e of this.replicators||[])e&&"function"==typeof e.cleanup&&await e.cleanup();this.removeDatabaseHooks()}installDatabaseHooks(){this.database.addHook("afterCreateResource",e=>{e.name!==(this.config.replicatorLogResource||"replicator_logs")&&this.installEventListeners(e,this.database,this)})}removeDatabaseHooks(){this.database.removeHook("afterCreateResource",this.installEventListeners.bind(this))}createReplicator(e,t,r,i){return function(e,t={},r=[],i=null){const s=Ss[e];if(!s)throw new Error(`Unknown replicator driver: ${e}. Available drivers: ${Object.keys(Ss).join(", ")}`);return new s(t,r,i)}(e,t,r,i)}async initializeReplicators(e){for(const t of this.config.replicators){const{driver:r,config:i={},resources:s,client:n,...o}=t,a=s||i.resources||{},c={...i,...o},u=this.createReplicator(r,c,a,n);u&&(await u.initialize(e),this.replicators.push(u))}}async uploadMetadataFile(e){"function"==typeof e.uploadMetadataFile&&await e.uploadMetadataFile()}async retryWithBackoff(e,t=3){let r;for(let i=1;i<=t;i++){const[s,n]=await ve(e);if(s)return s;{if(r=n,this.config.verbose&&console.warn(`[ReplicatorPlugin] Retry attempt ${i}/${t} failed: ${n.message}`),i===t)throw n;const e=1e3*Math.pow(2,i-1);this.config.verbose&&console.warn(`[ReplicatorPlugin] Waiting ${e}ms before retry...`),await new Promise(t=>setTimeout(t,e))}}throw r}async logError(e,t,r,i,s,n){const[o,a]=await ve(async()=>{const o=this.config.replicatorLogResource;if(this.database&&this.database.resources&&this.database.resources[o]){const a=this.database.resources[o];await a.insert({replicator:e.name||e.id,resourceName:t,operation:r,recordId:i,data:JSON.stringify(s),error:n.message,timestamp:(new Date).toISOString(),status:"error"})}});o||(this.config.verbose&&console.warn(`[ReplicatorPlugin] Failed to log error for ${t}: ${a.message}`),this.emit("replicator_log_error",{replicator:e.name||e.id,resourceName:t,operation:r,recordId:i,originalError:n.message,logError:a.message}))}async processReplicatorEvent(e,t,r,i,s=null){if(!this.config.enabled)return;const n=this.replicators.filter(r=>r.shouldReplicateResource&&r.shouldReplicateResource(t,e));if(0===n.length)return;const o=n.map(async n=>{const[o,a,c]=await ve(async()=>{const o=await this.retryWithBackoff(()=>n.replicate(t,e,i,r,s),this.config.maxRetries);return this.emit("replicated",{replicator:n.name||n.id,resourceName:t,operation:e,recordId:r,result:o,success:!0}),o});if(o)return c;throw this.config.verbose&&console.warn(`[ReplicatorPlugin] Replication failed for ${n.name||n.id} on ${t}: ${a.message}`),this.emit("replicator_error",{replicator:n.name||n.id,resourceName:t,operation:e,recordId:r,error:a.message}),this.config.logErrors&&this.database&&await this.logError(n,t,e,r,i,a),a});return Promise.allSettled(o)}async processreplicatorItem(e){const t=this.replicators.filter(t=>t.shouldReplicateResource&&t.shouldReplicateResource(e.resourceName,e.operation));if(0===t.length)return;const r=t.map(async t=>{const[r,i]=await ve(async()=>{const[r,i,s]=await ve(()=>t.replicate(e.resourceName,e.operation,e.data,e.recordId,e.beforeData));return r?(this.emit("replicated",{replicator:t.name||t.id,resourceName:e.resourceName,operation:e.operation,recordId:e.recordId,result:s,success:!0}),{success:!0,result:s}):(this.config.verbose&&console.warn(`[ReplicatorPlugin] Replicator item processing failed for ${t.name||t.id} on ${e.resourceName}: ${i.message}`),this.emit("replicator_error",{replicator:t.name||t.id,resourceName:e.resourceName,operation:e.operation,recordId:e.recordId,error:i.message}),this.config.logErrors&&this.database&&await this.logError(t,e.resourceName,e.operation,e.recordId,e.data,i),{success:!1,error:i.message})});return r||(this.config.verbose&&console.warn(`[ReplicatorPlugin] Wrapper processing failed for ${t.name||t.id} on ${e.resourceName}: ${i.message}`),this.emit("replicator_error",{replicator:t.name||t.id,resourceName:e.resourceName,operation:e.operation,recordId:e.recordId,error:i.message}),this.config.logErrors&&this.database&&await this.logError(t,e.resourceName,e.operation,e.recordId,e.data,i),{success:!1,error:i.message})});return Promise.allSettled(r)}async logreplicator(e){const t=this.replicatorLog||this.database.resources[Os(this.config.replicatorLogResource)];if(!t)return this.database&&this.database.options&&this.database.options.connectionString,void this.emit("replicator.log.failed",{error:"replicator log resource not found",item:e});const r={id:e.id||`repl-${Date.now()}-${Math.random().toString(36).slice(2)}`,resource:e.resource||e.resourceName||"",action:e.operation||e.action||"",data:e.data||{},timestamp:"number"==typeof e.timestamp?e.timestamp:Date.now(),createdAt:e.createdAt||(new Date).toISOString().slice(0,10)},[i,s]=await ve(async()=>{await t.insert(r)});i||(this.config.verbose&&console.warn(`[ReplicatorPlugin] Failed to log replicator item: ${s.message}`),this.emit("replicator.log.failed",{error:s,item:e}))}async updatereplicatorLog(e,t){if(!this.replicatorLog)return;const[r,i]=await ve(async()=>{await this.replicatorLog.update(e,{...t,lastAttempt:(new Date).toISOString()})});r||this.emit("replicator.updateLog.failed",{error:i.message,logId:e,updates:t})}async getreplicatorStats(){return{replicators:await Promise.all(this.replicators.map(async e=>{const t=await e.getStatus();return{id:e.id,driver:e.driver,config:e.config,status:t}})),queue:{length:this.queue.length,isProcessing:this.isProcessing},stats:this.stats,lastSync:this.stats.lastSync}}async getreplicatorLogs(e={}){if(!this.replicatorLog)return[];const{resourceName:t,operation:r,status:i,limit:s=100,offset:n=0}=e;let o={};t&&(o.resourceName=t),r&&(o.operation=r),i&&(o.status=i);return(await this.replicatorLog.list(o)).slice(n,n+s)}async retryFailedreplicators(){if(!this.replicatorLog)return{retried:0};const e=await this.replicatorLog.list({status:"failed"});let t=0;for(const r of e){const[e,i]=await ve(async()=>{await this.processReplicatorEvent(r.resourceName,r.operation,r.recordId,r.data)});e&&t++}return{retried:t}}async syncAllData(e){const t=this.replicators.find(t=>t.id===e);if(!t)throw new Error(`Replicator not found: ${e}`);this.stats.lastSync=(new Date).toISOString();for(const r in this.database.resources)if(Os(r)!==Os("replicator_logs")&&t.shouldReplicateResource(r)){this.emit("replicator.sync.resource",{resourceName:r,replicatorId:e});const i=this.database.resources[r],s=await i.getAll();for(const e of s)await t.replicate(r,"insert",e,e.id)}this.emit("replicator.sync.completed",{replicatorId:e,stats:this.stats})}async cleanup(){const[e,t]=await ve(async()=>{if(this.replicators&&this.replicators.length>0){const e=this.replicators.map(async e=>{const[t,r]=await ve(async()=>{e&&"function"==typeof e.cleanup&&await e.cleanup()});t||(this.config.verbose&&console.warn(`[ReplicatorPlugin] Failed to cleanup replicator ${e.name||e.id}: ${r.message}`),this.emit("replicator_cleanup_error",{replicator:e.name||e.id||"unknown",driver:e.driver||"unknown",error:r.message}))});await Promise.allSettled(e)}this.replicators=[],this.database=null,this.eventListenersInstalled.clear(),this.removeAllListeners()});e||(this.config.verbose&&console.warn(`[ReplicatorPlugin] Failed to cleanup plugin: ${t.message}`),this.emit("replicator_plugin_cleanup_error",{error:t.message}))}}export{ms as AVAILABLE_BEHAVIORS,Ue as AuditPlugin,te as AuthenticationError,Q as BaseError,Ni as CachePlugin,zi as Client,Bi as ConnectionString,de as ConnectionStringError,Ii as CostsPlugin,pe as CryptoError,gs as DEFAULT_BEHAVIOR,ws as Database,X as DatabaseError,ie as EncryptionError,he as ErrorMap,Pi as FullTextPlugin,ue as InvalidResourceItem,Ti as MetricsPlugin,ce as MissingMetadata,ne as NoSuchBucket,oe as NoSuchKey,ae as NotFound,ye as PartitionError,re as PermissionError,Me as Plugin,Le as PluginObject,Rs as ReplicatorPlugin,ys as Resource,ge as ResourceError,Oi as ResourceIdsPageReader,_i as ResourceIdsReader,se as ResourceNotFound,Ri as ResourceReader,ji as ResourceWriter,ws as S3db,Z as S3dbError,Yi as Schema,me as SchemaError,le as UnknownError,ee as ValidationError,Wi as Validator,ds as behaviors,H as calculateAttributeNamesSize,K as calculateAttributeSizes,Y as calculateEffectiveLimit,G as calculateSystemOverhead,W as calculateTotalSize,z as calculateUTF8Bytes,F as decode,B as decodeDecimal,Oe as decrypt,vs as default,U as encode,q as encodeDecimal,Se as encrypt,ps as getBehavior,J as getSizeBreakdown,xe as idGenerator,fe as mapAwsError,Re as md5,Ee as passwordGenerator,_e as sha256,xi as streamToString,V as transformValue,be as tryFn,we as tryFnSync};
|
|
1
|
+
import{customAlphabet as e,urlAlphabet as t}from"nanoid";import r from"node:zlib";import{PromisePool as i}from"@supercharge/promise-pool";import{ReadableStream as s}from"node:stream/web";import{mkdir as n,writeFile as o,readFile as a,stat as c,unlink as u,readdir as l,rm as h}from"fs/promises";import{createHash as f}from"crypto";import{chunk as d,merge as p,isString as m,isEmpty as g,invert as y,uniq as b,cloneDeep as w,get as v,set as k,isObject as _,isFunction as S}from"lodash-es";import O from"json-stable-stringify";import{NodeHttpHandler as R}from"@smithy/node-http-handler";import{S3Client as j,PutObjectCommand as x,GetObjectCommand as A,HeadObjectCommand as E,CopyObjectCommand as D,DeleteObjectCommand as C,DeleteObjectsCommand as $,ListObjectsV2Command as N}from"@aws-sdk/client-s3";import{flatten as I,unflatten as P}from"flat";import T from"fastest-validator";const M="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",L=Object.fromEntries([...M].map((e,t)=>[e,t])),U=e=>{if("number"!=typeof e||isNaN(e))return"undefined";if(!isFinite(e))return"undefined";if(0===e)return M[0];if(e<0)return"-"+U(-Math.floor(e));e=Math.floor(e);let t="";for(;e;)t=M[e%62]+t,e=Math.floor(e/62);return t},F=e=>{if("string"!=typeof e)return NaN;if(""===e)return 0;let t=!1;"-"===e[0]&&(t=!0,e=e.slice(1));let r=0;for(let t=0;t<e.length;t++){const i=L[e[t]];if(void 0===i)return NaN;r=62*r+i}return t?-r:r},q=e=>{if("number"!=typeof e||isNaN(e))return"undefined";if(!isFinite(e))return"undefined";const t=e<0;e=Math.abs(e);const[r,i]=e.toString().split("."),s=U(Number(r));return i?(t?"-":"")+s+"."+i:(t?"-":"")+s},B=e=>{if("string"!=typeof e)return NaN;let t=!1;"-"===e[0]&&(t=!0,e=e.slice(1));const[r,i]=e.split("."),s=F(r);if(isNaN(s))return NaN;const n=i?Number(s+"."+i):s;return t?-n:n};function z(e){"string"!=typeof e&&(e=String(e));let t=0;for(let r=0;r<e.length;r++){const i=e.codePointAt(r);i<=127?t+=1:i<=2047?t+=2:i<=65535?t+=3:i<=1114111&&(t+=4,i>65535&&r++)}return t}function H(e){let t=0;for(const r of Object.keys(e))t+=z(r);return t}function V(e){return null==e?"":"boolean"==typeof e?e?"1":"0":"number"==typeof e?String(e):"string"==typeof e?e:Array.isArray(e)?0===e.length?"[]":e.map(e=>String(e)).join("|"):"object"==typeof e?JSON.stringify(e):String(e)}function K(e){const t={};for(const[r,i]of Object.entries(e)){const e=z(V(i));t[r]=e}return t}function W(e){const t=K(e);return Object.values(t).reduce((e,t)=>e+t,0)+H(e)}function J(e){const t=K(e),r=H(e),i=Object.values(t).reduce((e,t)=>e+t,0),s=i+r,n=Object.entries(t).sort(([,e],[,t])=>t-e).map(([e,t])=>({attribute:e,size:t,percentage:(t/s*100).toFixed(2)+"%"}));return{total:s,valueSizes:t,namesSize:r,valueTotal:i,breakdown:n,detailedBreakdown:{values:i,names:r,total:s}}}function G(e={}){const{version:t="1",timestamps:r=!1,id:i=""}=e,s={_v:String(t)};r&&(s.createdAt="2024-01-01T00:00:00.000Z",s.updatedAt="2024-01-01T00:00:00.000Z"),i&&(s.id=i);const n={};for(const[e,t]of Object.entries(s))n[e]=t;return W(n)}function Y(e={}){const{s3Limit:t=2048,systemConfig:r={}}=e;return t-G(r)}class Q extends Error{constructor({verbose:e,bucket:t,key:r,message:i,code:s,statusCode:n,requestId:o,awsMessage:a,original:c,commandName:u,commandInput:l,metadata:h,suggestion:f,...d}){e&&(i+=`\n\nVerbose:\n\n${JSON.stringify(d,null,2)}`),super(i),"function"==typeof Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error(i).stack,super.name=this.constructor.name,this.name=this.constructor.name,this.bucket=t,this.key=r,this.thrownAt=new Date,this.code=s,this.statusCode=n,this.requestId=o,this.awsMessage=a,this.original=c,this.commandName=u,this.commandInput=l,this.metadata=h,this.suggestion=f,this.data={bucket:t,key:r,...d,verbose:e,message:i}}toJson(){return{name:this.name,message:this.message,code:this.code,statusCode:this.statusCode,requestId:this.requestId,awsMessage:this.awsMessage,bucket:this.bucket,key:this.key,thrownAt:this.thrownAt,commandName:this.commandName,commandInput:this.commandInput,metadata:this.metadata,suggestion:this.suggestion,data:this.data,original:this.original,stack:this.stack}}toString(){return`${this.name} | ${this.message}`}}class Z extends Q{constructor(e,t={}){let r,i,s,n,o,a;t.original&&(o=t.original,r=o.code||o.Code||o.name,i=o.statusCode||o.$metadata&&o.$metadata.httpStatusCode,s=o.requestId||o.$metadata&&o.$metadata.requestId,n=o.message,a=o.$metadata?{...o.$metadata}:void 0),super({message:e,...t,code:r,statusCode:i,requestId:s,awsMessage:n,original:o,metadata:a})}}class X extends Z{constructor(e,t={}){super(e,t),Object.assign(this,t)}}class ee extends Z{constructor(e,t={}){super(e,t),Object.assign(this,t)}}class te extends Z{constructor(e,t={}){super(e,t),Object.assign(this,t)}}class re extends Z{constructor(e,t={}){super(e,t),Object.assign(this,t)}}class ie extends Z{constructor(e,t={}){super(e,t),Object.assign(this,t)}}class se extends Z{constructor({bucket:e,resourceName:t,id:r,original:i,...s}){if("string"!=typeof r)throw new Error("id must be a string");if("string"!=typeof e)throw new Error("bucket must be a string");if("string"!=typeof t)throw new Error("resourceName must be a string");super(`Resource not found: ${t}/${r} [bucket:${e}]`,{bucket:e,resourceName:t,id:r,original:i,...s})}}class ne extends Z{constructor({bucket:e,original:t,...r}){if("string"!=typeof e)throw new Error("bucket must be a string");super(`Bucket does not exists [bucket:${e}]`,{bucket:e,original:t,...r})}}class oe extends Z{constructor({bucket:e,key:t,resourceName:r,id:i,original:s,...n}){if("string"!=typeof t)throw new Error("key must be a string");if("string"!=typeof e)throw new Error("bucket must be a string");if(void 0!==i&&"string"!=typeof i)throw new Error("id must be a string");super(`No such key: ${t} [bucket:${e}]`,{bucket:e,key:t,resourceName:r,id:i,original:s,...n}),this.resourceName=r,this.id=i}}class ae extends Z{constructor({bucket:e,key:t,resourceName:r,id:i,original:s,...n}){if("string"!=typeof t)throw new Error("key must be a string");if("string"!=typeof e)throw new Error("bucket must be a string");super(`Not found: ${t} [bucket:${e}]`,{bucket:e,key:t,resourceName:r,id:i,original:s,...n}),this.resourceName=r,this.id=i}}class ce extends Z{constructor({bucket:e,original:t,...r}){if("string"!=typeof e)throw new Error("bucket must be a string");super(`Missing metadata for bucket [bucket:${e}]`,{bucket:e,original:t,...r})}}class ue extends Z{constructor({bucket:e,resourceName:t,attributes:r,validation:i,message:s,original:n,...o}){if("string"!=typeof e)throw new Error("bucket must be a string");if("string"!=typeof t)throw new Error("resourceName must be a string");super(s||`Validation error: This item is not valid. Resource=${t} [bucket:${e}].\n${JSON.stringify(i,null,2)}`,{bucket:e,resourceName:t,attributes:r,validation:i,original:n,...o})}}class le extends Z{}const he={NotFound:ae,NoSuchKey:oe,UnknownError:le,NoSuchBucket:ne,MissingMetadata:ce,InvalidResourceItem:ue};function fe(e,t={}){const r=e.code||e.Code||e.name,i=e.$metadata?{...e.$metadata}:void 0,s=t.commandName,n=t.commandInput;let o;return"NoSuchKey"===r||"NotFound"===r?(o="Check if the key exists in the specified bucket and if your credentials have permission.",new oe({...t,original:e,metadata:i,commandName:s,commandInput:n,suggestion:o})):"NoSuchBucket"===r?(o="Check if the bucket exists and if your credentials have permission.",new ne({...t,original:e,metadata:i,commandName:s,commandInput:n,suggestion:o})):"AccessDenied"===r||403===e.statusCode||"Forbidden"===r?(o="Check your credentials and bucket policy.",new re("Access denied",{...t,original:e,metadata:i,commandName:s,commandInput:n,suggestion:o})):"ValidationError"===r||400===e.statusCode?(o="Check the request parameters and payload.",new ee("Validation error",{...t,original:e,metadata:i,commandName:s,commandInput:n,suggestion:o})):"MissingMetadata"===r?(o="Check if the object metadata is present and valid.",new ce({...t,original:e,metadata:i,commandName:s,commandInput:n,suggestion:o})):(o="Check the error details and AWS documentation.",new le("Unknown error",{...t,original:e,metadata:i,commandName:s,commandInput:n,suggestion:o}))}class de extends Z{constructor(e,t={}){super(e,{...t,suggestion:"Check the connection string format and credentials."})}}class pe extends Z{constructor(e,t={}){super(e,{...t,suggestion:"Check if the crypto library is available and input is valid."})}}class me extends Z{constructor(e,t={}){super(e,{...t,suggestion:"Check schema definition and input data."})}}class ge extends Z{constructor(e,t={}){super(e,{...t,suggestion:t.suggestion||"Check resource configuration, attributes, and operation context."}),Object.assign(this,t)}}class ye extends Z{constructor(e,t={}){super(e,{...t,suggestion:t.suggestion||"Check partition definition, fields, and input values."})}}function be(e){if(null==e){const e=new Error("fnOrPromise cannot be null or undefined");return e.stack=(new Error).stack,[!1,e,void 0]}if("function"==typeof e)try{const t=e();return null==t?[!0,null,t]:"function"==typeof t.then?t.then(e=>[!0,null,e]).catch(e=>{if(e instanceof Error&&Object.isExtensible(e)){const t=Object.getOwnPropertyDescriptor(e,"stack");if(t&&t.writable&&t.configurable&&e.hasOwnProperty("stack"))try{e.stack=(new Error).stack}catch(e){}}return[!1,e,void 0]}):[!0,null,t]}catch(e){if(e instanceof Error&&Object.isExtensible(e)){const t=Object.getOwnPropertyDescriptor(e,"stack");if(t&&t.writable&&t.configurable&&e.hasOwnProperty("stack"))try{e.stack=(new Error).stack}catch(e){}}return[!1,e,void 0]}return"function"==typeof e.then?Promise.resolve(e).then(e=>[!0,null,e]).catch(e=>{if(e instanceof Error&&Object.isExtensible(e)){const t=Object.getOwnPropertyDescriptor(e,"stack");if(t&&t.writable&&t.configurable&&e.hasOwnProperty("stack"))try{e.stack=(new Error).stack}catch(e){}}return[!1,e,void 0]}):[!0,null,e]}function we(e){try{return[!0,null,e()]}catch(e){return[!1,e,null]}}var ve=be;async function ke(){let e;if("undefined"!=typeof process){const[t,r,i]=await ve(async()=>{const{webcrypto:e}=await import("crypto");return e});if(!t)throw new pe("Crypto API not available",{original:r,context:"dynamicCrypto"});e=i}else"undefined"!=typeof window&&(e=window.crypto);if(!e)throw new pe("Could not load any crypto library",{context:"dynamicCrypto"});return e}async function _e(e){const[t,r,i]=await ve(ke);if(!t)throw new pe("Crypto API not available",{original:r});const s=(new TextEncoder).encode(e),[n,o,a]=await ve(()=>i.subtle.digest("SHA-256",s));if(!n)throw new pe("SHA-256 digest failed",{original:o,input:e});return Array.from(new Uint8Array(a)).map(e=>e.toString(16).padStart(2,"0")).join("")}async function Se(e,t){const[r,i,s]=await ve(ke);if(!r)throw new pe("Crypto API not available",{original:i});const n=s.getRandomValues(new Uint8Array(16)),[o,a,c]=await ve(()=>je(t,n));if(!o)throw new pe("Key derivation failed",{original:a,passphrase:t,salt:n});const u=s.getRandomValues(new Uint8Array(12)),l=(new TextEncoder).encode(e),[h,f,d]=await ve(()=>s.subtle.encrypt({name:"AES-GCM",iv:u},c,l));if(!h)throw new pe("Encryption failed",{original:f,content:e});const p=new Uint8Array(n.length+u.length+d.byteLength);return p.set(n),p.set(u,n.length),p.set(new Uint8Array(d),n.length+u.length),function(e){if("undefined"!=typeof process)return Buffer.from(e).toString("base64");{const[t,r,i]=we(()=>String.fromCharCode.apply(null,new Uint8Array(e)));if(!t)throw new pe("Failed to convert ArrayBuffer to base64 (browser)",{original:r});return window.btoa(i)}}(p)}async function Oe(e,t){const[r,i,s]=await ve(ke);if(!r)throw new pe("Crypto API not available",{original:i});const n=function(e){if("undefined"!=typeof process)return new Uint8Array(Buffer.from(e,"base64"));{const[t,r,i]=we(()=>window.atob(e));if(!t)throw new pe("Failed to decode base64 (browser)",{original:r});const s=i.length,n=new Uint8Array(s);for(let e=0;e<s;e++)n[e]=i.charCodeAt(e);return n}}(e),o=n.slice(0,16),a=n.slice(16,28),c=n.slice(28),[u,l,h]=await ve(()=>je(t,o));if(!u)throw new pe("Key derivation failed (decrypt)",{original:l,passphrase:t,salt:o});const[f,d,p]=await ve(()=>s.subtle.decrypt({name:"AES-GCM",iv:a},h,c));if(!f)throw new pe("Decryption failed",{original:d,encryptedBase64:e});return(new TextDecoder).decode(p)}async function Re(e){if("undefined"==typeof process)throw new pe("MD5 hashing is only available in Node.js environment",{context:"md5"});const[t,r,i]=await ve(async()=>{const{createHash:t}=await import("crypto");return t("md5").update(e).digest("base64")});if(!t)throw new pe("MD5 hashing failed",{original:r,data:e});return i}async function je(e,t){const[r,i,s]=await ve(ke);if(!r)throw new pe("Crypto API not available",{original:i});const n=(new TextEncoder).encode(e),[o,a,c]=await ve(()=>s.subtle.importKey("raw",n,{name:"PBKDF2"},!1,["deriveKey"]));if(!o)throw new pe("importKey failed",{original:a,passphrase:e});const[u,l,h]=await ve(()=>s.subtle.deriveKey({name:"PBKDF2",salt:t,iterations:1e5,hash:"SHA-256"},c,{name:"AES-GCM",length:256},!0,["encrypt","decrypt"]));if(!u)throw new pe("deriveKey failed",{original:l,passphrase:e,salt:t});return h}const xe=e(t,22),Ae=e("ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789",16);var Ee,De=Object.freeze({__proto__:null,idGenerator:xe,passwordGenerator:Ae});function Ce(){}function $e(){$e.init.call(this)}function Ne(e){return void 0===e._maxListeners?$e.defaultMaxListeners:e._maxListeners}function Ie(e,t,r,i){var s,n,o,a;if("function"!=typeof r)throw new TypeError('"listener" argument must be a function');if((n=e._events)?(n.newListener&&(e.emit("newListener",t,r.listener?r.listener:r),n=e._events),o=n[t]):(n=e._events=new Ce,e._eventsCount=0),o){if("function"==typeof o?o=n[t]=i?[r,o]:[o,r]:i?o.unshift(r):o.push(r),!o.warned&&(s=Ne(e))&&s>0&&o.length>s){o.warned=!0;var c=new Error("Possible EventEmitter memory leak detected. "+o.length+" "+t+" listeners added. Use emitter.setMaxListeners() to increase limit");c.name="MaxListenersExceededWarning",c.emitter=e,c.type=t,c.count=o.length,a=c,"function"==typeof console.warn?console.warn(a):console.log(a)}}else o=n[t]=r,++e._eventsCount;return e}function Pe(e,t,r){var i=!1;function s(){e.removeListener(t,s),i||(i=!0,r.apply(e,arguments))}return s.listener=r,s}function Te(e){var t=this._events;if(t){var r=t[e];if("function"==typeof r)return 1;if(r)return r.length}return 0}function Me(e,t){for(var r=new Array(t);t--;)r[t]=e[t];return r}Ce.prototype=Object.create(null),$e.EventEmitter=$e,$e.usingDomains=!1,$e.prototype.domain=void 0,$e.prototype._events=void 0,$e.prototype._maxListeners=void 0,$e.defaultMaxListeners=10,$e.init=function(){this.domain=null,$e.usingDomains&&(!Ee.active||this instanceof Ee.Domain||(this.domain=Ee.active)),this._events&&this._events!==Object.getPrototypeOf(this)._events||(this._events=new Ce,this._eventsCount=0),this._maxListeners=this._maxListeners||void 0},$e.prototype.setMaxListeners=function(e){if("number"!=typeof e||e<0||isNaN(e))throw new TypeError('"n" argument must be a positive number');return this._maxListeners=e,this},$e.prototype.getMaxListeners=function(){return Ne(this)},$e.prototype.emit=function(e){var t,r,i,s,n,o,a,c="error"===e;if(o=this._events)c=c&&null==o.error;else if(!c)return!1;if(a=this.domain,c){if(t=arguments[1],!a){if(t instanceof Error)throw t;var u=new Error('Uncaught, unspecified "error" event. ('+t+")");throw u.context=t,u}return t||(t=new Error('Uncaught, unspecified "error" event')),t.domainEmitter=this,t.domain=a,t.domainThrown=!1,a.emit("error",t),!1}if(!(r=o[e]))return!1;var l="function"==typeof r;switch(i=arguments.length){case 1:!function(e,t,r){if(t)e.call(r);else for(var i=e.length,s=Me(e,i),n=0;n<i;++n)s[n].call(r)}(r,l,this);break;case 2:!function(e,t,r,i){if(t)e.call(r,i);else for(var s=e.length,n=Me(e,s),o=0;o<s;++o)n[o].call(r,i)}(r,l,this,arguments[1]);break;case 3:!function(e,t,r,i,s){if(t)e.call(r,i,s);else for(var n=e.length,o=Me(e,n),a=0;a<n;++a)o[a].call(r,i,s)}(r,l,this,arguments[1],arguments[2]);break;case 4:!function(e,t,r,i,s,n){if(t)e.call(r,i,s,n);else for(var o=e.length,a=Me(e,o),c=0;c<o;++c)a[c].call(r,i,s,n)}(r,l,this,arguments[1],arguments[2],arguments[3]);break;default:for(s=new Array(i-1),n=1;n<i;n++)s[n-1]=arguments[n];!function(e,t,r,i){if(t)e.apply(r,i);else for(var s=e.length,n=Me(e,s),o=0;o<s;++o)n[o].apply(r,i)}(r,l,this,s)}return!0},$e.prototype.addListener=function(e,t){return Ie(this,e,t,!1)},$e.prototype.on=$e.prototype.addListener,$e.prototype.prependListener=function(e,t){return Ie(this,e,t,!0)},$e.prototype.once=function(e,t){if("function"!=typeof t)throw new TypeError('"listener" argument must be a function');return this.on(e,Pe(this,e,t)),this},$e.prototype.prependOnceListener=function(e,t){if("function"!=typeof t)throw new TypeError('"listener" argument must be a function');return this.prependListener(e,Pe(this,e,t)),this},$e.prototype.removeListener=function(e,t){var r,i,s,n,o;if("function"!=typeof t)throw new TypeError('"listener" argument must be a function');if(!(i=this._events))return this;if(!(r=i[e]))return this;if(r===t||r.listener&&r.listener===t)0===--this._eventsCount?this._events=new Ce:(delete i[e],i.removeListener&&this.emit("removeListener",e,r.listener||t));else if("function"!=typeof r){for(s=-1,n=r.length;n-- >0;)if(r[n]===t||r[n].listener&&r[n].listener===t){o=r[n].listener,s=n;break}if(s<0)return this;if(1===r.length){if(r[0]=void 0,0===--this._eventsCount)return this._events=new Ce,this;delete i[e]}else!function(e,t){for(var r=t,i=r+1,s=e.length;i<s;r+=1,i+=1)e[r]=e[i];e.pop()}(r,s);i.removeListener&&this.emit("removeListener",e,o||t)}return this},$e.prototype.off=function(e,t){return this.removeListener(e,t)},$e.prototype.removeAllListeners=function(e){var t,r;if(!(r=this._events))return this;if(!r.removeListener)return 0===arguments.length?(this._events=new Ce,this._eventsCount=0):r[e]&&(0===--this._eventsCount?this._events=new Ce:delete r[e]),this;if(0===arguments.length){for(var i,s=Object.keys(r),n=0;n<s.length;++n)"removeListener"!==(i=s[n])&&this.removeAllListeners(i);return this.removeAllListeners("removeListener"),this._events=new Ce,this._eventsCount=0,this}if("function"==typeof(t=r[e]))this.removeListener(e,t);else if(t)do{this.removeListener(e,t[t.length-1])}while(t[0]);return this},$e.prototype.listeners=function(e){var t,r=this._events;return r&&(t=r[e])?"function"==typeof t?[t.listener||t]:function(e){for(var t=new Array(e.length),r=0;r<t.length;++r)t[r]=e[r].listener||e[r];return t}(t):[]},$e.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):Te.call(e,t)},$e.prototype.listenerCount=Te,$e.prototype.eventNames=function(){return this._eventsCount>0?Reflect.ownKeys(this._events):[]};var Le=class extends $e{constructor(e={}){super(),this.name=this.constructor.name,this.options=e,this.hooks=new Map}async setup(e){this.database=e,this.beforeSetup(),await this.onSetup(),this.afterSetup()}async start(){this.beforeStart(),await this.onStart(),this.afterStart()}async stop(){this.beforeStop(),await this.onStop(),this.afterStop()}async onSetup(){}async onStart(){}async onStop(){}addHook(e,t,r){this.hooks.has(e)||this.hooks.set(e,new Map);const i=this.hooks.get(e);i.has(t)||i.set(t,[]),i.get(t).push(r)}removeHook(e,t,r){const i=this.hooks.get(e);if(i&&i.has(t)){const e=i.get(t),s=e.indexOf(r);s>-1&&e.splice(s,1)}}wrapResourceMethod(e,t,r){const i=e[t];if(e._pluginWrappers||(e._pluginWrappers=new Map),e._pluginWrappers.has(t)||e._pluginWrappers.set(t,[]),e._pluginWrappers.get(t).push(r),!e[`_wrapped_${t}`]){e[`_wrapped_${t}`]=i;const r=i&&i._isMockFunction;e[t]=async function(...r){let i=await e[`_wrapped_${t}`](...r);for(const s of e._pluginWrappers.get(t))i=await s.call(this,i,r,t);return i},r&&(Object.setPrototypeOf(e[t],Object.getPrototypeOf(i)),Object.assign(e[t],i))}}addMiddleware(e,t,r){if(e._pluginMiddlewares||(e._pluginMiddlewares={}),!e._pluginMiddlewares[t]){e._pluginMiddlewares[t]=[];const r=e[t].bind(e);e[t]=async function(...i){let s=-1;const n=async(...i)=>(s++,s<e._pluginMiddlewares[t].length?await e._pluginMiddlewares[t][s].call(this,n,...i):await r(...i));return await n(...i)}}e._pluginMiddlewares[t].push(r)}getPartitionValues(e,t){if(!t.config?.partitions)return{};const r={};for(const[i,s]of Object.entries(t.config.partitions))if(s.fields){r[i]={};for(const[n,o]of Object.entries(s.fields)){const s=this.getNestedFieldValue(e,n);null!=s&&(r[i][n]=t.applyPartitionRule(s,o))}}else r[i]={};return r}getNestedFieldValue(e,t){if(!t.includes("."))return e[t]??null;const r=t.split(".");let i=e;for(const e of r){if(!i||"object"!=typeof i||!(e in i))return null;i=i[e]}return i??null}beforeSetup(){this.emit("plugin.beforeSetup",new Date)}afterSetup(){this.emit("plugin.afterSetup",new Date)}beforeStart(){this.emit("plugin.beforeStart",new Date)}afterStart(){this.emit("plugin.afterStart",new Date)}beforeStop(){this.emit("plugin.beforeStop",new Date)}afterStop(){this.emit("plugin.afterStop",new Date)}};const Ue={setup(e){},start(){},stop(){}};class Fe extends Le{constructor(e={}){super(e),this.auditResource=null,this.config={includeData:!1!==e.includeData,includePartitions:!1!==e.includePartitions,maxDataSize:e.maxDataSize||1e4,...e}}async onSetup(){const[e,t,r]=await ve(()=>this.database.createResource({name:"audits",attributes:{id:"string|required",resourceName:"string|required",operation:"string|required",recordId:"string|required",userId:"string|optional",timestamp:"string|required",oldData:"string|optional",newData:"string|optional",partition:"string|optional",partitionValues:"string|optional",metadata:"string|optional"},behavior:"body-overflow"}));if(this.auditResource=e?r:this.database.resources.audits||null,e||this.auditResource){this.database.addHook("afterCreateResource",e=>{"audits"!==e.resource.name&&this.setupResourceAuditing(e.resource)});for(const e of Object.values(this.database.resources))"audits"!==e.name&&this.setupResourceAuditing(e)}}async onStart(){}async onStop(){}setupResourceAuditing(e){e.on("insert",async t=>{const r=this.config.includePartitions?this.getPartitionValues(t,e):null;await this.logAudit({resourceName:e.name,operation:"insert",recordId:t.id||"auto-generated",oldData:null,newData:this.config.includeData?JSON.stringify(this.truncateData(t)):null,partition:r?this.getPrimaryPartition(r):null,partitionValues:r?JSON.stringify(r):null})}),e.on("update",async t=>{let r=t.$before;if(this.config.includeData&&!r){const[i,s,n]=await ve(()=>e.get(t.id));i&&(r=n)}const i=this.config.includePartitions?this.getPartitionValues(t,e):null;await this.logAudit({resourceName:e.name,operation:"update",recordId:t.id,oldData:r&&this.config.includeData?JSON.stringify(this.truncateData(r)):null,newData:this.config.includeData?JSON.stringify(this.truncateData(t)):null,partition:i?this.getPrimaryPartition(i):null,partitionValues:i?JSON.stringify(i):null})}),e.on("delete",async t=>{let r=t;if(this.config.includeData&&!r){const[i,s,n]=await ve(()=>e.get(t.id));i&&(r=n)}const i=r&&this.config.includePartitions?this.getPartitionValues(r,e):null;await this.logAudit({resourceName:e.name,operation:"delete",recordId:t.id,oldData:r&&this.config.includeData?JSON.stringify(this.truncateData(r)):null,newData:null,partition:i?this.getPrimaryPartition(i):null,partitionValues:i?JSON.stringify(i):null})});const t=e.deleteMany.bind(e),r=this;e.deleteMany=async function(i){const s=[];if(r.config.includeData)for(const t of i){const[r,i,n]=await ve(()=>e.get(t));r?s.push(n):s.push({id:t})}else s.push(...i.map(e=>({id:e})));const n=await t(i);for(const t of s){const i=t&&r.config.includePartitions?r.getPartitionValues(t,e):null;await r.logAudit({resourceName:e.name,operation:"deleteMany",recordId:t.id,oldData:t&&r.config.includeData?JSON.stringify(r.truncateData(t)):null,newData:null,partition:i?r.getPrimaryPartition(i):null,partitionValues:i?JSON.stringify(i):null})}return n},e._originalDeleteMany=t}installEventListenersForResource(e){return this.setupResourceAuditing(e)}async logAudit(e){if(!this.auditResource)return;const t={id:`audit-${Date.now()}-${Math.random().toString(36).substring(2,11)}`,userId:this.getCurrentUserId?.()||"system",timestamp:(new Date).toISOString(),metadata:JSON.stringify({source:"audit-plugin",version:"2.0"}),resourceName:e.resourceName,operation:e.operation,recordId:e.recordId};null!==e.oldData&&(t.oldData=e.oldData),null!==e.newData&&(t.newData=e.newData),null!==e.partition&&(t.partition=e.partition),null!==e.partitionValues&&(t.partitionValues=e.partitionValues);try{await this.auditResource.insert(t)}catch(e){console.warn("Audit logging failed:",e.message)}}getPartitionValues(e,t){if(!this.config.includePartitions)return null;const r=t.config?.partitions||t.partitions;if(!r)return null;const i={};for(const[t,s]of Object.entries(r)){const r={};for(const t of Object.keys(s.fields))r[t]=this.getNestedFieldValue(e,t);Object.values(r).some(e=>null!=e)&&(i[t]=r)}return Object.keys(i).length>0?i:null}getNestedFieldValue(e,t){const r=t.split(".");let i=e;for(const e of r){if(!i||"object"!=typeof i||!(e in i))return;i=i[e]}return i}getPrimaryPartition(e){if(!e)return null;const t=Object.keys(e);return t.length>0?t[0]:null}truncateData(e){if(!this.config.includeData)return null;const t=JSON.stringify(e);return t.length<=this.config.maxDataSize?e:{...e,_truncated:!0,_originalSize:t.length,_truncatedAt:(new Date).toISOString()}}async getAuditLogs(e={}){if(!this.auditResource)return[];const{resourceName:t,operation:r,recordId:i,partition:s,startDate:n,endDate:o,limit:a=100,offset:c=0}=e;let u={};t&&(u.resourceName=t),r&&(u.operation=r),i&&(u.recordId=i),s&&(u.partition=s),(n||o)&&(u.timestamp={},n&&(u.timestamp.$gte=n),o&&(u.timestamp.$lte=o));return(await this.auditResource.page({query:u,limit:a,offset:c})).items||[]}async getRecordHistory(e,t){return await this.getAuditLogs({resourceName:e,recordId:t})}async getPartitionHistory(e,t,r){return await this.getAuditLogs({resourceName:e,partition:t,partitionValues:JSON.stringify(r)})}async getAuditStats(e={}){const t=await this.getAuditLogs(e),r={total:t.length,byOperation:{},byResource:{},byPartition:{},byUser:{},timeline:{}};for(const e of t){r.byOperation[e.operation]=(r.byOperation[e.operation]||0)+1,r.byResource[e.resourceName]=(r.byResource[e.resourceName]||0)+1,e.partition&&(r.byPartition[e.partition]=(r.byPartition[e.partition]||0)+1),r.byUser[e.userId]=(r.byUser[e.userId]||0)+1;const t=e.timestamp.split("T")[0];r.timeline[t]=(r.timeline[t]||0)+1}return r}}function qe(e,t){for(var r=0,i=e.length-1;i>=0;i--){var s=e[i];"."===s?e.splice(i,1):".."===s?(e.splice(i,1),r++):r&&(e.splice(i,1),r--)}if(t)for(;r--;r)e.unshift("..");return e}var Be=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/,ze=function(e){return Be.exec(e).slice(1)};function He(){for(var e="",t=!1,r=arguments.length-1;r>=-1&&!t;r--){var i=r>=0?arguments[r]:"/";if("string"!=typeof i)throw new TypeError("Arguments to path.resolve must be strings");i&&(e=i+"/"+e,t="/"===i.charAt(0))}return(t?"/":"")+(e=qe(Ge(e.split("/"),function(e){return!!e}),!t).join("/"))||"."}function Ve(e){var t=Ke(e),r="/"===Ye(e,-1);return(e=qe(Ge(e.split("/"),function(e){return!!e}),!t).join("/"))||t||(e="."),e&&r&&(e+="/"),(t?"/":"")+e}function Ke(e){return"/"===e.charAt(0)}function We(){return Ve(Ge(Array.prototype.slice.call(arguments,0),function(e,t){if("string"!=typeof e)throw new TypeError("Arguments to path.join must be strings");return e}).join("/"))}var Je={extname:function(e){return ze(e)[3]},basename:function(e,t){var r=ze(e)[2];return t&&r.substr(-1*t.length)===t&&(r=r.substr(0,r.length-t.length)),r},dirname:function(e){var t=ze(e),r=t[0],i=t[1];return r||i?(i&&(i=i.substr(0,i.length-1)),r+i):"."},sep:"/",delimiter:":",relative:function(e,t){function r(e){for(var t=0;t<e.length&&""===e[t];t++);for(var r=e.length-1;r>=0&&""===e[r];r--);return t>r?[]:e.slice(t,r-t+1)}e=He(e).substr(1),t=He(t).substr(1);for(var i=r(e.split("/")),s=r(t.split("/")),n=Math.min(i.length,s.length),o=n,a=0;a<n;a++)if(i[a]!==s[a]){o=a;break}var c=[];for(a=o;a<i.length;a++)c.push("..");return(c=c.concat(s.slice(o))).join("/")},join:We,isAbsolute:Ke,normalize:Ve,resolve:He};function Ge(e,t){if(e.filter)return e.filter(t);for(var r=[],i=0;i<e.length;i++)t(e[i],i,e)&&r.push(e[i]);return r}var Ye="b"==="ab".substr(-1)?function(e,t,r){return e.substr(t,r)}:function(e,t,r){return t<0&&(t=e.length+t),e.substr(t,r)};class Qe extends $e{constructor(e={}){super(),this.config=e}async _set(e,t){}async _get(e){}async _del(e){}async _clear(e){}validateKey(e){if(null==e||"string"!=typeof e||!e)throw new Error("Invalid key")}async set(e,t){return this.validateKey(e),await this._set(e,t),this.emit("set",t),t}async get(e){this.validateKey(e);const t=await this._get(e);return this.emit("get",t),t}async del(e){this.validateKey(e);const t=await this._del(e);return this.emit("delete",t),t}async delete(e){return this.del(e)}async clear(e){const t=await this._clear(e);return this.emit("clear",t),t}}function Ze(){throw new Error("setTimeout has not been defined")}function Xe(){throw new Error("clearTimeout has not been defined")}var et=Ze,tt=Xe;function rt(e){if(et===setTimeout)return setTimeout(e,0);if((et===Ze||!et)&&setTimeout)return et=setTimeout,setTimeout(e,0);try{return et(e,0)}catch(t){try{return et.call(null,e,0)}catch(t){return et.call(this,e,0)}}}"function"==typeof global.setTimeout&&(et=setTimeout),"function"==typeof global.clearTimeout&&(tt=clearTimeout);var it,st=[],nt=!1,ot=-1;function at(){nt&&it&&(nt=!1,it.length?st=it.concat(st):ot=-1,st.length&&ct())}function ct(){if(!nt){var e=rt(at);nt=!0;for(var t=st.length;t;){for(it=st,st=[];++ot<t;)it&&it[ot].run();ot=-1,t=st.length}it=null,nt=!1,function(e){if(tt===clearTimeout)return clearTimeout(e);if((tt===Xe||!tt)&&clearTimeout)return tt=clearTimeout,clearTimeout(e);try{return tt(e)}catch(t){try{return tt.call(null,e)}catch(t){return tt.call(this,e)}}}(e)}}function ut(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var r=1;r<arguments.length;r++)t[r-1]=arguments[r];st.push(new lt(e,t)),1!==st.length||nt||rt(ct)}function lt(e,t){this.fun=e,this.array=t}lt.prototype.run=function(){this.fun.apply(null,this.array)};var ht,ft={env:{}};ht="function"==typeof Object.create?function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:function(e,t){e.super_=t;var r=function(){};r.prototype=t.prototype,e.prototype=new r,e.prototype.constructor=e};var dt=/%[sdj%]/g;function pt(e){if(!jt(e)){for(var t=[],r=0;r<arguments.length;r++)t.push(bt(arguments[r]));return t.join(" ")}r=1;for(var i=arguments,s=i.length,n=String(e).replace(dt,function(e){if("%%"===e)return"%";if(r>=s)return e;switch(e){case"%s":return String(i[r++]);case"%d":return Number(i[r++]);case"%j":try{return JSON.stringify(i[r++])}catch(e){return"[Circular]"}default:return e}}),o=i[r];r<s;o=i[++r])Rt(o)||!Et(o)?n+=" "+o:n+=" "+bt(o);return n}function mt(e,t){if(xt(global.process))return function(){return mt(e,t).apply(this,arguments)};if(!0===ft.noDeprecation)return e;var r=!1;return function(){if(!r){if(ft.throwDeprecation)throw new Error(t);ft.traceDeprecation?console.trace(t):console.error(t),r=!0}return e.apply(this,arguments)}}var gt,yt={};function bt(e,t){var r={seen:[],stylize:vt};return arguments.length>=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),Ot(t)?r.showHidden=t:t&&function(e,t){if(!t||!Et(t))return e;var r=Object.keys(t),i=r.length;for(;i--;)e[r[i]]=t[r[i]]}(r,t),xt(r.showHidden)&&(r.showHidden=!1),xt(r.depth)&&(r.depth=2),xt(r.colors)&&(r.colors=!1),xt(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=wt),kt(r,e,r.depth)}function wt(e,t){var r=bt.styles[t];return r?"["+bt.colors[r][0]+"m"+e+"["+bt.colors[r][1]+"m":e}function vt(e,t){return e}function kt(e,t,r){if(e.customInspect&&t&&$t(t.inspect)&&t.inspect!==bt&&(!t.constructor||t.constructor.prototype!==t)){var i=t.inspect(r,e);return jt(i)||(i=kt(e,i,r)),i}var s=function(e,t){if(xt(t))return e.stylize("undefined","undefined");if(jt(t)){var r="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(r,"string")}if(i=t,"number"==typeof i)return e.stylize(""+t,"number");var i;if(Ot(t))return e.stylize(""+t,"boolean");if(Rt(t))return e.stylize("null","null")}(e,t);if(s)return s;var n=Object.keys(t),o=function(e){var t={};return e.forEach(function(e,r){t[e]=!0}),t}(n);if(e.showHidden&&(n=Object.getOwnPropertyNames(t)),Ct(t)&&(n.indexOf("message")>=0||n.indexOf("description")>=0))return _t(t);if(0===n.length){if($t(t)){var a=t.name?": "+t.name:"";return e.stylize("[Function"+a+"]","special")}if(At(t))return e.stylize(RegExp.prototype.toString.call(t),"regexp");if(Dt(t))return e.stylize(Date.prototype.toString.call(t),"date");if(Ct(t))return _t(t)}var c,u,l="",h=!1,f=["{","}"];(c=t,Array.isArray(c)&&(h=!0,f=["[","]"]),$t(t))&&(l=" [Function"+(t.name?": "+t.name:"")+"]");return At(t)&&(l=" "+RegExp.prototype.toString.call(t)),Dt(t)&&(l=" "+Date.prototype.toUTCString.call(t)),Ct(t)&&(l=" "+_t(t)),0!==n.length||h&&0!=t.length?r<0?At(t)?e.stylize(RegExp.prototype.toString.call(t),"regexp"):e.stylize("[Object]","special"):(e.seen.push(t),u=h?function(e,t,r,i,s){for(var n=[],o=0,a=t.length;o<a;++o)It(t,String(o))?n.push(St(e,t,r,i,String(o),!0)):n.push("");return s.forEach(function(s){s.match(/^\d+$/)||n.push(St(e,t,r,i,s,!0))}),n}(e,t,r,o,n):n.map(function(i){return St(e,t,r,o,i,h)}),e.seen.pop(),function(e,t,r){var i=e.reduce(function(e,t){return t.indexOf("\n"),e+t.replace(/\u001b\[\d\d?m/g,"").length+1},0);if(i>60)return r[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+r[1];return r[0]+t+" "+e.join(", ")+" "+r[1]}(u,l,f)):f[0]+l+f[1]}function _t(e){return"["+Error.prototype.toString.call(e)+"]"}function St(e,t,r,i,s,n){var o,a,c;if((c=Object.getOwnPropertyDescriptor(t,s)||{value:t[s]}).get?a=c.set?e.stylize("[Getter/Setter]","special"):e.stylize("[Getter]","special"):c.set&&(a=e.stylize("[Setter]","special")),It(i,s)||(o="["+s+"]"),a||(e.seen.indexOf(c.value)<0?(a=Rt(r)?kt(e,c.value,null):kt(e,c.value,r-1)).indexOf("\n")>-1&&(a=n?a.split("\n").map(function(e){return" "+e}).join("\n").substr(2):"\n"+a.split("\n").map(function(e){return" "+e}).join("\n")):a=e.stylize("[Circular]","special")),xt(o)){if(n&&s.match(/^\d+$/))return a;(o=JSON.stringify(""+s)).match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(o=o.substr(1,o.length-2),o=e.stylize(o,"name")):(o=o.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),o=e.stylize(o,"string"))}return o+": "+a}function Ot(e){return"boolean"==typeof e}function Rt(e){return null===e}function jt(e){return"string"==typeof e}function xt(e){return void 0===e}function At(e){return Et(e)&&"[object RegExp]"===Nt(e)}function Et(e){return"object"==typeof e&&null!==e}function Dt(e){return Et(e)&&"[object Date]"===Nt(e)}function Ct(e){return Et(e)&&("[object Error]"===Nt(e)||e instanceof Error)}function $t(e){return"function"==typeof e}function Nt(e){return Object.prototype.toString.call(e)}function It(e,t){return Object.prototype.hasOwnProperty.call(e,t)}bt.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},bt.styles={special:"cyan",number:"yellow",boolean:"yellow",undefined:"grey",null:"bold",string:"green",date:"magenta",regexp:"red"};var Pt=[],Tt=[],Mt="undefined"!=typeof Uint8Array?Uint8Array:Array,Lt=!1;function Ut(){Lt=!0;for(var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",t=0;t<64;++t)Pt[t]=e[t],Tt[e.charCodeAt(t)]=t;Tt["-".charCodeAt(0)]=62,Tt["_".charCodeAt(0)]=63}function Ft(e){return Pt[e>>18&63]+Pt[e>>12&63]+Pt[e>>6&63]+Pt[63&e]}function qt(e,t,r){for(var i,s=[],n=t;n<r;n+=3)i=(e[n]<<16)+(e[n+1]<<8)+e[n+2],s.push(Ft(i));return s.join("")}function Bt(e){var t;Lt||Ut();for(var r=e.length,i=r%3,s="",n=[],o=16383,a=0,c=r-i;a<c;a+=o)n.push(qt(e,a,a+o>c?c:a+o));return 1===i?(t=e[r-1],s+=Pt[t>>2],s+=Pt[t<<4&63],s+="=="):2===i&&(t=(e[r-2]<<8)+e[r-1],s+=Pt[t>>10],s+=Pt[t>>4&63],s+=Pt[t<<2&63],s+="="),n.push(s),n.join("")}function zt(e,t,r,i,s){var n,o,a=8*s-i-1,c=(1<<a)-1,u=c>>1,l=-7,h=r?s-1:0,f=r?-1:1,d=e[t+h];for(h+=f,n=d&(1<<-l)-1,d>>=-l,l+=a;l>0;n=256*n+e[t+h],h+=f,l-=8);for(o=n&(1<<-l)-1,n>>=-l,l+=i;l>0;o=256*o+e[t+h],h+=f,l-=8);if(0===n)n=1-u;else{if(n===c)return o?NaN:1/0*(d?-1:1);o+=Math.pow(2,i),n-=u}return(d?-1:1)*o*Math.pow(2,n-i)}function Ht(e,t,r,i,s,n){var o,a,c,u=8*n-s-1,l=(1<<u)-1,h=l>>1,f=23===s?Math.pow(2,-24)-Math.pow(2,-77):0,d=i?0:n-1,p=i?1:-1,m=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,o=l):(o=Math.floor(Math.log(t)/Math.LN2),t*(c=Math.pow(2,-o))<1&&(o--,c*=2),(t+=o+h>=1?f/c:f*Math.pow(2,1-h))*c>=2&&(o++,c/=2),o+h>=l?(a=0,o=l):o+h>=1?(a=(t*c-1)*Math.pow(2,s),o+=h):(a=t*Math.pow(2,h-1)*Math.pow(2,s),o=0));s>=8;e[r+d]=255&a,d+=p,a/=256,s-=8);for(o=o<<s|a,u+=s;u>0;e[r+d]=255&o,d+=p,o/=256,u-=8);e[r+d-p]|=128*m}var Vt={}.toString,Kt=Array.isArray||function(e){return"[object Array]"==Vt.call(e)};function Wt(){return Gt.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function Jt(e,t){if(Wt()<t)throw new RangeError("Invalid typed array length");return Gt.TYPED_ARRAY_SUPPORT?(e=new Uint8Array(t)).__proto__=Gt.prototype:(null===e&&(e=new Gt(t)),e.length=t),e}function Gt(e,t,r){if(!(Gt.TYPED_ARRAY_SUPPORT||this instanceof Gt))return new Gt(e,t,r);if("number"==typeof e){if("string"==typeof t)throw new Error("If encoding is specified then the first argument must be a string");return Zt(this,e)}return Yt(this,e,t,r)}function Yt(e,t,r,i){if("number"==typeof t)throw new TypeError('"value" argument must not be a number');return"undefined"!=typeof ArrayBuffer&&t instanceof ArrayBuffer?function(e,t,r,i){if(t.byteLength,r<0||t.byteLength<r)throw new RangeError("'offset' is out of bounds");if(t.byteLength<r+(i||0))throw new RangeError("'length' is out of bounds");t=void 0===r&&void 0===i?new Uint8Array(t):void 0===i?new Uint8Array(t,r):new Uint8Array(t,r,i);Gt.TYPED_ARRAY_SUPPORT?(e=t).__proto__=Gt.prototype:e=Xt(e,t);return e}(e,t,r,i):"string"==typeof t?function(e,t,r){"string"==typeof r&&""!==r||(r="utf8");if(!Gt.isEncoding(r))throw new TypeError('"encoding" must be a valid string encoding');var i=0|rr(t,r);e=Jt(e,i);var s=e.write(t,r);s!==i&&(e=e.slice(0,s));return e}(e,t,r):function(e,t){if(tr(t)){var r=0|er(t.length);return 0===(e=Jt(e,r)).length||t.copy(e,0,0,r),e}if(t){if("undefined"!=typeof ArrayBuffer&&t.buffer instanceof ArrayBuffer||"length"in t)return"number"!=typeof t.length||(i=t.length)!=i?Jt(e,0):Xt(e,t);if("Buffer"===t.type&&Kt(t.data))return Xt(e,t.data)}var i;throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.")}(e,t)}function Qt(e){if("number"!=typeof e)throw new TypeError('"size" argument must be a number');if(e<0)throw new RangeError('"size" argument must not be negative')}function Zt(e,t){if(Qt(t),e=Jt(e,t<0?0:0|er(t)),!Gt.TYPED_ARRAY_SUPPORT)for(var r=0;r<t;++r)e[r]=0;return e}function Xt(e,t){var r=t.length<0?0:0|er(t.length);e=Jt(e,r);for(var i=0;i<r;i+=1)e[i]=255&t[i];return e}function er(e){if(e>=Wt())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+Wt().toString(16)+" bytes");return 0|e}function tr(e){return!(null==e||!e._isBuffer)}function rr(e,t){if(tr(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var r=e.length;if(0===r)return 0;for(var i=!1;;)switch(t){case"ascii":case"latin1":case"binary":return r;case"utf8":case"utf-8":case void 0:return Er(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*r;case"hex":return r>>>1;case"base64":return Dr(e).length;default:if(i)return Er(e).length;t=(""+t).toLowerCase(),i=!0}}function ir(e,t,r){var i=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return"";if((r>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return br(this,t,r);case"utf8":case"utf-8":return pr(this,t,r);case"ascii":return gr(this,t,r);case"latin1":case"binary":return yr(this,t,r);case"base64":return dr(this,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return wr(this,t,r);default:if(i)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),i=!0}}function sr(e,t,r){var i=e[t];e[t]=e[r],e[r]=i}function nr(e,t,r,i,s){if(0===e.length)return-1;if("string"==typeof r?(i=r,r=0):r>2147483647?r=2147483647:r<-2147483648&&(r=-2147483648),r=+r,isNaN(r)&&(r=s?0:e.length-1),r<0&&(r=e.length+r),r>=e.length){if(s)return-1;r=e.length-1}else if(r<0){if(!s)return-1;r=0}if("string"==typeof t&&(t=Gt.from(t,i)),tr(t))return 0===t.length?-1:or(e,t,r,i,s);if("number"==typeof t)return t&=255,Gt.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?s?Uint8Array.prototype.indexOf.call(e,t,r):Uint8Array.prototype.lastIndexOf.call(e,t,r):or(e,[t],r,i,s);throw new TypeError("val must be string, number or Buffer")}function or(e,t,r,i,s){var n,o=1,a=e.length,c=t.length;if(void 0!==i&&("ucs2"===(i=String(i).toLowerCase())||"ucs-2"===i||"utf16le"===i||"utf-16le"===i)){if(e.length<2||t.length<2)return-1;o=2,a/=2,c/=2,r/=2}function u(e,t){return 1===o?e[t]:e.readUInt16BE(t*o)}if(s){var l=-1;for(n=r;n<a;n++)if(u(e,n)===u(t,-1===l?0:n-l)){if(-1===l&&(l=n),n-l+1===c)return l*o}else-1!==l&&(n-=n-l),l=-1}else for(r+c>a&&(r=a-c),n=r;n>=0;n--){for(var h=!0,f=0;f<c;f++)if(u(e,n+f)!==u(t,f)){h=!1;break}if(h)return n}return-1}function ar(e,t,r,i){r=Number(r)||0;var s=e.length-r;i?(i=Number(i))>s&&(i=s):i=s;var n=t.length;if(n%2!=0)throw new TypeError("Invalid hex string");i>n/2&&(i=n/2);for(var o=0;o<i;++o){var a=parseInt(t.substr(2*o,2),16);if(isNaN(a))return o;e[r+o]=a}return o}function cr(e,t,r,i){return Cr(Er(t,e.length-r),e,r,i)}function ur(e,t,r,i){return Cr(function(e){for(var t=[],r=0;r<e.length;++r)t.push(255&e.charCodeAt(r));return t}(t),e,r,i)}function lr(e,t,r,i){return ur(e,t,r,i)}function hr(e,t,r,i){return Cr(Dr(t),e,r,i)}function fr(e,t,r,i){return Cr(function(e,t){for(var r,i,s,n=[],o=0;o<e.length&&!((t-=2)<0);++o)i=(r=e.charCodeAt(o))>>8,s=r%256,n.push(s),n.push(i);return n}(t,e.length-r),e,r,i)}function dr(e,t,r){return 0===t&&r===e.length?Bt(e):Bt(e.slice(t,r))}function pr(e,t,r){r=Math.min(e.length,r);for(var i=[],s=t;s<r;){var n,o,a,c,u=e[s],l=null,h=u>239?4:u>223?3:u>191?2:1;if(s+h<=r)switch(h){case 1:u<128&&(l=u);break;case 2:128==(192&(n=e[s+1]))&&(c=(31&u)<<6|63&n)>127&&(l=c);break;case 3:n=e[s+1],o=e[s+2],128==(192&n)&&128==(192&o)&&(c=(15&u)<<12|(63&n)<<6|63&o)>2047&&(c<55296||c>57343)&&(l=c);break;case 4:n=e[s+1],o=e[s+2],a=e[s+3],128==(192&n)&&128==(192&o)&&128==(192&a)&&(c=(15&u)<<18|(63&n)<<12|(63&o)<<6|63&a)>65535&&c<1114112&&(l=c)}null===l?(l=65533,h=1):l>65535&&(l-=65536,i.push(l>>>10&1023|55296),l=56320|1023&l),i.push(l),s+=h}return function(e){var t=e.length;if(t<=mr)return String.fromCharCode.apply(String,e);var r="",i=0;for(;i<t;)r+=String.fromCharCode.apply(String,e.slice(i,i+=mr));return r}(i)}Gt.TYPED_ARRAY_SUPPORT=void 0===global.TYPED_ARRAY_SUPPORT||global.TYPED_ARRAY_SUPPORT,Wt(),Gt.poolSize=8192,Gt._augment=function(e){return e.__proto__=Gt.prototype,e},Gt.from=function(e,t,r){return Yt(null,e,t,r)},Gt.TYPED_ARRAY_SUPPORT&&(Gt.prototype.__proto__=Uint8Array.prototype,Gt.__proto__=Uint8Array,"undefined"!=typeof Symbol&&Symbol.species&&Gt[Symbol.species]),Gt.alloc=function(e,t,r){return function(e,t,r,i){return Qt(t),t<=0?Jt(e,t):void 0!==r?"string"==typeof i?Jt(e,t).fill(r,i):Jt(e,t).fill(r):Jt(e,t)}(null,e,t,r)},Gt.allocUnsafe=function(e){return Zt(null,e)},Gt.allocUnsafeSlow=function(e){return Zt(null,e)},Gt.isBuffer=function(e){return null!=e&&(!!e._isBuffer||$r(e)||function(e){return"function"==typeof e.readFloatLE&&"function"==typeof e.slice&&$r(e.slice(0,0))}(e))},Gt.compare=function(e,t){if(!tr(e)||!tr(t))throw new TypeError("Arguments must be Buffers");if(e===t)return 0;for(var r=e.length,i=t.length,s=0,n=Math.min(r,i);s<n;++s)if(e[s]!==t[s]){r=e[s],i=t[s];break}return r<i?-1:i<r?1:0},Gt.isEncoding=function(e){switch(String(e).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"latin1":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return!0;default:return!1}},Gt.concat=function(e,t){if(!Kt(e))throw new TypeError('"list" argument must be an Array of Buffers');if(0===e.length)return Gt.alloc(0);var r;if(void 0===t)for(t=0,r=0;r<e.length;++r)t+=e[r].length;var i=Gt.allocUnsafe(t),s=0;for(r=0;r<e.length;++r){var n=e[r];if(!tr(n))throw new TypeError('"list" argument must be an Array of Buffers');n.copy(i,s),s+=n.length}return i},Gt.byteLength=rr,Gt.prototype._isBuffer=!0,Gt.prototype.swap16=function(){var e=this.length;if(e%2!=0)throw new RangeError("Buffer size must be a multiple of 16-bits");for(var t=0;t<e;t+=2)sr(this,t,t+1);return this},Gt.prototype.swap32=function(){var e=this.length;if(e%4!=0)throw new RangeError("Buffer size must be a multiple of 32-bits");for(var t=0;t<e;t+=4)sr(this,t,t+3),sr(this,t+1,t+2);return this},Gt.prototype.swap64=function(){var e=this.length;if(e%8!=0)throw new RangeError("Buffer size must be a multiple of 64-bits");for(var t=0;t<e;t+=8)sr(this,t,t+7),sr(this,t+1,t+6),sr(this,t+2,t+5),sr(this,t+3,t+4);return this},Gt.prototype.toString=function(){var e=0|this.length;return 0===e?"":0===arguments.length?pr(this,0,e):ir.apply(this,arguments)},Gt.prototype.equals=function(e){if(!tr(e))throw new TypeError("Argument must be a Buffer");return this===e||0===Gt.compare(this,e)},Gt.prototype.inspect=function(){var e="";return this.length>0&&(e=this.toString("hex",0,50).match(/.{2}/g).join(" "),this.length>50&&(e+=" ... ")),"<Buffer "+e+">"},Gt.prototype.compare=function(e,t,r,i,s){if(!tr(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===r&&(r=e?e.length:0),void 0===i&&(i=0),void 0===s&&(s=this.length),t<0||r>e.length||i<0||s>this.length)throw new RangeError("out of range index");if(i>=s&&t>=r)return 0;if(i>=s)return-1;if(t>=r)return 1;if(this===e)return 0;for(var n=(s>>>=0)-(i>>>=0),o=(r>>>=0)-(t>>>=0),a=Math.min(n,o),c=this.slice(i,s),u=e.slice(t,r),l=0;l<a;++l)if(c[l]!==u[l]){n=c[l],o=u[l];break}return n<o?-1:o<n?1:0},Gt.prototype.includes=function(e,t,r){return-1!==this.indexOf(e,t,r)},Gt.prototype.indexOf=function(e,t,r){return nr(this,e,t,r,!0)},Gt.prototype.lastIndexOf=function(e,t,r){return nr(this,e,t,r,!1)},Gt.prototype.write=function(e,t,r,i){if(void 0===t)i="utf8",r=this.length,t=0;else if(void 0===r&&"string"==typeof t)i=t,r=this.length,t=0;else{if(!isFinite(t))throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported");t|=0,isFinite(r)?(r|=0,void 0===i&&(i="utf8")):(i=r,r=void 0)}var s=this.length-t;if((void 0===r||r>s)&&(r=s),e.length>0&&(r<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");i||(i="utf8");for(var n=!1;;)switch(i){case"hex":return ar(this,e,t,r);case"utf8":case"utf-8":return cr(this,e,t,r);case"ascii":return ur(this,e,t,r);case"latin1":case"binary":return lr(this,e,t,r);case"base64":return hr(this,e,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return fr(this,e,t,r);default:if(n)throw new TypeError("Unknown encoding: "+i);i=(""+i).toLowerCase(),n=!0}},Gt.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var mr=4096;function gr(e,t,r){var i="";r=Math.min(e.length,r);for(var s=t;s<r;++s)i+=String.fromCharCode(127&e[s]);return i}function yr(e,t,r){var i="";r=Math.min(e.length,r);for(var s=t;s<r;++s)i+=String.fromCharCode(e[s]);return i}function br(e,t,r){var i=e.length;(!t||t<0)&&(t=0),(!r||r<0||r>i)&&(r=i);for(var s="",n=t;n<r;++n)s+=Ar(e[n]);return s}function wr(e,t,r){for(var i=e.slice(t,r),s="",n=0;n<i.length;n+=2)s+=String.fromCharCode(i[n]+256*i[n+1]);return s}function vr(e,t,r){if(e%1!=0||e<0)throw new RangeError("offset is not uint");if(e+t>r)throw new RangeError("Trying to access beyond buffer length")}function kr(e,t,r,i,s,n){if(!tr(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>s||t<n)throw new RangeError('"value" argument is out of bounds');if(r+i>e.length)throw new RangeError("Index out of range")}function _r(e,t,r,i){t<0&&(t=65535+t+1);for(var s=0,n=Math.min(e.length-r,2);s<n;++s)e[r+s]=(t&255<<8*(i?s:1-s))>>>8*(i?s:1-s)}function Sr(e,t,r,i){t<0&&(t=4294967295+t+1);for(var s=0,n=Math.min(e.length-r,4);s<n;++s)e[r+s]=t>>>8*(i?s:3-s)&255}function Or(e,t,r,i,s,n){if(r+i>e.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("Index out of range")}function Rr(e,t,r,i,s){return s||Or(e,0,r,4),Ht(e,t,r,i,23,4),r+4}function jr(e,t,r,i,s){return s||Or(e,0,r,8),Ht(e,t,r,i,52,8),r+8}Gt.prototype.slice=function(e,t){var r,i=this.length;if((e=~~e)<0?(e+=i)<0&&(e=0):e>i&&(e=i),(t=void 0===t?i:~~t)<0?(t+=i)<0&&(t=0):t>i&&(t=i),t<e&&(t=e),Gt.TYPED_ARRAY_SUPPORT)(r=this.subarray(e,t)).__proto__=Gt.prototype;else{var s=t-e;r=new Gt(s,void 0);for(var n=0;n<s;++n)r[n]=this[n+e]}return r},Gt.prototype.readUIntLE=function(e,t,r){e|=0,t|=0,r||vr(e,t,this.length);for(var i=this[e],s=1,n=0;++n<t&&(s*=256);)i+=this[e+n]*s;return i},Gt.prototype.readUIntBE=function(e,t,r){e|=0,t|=0,r||vr(e,t,this.length);for(var i=this[e+--t],s=1;t>0&&(s*=256);)i+=this[e+--t]*s;return i},Gt.prototype.readUInt8=function(e,t){return t||vr(e,1,this.length),this[e]},Gt.prototype.readUInt16LE=function(e,t){return t||vr(e,2,this.length),this[e]|this[e+1]<<8},Gt.prototype.readUInt16BE=function(e,t){return t||vr(e,2,this.length),this[e]<<8|this[e+1]},Gt.prototype.readUInt32LE=function(e,t){return t||vr(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},Gt.prototype.readUInt32BE=function(e,t){return t||vr(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},Gt.prototype.readIntLE=function(e,t,r){e|=0,t|=0,r||vr(e,t,this.length);for(var i=this[e],s=1,n=0;++n<t&&(s*=256);)i+=this[e+n]*s;return i>=(s*=128)&&(i-=Math.pow(2,8*t)),i},Gt.prototype.readIntBE=function(e,t,r){e|=0,t|=0,r||vr(e,t,this.length);for(var i=t,s=1,n=this[e+--i];i>0&&(s*=256);)n+=this[e+--i]*s;return n>=(s*=128)&&(n-=Math.pow(2,8*t)),n},Gt.prototype.readInt8=function(e,t){return t||vr(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},Gt.prototype.readInt16LE=function(e,t){t||vr(e,2,this.length);var r=this[e]|this[e+1]<<8;return 32768&r?4294901760|r:r},Gt.prototype.readInt16BE=function(e,t){t||vr(e,2,this.length);var r=this[e+1]|this[e]<<8;return 32768&r?4294901760|r:r},Gt.prototype.readInt32LE=function(e,t){return t||vr(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},Gt.prototype.readInt32BE=function(e,t){return t||vr(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},Gt.prototype.readFloatLE=function(e,t){return t||vr(e,4,this.length),zt(this,e,!0,23,4)},Gt.prototype.readFloatBE=function(e,t){return t||vr(e,4,this.length),zt(this,e,!1,23,4)},Gt.prototype.readDoubleLE=function(e,t){return t||vr(e,8,this.length),zt(this,e,!0,52,8)},Gt.prototype.readDoubleBE=function(e,t){return t||vr(e,8,this.length),zt(this,e,!1,52,8)},Gt.prototype.writeUIntLE=function(e,t,r,i){(e=+e,t|=0,r|=0,i)||kr(this,e,t,r,Math.pow(2,8*r)-1,0);var s=1,n=0;for(this[t]=255&e;++n<r&&(s*=256);)this[t+n]=e/s&255;return t+r},Gt.prototype.writeUIntBE=function(e,t,r,i){(e=+e,t|=0,r|=0,i)||kr(this,e,t,r,Math.pow(2,8*r)-1,0);var s=r-1,n=1;for(this[t+s]=255&e;--s>=0&&(n*=256);)this[t+s]=e/n&255;return t+r},Gt.prototype.writeUInt8=function(e,t,r){return e=+e,t|=0,r||kr(this,e,t,1,255,0),Gt.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},Gt.prototype.writeUInt16LE=function(e,t,r){return e=+e,t|=0,r||kr(this,e,t,2,65535,0),Gt.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):_r(this,e,t,!0),t+2},Gt.prototype.writeUInt16BE=function(e,t,r){return e=+e,t|=0,r||kr(this,e,t,2,65535,0),Gt.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):_r(this,e,t,!1),t+2},Gt.prototype.writeUInt32LE=function(e,t,r){return e=+e,t|=0,r||kr(this,e,t,4,4294967295,0),Gt.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):Sr(this,e,t,!0),t+4},Gt.prototype.writeUInt32BE=function(e,t,r){return e=+e,t|=0,r||kr(this,e,t,4,4294967295,0),Gt.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):Sr(this,e,t,!1),t+4},Gt.prototype.writeIntLE=function(e,t,r,i){if(e=+e,t|=0,!i){var s=Math.pow(2,8*r-1);kr(this,e,t,r,s-1,-s)}var n=0,o=1,a=0;for(this[t]=255&e;++n<r&&(o*=256);)e<0&&0===a&&0!==this[t+n-1]&&(a=1),this[t+n]=(e/o|0)-a&255;return t+r},Gt.prototype.writeIntBE=function(e,t,r,i){if(e=+e,t|=0,!i){var s=Math.pow(2,8*r-1);kr(this,e,t,r,s-1,-s)}var n=r-1,o=1,a=0;for(this[t+n]=255&e;--n>=0&&(o*=256);)e<0&&0===a&&0!==this[t+n+1]&&(a=1),this[t+n]=(e/o|0)-a&255;return t+r},Gt.prototype.writeInt8=function(e,t,r){return e=+e,t|=0,r||kr(this,e,t,1,127,-128),Gt.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},Gt.prototype.writeInt16LE=function(e,t,r){return e=+e,t|=0,r||kr(this,e,t,2,32767,-32768),Gt.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):_r(this,e,t,!0),t+2},Gt.prototype.writeInt16BE=function(e,t,r){return e=+e,t|=0,r||kr(this,e,t,2,32767,-32768),Gt.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):_r(this,e,t,!1),t+2},Gt.prototype.writeInt32LE=function(e,t,r){return e=+e,t|=0,r||kr(this,e,t,4,2147483647,-2147483648),Gt.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):Sr(this,e,t,!0),t+4},Gt.prototype.writeInt32BE=function(e,t,r){return e=+e,t|=0,r||kr(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),Gt.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):Sr(this,e,t,!1),t+4},Gt.prototype.writeFloatLE=function(e,t,r){return Rr(this,e,t,!0,r)},Gt.prototype.writeFloatBE=function(e,t,r){return Rr(this,e,t,!1,r)},Gt.prototype.writeDoubleLE=function(e,t,r){return jr(this,e,t,!0,r)},Gt.prototype.writeDoubleBE=function(e,t,r){return jr(this,e,t,!1,r)},Gt.prototype.copy=function(e,t,r,i){if(r||(r=0),i||0===i||(i=this.length),t>=e.length&&(t=e.length),t||(t=0),i>0&&i<r&&(i=r),i===r)return 0;if(0===e.length||0===this.length)return 0;if(t<0)throw new RangeError("targetStart out of bounds");if(r<0||r>=this.length)throw new RangeError("sourceStart out of bounds");if(i<0)throw new RangeError("sourceEnd out of bounds");i>this.length&&(i=this.length),e.length-t<i-r&&(i=e.length-t+r);var s,n=i-r;if(this===e&&r<t&&t<i)for(s=n-1;s>=0;--s)e[s+t]=this[s+r];else if(n<1e3||!Gt.TYPED_ARRAY_SUPPORT)for(s=0;s<n;++s)e[s+t]=this[s+r];else Uint8Array.prototype.set.call(e,this.subarray(r,r+n),t);return n},Gt.prototype.fill=function(e,t,r,i){if("string"==typeof e){if("string"==typeof t?(i=t,t=0,r=this.length):"string"==typeof r&&(i=r,r=this.length),1===e.length){var s=e.charCodeAt(0);s<256&&(e=s)}if(void 0!==i&&"string"!=typeof i)throw new TypeError("encoding must be a string");if("string"==typeof i&&!Gt.isEncoding(i))throw new TypeError("Unknown encoding: "+i)}else"number"==typeof e&&(e&=255);if(t<0||this.length<t||this.length<r)throw new RangeError("Out of range index");if(r<=t)return this;var n;if(t>>>=0,r=void 0===r?this.length:r>>>0,e||(e=0),"number"==typeof e)for(n=t;n<r;++n)this[n]=e;else{var o=tr(e)?e:Er(new Gt(e,i).toString()),a=o.length;for(n=0;n<r-t;++n)this[n+t]=o[n%a]}return this};var xr=/[^+\/0-9A-Za-z-_]/g;function Ar(e){return e<16?"0"+e.toString(16):e.toString(16)}function Er(e,t){var r;t=t||1/0;for(var i=e.length,s=null,n=[],o=0;o<i;++o){if((r=e.charCodeAt(o))>55295&&r<57344){if(!s){if(r>56319){(t-=3)>-1&&n.push(239,191,189);continue}if(o+1===i){(t-=3)>-1&&n.push(239,191,189);continue}s=r;continue}if(r<56320){(t-=3)>-1&&n.push(239,191,189),s=r;continue}r=65536+(s-55296<<10|r-56320)}else s&&(t-=3)>-1&&n.push(239,191,189);if(s=null,r<128){if((t-=1)<0)break;n.push(r)}else if(r<2048){if((t-=2)<0)break;n.push(r>>6|192,63&r|128)}else if(r<65536){if((t-=3)<0)break;n.push(r>>12|224,r>>6&63|128,63&r|128)}else{if(!(r<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;n.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128)}}return n}function Dr(e){return function(e){var t,r,i,s,n,o;Lt||Ut();var a=e.length;if(a%4>0)throw new Error("Invalid string. Length must be a multiple of 4");n="="===e[a-2]?2:"="===e[a-1]?1:0,o=new Mt(3*a/4-n),i=n>0?a-4:a;var c=0;for(t=0,r=0;t<i;t+=4,r+=3)s=Tt[e.charCodeAt(t)]<<18|Tt[e.charCodeAt(t+1)]<<12|Tt[e.charCodeAt(t+2)]<<6|Tt[e.charCodeAt(t+3)],o[c++]=s>>16&255,o[c++]=s>>8&255,o[c++]=255&s;return 2===n?(s=Tt[e.charCodeAt(t)]<<2|Tt[e.charCodeAt(t+1)]>>4,o[c++]=255&s):1===n&&(s=Tt[e.charCodeAt(t)]<<10|Tt[e.charCodeAt(t+1)]<<4|Tt[e.charCodeAt(t+2)]>>2,o[c++]=s>>8&255,o[c++]=255&s),o}(function(e){if((e=function(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}(e).replace(xr,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function Cr(e,t,r,i){for(var s=0;s<i&&!(s+r>=t.length||s>=e.length);++s)t[s+r]=e[s];return s}function $r(e){return!!e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}function Nr(){this.head=null,this.tail=null,this.length=0}Nr.prototype.push=function(e){var t={data:e,next:null};this.length>0?this.tail.next=t:this.head=t,this.tail=t,++this.length},Nr.prototype.unshift=function(e){var t={data:e,next:this.head};0===this.length&&(this.tail=t),this.head=t,++this.length},Nr.prototype.shift=function(){if(0!==this.length){var e=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,e}},Nr.prototype.clear=function(){this.head=this.tail=null,this.length=0},Nr.prototype.join=function(e){if(0===this.length)return"";for(var t=this.head,r=""+t.data;t=t.next;)r+=e+t.data;return r},Nr.prototype.concat=function(e){if(0===this.length)return Gt.alloc(0);if(1===this.length)return this.head.data;for(var t=Gt.allocUnsafe(e>>>0),r=this.head,i=0;r;)r.data.copy(t,i),i+=r.data.length,r=r.next;return t};var Ir=Gt.isEncoding||function(e){switch(e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function Pr(e){switch(this.encoding=(e||"utf8").toLowerCase().replace(/[-_]/,""),function(e){if(e&&!Ir(e))throw new Error("Unknown encoding: "+e)}(e),this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2,this.detectIncompleteChar=Mr;break;case"base64":this.surrogateSize=3,this.detectIncompleteChar=Lr;break;default:return void(this.write=Tr)}this.charBuffer=new Gt(6),this.charReceived=0,this.charLength=0}function Tr(e){return e.toString(this.encoding)}function Mr(e){this.charReceived=e.length%2,this.charLength=this.charReceived?2:0}function Lr(e){this.charReceived=e.length%3,this.charLength=this.charReceived?3:0}Pr.prototype.write=function(e){for(var t="";this.charLength;){var r=e.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:e.length;if(e.copy(this.charBuffer,this.charReceived,0,r),this.charReceived+=r,this.charReceived<this.charLength)return"";if(e=e.slice(r,e.length),!((s=(t=this.charBuffer.slice(0,this.charLength).toString(this.encoding)).charCodeAt(t.length-1))>=55296&&s<=56319)){if(this.charReceived=this.charLength=0,0===e.length)return t;break}this.charLength+=this.surrogateSize,t=""}this.detectIncompleteChar(e);var i=e.length;this.charLength&&(e.copy(this.charBuffer,0,e.length-this.charReceived,i),i-=this.charReceived);var s;i=(t+=e.toString(this.encoding,0,i)).length-1;if((s=t.charCodeAt(i))>=55296&&s<=56319){var n=this.surrogateSize;return this.charLength+=n,this.charReceived+=n,this.charBuffer.copy(this.charBuffer,n,0,n),e.copy(this.charBuffer,0,0,n),t.substring(0,i)}return t},Pr.prototype.detectIncompleteChar=function(e){for(var t=e.length>=3?3:e.length;t>0;t--){var r=e[e.length-t];if(1==t&&r>>5==6){this.charLength=2;break}if(t<=2&&r>>4==14){this.charLength=3;break}if(t<=3&&r>>3==30){this.charLength=4;break}}this.charReceived=t},Pr.prototype.end=function(e){var t="";if(e&&e.length&&(t=this.write(e)),this.charReceived){var r=this.charReceived,i=this.charBuffer,s=this.encoding;t+=i.slice(0,r).toString(s)}return t},qr.ReadableState=Fr;var Ur=function(e){if(xt(gt)&&(gt=ft.env.NODE_DEBUG||""),e=e.toUpperCase(),!yt[e])if(new RegExp("\\b"+e+"\\b","i").test(gt)){yt[e]=function(){var t=pt.apply(null,arguments);console.error("%s %d: %s",e,0,t)}}else yt[e]=function(){};return yt[e]}("stream");function Fr(e,t){e=e||{},this.objectMode=!!e.objectMode,t instanceof mi&&(this.objectMode=this.objectMode||!!e.readableObjectMode);var r=e.highWaterMark,i=this.objectMode?16:16384;this.highWaterMark=r||0===r?r:i,this.highWaterMark=~~this.highWaterMark,this.buffer=new Nr,this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.resumeScheduled=!1,this.defaultEncoding=e.defaultEncoding||"utf8",this.ranOut=!1,this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,e.encoding&&(this.decoder=new Pr(e.encoding),this.encoding=e.encoding)}function qr(e){if(!(this instanceof qr))return new qr(e);this._readableState=new Fr(e,this),this.readable=!0,e&&"function"==typeof e.read&&(this._read=e.read),$e.call(this)}function Br(e,t,r,i,s){var n=function(e,t){var r=null;Buffer.isBuffer(t)||"string"==typeof t||null==t||e.objectMode||(r=new TypeError("Invalid non-string/buffer chunk"));return r}(t,r);if(n)e.emit("error",n);else if(null===r)t.reading=!1,function(e,t){if(t.ended)return;if(t.decoder){var r=t.decoder.end();r&&r.length&&(t.buffer.push(r),t.length+=t.objectMode?1:r.length)}t.ended=!0,Vr(e)}(e,t);else if(t.objectMode||r&&r.length>0)if(t.ended&&!s){var o=new Error("stream.push() after EOF");e.emit("error",o)}else if(t.endEmitted&&s){var a=new Error("stream.unshift() after end event");e.emit("error",a)}else{var c;!t.decoder||s||i||(r=t.decoder.write(r),c=!t.objectMode&&0===r.length),s||(t.reading=!1),c||(t.flowing&&0===t.length&&!t.sync?(e.emit("data",r),e.read(0)):(t.length+=t.objectMode?1:r.length,s?t.buffer.unshift(r):t.buffer.push(r),t.needReadable&&Vr(e))),function(e,t){t.readingMore||(t.readingMore=!0,ut(Wr,e,t))}(e,t)}else s||(t.reading=!1);return function(e){return!e.ended&&(e.needReadable||e.length<e.highWaterMark||0===e.length)}(t)}ht(qr,$e),qr.prototype.push=function(e,t){var r=this._readableState;return r.objectMode||"string"!=typeof e||(t=t||r.defaultEncoding)!==r.encoding&&(e=Buffer.from(e,t),t=""),Br(this,r,e,t,!1)},qr.prototype.unshift=function(e){return Br(this,this._readableState,e,"",!0)},qr.prototype.isPaused=function(){return!1===this._readableState.flowing},qr.prototype.setEncoding=function(e){return this._readableState.decoder=new Pr(e),this._readableState.encoding=e,this};var zr=8388608;function Hr(e,t){return e<=0||0===t.length&&t.ended?0:t.objectMode?1:e!=e?t.flowing&&t.length?t.buffer.head.data.length:t.length:(e>t.highWaterMark&&(t.highWaterMark=function(e){return e>=zr?e=zr:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function Vr(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(Ur("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?ut(Kr,e):Kr(e))}function Kr(e){Ur("emit readable"),e.emit("readable"),Yr(e)}function Wr(e,t){for(var r=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length<t.highWaterMark&&(Ur("maybeReadMore read 0"),e.read(0),r!==t.length);)r=t.length;t.readingMore=!1}function Jr(e){Ur("readable nexttick read 0"),e.read(0)}function Gr(e,t){t.reading||(Ur("resume read 0"),e.read(0)),t.resumeScheduled=!1,t.awaitDrain=0,e.emit("resume"),Yr(e),t.flowing&&!t.reading&&e.read(0)}function Yr(e){var t=e._readableState;for(Ur("flow",t.flowing);t.flowing&&null!==e.read(););}function Qr(e,t){return 0===t.length?null:(t.objectMode?r=t.buffer.shift():!e||e>=t.length?(r=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.head.data:t.buffer.concat(t.length),t.buffer.clear()):r=function(e,t,r){var i;e<t.head.data.length?(i=t.head.data.slice(0,e),t.head.data=t.head.data.slice(e)):i=e===t.head.data.length?t.shift():r?function(e,t){var r=t.head,i=1,s=r.data;e-=s.length;for(;r=r.next;){var n=r.data,o=e>n.length?n.length:e;if(o===n.length?s+=n:s+=n.slice(0,e),0===(e-=o)){o===n.length?(++i,r.next?t.head=r.next:t.head=t.tail=null):(t.head=r,r.data=n.slice(o));break}++i}return t.length-=i,s}(e,t):function(e,t){var r=Buffer.allocUnsafe(e),i=t.head,s=1;i.data.copy(r),e-=i.data.length;for(;i=i.next;){var n=i.data,o=e>n.length?n.length:e;if(n.copy(r,r.length-e,0,o),0===(e-=o)){o===n.length?(++s,i.next?t.head=i.next:t.head=t.tail=null):(t.head=i,i.data=n.slice(o));break}++s}return t.length-=s,r}(e,t);return i}(e,t.buffer,t.decoder),r);var r}function Zr(e){var t=e._readableState;if(t.length>0)throw new Error('"endReadable()" called on non-empty stream');t.endEmitted||(t.ended=!0,ut(Xr,t,e))}function Xr(e,t){e.endEmitted||0!==e.length||(e.endEmitted=!0,t.readable=!1,t.emit("end"))}function ei(e,t){for(var r=0,i=e.length;r<i;r++)if(e[r]===t)return r;return-1}function ti(){}function ri(e,t,r){this.chunk=e,this.encoding=t,this.callback=r,this.next=null}function ii(e,t){Object.defineProperty(this,"buffer",{get:mt(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.")}),e=e||{},this.objectMode=!!e.objectMode,t instanceof mi&&(this.objectMode=this.objectMode||!!e.writableObjectMode);var r=e.highWaterMark,i=this.objectMode?16:16384;this.highWaterMark=r||0===r?r:i,this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var s=!1===e.decodeStrings;this.decodeStrings=!s,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var r=e._writableState,i=r.sync,s=r.writecb;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(r),t)!function(e,t,r,i,s){--t.pendingcb,r?ut(s,i):s(i);e._writableState.errorEmitted=!0,e.emit("error",i)}(e,r,i,t,s);else{var n=ci(r);n||r.corked||r.bufferProcessing||!r.bufferedRequest||ai(e,r),i?ut(oi,e,r,n,s):oi(e,r,n,s)}}(t,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.bufferedRequestCount=0,this.corkedRequestsFree=new hi(this)}function si(e){if(!(this instanceof si||this instanceof mi))return new si(e);this._writableState=new ii(e,this),this.writable=!0,e&&("function"==typeof e.write&&(this._write=e.write),"function"==typeof e.writev&&(this._writev=e.writev)),$e.call(this)}function ni(e,t,r,i,s,n,o){t.writelen=i,t.writecb=o,t.writing=!0,t.sync=!0,r?e._writev(s,t.onwrite):e._write(s,n,t.onwrite),t.sync=!1}function oi(e,t,r,i){r||function(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}(e,t),t.pendingcb--,i(),li(e,t)}function ai(e,t){t.bufferProcessing=!0;var r=t.bufferedRequest;if(e._writev&&r&&r.next){var i=t.bufferedRequestCount,s=new Array(i),n=t.corkedRequestsFree;n.entry=r;for(var o=0;r;)s[o]=r,r=r.next,o+=1;ni(e,t,!0,t.length,s,"",n.finish),t.pendingcb++,t.lastBufferedRequest=null,n.next?(t.corkedRequestsFree=n.next,n.next=null):t.corkedRequestsFree=new hi(t)}else{for(;r;){var a=r.chunk,c=r.encoding,u=r.callback;if(ni(e,t,!1,t.objectMode?1:a.length,a,c,u),r=r.next,t.writing)break}null===r&&(t.lastBufferedRequest=null)}t.bufferedRequestCount=0,t.bufferedRequest=r,t.bufferProcessing=!1}function ci(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function ui(e,t){t.prefinished||(t.prefinished=!0,e.emit("prefinish"))}function li(e,t){var r=ci(t);return r&&(0===t.pendingcb?(ui(e,t),t.finished=!0,e.emit("finish")):ui(e,t)),r}function hi(e){var t=this;this.next=null,this.entry=null,this.finish=function(r){var i=t.entry;for(t.entry=null;i;){var s=i.callback;e.pendingcb--,s(r),i=i.next}e.corkedRequestsFree?e.corkedRequestsFree.next=t:e.corkedRequestsFree=t}}qr.prototype.read=function(e){Ur("read",e),e=parseInt(e,10);var t=this._readableState,r=e;if(0!==e&&(t.emittedReadable=!1),0===e&&t.needReadable&&(t.length>=t.highWaterMark||t.ended))return Ur("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?Zr(this):Vr(this),null;if(0===(e=Hr(e,t))&&t.ended)return 0===t.length&&Zr(this),null;var i,s=t.needReadable;return Ur("need readable",s),(0===t.length||t.length-e<t.highWaterMark)&&Ur("length less than watermark",s=!0),t.ended||t.reading?Ur("reading or ended",s=!1):s&&(Ur("do read"),t.reading=!0,t.sync=!0,0===t.length&&(t.needReadable=!0),this._read(t.highWaterMark),t.sync=!1,t.reading||(e=Hr(r,t))),null===(i=e>0?Qr(e,t):null)?(t.needReadable=!0,e=0):t.length-=e,0===t.length&&(t.ended||(t.needReadable=!0),r!==e&&t.ended&&Zr(this)),null!==i&&this.emit("data",i),i},qr.prototype._read=function(e){this.emit("error",new Error("not implemented"))},qr.prototype.pipe=function(e,t){var r=this,i=this._readableState;switch(i.pipesCount){case 0:i.pipes=e;break;case 1:i.pipes=[i.pipes,e];break;default:i.pipes.push(e)}i.pipesCount+=1,Ur("pipe count=%d opts=%j",i.pipesCount,t);var s=!t||!1!==t.end?o:u;function n(e){Ur("onunpipe"),e===r&&u()}function o(){Ur("onend"),e.end()}i.endEmitted?ut(s):r.once("end",s),e.on("unpipe",n);var a=function(e){return function(){var t=e._readableState;Ur("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&e.listeners("data").length&&(t.flowing=!0,Yr(e))}}(r);e.on("drain",a);var c=!1;function u(){Ur("cleanup"),e.removeListener("close",d),e.removeListener("finish",p),e.removeListener("drain",a),e.removeListener("error",f),e.removeListener("unpipe",n),r.removeListener("end",o),r.removeListener("end",u),r.removeListener("data",h),c=!0,!i.awaitDrain||e._writableState&&!e._writableState.needDrain||a()}var l=!1;function h(t){Ur("ondata"),l=!1,!1!==e.write(t)||l||((1===i.pipesCount&&i.pipes===e||i.pipesCount>1&&-1!==ei(i.pipes,e))&&!c&&(Ur("false write response, pause",r._readableState.awaitDrain),r._readableState.awaitDrain++,l=!0),r.pause())}function f(t){var r;Ur("onerror",t),m(),e.removeListener("error",f),0===(r="error",e.listeners(r).length)&&e.emit("error",t)}function d(){e.removeListener("finish",p),m()}function p(){Ur("onfinish"),e.removeListener("close",d),m()}function m(){Ur("unpipe"),r.unpipe(e)}return r.on("data",h),function(e,t,r){if("function"==typeof e.prependListener)return e.prependListener(t,r);e._events&&e._events[t]?Array.isArray(e._events[t])?e._events[t].unshift(r):e._events[t]=[r,e._events[t]]:e.on(t,r)}(e,"error",f),e.once("close",d),e.once("finish",p),e.emit("pipe",r),i.flowing||(Ur("pipe resume"),r.resume()),e},qr.prototype.unpipe=function(e){var t=this._readableState;if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes||(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this)),this;if(!e){var r=t.pipes,i=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var s=0;s<i;s++)r[s].emit("unpipe",this);return this}var n=ei(t.pipes,e);return-1===n||(t.pipes.splice(n,1),t.pipesCount-=1,1===t.pipesCount&&(t.pipes=t.pipes[0]),e.emit("unpipe",this)),this},qr.prototype.on=function(e,t){var r=$e.prototype.on.call(this,e,t);if("data"===e)!1!==this._readableState.flowing&&this.resume();else if("readable"===e){var i=this._readableState;i.endEmitted||i.readableListening||(i.readableListening=i.needReadable=!0,i.emittedReadable=!1,i.reading?i.length&&Vr(this):ut(Jr,this))}return r},qr.prototype.addListener=qr.prototype.on,qr.prototype.resume=function(){var e=this._readableState;return e.flowing||(Ur("resume"),e.flowing=!0,function(e,t){t.resumeScheduled||(t.resumeScheduled=!0,ut(Gr,e,t))}(this,e)),this},qr.prototype.pause=function(){return Ur("call pause flowing=%j",this._readableState.flowing),!1!==this._readableState.flowing&&(Ur("pause"),this._readableState.flowing=!1,this.emit("pause")),this},qr.prototype.wrap=function(e){var t=this._readableState,r=!1,i=this;for(var s in e.on("end",function(){if(Ur("wrapped end"),t.decoder&&!t.ended){var e=t.decoder.end();e&&e.length&&i.push(e)}i.push(null)}),e.on("data",function(s){(Ur("wrapped data"),t.decoder&&(s=t.decoder.write(s)),t.objectMode&&null==s)||(t.objectMode||s&&s.length)&&(i.push(s)||(r=!0,e.pause()))}),e)void 0===this[s]&&"function"==typeof e[s]&&(this[s]=function(t){return function(){return e[t].apply(e,arguments)}}(s));return function(e,t){for(var r=0,i=e.length;r<i;r++)t(e[r],r)}(["error","close","destroy","pause","resume"],function(t){e.on(t,i.emit.bind(i,t))}),i._read=function(t){Ur("wrapped _read",t),r&&(r=!1,e.resume())},i},qr._fromList=Qr,si.WritableState=ii,ht(si,$e),ii.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},si.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))},si.prototype.write=function(e,t,r){var i=this._writableState,s=!1;return"function"==typeof t&&(r=t,t=null),Gt.isBuffer(e)?t="buffer":t||(t=i.defaultEncoding),"function"!=typeof r&&(r=ti),i.ended?function(e,t){var r=new Error("write after end");e.emit("error",r),ut(t,r)}(this,r):function(e,t,r,i){var s=!0,n=!1;return null===r?n=new TypeError("May not write null values to stream"):Gt.isBuffer(r)||"string"==typeof r||void 0===r||t.objectMode||(n=new TypeError("Invalid non-string/buffer chunk")),n&&(e.emit("error",n),ut(i,n),s=!1),s}(this,i,e,r)&&(i.pendingcb++,s=function(e,t,r,i,s){r=function(e,t,r){e.objectMode||!1===e.decodeStrings||"string"!=typeof t||(t=Gt.from(t,r));return t}(t,r,i),Gt.isBuffer(r)&&(i="buffer");var n=t.objectMode?1:r.length;t.length+=n;var o=t.length<t.highWaterMark;o||(t.needDrain=!0);if(t.writing||t.corked){var a=t.lastBufferedRequest;t.lastBufferedRequest=new ri(r,i,s),a?a.next=t.lastBufferedRequest:t.bufferedRequest=t.lastBufferedRequest,t.bufferedRequestCount+=1}else ni(e,t,!1,n,r,i,s);return o}(this,i,e,t,r)),s},si.prototype.cork=function(){this._writableState.corked++},si.prototype.uncork=function(){var e=this._writableState;e.corked&&(e.corked--,e.writing||e.corked||e.finished||e.bufferProcessing||!e.bufferedRequest||ai(this,e))},si.prototype.setDefaultEncoding=function(e){if("string"==typeof e&&(e=e.toLowerCase()),!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((e+"").toLowerCase())>-1))throw new TypeError("Unknown encoding: "+e);return this._writableState.defaultEncoding=e,this},si.prototype._write=function(e,t,r){r(new Error("not implemented"))},si.prototype._writev=null,si.prototype.end=function(e,t,r){var i=this._writableState;"function"==typeof e?(r=e,e=null,t=null):"function"==typeof t&&(r=t,t=null),null!=e&&this.write(e,t),i.corked&&(i.corked=1,this.uncork()),i.ending||i.finished||function(e,t,r){t.ending=!0,li(e,t),r&&(t.finished?ut(r):e.once("finish",r));t.ended=!0,e.writable=!1}(this,i,r)},ht(mi,qr);for(var fi=Object.keys(si.prototype),di=0;di<fi.length;di++){var pi=fi[di];mi.prototype[pi]||(mi.prototype[pi]=si.prototype[pi])}function mi(e){if(!(this instanceof mi))return new mi(e);qr.call(this,e),si.call(this,e),e&&!1===e.readable&&(this.readable=!1),e&&!1===e.writable&&(this.writable=!1),this.allowHalfOpen=!0,e&&!1===e.allowHalfOpen&&(this.allowHalfOpen=!1),this.once("end",gi)}function gi(){this.allowHalfOpen||this._writableState.ended||ut(yi,this)}function yi(e){e.end()}function bi(e){this.afterTransform=function(t,r){return function(e,t,r){var i=e._transformState;i.transforming=!1;var s=i.writecb;if(!s)return e.emit("error",new Error("no writecb in Transform class"));i.writechunk=null,i.writecb=null,null!=r&&e.push(r);s(t);var n=e._readableState;n.reading=!1,(n.needReadable||n.length<n.highWaterMark)&&e._read(n.highWaterMark)}(e,t,r)},this.needTransform=!1,this.transforming=!1,this.writecb=null,this.writechunk=null,this.writeencoding=null}function wi(e){if(!(this instanceof wi))return new wi(e);mi.call(this,e),this._transformState=new bi(this);var t=this;this._readableState.needReadable=!0,this._readableState.sync=!1,e&&("function"==typeof e.transform&&(this._transform=e.transform),"function"==typeof e.flush&&(this._flush=e.flush)),this.once("prefinish",function(){"function"==typeof this._flush?this._flush(function(e){vi(t,e)}):vi(t)})}function vi(e,t){if(t)return e.emit("error",t);var r=e._writableState,i=e._transformState;if(r.length)throw new Error("Calling transform done when ws.length != 0");if(i.transforming)throw new Error("Calling transform done when still transforming");return e.push(null)}function ki(e){if(!(this instanceof ki))return new ki(e);wi.call(this,e)}function _i(){$e.call(this)}ht(wi,mi),wi.prototype.push=function(e,t){return this._transformState.needTransform=!1,mi.prototype.push.call(this,e,t)},wi.prototype._transform=function(e,t,r){throw new Error("Not implemented")},wi.prototype._write=function(e,t,r){var i=this._transformState;if(i.writecb=r,i.writechunk=e,i.writeencoding=t,!i.transforming){var s=this._readableState;(i.needTransform||s.needReadable||s.length<s.highWaterMark)&&this._read(s.highWaterMark)}},wi.prototype._read=function(e){var t=this._transformState;null!==t.writechunk&&t.writecb&&!t.transforming?(t.transforming=!0,this._transform(t.writechunk,t.writeencoding,t.afterTransform)):t.needTransform=!0},ht(ki,wi),ki.prototype._transform=function(e,t,r){r(null,e)},ht(_i,$e),_i.Readable=qr,_i.Writable=si,_i.Duplex=mi,_i.Transform=wi,_i.PassThrough=ki,_i.Stream=_i,_i.prototype.pipe=function(e,t){var r=this;function i(t){e.writable&&!1===e.write(t)&&r.pause&&r.pause()}function s(){r.readable&&r.resume&&r.resume()}r.on("data",i),e.on("drain",s),e._isStdio||t&&!1===t.end||(r.on("end",o),r.on("close",a));var n=!1;function o(){n||(n=!0,e.end())}function a(){n||(n=!0,"function"==typeof e.destroy&&e.destroy())}function c(e){if(u(),0===$e.listenerCount(this,"error"))throw e}function u(){r.removeListener("data",i),e.removeListener("drain",s),r.removeListener("end",o),r.removeListener("close",a),r.removeListener("error",c),e.removeListener("error",c),r.removeListener("end",u),r.removeListener("close",u),e.removeListener("close",u)}return r.on("error",c),e.on("error",c),r.on("end",u),r.on("close",u),e.on("close",u),e.emit("pipe",r),e};class Si extends $e{constructor({resource:e}){super(),this.resource=e,this.client=e.client,this.stream=new s({highWaterMark:3*this.client.parallelism,start:this._start.bind(this),pull:this._pull.bind(this),cancel:this._cancel.bind(this)})}build(){return this.stream.getReader()}async _start(e){this.controller=e,this.continuationToken=null,this.closeNextIteration=!1}async _pull(e){if(this.closeNextIteration)return void e.close();const t=await this.client.listObjects({prefix:`resource=${this.resource.name}`,continuationToken:this.continuationToken}),r=t?.Contents.map(e=>e.Key).map(e=>e.replace(this.client.config.keyPrefix,"")).map(e=>e.startsWith("/")?e.replace("/",""):e).map(e=>e.replace(`resource=${this.resource.name}/id=`,""));this.continuationToken=t.NextContinuationToken,this.enqueue(r),t.IsTruncated||(this.closeNextIteration=!0)}enqueue(e){e.forEach(e=>{this.controller.enqueue(e),this.emit("id",e)})}_cancel(e){}}var Oi=Si;class Ri extends Oi{enqueue(e){this.controller.enqueue(e),this.emit("page",e)}}class ji extends $e{constructor({resource:e,batchSize:t=10,concurrency:r=5}){if(super(),!e)throw new Error("Resource is required for ResourceReader");this.resource=e,this.client=e.client,this.batchSize=t,this.concurrency=r,this.input=new Ri({resource:this.resource}),this.transform=new wi({objectMode:!0,transform:this._transform.bind(this)}),this.input.on("data",e=>{this.transform.write(e)}),this.input.on("end",()=>{this.transform.end()}),this.input.on("error",e=>{this.emit("error",e)}),this.transform.on("data",e=>{this.emit("data",e)}),this.transform.on("end",()=>{this.emit("end")}),this.transform.on("error",e=>{this.emit("error",e)})}build(){return this}async _transform(e,t,r){const[s,n]=await ve(async()=>{await i.for(e).withConcurrency(this.concurrency).handleError(async(e,t)=>{this.emit("error",e,t)}).process(async e=>{const t=await this.resource.get(e);return this.push(t),t})});r(n)}resume(){this.input.resume()}}class xi extends $e{constructor({resource:e,batchSize:t=10,concurrency:r=5}){super(),this.resource=e,this.client=e.client,this.batchSize=t,this.concurrency=r,this.buffer=[],this.writing=!1,this.writable=new si({objectMode:!0,write:this._write.bind(this)}),this.writable.on("finish",()=>{this.emit("finish")}),this.writable.on("error",e=>{this.emit("error",e)})}build(){return this}write(e){return this.buffer.push(e),this._maybeWrite().catch(e=>{this.emit("error",e)}),!0}end(){this.ended=!0,this._maybeWrite().catch(e=>{this.emit("error",e)})}async _maybeWrite(){if(!this.writing&&(0!==this.buffer.length||this.ended)){for(this.writing=!0;this.buffer.length>0;){const e=this.buffer.splice(0,this.batchSize),[t,r]=await ve(async()=>{await i.for(e).withConcurrency(this.concurrency).handleError(async(e,t)=>{this.emit("error",e,t)}).process(async e=>{const[t,r,i]=await ve(async()=>await this.resource.insert(e));return t?i:(this.emit("error",r,e),null)})});t||this.emit("error",r)}this.writing=!1,this.ended&&this.writable.emit("finish")}}async _write(e,t,r){r()}}function Ai(e){return new Promise((t,r)=>{if(!e)return r(new Error("streamToString: stream is undefined"));const i=[];e.on("data",e=>i.push(e)),e.on("error",r),e.on("end",()=>t(Buffer.concat(i).toString("utf-8")))})}var Ei=class extends Qe{constructor({client:e,keyPrefix:t="cache",ttl:r=0,prefix:i}){super(),this.client=e,this.keyPrefix=t,this.config.ttl=r,this.config.client=e,this.config.prefix=void 0!==i?i:t+(t.endsWith("/")?"":"/")}async _set(e,t){let i=JSON.stringify(t);const s=i.length;return i=r.gzipSync(i).toString("base64"),this.client.putObject({key:We(this.keyPrefix,e),body:i,contentEncoding:"gzip",contentType:"application/gzip",metadata:{compressor:"zlib",compressed:"true","client-id":this.client.id,"length-serialized":String(s),"length-compressed":String(i.length),"compression-gain":(i.length/s).toFixed(2)}})}async _get(e){const[t,i,s]=await ve(async()=>{const{Body:t}=await this.client.getObject(We(this.keyPrefix,e));let i=await Ai(t);return i=Buffer.from(i,"base64"),i=r.unzipSync(i).toString(),JSON.parse(i)});if(t)return s;if("NoSuchKey"===i.name||"NotFound"===i.name)return null;throw i}async _del(e){return await this.client.deleteObject(We(this.keyPrefix,e)),!0}async _clear(){const e=await this.client.getAllKeys({prefix:this.keyPrefix});await this.client.deleteObjects(e)}async size(){return(await this.keys()).length}async keys(){const e=await this.client.getAllKeys({prefix:this.keyPrefix}),t=this.keyPrefix.endsWith("/")?this.keyPrefix:this.keyPrefix+"/";return e.map(e=>e.startsWith(t)?e.slice(t.length):e)}};var Di=class extends Qe{constructor(e={}){super(e),this.cache={},this.meta={},this.maxSize=void 0!==e.maxSize?e.maxSize:1e3,this.ttl=void 0!==e.ttl?e.ttl:3e5}async _set(e,t){if(this.maxSize>0&&Object.keys(this.cache).length>=this.maxSize){const e=Object.entries(this.meta).sort((e,t)=>e[1].ts-t[1].ts)[0]?.[0];e&&(delete this.cache[e],delete this.meta[e])}return this.cache[e]=t,this.meta[e]={ts:Date.now()},t}async _get(e){if(!Object.prototype.hasOwnProperty.call(this.cache,e))return null;if(this.ttl>0){const t=Date.now(),r=this.meta[e];if(r&&t-r.ts>1e3*this.ttl)return delete this.cache[e],delete this.meta[e],null}return this.cache[e]}async _del(e){return delete this.cache[e],delete this.meta[e],!0}async _clear(e){if(!e)return this.cache={},this.meta={},!0;for(const t of Object.keys(this.cache))t.startsWith(e)&&(delete this.cache[t],delete this.meta[t]);return!0}async size(){return Object.keys(this.cache).length}async keys(){return Object.keys(this.cache)}},Ci={};class $i extends Qe{constructor({directory:e,prefix:t="cache",ttl:r=36e5,enableCompression:i=!0,compressionThreshold:s=1024,createDirectory:n=!0,fileExtension:o=".cache",enableMetadata:a=!0,maxFileSize:c=10485760,enableStats:u=!1,enableCleanup:l=!0,cleanupInterval:h=3e5,encoding:f="utf8",fileMode:d=420,enableBackup:p=!1,backupSuffix:m=".bak",enableLocking:g=!1,lockTimeout:y=5e3,enableJournal:b=!1,journalFile:w="cache.journal",...v}){if(super(v),!e)throw new Error("FilesystemCache: directory parameter is required");this.directory=Je.resolve(e),this.prefix=t,this.ttl=r,this.enableCompression=i,this.compressionThreshold=s,this.createDirectory=n,this.fileExtension=o,this.enableMetadata=a,this.maxFileSize=c,this.enableStats=u,this.enableCleanup=l,this.cleanupInterval=h,this.encoding=f,this.fileMode=d,this.enableBackup=p,this.backupSuffix=m,this.enableLocking=g,this.lockTimeout=y,this.enableJournal=b,this.journalFile=Je.join(this.directory,w),this.stats={hits:0,misses:0,sets:0,deletes:0,clears:0,errors:0},this.locks=new Map,this.cleanupTimer=null,this._init()}async _init(){this.createDirectory&&await this._ensureDirectory(this.directory),this.enableCleanup&&this.cleanupInterval>0&&(this.cleanupTimer=setInterval(()=>{this._cleanup().catch(e=>{console.warn("FilesystemCache cleanup error:",e.message)})},this.cleanupInterval))}async _ensureDirectory(e){const[t,r]=await ve(async()=>{await n(e,{recursive:!0})});if(!t&&"EEXIST"!==r.code)throw new Error(`Failed to create cache directory: ${r.message}`)}_getFilePath(e){const t=e.replace(/[<>:"/\\|?*]/g,"_"),r=`${this.prefix}_${t}${this.fileExtension}`;return Je.join(this.directory,r)}_getMetadataPath(e){return e+".meta"}async _set(e,t){const i=this._getFilePath(e);try{let s=JSON.stringify(t);const n=Buffer.byteLength(s,this.encoding);if(n>this.maxFileSize)throw new Error(`Cache data exceeds maximum file size: ${n} > ${this.maxFileSize}`);let a=!1,c=s;if(this.enableCompression&&n>=this.compressionThreshold){c=r.gzipSync(Buffer.from(s,this.encoding)).toString("base64"),a=!0}if(this.enableBackup&&await this._fileExists(i)){const e=i+this.backupSuffix;await this._copyFile(i,e)}this.enableLocking&&await this._acquireLock(i);try{if(await o(i,c,{encoding:a?"utf8":this.encoding,mode:this.fileMode}),this.enableMetadata){const t={key:e,timestamp:Date.now(),ttl:this.ttl,compressed:a,originalSize:n,compressedSize:a?Buffer.byteLength(c,"utf8"):n,compressionRatio:a?(Buffer.byteLength(c,"utf8")/n).toFixed(2):1};await o(this._getMetadataPath(i),JSON.stringify(t),{encoding:this.encoding,mode:this.fileMode})}this.enableStats&&this.stats.sets++,this.enableJournal&&await this._journalOperation("set",e,{size:n,compressed:a})}finally{this.enableLocking&&this._releaseLock(i)}return t}catch(t){throw this.enableStats&&this.stats.errors++,new Error(`Failed to set cache key '${e}': ${t.message}`)}}async _get(e){const t=this._getFilePath(e);try{if(!await this._fileExists(t))return this.enableStats&&this.stats.misses++,null;let i=!1;if(this.enableMetadata){const e=this._getMetadataPath(t);if(await this._fileExists(e)){const[t,r,s]=await ve(async()=>{const t=await a(e,this.encoding);return JSON.parse(t)});if(t&&s.ttl>0){i=Date.now()-s.timestamp>s.ttl}}}else if(this.ttl>0){const e=await c(t);i=Date.now()-e.mtime.getTime()>this.ttl}if(i)return await this._del(e),this.enableStats&&this.stats.misses++,null;this.enableLocking&&await this._acquireLock(t);try{const e=await a(t,this.encoding);let i=!1;if(this.enableMetadata){const e=this._getMetadataPath(t);if(await this._fileExists(e)){const[t,r,s]=await ve(async()=>{const t=await a(e,this.encoding);return JSON.parse(t)});t&&(i=s.compressed)}}let s=e;if(i||this.enableCompression&&e.match(/^[A-Za-z0-9+/=]+$/))try{const t=Buffer.from(e,"base64");s=r.gunzipSync(t).toString(this.encoding)}catch(t){s=e}const n=JSON.parse(s);return this.enableStats&&this.stats.hits++,n}finally{this.enableLocking&&this._releaseLock(t)}}catch(t){return this.enableStats&&this.stats.errors++,await this._del(e),null}}async _del(e){const t=this._getFilePath(e);try{if(await this._fileExists(t)&&await u(t),this.enableMetadata){const e=this._getMetadataPath(t);await this._fileExists(e)&&await u(e)}if(this.enableBackup){const e=t+this.backupSuffix;await this._fileExists(e)&&await u(e)}return this.enableStats&&this.stats.deletes++,this.enableJournal&&await this._journalOperation("delete",e),!0}catch(t){throw this.enableStats&&this.stats.errors++,new Error(`Failed to delete cache key '${e}': ${t.message}`)}}async _clear(e){try{if(!await this._fileExists(this.directory))return this.enableStats&&this.stats.clears++,!0;const t=(await l(this.directory)).filter(t=>{if(!t.startsWith(this.prefix))return!1;if(!t.endsWith(this.fileExtension))return!1;if(e){return t.slice(this.prefix.length+1,-this.fileExtension.length).startsWith(e)}return!0});for(const e of t){const t=Je.join(this.directory,e);try{await this._fileExists(t)&&await u(t)}catch(e){if("ENOENT"!==e.code)throw e}if(this.enableMetadata)try{const e=this._getMetadataPath(t);await this._fileExists(e)&&await u(e)}catch(e){if("ENOENT"!==e.code)throw e}if(this.enableBackup)try{const e=t+this.backupSuffix;await this._fileExists(e)&&await u(e)}catch(e){if("ENOENT"!==e.code)throw e}}return this.enableStats&&this.stats.clears++,this.enableJournal&&await this._journalOperation("clear",e||"all",{count:t.length}),!0}catch(e){if("ENOENT"===e.code)return this.enableStats&&this.stats.clears++,!0;throw this.enableStats&&this.stats.errors++,new Error(`Failed to clear cache: ${e.message}`)}}async size(){return(await this.keys()).length}async keys(){try{const e=(await l(this.directory)).filter(e=>e.startsWith(this.prefix)&&e.endsWith(this.fileExtension));return e.map(e=>e.slice(this.prefix.length+1,-this.fileExtension.length))}catch(e){return console.warn("FilesystemCache: Failed to list keys:",e.message),[]}}async _fileExists(e){const[t]=await ve(async()=>{await c(e)});return t}async _copyFile(e,t){const[r,i]=await ve(async()=>{const r=await a(e);await o(t,r)});r||console.warn("FilesystemCache: Failed to create backup:",i.message)}async _cleanup(){if(this.ttl&&!(this.ttl<=0))try{const e=await l(this.directory),t=Date.now();for(const r of e){if(!r.startsWith(this.prefix)||!r.endsWith(this.fileExtension))continue;const e=Je.join(this.directory,r);let i=!1;if(this.enableMetadata){const r=this._getMetadataPath(e);if(await this._fileExists(r)){const[e,s,n]=await ve(async()=>{const e=await a(r,this.encoding);return JSON.parse(e)});if(e&&n.ttl>0){i=t-n.timestamp>n.ttl}}}else{const[r,s,n]=await ve(async()=>await c(e));if(r){i=t-n.mtime.getTime()>this.ttl}}if(i){const e=r.slice(this.prefix.length+1,-this.fileExtension.length);await this._del(e)}}}catch(e){console.warn("FilesystemCache cleanup error:",e.message)}}async _acquireLock(e){if(!this.enableLocking)return;const t=e,r=Date.now();for(;this.locks.has(t);){if(Date.now()-r>this.lockTimeout)throw new Error(`Lock timeout for file: ${e}`);await new Promise(e=>setTimeout(e,10))}this.locks.set(t,Date.now())}_releaseLock(e){this.enableLocking&&this.locks.delete(e)}async _journalOperation(e,t,r={}){if(!this.enableJournal)return;const i={timestamp:(new Date).toISOString(),operation:e,key:t,metadata:r},[s,n]=await ve(async()=>{const e=JSON.stringify(i)+"\n";await Ci.promises.appendFile(this.journalFile,e,this.encoding)});s||console.warn("FilesystemCache journal error:",n.message)}destroy(){this.cleanupTimer&&(clearInterval(this.cleanupTimer),this.cleanupTimer=null)}getStats(){return{...this.stats,directory:this.directory,ttl:this.ttl,compression:this.enableCompression,metadata:this.enableMetadata,cleanup:this.enableCleanup,locking:this.enableLocking,journal:this.enableJournal}}}class Ni extends $i{constructor({partitionStrategy:e="hierarchical",trackUsage:t=!0,preloadRelated:r=!1,preloadThreshold:i=10,maxCacheSize:s=null,usageStatsFile:n="partition-usage.json",...o}){super(o),this.partitionStrategy=e,this.trackUsage=t,this.preloadRelated=r,this.preloadThreshold=i,this.maxCacheSize=s,this.usageStatsFile=Je.join(this.directory,n),this.partitionUsage=new Map,this.loadUsageStats()}_getPartitionCacheKey(e,t,r,i={},s={}){const n=[`resource=${e}`,`action=${t}`];if(r&&Object.keys(i).length>0){n.push(`partition=${r}`);const e=Object.entries(i).sort(([e],[t])=>e.localeCompare(t));for(const[t,r]of e)null!=r&&n.push(`${t}=${r}`)}if(Object.keys(s).length>0){const e=Object.entries(s).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${e}=${t}`).join("|");n.push(`params=${Buffer.from(e).toString("base64")}`)}return n.join("/")+this.fileExtension}_getPartitionDirectory(e,t,r={}){const i=Je.join(this.directory,`resource=${e}`);if(!t)return i;if("flat"===this.partitionStrategy)return Je.join(i,"partitions");if("temporal"===this.partitionStrategy&&this._isTemporalPartition(t,r))return this._getTemporalDirectory(i,t,r);const s=[i,`partition=${t}`],n=Object.entries(r).sort(([e],[t])=>e.localeCompare(t));for(const[e,t]of n)null!=t&&s.push(`${e}=${this._sanitizePathValue(t)}`);return Je.join(...s)}async _set(e,t,r={}){const{resource:i,action:s,partition:n,partitionValues:o,params:a}=r;if(i&&n){const e=this._getPartitionCacheKey(i,s,n,o,a),r=this._getPartitionDirectory(i,n,o);await this._ensureDirectory(r);const c=Je.join(r,this._sanitizeFileName(e));this.trackUsage&&await this._trackPartitionUsage(i,n,o);const u={data:t,metadata:{resource:i,partition:n,partitionValues:o,timestamp:Date.now(),ttl:this.ttl}};return this._writeFileWithMetadata(c,u)}return super._set(e,t)}async set(e,t,r,i={}){if("string"==typeof e&&"string"==typeof t&&i.partition){const s=this._getPartitionCacheKey(e,t,i.partition,i.partitionValues,i.params);return this._set(s,r,{resource:e,action:t,...i})}return super.set(e,t)}async get(e,t,r={}){if("string"==typeof e&&"string"==typeof t&&r.partition){const i=this._getPartitionCacheKey(e,t,r.partition,r.partitionValues,r.params);return this._get(i,{resource:e,action:t,...r})}return super.get(e)}async _get(e,t={}){const{resource:r,action:i,partition:s,partitionValues:n,params:o}=t;if(r&&s){const e=this._getPartitionCacheKey(r,i,s,n,o),t=this._getPartitionDirectory(r,s,n),a=Je.join(t,this._sanitizeFileName(e));if(!await this._fileExists(a))return this.preloadRelated&&await this._preloadRelatedPartitions(r,s,n),null;const c=await this._readFileWithMetadata(a);return c&&this.trackUsage&&await this._trackPartitionUsage(r,s,n),c?.data||null}return super._get(e)}async clearPartition(e,t,r={}){const i=this._getPartitionDirectory(e,t,r),[s,n]=await ve(async()=>{await this._fileExists(i)&&await h(i,{recursive:!0})});s||console.warn(`Failed to clear partition cache: ${n.message}`);const o=this._getUsageKey(e,t,r);return this.partitionUsage.delete(o),await this._saveUsageStats(),s}async clearResourcePartitions(e){const t=Je.join(this.directory,`resource=${e}`),[r,i]=await ve(async()=>{await this._fileExists(t)&&await h(t,{recursive:!0})});for(const[t]of this.partitionUsage.entries())t.startsWith(`${e}/`)&&this.partitionUsage.delete(t);return await this._saveUsageStats(),r}async getPartitionStats(e,t=null){const r={totalFiles:0,totalSize:0,partitions:{},usage:{}},i=Je.join(this.directory,`resource=${e}`);if(!await this._fileExists(i))return r;await this._calculateDirectoryStats(i,r);for(const[i,s]of this.partitionUsage.entries())if(i.startsWith(`${e}/`)){const e=i.split("/")[1];t&&e!==t||(r.usage[e]=s)}return r}async getCacheRecommendations(e){const t=[],r=Date.now();for(const[i,s]of this.partitionUsage.entries())if(i.startsWith(`${e}/`)){const[,e]=i.split("/"),n=(r-s.lastAccess)/864e5,o=s.count/Math.max(1,n);let a="keep",c=s.count;n>30?(a="archive",c=0):o<.1?(a="reduce_ttl",c=1):o>10&&(a="preload",c=100),t.push({partition:e,recommendation:a,priority:c,usage:o,lastAccess:new Date(s.lastAccess).toISOString()})}return t.sort((e,t)=>t.priority-e.priority)}async warmPartitionCache(e,t={}){const{partitions:r=[],maxFiles:i=1e3}=t;let s=0;for(const t of r){const r=`${e}/${t}`,n=this.partitionUsage.get(r);if(n&&n.count>=this.preloadThreshold&&(console.log(`🔥 Warming cache for ${e}/${t} (${n.count} accesses)`),s++),s>=i)break}return s}async _trackPartitionUsage(e,t,r){const i=this._getUsageKey(e,t,r),s=this.partitionUsage.get(i)||{count:0,firstAccess:Date.now(),lastAccess:Date.now()};s.count++,s.lastAccess=Date.now(),this.partitionUsage.set(i,s),s.count%10==0&&await this._saveUsageStats()}_getUsageKey(e,t,r){const i=Object.entries(r).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${e}=${t}`).join("|");return`${e}/${t}/${i}`}async _preloadRelatedPartitions(e,t,r){console.log(`🎯 Preloading related partitions for ${e}/${t}`),r.timestamp||r.date}_isTemporalPartition(e,t){const r=["date","timestamp","createdAt","updatedAt"];return Object.keys(t).some(e=>r.some(t=>e.toLowerCase().includes(t)))}_getTemporalDirectory(e,t,r){const i=Object.values(r)[0];if("string"==typeof i&&i.match(/^\d{4}-\d{2}-\d{2}/)){const[t,r,s]=i.split("-");return Je.join(e,"temporal",t,r,s)}return Je.join(e,`partition=${t}`)}_sanitizePathValue(e){return String(e).replace(/[<>:"/\\|?*]/g,"_")}_sanitizeFileName(e){return e.replace(/[<>:"/\\|?*]/g,"_")}async _calculateDirectoryStats(e,t){const[r,i,s]=await ve(()=>l(e));if(r)for(const r of s){const i=Je.join(e,r),[s,n,o]=await ve(()=>c(i));s&&(o.isDirectory()?await this._calculateDirectoryStats(i,t):(t.totalFiles++,t.totalSize+=o.size))}}async loadUsageStats(){const[e,t,r]=await ve(async()=>{const e=await a(this.usageStatsFile,"utf8");return JSON.parse(e)});e&&r&&(this.partitionUsage=new Map(Object.entries(r)))}async _saveUsageStats(){const e=Object.fromEntries(this.partitionUsage);await ve(async()=>{await o(this.usageStatsFile,JSON.stringify(e,null,2),"utf8")})}async _writeFileWithMetadata(e,t){const r=JSON.stringify(t),[i,s]=await ve(async()=>{await o(e,r,{encoding:this.encoding,mode:this.fileMode})});if(!i)throw new Error(`Failed to write cache file: ${s.message}`);return!0}async _readFileWithMetadata(e){const[t,r,i]=await ve(async()=>await a(e,this.encoding));if(!t||!i)return null;try{return JSON.parse(i)}catch(e){return{data:i}}}}class Ii extends Le{constructor(e={}){super(e),this.driverName=e.driver||"s3",this.ttl=e.ttl,this.maxSize=e.maxSize,this.config=e.config||{},this.includePartitions=!1!==e.includePartitions,this.partitionStrategy=e.partitionStrategy||"hierarchical",this.partitionAware=!1!==e.partitionAware,this.trackUsage=!1!==e.trackUsage,this.preloadRelated=!1!==e.preloadRelated,this.legacyConfig={memoryOptions:e.memoryOptions,filesystemOptions:e.filesystemOptions,s3Options:e.s3Options,driver:e.driver}}async setup(e){await super.setup(e)}async onSetup(){if(this.driverName&&"object"==typeof this.driverName)this.driver=this.driverName;else if("memory"===this.driverName){const e={...this.legacyConfig.memoryOptions,...this.config};void 0!==this.ttl&&(e.ttl=this.ttl),void 0!==this.maxSize&&(e.maxSize=this.maxSize),this.driver=new Di(e)}else if("filesystem"===this.driverName){const e={...this.legacyConfig.filesystemOptions,...this.config};void 0!==this.ttl&&(e.ttl=this.ttl),void 0!==this.maxSize&&(e.maxSize=this.maxSize),this.partitionAware?this.driver=new Ni({partitionStrategy:this.partitionStrategy,trackUsage:this.trackUsage,preloadRelated:this.preloadRelated,...e}):this.driver=new $i(e)}else{const e={client:this.database.client,...this.legacyConfig.s3Options,...this.config};void 0!==this.ttl&&(e.ttl=this.ttl),void 0!==this.maxSize&&(e.maxSize=this.maxSize),this.driver=new Ei(e)}this.installDatabaseHooks(),this.installResourceHooks()}installDatabaseHooks(){this.database.addHook("afterCreateResource",async({resource:e})=>{this.installResourceHooksForResource(e)})}async onStart(){}async onStop(){}installResourceHooks(){for(const e of Object.values(this.database.resources))this.installResourceHooksForResource(e)}installResourceHooksForResource(e){if(!this.driver)return;Object.defineProperty(e,"cache",{value:this.driver,writable:!0,configurable:!0,enumerable:!1}),e.cacheKeyFor=async(t={})=>{const{action:r,params:i={},partition:s,partitionValues:n}=t;return this.generateCacheKey(e,r,i,s,n)},this.driver instanceof Ni&&(e.clearPartitionCache=async(t,r={})=>await this.driver.clearPartition(e.name,t,r),e.getPartitionCacheStats=async(t=null)=>await this.driver.getPartitionStats(e.name,t),e.getCacheRecommendations=async()=>await this.driver.getCacheRecommendations(e.name),e.warmPartitionCache=async(t=[],r={})=>await this.driver.warmPartitionCache(e.name,{partitions:t,...r}));const t=["count","listIds","getMany","getAll","page","list","get","exists","content","hasContent","query","getFromPartition"];for(const r of t)e.useMiddleware(r,async(t,i)=>{let s;if("getMany"===r)s=await e.cacheKeyFor({action:r,params:{ids:t.args[0]}});else if("page"===r){const{offset:i,size:n,partition:o,partitionValues:a}=t.args[0]||{};s=await e.cacheKeyFor({action:r,params:{offset:i,size:n},partition:o,partitionValues:a})}else if("list"===r||"listIds"===r||"count"===r){const{partition:i,partitionValues:n}=t.args[0]||{};s=await e.cacheKeyFor({action:r,partition:i,partitionValues:n})}else if("query"===r){const i=t.args[0]||{},n=t.args[1]||{};s=await e.cacheKeyFor({action:r,params:{filter:i,options:{limit:n.limit,offset:n.offset}},partition:n.partition,partitionValues:n.partitionValues})}else if("getFromPartition"===r){const{id:i,partitionName:n,partitionValues:o}=t.args[0]||{};s=await e.cacheKeyFor({action:r,params:{id:i,partitionName:n},partition:n,partitionValues:o})}else"getAll"===r?s=await e.cacheKeyFor({action:r}):["get","exists","content","hasContent"].includes(r)&&(s=await e.cacheKeyFor({action:r,params:{id:t.args[0]}}));if(this.driver instanceof Ni){let n,o;if("list"===r||"listIds"===r||"count"===r||"page"===r){const e=t.args[0]||{};n=e.partition,o=e.partitionValues}else if("query"===r){const e=t.args[1]||{};n=e.partition,o=e.partitionValues}else if("getFromPartition"===r){const{partitionName:e,partitionValues:r}=t.args[0]||{};n=e,o=r}const[a,c,u]=await ve(()=>e.cache._get(s,{resource:e.name,action:r,partition:n,partitionValues:o}));if(a&&null!=u)return u;if(!a&&"NoSuchKey"!==c.name)throw c;const l=await i();return await e.cache._set(s,l,{resource:e.name,action:r,partition:n,partitionValues:o}),l}{const[t,r,n]=await ve(()=>e.cache.get(s));if(t&&null!=n)return n;if(!t&&"NoSuchKey"!==r.name)throw r;const o=await i();return await e.cache.set(s,o),o}});const r=["insert","update","delete","deleteMany","setContent","deleteContent","replace"];for(const t of r)e.useMiddleware(t,async(r,i)=>{const s=await i();if("insert"===t)await this.clearCacheForResource(e,r.args[0]);else if("update"===t)await this.clearCacheForResource(e,{id:r.args[0],...r.args[1]});else if("delete"===t){let t={id:r.args[0]};if("function"==typeof e.get){const[i,s,n]=await ve(()=>e.get(r.args[0]));i&&n&&(t=n)}await this.clearCacheForResource(e,t)}else if("setContent"===t||"deleteContent"===t){const t=r.args[0]?.id||r.args[0];await this.clearCacheForResource(e,{id:t})}else if("replace"===t){const t=r.args[0];await this.clearCacheForResource(e,{id:t,...r.args[1]})}else"deleteMany"===t&&await this.clearCacheForResource(e);return s})}async clearCacheForResource(e,t){if(!e.cache)return;const r=`resource=${e.name}`;if(t&&t.id){const i=["get","exists","content","hasContent"];for(const r of i)try{const i=await this.generateCacheKey(e,r,{id:t.id});await e.cache.clear(i.replace(".json.gz",""))}catch(e){}if(!0===this.config.includePartitions&&e.config?.partitions&&Object.keys(e.config.partitions).length>0){const i=this.getPartitionValues(t,e);for(const[t,s]of Object.entries(i))if(s&&Object.keys(s).length>0&&Object.values(s).some(e=>null!=e))try{const i=We(r,`partition=${t}`);await e.cache.clear(i)}catch(e){}}}try{await e.cache.clear(r)}catch(t){const i=["count","list","listIds","getAll","page","query"];for(const t of i)try{await e.cache.clear(`${r}/action=${t}`),await e.cache.clear(`resource=${e.name}/action=${t}`)}catch(e){}}}async generateCacheKey(e,t,r={},i=null,s=null){const n=[`resource=${e.name}`,`action=${t}`];if(i&&s&&Object.keys(s).length>0){n.push(`partition:${i}`);for(const[e,t]of Object.entries(s))null!=t&&n.push(`${e}:${t}`)}if(Object.keys(r).length>0){const e=await this.hashParams(r);n.push(e)}return We(...n)+".json.gz"}async hashParams(e){const t=Object.keys(e).sort().map(t=>`${t}:${JSON.stringify(e[t])}`).join("|")||"empty";return await _e(t)}async getCacheStats(){return this.driver?{size:await this.driver.size(),keys:await this.driver.keys(),driver:this.driver.constructor.name}:null}async clearAllCache(){if(this.driver)for(const e of Object.values(this.database.resources))if(e.cache){const t=`resource=${e.name}`;await e.cache.clear(t)}}async warmCache(e,t={}){const r=this.database.resources[e];if(!r)throw new Error(`Resource '${e}' not found`);const{includePartitions:i=!0}=t;if(this.driver instanceof Ni&&r.warmPartitionCache){const e=r.config.partitions?Object.keys(r.config.partitions):[];return await r.warmPartitionCache(e,t)}if(await r.getAll(),i&&r.config.partitions)for(const[e,t]of Object.entries(r.config.partitions))if(t.fields){const t=await r.getAll(),i=Array.isArray(t)?t:[],s=new Set;for(const t of i.slice(0,10)){const i=this.getPartitionValues(t,r);i[e]&&s.add(JSON.stringify(i[e]))}for(const t of s){const i=JSON.parse(t);await r.list({partition:e,partitionValues:i})}}}async getPartitionCacheStats(e,t=null){if(!(this.driver instanceof Ni))throw new Error("Partition cache statistics are only available with PartitionAwareFilesystemCache");return await this.driver.getPartitionStats(e,t)}async getCacheRecommendations(e){if(!(this.driver instanceof Ni))throw new Error("Cache recommendations are only available with PartitionAwareFilesystemCache");return await this.driver.getCacheRecommendations(e)}async clearPartitionCache(e,t,r={}){if(!(this.driver instanceof Ni))throw new Error("Partition cache clearing is only available with PartitionAwareFilesystemCache");return await this.driver.clearPartition(e,t,r)}async analyzeCacheUsage(){if(!(this.driver instanceof Ni))return{message:"Cache usage analysis is only available with PartitionAwareFilesystemCache"};const e={totalResources:Object.keys(this.database.resources).length,resourceStats:{},recommendations:{},summary:{mostUsedPartitions:[],leastUsedPartitions:[],suggestedOptimizations:[]}};for(const[t,r]of Object.entries(this.database.resources))try{e.resourceStats[t]=await this.driver.getPartitionStats(t),e.recommendations[t]=await this.driver.getCacheRecommendations(t)}catch(r){e.resourceStats[t]={error:r.message}}const t=Object.values(e.recommendations).flat();return e.summary.mostUsedPartitions=t.filter(e=>"preload"===e.recommendation).sort((e,t)=>t.priority-e.priority).slice(0,5),e.summary.leastUsedPartitions=t.filter(e=>"archive"===e.recommendation).slice(0,5),e.summary.suggestedOptimizations=[`Consider preloading ${e.summary.mostUsedPartitions.length} high-usage partitions`,`Archive ${e.summary.leastUsedPartitions.length} unused partitions`,"Monitor cache hit rates for partition efficiency"],e}}const Pi={async setup(e){e&&e.client&&(this.client=e.client,this.map={PutObjectCommand:"put",GetObjectCommand:"get",HeadObjectCommand:"head",DeleteObjectCommand:"delete",DeleteObjectsCommand:"delete",ListObjectsV2Command:"list"},this.costs={total:0,prices:{put:5e-6,copy:5e-6,list:5e-6,post:5e-6,get:4e-4/1e3,select:4e-4/1e3,delete:4e-4/1e3,head:4e-4/1e3},requests:{total:0,put:0,post:0,copy:0,list:0,get:0,select:0,delete:0,head:0},events:{total:0,PutObjectCommand:0,GetObjectCommand:0,HeadObjectCommand:0,DeleteObjectCommand:0,DeleteObjectsCommand:0,ListObjectsV2Command:0}},this.client.costs=JSON.parse(JSON.stringify(this.costs)))},async start(){this.client&&(this.client.on("command.response",e=>this.addRequest(e,this.map[e])),this.client.on("command.error",e=>this.addRequest(e,this.map[e])))},addRequest(e,t){t&&(this.costs.events[e]++,this.costs.events.total++,this.costs.requests.total++,this.costs.requests[t]++,this.costs.total+=this.costs.prices[t],this.client&&this.client.costs&&(this.client.costs.events[e]++,this.client.costs.events.total++,this.client.costs.requests.total++,this.client.costs.requests[t]++,this.client.costs.total+=this.client.costs.prices[t]))}};class Ti extends Le{constructor(e={}){super(),this.indexResource=null,this.config={minWordLength:e.minWordLength||3,maxResults:e.maxResults||100,...e},this.indexes=new Map}async setup(e){this.database=e;const[t,r,i]=await ve(()=>e.createResource({name:"fulltext_indexes",attributes:{id:"string|required",resourceName:"string|required",fieldName:"string|required",word:"string|required",recordIds:"json|required",count:"number|required",lastUpdated:"string|required"}}));this.indexResource=t?i:e.resources.fulltext_indexes,await this.loadIndexes(),this.installDatabaseHooks(),this.installIndexingHooks()}async start(){}async stop(){await this.saveIndexes(),this.removeDatabaseHooks()}async loadIndexes(){if(!this.indexResource)return;const[e,t,r]=await ve(()=>this.indexResource.getAll());if(e)for(const e of r){const t=`${e.resourceName}:${e.fieldName}:${e.word}`;this.indexes.set(t,{recordIds:e.recordIds||[],count:e.count||0})}}async saveIndexes(){if(!this.indexResource)return;const[e,t]=await ve(async()=>{const e=await this.indexResource.getAll();for(const t of e)await this.indexResource.delete(t.id);for(const[e,t]of this.indexes.entries()){const[r,i,s]=e.split(":");await this.indexResource.insert({id:`index-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,resourceName:r,fieldName:i,word:s,recordIds:t.recordIds,count:t.count,lastUpdated:(new Date).toISOString()})}})}installDatabaseHooks(){this.database.addHook("afterCreateResource",e=>{"fulltext_indexes"!==e.name&&this.installResourceHooks(e)})}removeDatabaseHooks(){this.database.removeHook("afterCreateResource",this.installResourceHooks.bind(this))}installIndexingHooks(){this.database.plugins||(this.database.plugins={}),this.database.plugins.fulltext=this;for(const e of Object.values(this.database.resources))"fulltext_indexes"!==e.name&&this.installResourceHooks(e);this.database._fulltextProxyInstalled||(this.database._previousCreateResourceForFullText=this.database.createResource,this.database.createResource=async function(...e){const t=await this._previousCreateResourceForFullText(...e);return this.plugins?.fulltext&&"fulltext_indexes"!==t.name&&this.plugins.fulltext.installResourceHooks(t),t},this.database._fulltextProxyInstalled=!0);for(const e of Object.values(this.database.resources))"fulltext_indexes"!==e.name&&this.installResourceHooks(e)}installResourceHooks(e){e._insert=e.insert,e._update=e.update,e._delete=e.delete,e._deleteMany=e.deleteMany,this.wrapResourceMethod(e,"insert",async(t,r,i)=>{const[s]=r;return this.indexRecord(e.name,t.id,s).catch(()=>{}),t}),this.wrapResourceMethod(e,"update",async(t,r,i)=>{const[s,n]=r;return this.removeRecordFromIndex(e.name,s).catch(()=>{}),this.indexRecord(e.name,s,t).catch(()=>{}),t}),this.wrapResourceMethod(e,"delete",async(t,r,i)=>{const[s]=r;return this.removeRecordFromIndex(e.name,s).catch(()=>{}),t}),this.wrapResourceMethod(e,"deleteMany",async(t,r,i)=>{const[s]=r;for(const t of s)this.removeRecordFromIndex(e.name,t).catch(()=>{});return t})}async indexRecord(e,t,r){const i=this.getIndexedFields(e);if(i&&0!==i.length)for(const s of i){const i=this.getFieldValue(r,s);if(!i)continue;const n=this.tokenize(i);for(const r of n){if(r.length<this.config.minWordLength)continue;const i=`${e}:${s}:${r.toLowerCase()}`,n=this.indexes.get(i)||{recordIds:[],count:0};n.recordIds.includes(t)||(n.recordIds.push(t),n.count=n.recordIds.length),this.indexes.set(i,n)}}}async removeRecordFromIndex(e,t){for(const[r,i]of this.indexes.entries())if(r.startsWith(`${e}:`)){const e=i.recordIds.indexOf(t);e>-1&&(i.recordIds.splice(e,1),i.count=i.recordIds.length,0===i.recordIds.length?this.indexes.delete(r):this.indexes.set(r,i))}}getFieldValue(e,t){if(!t.includes("."))return e&&void 0!==e[t]?e[t]:null;const r=t.split(".");let i=e;for(const e of r){if(!i||"object"!=typeof i||!(e in i))return null;i=i[e]}return i}tokenize(e){if(!e)return[];return String(e).toLowerCase().replace(/[^\w\s\u00C0-\u017F]/g," ").split(/\s+/).filter(e=>e.length>0)}getIndexedFields(e){if(this.config.fields)return this.config.fields;return{users:["name","email"],products:["name","description"],articles:["title","content"]}[e]||[]}async search(e,t,r={}){const{fields:i=null,limit:s=this.config.maxResults,offset:n=0,exactMatch:o=!1}=r;if(!t||0===t.trim().length)return[];const a=this.tokenize(t),c=new Map,u=i||this.getIndexedFields(e);if(0===u.length)return[];for(const t of a)if(!(t.length<this.config.minWordLength))for(const r of u)if(o){const i=`${e}:${r}:${t.toLowerCase()}`,s=this.indexes.get(i);if(s)for(const e of s.recordIds){const t=c.get(e)||0;c.set(e,t+1)}}else for(const[i,s]of this.indexes.entries())if(i.startsWith(`${e}:${r}:${t.toLowerCase()}`))for(const e of s.recordIds){const t=c.get(e)||0;c.set(e,t+1)}return Array.from(c.entries()).map(([e,t])=>({recordId:e,score:t})).sort((e,t)=>t.score-e.score).slice(n,n+s)}async searchRecords(e,t,r={}){const i=await this.search(e,t,r);if(0===i.length)return[];const s=this.database.resources[e];if(!s)throw new Error(`Resource '${e}' not found`);const n=i.map(e=>e.recordId);return(await s.getMany(n)).filter(e=>e&&"object"==typeof e).map(e=>{const t=i.find(t=>t.recordId===e.id);return{...e,_searchScore:t?t.score:0}}).sort((e,t)=>t._searchScore-e._searchScore)}async rebuildIndex(e){const t=this.database.resources[e];if(!t)throw new Error(`Resource '${e}' not found`);for(const[t]of this.indexes.entries())t.startsWith(`${e}:`)&&this.indexes.delete(t);const r=await t.getAll();for(let t=0;t<r.length;t+=100){const i=r.slice(t,t+100);for(const t of i){const[r,i]=await ve(()=>this.indexRecord(e,t.id,t))}}await this.saveIndexes()}async getIndexStats(){const e={totalIndexes:this.indexes.size,resources:{},totalWords:0};for(const[t,r]of this.indexes.entries()){const[i,s]=t.split(":");e.resources[i]||(e.resources[i]={fields:{},totalRecords:new Set,totalWords:0}),e.resources[i].fields[s]||(e.resources[i].fields[s]={words:0,totalOccurrences:0}),e.resources[i].fields[s].words++,e.resources[i].fields[s].totalOccurrences+=r.count,e.resources[i].totalWords++;for(const t of r.recordIds)e.resources[i].totalRecords.add(t);e.totalWords++}for(const t in e.resources)e.resources[t].totalRecords=e.resources[t].totalRecords.size;return e}async rebuildAllIndexes({timeout:e}={}){return e?Promise.race([this._rebuildAllIndexesInternal(),new Promise((t,r)=>setTimeout(()=>r(new Error("Timeout")),e))]):this._rebuildAllIndexesInternal()}async _rebuildAllIndexesInternal(){const e=Object.keys(this.database.resources).filter(e=>"fulltext_indexes"!==e);for(const t of e){const[e,r]=await ve(()=>this.rebuildIndex(t))}}async clearIndex(e){for(const[t]of this.indexes.entries())t.startsWith(`${e}:`)&&this.indexes.delete(t);await this.saveIndexes()}async clearAllIndexes(){this.indexes.clear(),await this.saveIndexes()}}class Mi extends Le{constructor(e={}){super(),this.config={collectPerformance:!1!==e.collectPerformance,collectErrors:!1!==e.collectErrors,collectUsage:!1!==e.collectUsage,retentionDays:e.retentionDays||30,flushInterval:e.flushInterval||6e4,...e},this.metrics={operations:{insert:{count:0,totalTime:0,errors:0},update:{count:0,totalTime:0,errors:0},delete:{count:0,totalTime:0,errors:0},get:{count:0,totalTime:0,errors:0},list:{count:0,totalTime:0,errors:0},count:{count:0,totalTime:0,errors:0}},resources:{},errors:[],performance:[],startTime:(new Date).toISOString()},this.flushTimer=null}async setup(e){if(this.database=e,"undefined"!=typeof process&&"test"===process.env.NODE_ENV)return;const[t,r]=await ve(async()=>{const[t,r,i]=await ve(()=>e.createResource({name:"metrics",attributes:{id:"string|required",type:"string|required",resourceName:"string",operation:"string",count:"number|required",totalTime:"number|required",errors:"number|required",avgTime:"number|required",timestamp:"string|required",metadata:"json"}}));this.metricsResource=t?i:e.resources.metrics;const[s,n,o]=await ve(()=>e.createResource({name:"error_logs",attributes:{id:"string|required",resourceName:"string|required",operation:"string|required",error:"string|required",timestamp:"string|required",metadata:"json"}}));this.errorsResource=s?o:e.resources.error_logs;const[a,c,u]=await ve(()=>e.createResource({name:"performance_logs",attributes:{id:"string|required",resourceName:"string|required",operation:"string|required",duration:"number|required",timestamp:"string|required",metadata:"json"}}));this.performanceResource=a?u:e.resources.performance_logs});t||(this.metricsResource=e.resources.metrics,this.errorsResource=e.resources.error_logs,this.performanceResource=e.resources.performance_logs),this.installDatabaseHooks(),this.installMetricsHooks(),"undefined"!=typeof process&&"test"!==process.env.NODE_ENV&&this.startFlushTimer()}async start(){}async stop(){this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.removeDatabaseHooks()}installDatabaseHooks(){this.database.addHook("afterCreateResource",e=>{"metrics"!==e.name&&"error_logs"!==e.name&&"performance_logs"!==e.name&&this.installResourceHooks(e)})}removeDatabaseHooks(){this.database.removeHook("afterCreateResource",this.installResourceHooks.bind(this))}installMetricsHooks(){for(const e of Object.values(this.database.resources))["metrics","error_logs","performance_logs"].includes(e.name)||this.installResourceHooks(e);this.database._createResource=this.database.createResource,this.database.createResource=async function(...e){const t=await this._createResource(...e);return this.plugins?.metrics&&!["metrics","error_logs","performance_logs"].includes(t.name)&&this.plugins.metrics.installResourceHooks(t),t}}installResourceHooks(e){e._insert=e.insert,e._update=e.update,e._delete=e.delete,e._deleteMany=e.deleteMany,e._get=e.get,e._getMany=e.getMany,e._getAll=e.getAll,e._list=e.list,e._listIds=e.listIds,e._count=e.count,e._page=e.page,e.insert=async function(...t){const r=Date.now(),[i,s,n]=await ve(()=>e._insert(...t));if(this.recordOperation(e.name,"insert",Date.now()-r,!i),i||this.recordError(e.name,"insert",s),!i)throw s;return n}.bind(this),e.update=async function(...t){const r=Date.now(),[i,s,n]=await ve(()=>e._update(...t));if(this.recordOperation(e.name,"update",Date.now()-r,!i),i||this.recordError(e.name,"update",s),!i)throw s;return n}.bind(this),e.delete=async function(...t){const r=Date.now(),[i,s,n]=await ve(()=>e._delete(...t));if(this.recordOperation(e.name,"delete",Date.now()-r,!i),i||this.recordError(e.name,"delete",s),!i)throw s;return n}.bind(this),e.deleteMany=async function(...t){const r=Date.now(),[i,s,n]=await ve(()=>e._deleteMany(...t));if(this.recordOperation(e.name,"delete",Date.now()-r,!i),i||this.recordError(e.name,"delete",s),!i)throw s;return n}.bind(this),e.get=async function(...t){const r=Date.now(),[i,s,n]=await ve(()=>e._get(...t));if(this.recordOperation(e.name,"get",Date.now()-r,!i),i||this.recordError(e.name,"get",s),!i)throw s;return n}.bind(this),e.getMany=async function(...t){const r=Date.now(),[i,s,n]=await ve(()=>e._getMany(...t));if(this.recordOperation(e.name,"get",Date.now()-r,!i),i||this.recordError(e.name,"get",s),!i)throw s;return n}.bind(this),e.getAll=async function(...t){const r=Date.now(),[i,s,n]=await ve(()=>e._getAll(...t));if(this.recordOperation(e.name,"list",Date.now()-r,!i),i||this.recordError(e.name,"list",s),!i)throw s;return n}.bind(this),e.list=async function(...t){const r=Date.now(),[i,s,n]=await ve(()=>e._list(...t));if(this.recordOperation(e.name,"list",Date.now()-r,!i),i||this.recordError(e.name,"list",s),!i)throw s;return n}.bind(this),e.listIds=async function(...t){const r=Date.now(),[i,s,n]=await ve(()=>e._listIds(...t));if(this.recordOperation(e.name,"list",Date.now()-r,!i),i||this.recordError(e.name,"list",s),!i)throw s;return n}.bind(this),e.count=async function(...t){const r=Date.now(),[i,s,n]=await ve(()=>e._count(...t));if(this.recordOperation(e.name,"count",Date.now()-r,!i),i||this.recordError(e.name,"count",s),!i)throw s;return n}.bind(this),e.page=async function(...t){const r=Date.now(),[i,s,n]=await ve(()=>e._page(...t));if(this.recordOperation(e.name,"list",Date.now()-r,!i),i||this.recordError(e.name,"list",s),!i)throw s;return n}.bind(this)}recordOperation(e,t,r,i){this.metrics.operations[t]&&(this.metrics.operations[t].count++,this.metrics.operations[t].totalTime+=r,i&&this.metrics.operations[t].errors++),this.metrics.resources[e]||(this.metrics.resources[e]={insert:{count:0,totalTime:0,errors:0},update:{count:0,totalTime:0,errors:0},delete:{count:0,totalTime:0,errors:0},get:{count:0,totalTime:0,errors:0},list:{count:0,totalTime:0,errors:0},count:{count:0,totalTime:0,errors:0}}),this.metrics.resources[e][t]&&(this.metrics.resources[e][t].count++,this.metrics.resources[e][t].totalTime+=r,i&&this.metrics.resources[e][t].errors++),this.config.collectPerformance&&this.metrics.performance.push({resourceName:e,operation:t,duration:r,timestamp:(new Date).toISOString()})}recordError(e,t,r){this.config.collectErrors&&this.metrics.errors.push({resourceName:e,operation:t,error:r.message,stack:r.stack,timestamp:(new Date).toISOString()})}startFlushTimer(){this.flushTimer&&clearInterval(this.flushTimer),this.config.flushInterval>0&&(this.flushTimer=setInterval(()=>{this.flushMetrics().catch(()=>{})},this.config.flushInterval))}async flushMetrics(){if(!this.metricsResource)return;const[e,t]=await ve(async()=>{let e,t,r,i;"undefined"!=typeof process&&"test"===process.env.NODE_ENV?(e={},t={},r={},i={}):(e={global:"true"},t={perf:"true"},r={error:"true"},i={resource:"true"});for(const[t,r]of Object.entries(this.metrics.operations))r.count>0&&await this.metricsResource.insert({id:`metrics-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,type:"operation",resourceName:"global",operation:t,count:r.count,totalTime:r.totalTime,errors:r.errors,avgTime:r.count>0?r.totalTime/r.count:0,timestamp:(new Date).toISOString(),metadata:e});for(const[e,t]of Object.entries(this.metrics.resources))for(const[r,s]of Object.entries(t))s.count>0&&await this.metricsResource.insert({id:`metrics-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,type:"operation",resourceName:e,operation:r,count:s.count,totalTime:s.totalTime,errors:s.errors,avgTime:s.count>0?s.totalTime/s.count:0,timestamp:(new Date).toISOString(),metadata:i});if(this.config.collectPerformance&&this.metrics.performance.length>0)for(const e of this.metrics.performance)await this.performanceResource.insert({id:`perf-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,resourceName:e.resourceName,operation:e.operation,duration:e.duration,timestamp:e.timestamp,metadata:t});if(this.config.collectErrors&&this.metrics.errors.length>0)for(const e of this.metrics.errors)await this.errorsResource.insert({id:`error-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,resourceName:e.resourceName,operation:e.operation,error:e.error,stack:e.stack,timestamp:e.timestamp,metadata:r});this.resetMetrics()})}resetMetrics(){for(const e of Object.keys(this.metrics.operations))this.metrics.operations[e]={count:0,totalTime:0,errors:0};for(const e of Object.keys(this.metrics.resources))for(const t of Object.keys(this.metrics.resources[e]))this.metrics.resources[e][t]={count:0,totalTime:0,errors:0};this.metrics.performance=[],this.metrics.errors=[]}async getMetrics(e={}){const{type:t="operation",resourceName:r,operation:i,startDate:s,endDate:n,limit:o=100,offset:a=0}=e;if(!this.metricsResource)return[];let c=(await this.metricsResource.getAll()).filter(e=>(!t||e.type===t)&&((!r||e.resourceName===r)&&((!i||e.operation===i)&&(!(s&&new Date(e.timestamp)<new Date(s))&&!(n&&new Date(e.timestamp)>new Date(n))))));return c.sort((e,t)=>new Date(t.timestamp)-new Date(e.timestamp)),c.slice(a,a+o)}async getErrorLogs(e={}){if(!this.errorsResource)return[];const{resourceName:t,operation:r,startDate:i,endDate:s,limit:n=100,offset:o=0}=e;let a=(await this.errorsResource.getAll()).filter(e=>(!t||e.resourceName===t)&&((!r||e.operation===r)&&(!(i&&new Date(e.timestamp)<new Date(i))&&!(s&&new Date(e.timestamp)>new Date(s)))));return a.sort((e,t)=>new Date(t.timestamp)-new Date(e.timestamp)),a.slice(o,o+n)}async getPerformanceLogs(e={}){if(!this.performanceResource)return[];const{resourceName:t,operation:r,startDate:i,endDate:s,limit:n=100,offset:o=0}=e;let a=(await this.performanceResource.getAll()).filter(e=>(!t||e.resourceName===t)&&((!r||e.operation===r)&&(!(i&&new Date(e.timestamp)<new Date(i))&&!(s&&new Date(e.timestamp)>new Date(s)))));return a.sort((e,t)=>new Date(t.timestamp)-new Date(e.timestamp)),a.slice(o,o+n)}async getStats(){const e=new Date,t=new Date(e.getTime()-864e5),[r,i,s]=await Promise.all([this.getMetrics({startDate:t.toISOString()}),this.getErrorLogs({startDate:t.toISOString()}),this.getPerformanceLogs({startDate:t.toISOString()})]),n={period:"24h",totalOperations:0,totalErrors:i.length,avgResponseTime:0,operationsByType:{},resources:{},uptime:{startTime:this.metrics.startTime,duration:e.getTime()-new Date(this.metrics.startTime).getTime()}};for(const e of r)if("operation"===e.type){n.totalOperations+=e.count,n.operationsByType[e.operation]||(n.operationsByType[e.operation]={count:0,errors:0,avgTime:0}),n.operationsByType[e.operation].count+=e.count,n.operationsByType[e.operation].errors+=e.errors;const t=n.operationsByType[e.operation],r=t.count,i=(t.avgTime*(r-e.count)+e.totalTime)/r;t.avgTime=i}const o=r.reduce((e,t)=>e+t.totalTime,0),a=r.reduce((e,t)=>e+t.count,0);return n.avgResponseTime=a>0?o/a:0,n}async cleanupOldData(){const e=new Date;if(e.setDate(e.getDate()-this.config.retentionDays),this.metricsResource){const t=await this.getMetrics({endDate:e.toISOString()});for(const e of t)await this.metricsResource.delete(e.id)}if(this.errorsResource){const t=await this.getErrorLogs({endDate:e.toISOString()});for(const e of t)await this.errorsResource.delete(e.id)}if(this.performanceResource){const t=await this.getPerformanceLogs({endDate:e.toISOString()});for(const e of t)await this.performanceResource.delete(e.id)}}}var Li=class extends $e{constructor(e={}){super(),this.config=e,this.name=this.constructor.name,this.enabled=!1!==e.enabled}async initialize(e){this.database=e,this.emit("initialized",{replicator:this.name})}async replicate(e,t,r,i){throw new Error(`replicate() method must be implemented by ${this.name}`)}async replicateBatch(e,t){throw new Error(`replicateBatch() method must be implemented by ${this.name}`)}async testConnection(){throw new Error(`testConnection() method must be implemented by ${this.name}`)}async getStatus(){return{name:this.name,config:this.config,connected:!1}}async cleanup(){this.emit("cleanup",{replicator:this.name})}validateConfig(){return{isValid:!0,errors:[]}}};var Ui=class extends Li{constructor(e={},t={}){super(e),this.projectId=e.projectId,this.datasetId=e.datasetId,this.bigqueryClient=null,this.credentials=e.credentials,this.location=e.location||"US",this.logTable=e.logTable,this.resources=this.parseResourcesConfig(t)}parseResourcesConfig(e){const t={};for(const[r,i]of Object.entries(e))"string"==typeof i?t[r]=[{table:i,actions:["insert"],transform:null}]:Array.isArray(i)?t[r]=i.map(e=>"string"==typeof e?{table:e,actions:["insert"],transform:null}:{table:e.table,actions:e.actions||["insert"],transform:e.transform||null}):"object"==typeof i&&(t[r]=[{table:i.table,actions:i.actions||["insert"],transform:i.transform||null}]);return t}validateConfig(){const e=[];this.projectId||e.push("projectId is required"),this.datasetId||e.push("datasetId is required"),0===Object.keys(this.resources).length&&e.push("At least one resource must be configured");for(const[t,r]of Object.entries(this.resources))for(const i of r){i.table||e.push(`Table name is required for resource '${t}'`),Array.isArray(i.actions)&&0!==i.actions.length||e.push(`Actions array is required for resource '${t}'`);const r=["insert","update","delete"],s=i.actions.filter(e=>!r.includes(e));s.length>0&&e.push(`Invalid actions for resource '${t}': ${s.join(", ")}. Valid actions: ${r.join(", ")}`),i.transform&&"function"!=typeof i.transform&&e.push(`Transform must be a function for resource '${t}'`)}return{isValid:0===e.length,errors:e}}async initialize(e){await super.initialize(e);const[t,r,i]=await ve(()=>import("@google-cloud/bigquery"));if(!t)throw this.config.verbose&&console.warn(`[BigqueryReplicator] Failed to import BigQuery SDK: ${r.message}`),this.emit("initialization_error",{replicator:this.name,error:r.message}),r;const{BigQuery:s}=i;this.bigqueryClient=new s({projectId:this.projectId,credentials:this.credentials,location:this.location}),this.emit("initialized",{replicator:this.name,projectId:this.projectId,datasetId:this.datasetId,resources:Object.keys(this.resources)})}shouldReplicateResource(e){return this.resources.hasOwnProperty(e)}shouldReplicateAction(e,t){return!!this.resources[e]&&this.resources[e].some(e=>e.actions.includes(t))}getTablesForResource(e,t){return this.resources[e]?this.resources[e].filter(e=>e.actions.includes(t)).map(e=>({table:e.table,transform:e.transform})):[]}applyTransform(e,t){let r=this._cleanInternalFields(e);return t?t(JSON.parse(JSON.stringify(r))):r}_cleanInternalFields(e){if(!e||"object"!=typeof e)return e;const t={...e};return Object.keys(t).forEach(e=>{(e.startsWith("$")||e.startsWith("_"))&&delete t[e]}),t}async replicate(e,t,r,i,s=null){if(!this.enabled||!this.shouldReplicateResource(e))return{skipped:!0,reason:"resource_not_included"};if(!this.shouldReplicateAction(e,t))return{skipped:!0,reason:"action_not_included"};const n=this.getTablesForResource(e,t);if(0===n.length)return{skipped:!0,reason:"no_tables_for_action"};const o=[],a=[],[c,u,l]=await ve(async()=>{const s=this.bigqueryClient.dataset(this.datasetId);for(const e of n){const[n,c]=await ve(async()=>{const n=s.table(e.table);let a;if("insert"===t){const t=this.applyTransform(r,e.transform);try{a=await n.insert([t])}catch(e){const{errors:t,response:r}=e;throw this.config.verbose&&(console.error("[BigqueryReplicator] BigQuery insert error details:"),t&&console.error(JSON.stringify(t,null,2)),r&&console.error(JSON.stringify(r,null,2))),e}}else if("update"===t){const t=this.applyTransform(r,e.transform),s=Object.keys(t).filter(e=>"id"!==e).map(e=>`${e} = @${e}`).join(", "),n={id:i,...t},o=`UPDATE \`${this.projectId}.${this.datasetId}.${e.table}\` SET ${s} WHERE id = @id`,c=2;let u=null;for(let e=1;e<=c;e++){const[t,r]=await ve(async()=>{const[e]=await this.bigqueryClient.createQueryJob({query:o,params:n,location:this.location});return await e.getQueryResults(),[e]});if(t){a=t;break}if(u=r,this.config.verbose&&(console.warn(`[BigqueryReplicator] Update attempt ${e} failed: ${r.message}`),r.errors&&(console.error("[BigqueryReplicator] BigQuery update error details:"),console.error("Errors:",JSON.stringify(r.errors,null,2)))),r?.message?.includes("streaming buffer")&&e<c){const e=30;this.config.verbose&&console.warn(`[BigqueryReplicator] Retrying in ${e} seconds due to streaming buffer issue`),await new Promise(t=>setTimeout(t,1e3*e));continue}throw r}if(!a)throw u}else{if("delete"!==t)throw new Error(`Unsupported operation: ${t}`);{const t=`DELETE FROM \`${this.projectId}.${this.datasetId}.${e.table}\` WHERE id = @id`;try{const[e]=await this.bigqueryClient.createQueryJob({query:t,params:{id:i},location:this.location});await e.getQueryResults(),a=[e]}catch(e){throw this.config.verbose&&(console.error("[BigqueryReplicator] BigQuery delete error details:"),console.error("Query:",t),e.errors&&console.error("Errors:",JSON.stringify(e.errors,null,2)),e.response&&console.error("Response:",JSON.stringify(e.response,null,2))),e}}}o.push({table:e.table,success:!0,jobId:a[0]?.id})});n||a.push({table:e.table,error:c.message})}if(this.logTable){const[n,o]=await ve(async()=>{const n=s.table(this.logTable);await n.insert([{resource_name:e,operation:t,record_id:i,data:JSON.stringify(r),timestamp:(new Date).toISOString(),source:"s3db-replicator"}])})}const c=0===a.length;return a.length>0&&console.warn(`[BigqueryReplicator] Replication completed with errors for ${e}:`,a),this.emit("replicated",{replicator:this.name,resourceName:e,operation:t,id:i,tables:n.map(e=>e.table),results:o,errors:a,success:c}),{success:c,results:o,errors:a,tables:n.map(e=>e.table)}});return c?l:(this.config.verbose&&console.warn(`[BigqueryReplicator] Replication failed for ${e}: ${u.message}`),this.emit("replicator_error",{replicator:this.name,resourceName:e,operation:t,id:i,error:u.message}),{success:!1,error:u.message})}async replicateBatch(e,t){const r=[],i=[];for(const s of t){const[t,n,o]=await ve(()=>this.replicate(e,s.operation,s.data,s.id,s.beforeData));t?r.push(o):(this.config.verbose&&console.warn(`[BigqueryReplicator] Batch replication failed for record ${s.id}: ${n.message}`),i.push({id:s.id,error:n.message}))}return i.length>0&&console.warn(`[BigqueryReplicator] Batch replication completed with ${i.length} error(s) for ${e}:`,i),{success:0===i.length,results:r,errors:i}}async testConnection(){const[e,t]=await ve(async()=>{this.bigqueryClient||await this.initialize();const e=this.bigqueryClient.dataset(this.datasetId);return await e.getMetadata(),!0});return!!e||(this.config.verbose&&console.warn(`[BigqueryReplicator] Connection test failed: ${t.message}`),this.emit("connection_error",{replicator:this.name,error:t.message}),!1)}async cleanup(){}getStatus(){return{...super.getStatus(),projectId:this.projectId,datasetId:this.datasetId,resources:this.resources,logTable:this.logTable}}};var Fi=class extends Li{constructor(e={},t={}){super(e),this.connectionString=e.connectionString,this.host=e.host,this.port=e.port||5432,this.database=e.database,this.user=e.user,this.password=e.password,this.client=null,this.ssl=e.ssl,this.logTable=e.logTable,this.resources=this.parseResourcesConfig(t)}parseResourcesConfig(e){const t={};for(const[r,i]of Object.entries(e))"string"==typeof i?t[r]=[{table:i,actions:["insert"]}]:Array.isArray(i)?t[r]=i.map(e=>"string"==typeof e?{table:e,actions:["insert"]}:{table:e.table,actions:e.actions||["insert"]}):"object"==typeof i&&(t[r]=[{table:i.table,actions:i.actions||["insert"]}]);return t}validateConfig(){const e=[];this.connectionString||this.host&&this.database||e.push("Either connectionString or host+database must be provided"),0===Object.keys(this.resources).length&&e.push("At least one resource must be configured");for(const[t,r]of Object.entries(this.resources))for(const i of r){i.table||e.push(`Table name is required for resource '${t}'`),Array.isArray(i.actions)&&0!==i.actions.length||e.push(`Actions array is required for resource '${t}'`);const r=["insert","update","delete"],s=i.actions.filter(e=>!r.includes(e));s.length>0&&e.push(`Invalid actions for resource '${t}': ${s.join(", ")}. Valid actions: ${r.join(", ")}`)}return{isValid:0===e.length,errors:e}}async initialize(e){await super.initialize(e);const[t,r,i]=await ve(()=>import("pg"));if(!t)throw this.config.verbose&&console.warn(`[PostgresReplicator] Failed to import pg SDK: ${r.message}`),this.emit("initialization_error",{replicator:this.name,error:r.message}),r;const{Client:s}=i,n=this.connectionString?{connectionString:this.connectionString,ssl:this.ssl}:{host:this.host,port:this.port,database:this.database,user:this.user,password:this.password,ssl:this.ssl};this.client=new s(n),await this.client.connect(),this.logTable&&await this.createLogTableIfNotExists(),this.emit("initialized",{replicator:this.name,database:this.database||"postgres",resources:Object.keys(this.resources)})}async createLogTableIfNotExists(){const e=`\n CREATE TABLE IF NOT EXISTS ${this.logTable} (\n id SERIAL PRIMARY KEY,\n resource_name VARCHAR(255) NOT NULL,\n operation VARCHAR(50) NOT NULL,\n record_id VARCHAR(255) NOT NULL,\n data JSONB,\n timestamp TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n source VARCHAR(100) DEFAULT 's3db-replicator',\n created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()\n );\n CREATE INDEX IF NOT EXISTS idx_${this.logTable}_resource_name ON ${this.logTable}(resource_name);\n CREATE INDEX IF NOT EXISTS idx_${this.logTable}_operation ON ${this.logTable}(operation);\n CREATE INDEX IF NOT EXISTS idx_${this.logTable}_record_id ON ${this.logTable}(record_id);\n CREATE INDEX IF NOT EXISTS idx_${this.logTable}_timestamp ON ${this.logTable}(timestamp);\n `;await this.client.query(e)}shouldReplicateResource(e){return this.resources.hasOwnProperty(e)}shouldReplicateAction(e,t){return!!this.resources[e]&&this.resources[e].some(e=>e.actions.includes(t))}getTablesForResource(e,t){return this.resources[e]?this.resources[e].filter(e=>e.actions.includes(t)).map(e=>e.table):[]}async replicate(e,t,r,i,s=null){if(!this.enabled||!this.shouldReplicateResource(e))return{skipped:!0,reason:"resource_not_included"};if(!this.shouldReplicateAction(e,t))return{skipped:!0,reason:"action_not_included"};const n=this.getTablesForResource(e,t);if(0===n.length)return{skipped:!0,reason:"no_tables_for_action"};const o=[],a=[],[c,u,l]=await ve(async()=>{for(const e of n){const[s,n]=await ve(async()=>{let s;if("insert"===t){const t=this._cleanInternalFields(r),i=Object.keys(t),n=i.map(e=>t[e]),o=i.map(e=>`"${e}"`).join(", "),a=i.map((e,t)=>`$${t+1}`).join(", "),c=`INSERT INTO ${e} (${o}) VALUES (${a}) ON CONFLICT (id) DO NOTHING RETURNING *`;s=await this.client.query(c,n)}else if("update"===t){const t=this._cleanInternalFields(r),n=Object.keys(t).filter(e=>"id"!==e),o=n.map((e,t)=>`"${e}"=$${t+1}`).join(", "),a=n.map(e=>t[e]);a.push(i);const c=`UPDATE ${e} SET ${o} WHERE id=$${n.length+1} RETURNING *`;s=await this.client.query(c,a)}else{if("delete"!==t)throw new Error(`Unsupported operation: ${t}`);{const t=`DELETE FROM ${e} WHERE id=$1 RETURNING *`;s=await this.client.query(t,[i])}}o.push({table:e,success:!0,rows:s.rows,rowCount:s.rowCount})});s||a.push({table:e,error:n.message})}if(this.logTable){const[s,n]=await ve(async()=>{await this.client.query(`INSERT INTO ${this.logTable} (resource_name, operation, record_id, data, timestamp, source) VALUES ($1, $2, $3, $4, $5, $6)`,[e,t,i,JSON.stringify(r),(new Date).toISOString(),"s3db-replicator"])})}const s=0===a.length;return a.length>0&&console.warn(`[PostgresReplicator] Replication completed with errors for ${e}:`,a),this.emit("replicated",{replicator:this.name,resourceName:e,operation:t,id:i,tables:n,results:o,errors:a,success:s}),{success:s,results:o,errors:a,tables:n}});return c?l:(this.config.verbose&&console.warn(`[PostgresReplicator] Replication failed for ${e}: ${u.message}`),this.emit("replicator_error",{replicator:this.name,resourceName:e,operation:t,id:i,error:u.message}),{success:!1,error:u.message})}async replicateBatch(e,t){const r=[],i=[];for(const s of t){const[t,n,o]=await ve(()=>this.replicate(e,s.operation,s.data,s.id,s.beforeData));t?r.push(o):(this.config.verbose&&console.warn(`[PostgresReplicator] Batch replication failed for record ${s.id}: ${n.message}`),i.push({id:s.id,error:n.message}))}return i.length>0&&console.warn(`[PostgresReplicator] Batch replication completed with ${i.length} error(s) for ${e}:`,i),{success:0===i.length,results:r,errors:i}}async testConnection(){const[e,t]=await ve(async()=>(this.client||await this.initialize(),await this.client.query("SELECT 1"),!0));return!!e||(this.config.verbose&&console.warn(`[PostgresReplicator] Connection test failed: ${t.message}`),this.emit("connection_error",{replicator:this.name,error:t.message}),!1)}_cleanInternalFields(e){if(!e||"object"!=typeof e)return e;const t={...e};return Object.keys(t).forEach(e=>{(e.startsWith("$")||e.startsWith("_"))&&delete t[e]}),t}async cleanup(){this.client&&await this.client.end()}getStatus(){return{...super.getStatus(),database:this.database||"postgres",resources:this.resources,logTable:this.logTable}}};function qi(){}function Bi(){}qi.defaultMaxSockets=4,Bi.defaultMaxSockets=4;class zi{constructor(e){let t;const[r,i,s]=ve(()=>new URL(e));if(!r)throw new de("Invalid connection string: "+e,{original:i,input:e});t=s,this.region="us-east-1","s3:"===t.protocol?this.defineFromS3(t):this.defineFromCustomUri(t);for(const[e,r]of t.searchParams.entries())this[e]=r}defineFromS3(e){const[t,r,i]=we(()=>decodeURIComponent(e.hostname));if(!t)throw new de("Invalid bucket in connection string",{original:r,input:e.hostname});this.bucket=i||"s3db";const[s,n,o]=we(()=>decodeURIComponent(e.username));if(!s)throw new de("Invalid accessKeyId in connection string",{original:n,input:e.username});this.accessKeyId=o;const[a,c,u]=we(()=>decodeURIComponent(e.password));if(!a)throw new de("Invalid secretAccessKey in connection string",{original:c,input:e.password});if(this.secretAccessKey=u,this.endpoint="https://s3.us-east-1.amazonaws.com",["/","",null].includes(e.pathname))this.keyPrefix="";else{let[,...t]=e.pathname.split("/");this.keyPrefix=[...t||[]].join("/")}}defineFromCustomUri(e){this.forcePathStyle=!0,this.endpoint=e.origin;const[t,r,i]=we(()=>decodeURIComponent(e.username));if(!t)throw new de("Invalid accessKeyId in connection string",{original:r,input:e.username});this.accessKeyId=i;const[s,n,o]=we(()=>decodeURIComponent(e.password));if(!s)throw new de("Invalid secretAccessKey in connection string",{original:n,input:e.password});if(this.secretAccessKey=o,["/","",null].includes(e.pathname))this.bucket="s3db",this.keyPrefix="";else{let[,t,...r]=e.pathname.split("/");if(t){const[e,r,i]=we(()=>decodeURIComponent(t));if(!e)throw new de("Invalid bucket in connection string",{original:r,input:t});this.bucket=i}else this.bucket="s3db";this.keyPrefix=[...r||[]].join("/")}}}class Hi extends $e{constructor({verbose:e=!1,id:t=null,AwsS3Client:r,connectionString:i,parallelism:s=10,httpClientOptions:n={}}){super(),this.verbose=e,this.id=t??xe(77),this.parallelism=s,this.config=new zi(i),this.httpClientOptions={keepAlive:!0,keepAliveMsecs:1e3,maxSockets:50,maxFreeSockets:10,timeout:6e4,...n},this.client=r||this.createClient()}createClient(){const e=new qi(this.httpClientOptions),t=new Bi(this.httpClientOptions),r=new R({httpAgent:e,httpsAgent:t});let i={region:this.config.region,endpoint:this.config.endpoint,requestHandler:r};this.config.forcePathStyle&&(i.forcePathStyle=!0),this.config.accessKeyId&&(i.credentials={accessKeyId:this.config.accessKeyId,secretAccessKey:this.config.secretAccessKey});const s=new j(i);return s.middlewareStack.add((e,t)=>async r=>{if("DeleteObjectsCommand"===t.commandName){const e=r.request.body;if(e&&"string"==typeof e){const t=await Re(e);r.request.headers["Content-MD5"]=t}}return e(r)},{step:"build",name:"addContentMd5ForDeleteObjects",priority:"high"}),s}async sendCommand(e){this.emit("command.request",e.constructor.name,e.input);const[t,r,i]=await ve(()=>this.client.send(e));if(!t){throw fe(r,{bucket:this.config.bucket,key:e.input&&e.input.Key,commandName:e.constructor.name,commandInput:e.input})}return this.emit("command.response",e.constructor.name,i,e.input),i}async putObject({key:e,metadata:t,contentType:r,body:i,contentEncoding:s,contentLength:n}){const o="string"==typeof this.config.keyPrefix?this.config.keyPrefix:"";o&&Je.join(o,e);const a={};if(t)for(const[e,r]of Object.entries(t)){const t=String(e).replace(/[^a-zA-Z0-9\-_]/g,"_"),i=String(r),s=/[^\x00-\x7F]/.test(i);a[t]=s?Buffer.from(i,"utf8").toString("base64"):i}const c={Bucket:this.config.bucket,Key:o?Je.join(o,e):e,Metadata:a,Body:i||Buffer.alloc(0)};let u,l;void 0!==r&&(c.ContentType=r),void 0!==s&&(c.ContentEncoding=s),void 0!==n&&(c.ContentLength=n);try{return u=await this.sendCommand(new x(c)),u}catch(t){throw l=t,fe(t,{bucket:this.config.bucket,key:e,commandName:"PutObjectCommand",commandInput:c})}finally{this.emit("putObject",l||u,{key:e,metadata:t,contentType:r,body:i,contentEncoding:s,contentLength:n})}}async getObject(e){const t="string"==typeof this.config.keyPrefix?this.config.keyPrefix:"",r={Bucket:this.config.bucket,Key:t?Je.join(t,e):e};let i,s;try{if(i=await this.sendCommand(new A(r)),i.Metadata){const e={};for(const[t,r]of Object.entries(i.Metadata))if("string"==typeof r)try{const i=Buffer.from(r,"base64").toString("utf8"),s=/[^\x00-\x7F]/.test(i),n=Buffer.from(i,"utf8").toString("base64")===r;e[t]=n&&s&&i!==r?i:r}catch(i){e[t]=r}else e[t]=r;i.Metadata=e}return i}catch(t){throw s=t,fe(t,{bucket:this.config.bucket,key:e,commandName:"GetObjectCommand",commandInput:r})}finally{this.emit("getObject",s||i,{key:e})}}async headObject(e){const t="string"==typeof this.config.keyPrefix?this.config.keyPrefix:"",r={Bucket:this.config.bucket,Key:t?Je.join(t,e):e};let i,s;try{return i=await this.sendCommand(new E(r)),i}catch(t){throw s=t,fe(t,{bucket:this.config.bucket,key:e,commandName:"HeadObjectCommand",commandInput:r})}finally{this.emit("headObject",s||i,{key:e})}}async copyObject({from:e,to:t}){const r={Bucket:this.config.bucket,Key:this.config.keyPrefix?Je.join(this.config.keyPrefix,t):t,CopySource:Je.join(this.config.bucket,this.config.keyPrefix?Je.join(this.config.keyPrefix,e):e)};let i,s;try{return i=await this.sendCommand(new D(r)),i}catch(e){throw s=e,fe(e,{bucket:this.config.bucket,key:t,commandName:"CopyObjectCommand",commandInput:r})}finally{this.emit("copyObject",s||i,{from:e,to:t})}}async exists(e){const[t,r]=await ve(()=>this.headObject(e));if(t)return!0;if("NoSuchKey"===r.name||"NotFound"===r.name)return!1;throw r}async deleteObject(e){const t="string"==typeof this.config.keyPrefix?this.config.keyPrefix:"";t&&Je.join(t,e);const r={Bucket:this.config.bucket,Key:t?Je.join(t,e):e};let i,s;try{return i=await this.sendCommand(new C(r)),i}catch(t){throw s=t,fe(t,{bucket:this.config.bucket,key:e,commandName:"DeleteObjectCommand",commandInput:r})}finally{this.emit("deleteObject",s||i,{key:e})}}async deleteObjects(e){const t="string"==typeof this.config.keyPrefix?this.config.keyPrefix:"",r=d(e,1e3),{results:s,errors:n}=await i.for(r).withConcurrency(this.parallelism).process(async e=>{for(const r of e)t&&Je.join(t,r),this.config.bucket,await this.exists(r);const r={Bucket:this.config.bucket,Delete:{Objects:e.map(e=>({Key:t?Je.join(t,e):e}))}};let i;const[s,n,o]=await ve(()=>this.sendCommand(new $(r)));if(!s)throw n;return i=o,i&&i.Errors&&i.Errors.length,i&&i.Deleted&&(i.Deleted.length,e.length),i}),o={deleted:s,notFound:n};return this.emit("deleteObjects",o,e),o}async deleteAll({prefix:e}={}){const t="string"==typeof this.config.keyPrefix?this.config.keyPrefix:"";let r,i=0;do{const s=new N({Bucket:this.config.bucket,Prefix:t?Je.join(t,e||""):e||"",ContinuationToken:r}),n=await this.client.send(s);if(n.Contents&&n.Contents.length>0){const t=new $({Bucket:this.config.bucket,Delete:{Objects:n.Contents.map(e=>({Key:e.Key}))}}),r=await this.client.send(t),s=r.Deleted?r.Deleted.length:0;i+=s,this.emit("deleteAll",{prefix:e,batch:s,total:i})}r=n.IsTruncated?n.NextContinuationToken:void 0}while(r);return this.emit("deleteAllComplete",{prefix:e,totalDeleted:i}),i}async moveObject({from:e,to:t}){const[r,i]=await ve(async()=>{await this.copyObject({from:e,to:t}),await this.deleteObject(e)});if(!r)throw new le("Unknown error in moveObject",{bucket:this.config.bucket,from:e,to:t,original:i});return!0}async listObjects({prefix:e,maxKeys:t=1e3,continuationToken:r}={}){const i={Bucket:this.config.bucket,MaxKeys:t,ContinuationToken:r,Prefix:this.config.keyPrefix?Je.join(this.config.keyPrefix,e||""):e||""},[s,n,o]=await ve(()=>this.sendCommand(new N(i)));if(!s)throw new le("Unknown error in listObjects",{prefix:e,bucket:this.config.bucket,original:n});return this.emit("listObjects",o,i),o}async count({prefix:e}={}){let t,r=0,i=!0;for(;i;){const s={prefix:e,continuationToken:t},n=await this.listObjects(s);r+=n.KeyCount||0,i=n.IsTruncated||!1,t=n.NextContinuationToken}return this.emit("count",r,{prefix:e}),r}async getAllKeys({prefix:e}={}){let t,r=[],i=!0;for(;i;){const s={prefix:e,continuationToken:t},n=await this.listObjects(s);n.Contents&&(r=r.concat(n.Contents.map(e=>e.Key))),i=n.IsTruncated||!1,t=n.NextContinuationToken}return this.config.keyPrefix&&(r=r.map(e=>e.replace(this.config.keyPrefix,"")).map(e=>e.startsWith("/")?e.replace("/",""):e)),this.emit("getAllKeys",r,{prefix:e}),r}async getContinuationTokenAfterOffset(e={}){const{prefix:t,offset:r=1e3}=e;if(0===r)return null;let i,s=!0,n=0;for(;s;){const e={prefix:t,maxKeys:r<1e3?r:r-n>1e3?1e3:r-n,continuationToken:i},o=await this.listObjects(e);if(o.Contents&&(n+=o.Contents.length),s=o.IsTruncated||!1,i=o.NextContinuationToken,n>=r)break}return this.emit("getContinuationTokenAfterOffset",i||null,e),i||null}async getKeysPage(e={}){const{prefix:t,offset:r=0,amount:i=100}=e;let s,n=[],o=!0;if(r>0&&(s=await this.getContinuationTokenAfterOffset({prefix:t,offset:r}),!s))return this.emit("getKeysPage",[],e),[];for(;o;){const e={prefix:t,continuationToken:s},r=await this.listObjects(e);if(r.Contents&&(n=n.concat(r.Contents.map(e=>e.Key))),o=r.IsTruncated||!1,s=r.NextContinuationToken,n.length>=i){n=n.slice(0,i);break}}return this.config.keyPrefix&&(n=n.map(e=>e.replace(this.config.keyPrefix,"")).map(e=>e.startsWith("/")?e.replace("/",""):e)),this.emit("getKeysPage",n,e),n}async moveAllObjects({prefixFrom:e,prefixTo:t}){const r=await this.getAllKeys({prefix:e}),{results:s,errors:n}=await i.for(r).withConcurrency(this.parallelism).process(async r=>{const i=r.replace(e,t),[s,n]=await ve(async()=>{await this.moveObject({from:r,to:i})});if(!s)throw new le("Unknown error in moveAllObjects",{bucket:this.config.bucket,from:r,to:i,original:n});return i});if(this.emit("moveAllObjects",{results:s,errors:n},{prefixFrom:e,prefixTo:t}),n.length>0)throw new Error("Some objects could not be moved");return s}}var Vi=Hi;async function Ki(e,t,r){if(!this.passphrase)return t.push(new ee("Missing configuration for secrets encryption.",{actual:e,type:"encryptionKeyMissing",suggestion:"Provide a passphrase for secret encryption."})),e;const[i,s,n]=await ve(()=>Se(String(e),this.passphrase));return i?n:(t.push(new ee("Problem encrypting secret.",{actual:e,type:"encryptionProblem",error:s,suggestion:"Check the passphrase and input value."})),e)}async function Wi(e,t,r){if(m(e))return e;const[i,s,n]=we(()=>JSON.stringify(e));if(!i)throw new ee("Failed to stringify JSON",{original:s,input:e});return n}class Ji extends T{constructor({options:e,passphrase:t,autoEncrypt:r=!0}={}){super(p({},{useNewCustomCheckerFunction:!0,messages:{encryptionKeyMissing:"Missing configuration for secrets encryption.",encryptionProblem:"Problem encrypting secret. Actual: {actual}. Error: {error}"},defaults:{string:{trim:!0},object:{strict:"remove"},number:{convert:!0}}},e)),this.passphrase=t,this.autoEncrypt=r,this.alias("secret",{type:"string",custom:this.autoEncrypt?Ki:void 0,messages:{string:"The '{field}' field must be a string.",stringMin:"This secret '{field}' field length must be at least {expected} long."}}),this.alias("secretAny",{type:"any",custom:this.autoEncrypt?Ki:void 0}),this.alias("secretNumber",{type:"number",custom:this.autoEncrypt?Ki:void 0}),this.alias("json",{type:"any",custom:this.autoEncrypt?Wi:void 0})}}const Gi=new Proxy(Ji,{instance:null,construct(e,t){return this.instance||(this.instance=new e(...t)),this.instance}});const Yi={trim:e=>null==e?e:e.trim(),encrypt:async(e,{passphrase:t})=>{if(null==e)return e;const[r,i,s]=await be(()=>Se(e,t));return r?s:e},decrypt:async(e,{passphrase:t})=>{if(null==e)return e;const[r,i,s]=await be(()=>Oe(e,t));return r?"null"===s?null:"undefined"!==s?s:void 0:e},toString:e=>null==e?e:String(e),fromArray:(e,{separator:t})=>{if(null==e||!Array.isArray(e))return e;if(0===e.length)return"";return e.map(e=>"string"==typeof e?e.replace(/\\/g,"\\\\").replace(new RegExp(`\\${t}`,"g"),`\\${t}`):String(e)).join(t)},toArray:(e,{separator:t})=>{if(Array.isArray(e))return e;if(null==e)return e;if(""===e)return[];const r=[];let i="",s=0;const n=String(e);for(;s<n.length;)"\\"===n[s]&&s+1<n.length?(i+=n[s+1],s+=2):n[s]===t?(r.push(i),i="",s++):(i+=n[s],s++);return r.push(i),r},toJSON:e=>{if(null===e)return null;if(void 0===e)return;if("string"==typeof e){const[t,r,i]=we(()=>JSON.parse(e));return e}const[t,r,i]=we(()=>JSON.stringify(e));return t?i:e},fromJSON:e=>{if(null===e)return null;if(void 0===e)return;if("string"!=typeof e)return e;if(""===e)return"";const[t,r,i]=we(()=>JSON.parse(e));return t?i:e},toNumber:e=>m(e)?e.includes(".")?parseFloat(e):parseInt(e):e,toBool:e=>[!0,1,"true","1","yes","y"].includes(e),fromBool:e=>[!0,1,"true","1","yes","y"].includes(e)?"1":"0",fromBase62:e=>{if(null==e||""===e)return e;if("number"==typeof e)return e;if("string"==typeof e){const t=F(e);return isNaN(t)?void 0:t}},toBase62:e=>{if(null==e||""===e)return e;if("number"==typeof e)return U(e);if("string"==typeof e){const t=Number(e);return isNaN(t)?e:U(t)}return e},fromBase62Decimal:e=>{if(null==e||""===e)return e;if("number"==typeof e)return e;if("string"==typeof e){const t=B(e);return isNaN(t)?void 0:t}},toBase62Decimal:e=>{if(null==e||""===e)return e;if("number"==typeof e)return q(e);if("string"==typeof e){const t=Number(e);return isNaN(t)?e:q(t)}return e},fromArrayOfNumbers:(e,{separator:t})=>{if(null==e||!Array.isArray(e))return e;if(0===e.length)return"";return e.map(e=>{if("number"==typeof e&&!isNaN(e))return U(e);const t=Number(e);return isNaN(t)?"":U(t)}).join(t)},toArrayOfNumbers:(e,{separator:t})=>{if(Array.isArray(e))return e.map(e=>"number"==typeof e?e:F(e));if(null==e)return e;if(""===e)return[];const r=String(e),i=[];let s="",n=0;for(;n<r.length;)"\\"===r[n]&&n+1<r.length?(s+=r[n+1],n+=2):r[n]===t?(i.push(s),s="",n++):(s+=r[n],n++);return i.push(s),i.map(e=>{if("number"==typeof e)return e;if("string"==typeof e&&""!==e){const t=F(e);return isNaN(t)?NaN:t}return NaN})},fromArrayOfDecimals:(e,{separator:t})=>{if(null==e||!Array.isArray(e))return e;if(0===e.length)return"";return e.map(e=>{if("number"==typeof e&&!isNaN(e))return q(e);const t=Number(e);return isNaN(t)?"":q(t)}).join(t)},toArrayOfDecimals:(e,{separator:t})=>{if(Array.isArray(e))return e.map(e=>"number"==typeof e?e:B(e));if(null==e)return e;if(""===e)return[];const r=String(e),i=[];let s="",n=0;for(;n<r.length;)"\\"===r[n]&&n+1<r.length?(s+=r[n+1],n+=2):r[n]===t?(i.push(s),s="",n++):(s+=r[n],n++);return i.push(s),i.map(e=>{if("number"==typeof e)return e;if("string"==typeof e&&""!==e){const t=B(e);return isNaN(t)?NaN:t}return NaN})}};class Qi{constructor(e){const{map:t,name:r,attributes:i,passphrase:s,version:n=1,options:o={}}=e;this.name=r,this.version=n,this.attributes=i||{},this.passphrase=s??"secret",this.options=p({},this.defaultOptions(),o),this.allNestedObjectsOptional=this.options.allNestedObjectsOptional??!1;const a=this.preprocessAttributesForValidation(this.attributes);if(this.validator=new Gi({autoEncrypt:!1}).compile(p({$$async:!0},a)),this.options.generateAutoHooks&&this.generateAutoHooks(),g(t)){const e=I(this.attributes,{safe:!0}),t=Object.keys(e).filter(e=>!e.includes("$$")),r=this.extractObjectKeys(this.attributes),i=[...new Set([...t,...r])],{mapping:s,reversedMapping:n}=function(e){const t={},r={};return e.forEach((e,i)=>{const s=U(i);t[e]=s,r[s]=e}),{mapping:t,reversedMapping:r}}(i);this.map=s,this.reversedMap=n}else this.map=t,this.reversedMap=y(t)}defaultOptions(){return{autoEncrypt:!0,autoDecrypt:!0,arraySeparator:"|",generateAutoHooks:!0,hooks:{beforeMap:{},afterMap:{},beforeUnmap:{},afterUnmap:{}}}}addHook(e,t,r){this.options.hooks[e][t]||(this.options.hooks[e][t]=[]),this.options.hooks[e][t]=b([...this.options.hooks[e][t],r])}extractObjectKeys(e,t=""){const r=[];for(const[i,s]of Object.entries(e)){if(i.startsWith("$$"))continue;const e=t?`${t}.${i}`:i;"object"!=typeof s||null===s||Array.isArray(s)||(r.push(e),"object"===s.$$type&&r.push(...this.extractObjectKeys(s,e)))}return r}generateAutoHooks(){const e=I(w(this.attributes),{safe:!0});for(const[t,r]of Object.entries(e))if(r.includes("array")){if(r.includes("items:string"))this.addHook("beforeMap",t,"fromArray"),this.addHook("afterUnmap",t,"toArray");else if(r.includes("items:number")){r.includes("integer:true")||r.includes("|integer:")||r.includes("|integer")?(this.addHook("beforeMap",t,"fromArrayOfNumbers"),this.addHook("afterUnmap",t,"toArrayOfNumbers")):(this.addHook("beforeMap",t,"fromArrayOfDecimals"),this.addHook("afterUnmap",t,"toArrayOfDecimals"))}}else if(r.includes("secret"))this.options.autoEncrypt&&this.addHook("beforeMap",t,"encrypt"),this.options.autoDecrypt&&this.addHook("afterUnmap",t,"decrypt");else{if(r.includes("number")){r.includes("integer:true")||r.includes("|integer:")||r.includes("|integer")?(this.addHook("beforeMap",t,"toBase62"),this.addHook("afterUnmap",t,"fromBase62")):(this.addHook("beforeMap",t,"toBase62Decimal"),this.addHook("afterUnmap",t,"fromBase62Decimal"));continue}r.includes("boolean")?(this.addHook("beforeMap",t,"fromBool"),this.addHook("afterUnmap",t,"toBool")):(r.includes("json")||"object"===r||r.includes("object"))&&(this.addHook("beforeMap",t,"toJSON"),this.addHook("afterUnmap",t,"fromJSON"))}}static import(e){let{map:t,name:r,options:i,version:s,attributes:n}=m(e)?JSON.parse(e):e;const[o,a,c]=we(()=>Qi._importAttributes(n));if(!o)throw new me("Failed to import schema attributes",{original:a,input:n});n=c;return new Qi({map:t,name:r,options:i,version:s,attributes:n})}static _importAttributes(e){if("string"==typeof e){const[t,r,i]=we(()=>JSON.parse(e));if(t&&"object"==typeof i&&null!==i){const[t,r,s]=we(()=>Qi._importAttributes(i));if(!t)throw new me("Failed to parse nested schema attribute",{original:r,input:e});return s}return e}if(Array.isArray(e)){const[t,r,i]=we(()=>e.map(e=>Qi._importAttributes(e)));if(!t)throw new me("Failed to import array schema attributes",{original:r,input:e});return i}if("object"==typeof e&&null!==e){const t={};for(const[r,i]of Object.entries(e)){const[e,s,n]=we(()=>Qi._importAttributes(i));if(!e)throw new me("Failed to import object schema attribute",{original:s,key:r,input:i});t[r]=n}return t}return e}export(){return{version:this.version,name:this.name,options:this.options,attributes:this._exportAttributes(this.attributes),map:this.map}}_exportAttributes(e){if("string"==typeof e)return e;if(Array.isArray(e))return e.map(e=>this._exportAttributes(e));if("object"==typeof e&&null!==e){const t={};for(const[r,i]of Object.entries(e))t[r]=this._exportAttributes(i);return t}return e}async applyHooksActions(e,t){const r=w(e);for(const[e,i]of Object.entries(this.options.hooks[t]))for(const t of i){const i=v(r,e);void 0!==i&&"function"==typeof Yi[t]&&k(r,e,await Yi[t](i,{passphrase:this.passphrase,separator:this.options.arraySeparator}))}return r}async validate(e,{mutateOriginal:t=!1}={}){let r=t?e:w(e);return await this.validator(r)}async mapper(e){let t=w(e);t=await this.applyHooksActions(t,"beforeMap");const r=I(t,{safe:!0}),i={_v:this.version+""};for(const[e,t]of Object.entries(r)){const r=this.map[e]||e,s=this.getAttributeDefinition(e);"number"==typeof t&&"string"==typeof s&&s.includes("number")?i[r]=U(t):"string"==typeof t?"[object Object]"===t?i[r]="{}":(t.startsWith("{")||t.startsWith("["),i[r]=t):Array.isArray(t)||"object"==typeof t&&null!==t?i[r]=JSON.stringify(t):i[r]=t}return await this.applyHooksActions(i,"afterMap"),i}async unmapper(e,t){let r=w(e);delete r._v,r=await this.applyHooksActions(r,"beforeUnmap");const i=t?y(t):this.reversedMap,s={};for(const[e,t]of Object.entries(r)){const r=i&&i[e]?i[e]:e;let n=t;const o=this.getAttributeDefinition(r);if("string"!=typeof o||!o.includes("number")||o.includes("array")||o.includes("decimal")){if("string"==typeof t)if("[object Object]"===t)n={};else if(t.startsWith("{")||t.startsWith("[")){const[e,r,i]=we(()=>JSON.parse(t));e&&(n=i)}}else"string"==typeof n&&""!==n?n=F(n):"number"==typeof n||(n=void 0);if(this.attributes&&"string"==typeof o&&o.includes("array"))if(Array.isArray(n));else if("string"==typeof n&&n.trim().startsWith("[")){const[e,t,r]=we(()=>JSON.parse(n));e&&Array.isArray(r)&&(n=r)}else n=Yi.toArray(n,{separator:this.options.arraySeparator});if(this.options.hooks&&this.options.hooks.afterUnmap&&this.options.hooks.afterUnmap[r])for(const e of this.options.hooks.afterUnmap[r])"function"==typeof Yi[e]&&(n=await Yi[e](n,{passphrase:this.passphrase,separator:this.options.arraySeparator}));s[r]=n}await this.applyHooksActions(s,"afterUnmap");const n=P(s);for(const[t,r]of Object.entries(e))t.startsWith("$")&&(n[t]=r);return n}getAttributeDefinition(e){const t=e.split(".");let r=this.attributes;for(const e of t){if(!r)return;r=r[e]}return r}preprocessAttributesForValidation(e){const t={};for(const[r,i]of Object.entries(e))if("object"!=typeof i||null===i||Array.isArray(i))t[r]=i;else{const e=i.$$type&&i.$$type.includes("required"),s=i.$$type&&i.$$type.includes("optional"),n={type:"object",properties:this.preprocessAttributesForValidation(i),strict:!1};e||(s||this.allNestedObjectsOptional)&&(n.optional=!0),t[r]=n}return t}}var Zi=Qi;const Xi=2047;var es=Object.freeze({__proto__:null,S3_METADATA_LIMIT_BYTES:Xi,handleGet:async function({resource:e,metadata:t,body:r}){return{metadata:t,body:r}},handleInsert:async function({resource:e,data:t,mappedData:r,originalData:i}){const s=W(r),n=Y({s3Limit:Xi,systemConfig:{version:e.version,timestamps:e.config.timestamps,id:t.id}});if(s>n)throw new Error(`S3 metadata size exceeds 2KB limit. Current size: ${s} bytes, effective limit: ${n} bytes, absolute limit: 2047 bytes`);return{mappedData:r,body:""}},handleUpdate:async function({resource:e,id:t,data:r,mappedData:i,originalData:s}){const n=W(i),o=Y({s3Limit:Xi,systemConfig:{version:e.version,timestamps:e.config.timestamps,id:t}});if(n>o)throw new Error(`S3 metadata size exceeds 2KB limit. Current size: ${n} bytes, effective limit: ${o} bytes, absolute limit: 2047 bytes`);return{mappedData:i,body:JSON.stringify(i)}},handleUpsert:async function({resource:e,id:t,data:r,mappedData:i}){const s=W(i),n=Y({s3Limit:Xi,systemConfig:{version:e.version,timestamps:e.config.timestamps,id:t}});if(s>n)throw new Error(`S3 metadata size exceeds 2KB limit. Current size: ${s} bytes, effective limit: ${n} bytes, absolute limit: 2047 bytes`);return{mappedData:i,body:""}}});var ts=Object.freeze({__proto__:null,handleGet:async function({resource:e,metadata:t,body:r}){if(r&&""!==r.trim())try{const e=JSON.parse(r);return{metadata:{...e,...t},body:r}}catch(e){return{metadata:t,body:r}}return{metadata:t,body:r}},handleInsert:async function({resource:e,data:t,mappedData:r,originalData:i}){const s=W(r);return s>Y({s3Limit:Xi,systemConfig:{version:e.version,timestamps:e.config.timestamps,id:t.id}})?(e.emit("exceedsLimit",{operation:"insert",totalSize:s,limit:2047,excess:s-2047,data:i||t}),{mappedData:{_v:r._v},body:JSON.stringify(r)}):{mappedData:r,body:""}},handleUpdate:async function({resource:e,id:t,data:r,mappedData:i,originalData:s}){const n=W(i);return n>Y({s3Limit:Xi,systemConfig:{version:e.version,timestamps:e.config.timestamps,id:t}})&&e.emit("exceedsLimit",{operation:"update",id:t,totalSize:n,limit:2047,excess:n-2047,data:s||r}),{mappedData:i,body:JSON.stringify(r)}},handleUpsert:async function({resource:e,id:t,data:r,mappedData:i,originalData:s}){const n=W(i);return n>Y({s3Limit:Xi,systemConfig:{version:e.version,timestamps:e.config.timestamps,id:t}})&&e.emit("exceedsLimit",{operation:"upsert",id:t,totalSize:n,limit:2047,excess:n-2047,data:s||r}),{mappedData:i,body:JSON.stringify(r)}}});const rs="$truncated",is="true",ss=z(rs)+z(is);async function ns({resource:e,data:t,mappedData:r,originalData:i}){const s=Y({s3Limit:Xi,systemConfig:{version:e.version,timestamps:e.config.timestamps,id:t.id}}),n=K(r),o=Object.entries(n).sort(([,e],[,t])=>e-t),a={};let c=0,u=!1;r._v&&(a._v=r._v,c+=n._v);for(const[e,t]of o){if("_v"===e)continue;const i=r[e];if(!(c+(t+(u?0:ss))<=s)){const t=s-c-(u?0:ss);if(t>0){const r=os(i,t);a[e]=r,u=!0,c+=z(r)}else a[e]="",u=!0;break}a[e]=i,c+=t}let l=W(a)+(u?ss:0);for(;l>s;){const e=Object.keys(a).filter(e=>"_v"!==e&&"$truncated"!==e);if(0===e.length)break;a[e[e.length-1]]="",l=W(a)+ss,u=!0}return u&&(a[rs]=is),{mappedData:a,body:""}}function os(e,t){if("string"==typeof e)return as(e,t);if("object"==typeof e&&null!==e){return as(JSON.stringify(e),t)}return as(String(e),t)}function as(e,t){const r=new TextEncoder;let i=r.encode(e);if(i.length<=t)return e;let s=e.length;for(;s>0;){const n=e.substring(0,s);if(i=r.encode(n),i.length<=t)return n;s--}return""}var cs=Object.freeze({__proto__:null,handleGet:async function({resource:e,metadata:t,body:r}){return{metadata:t,body:r}},handleInsert:ns,handleUpdate:async function({resource:e,id:t,data:r,mappedData:i,originalData:s}){return ns({resource:e,data:r,mappedData:i,originalData:s})},handleUpsert:async function({resource:e,id:t,data:r,mappedData:i}){return ns({resource:e,data:r,mappedData:i})}});const us="$overflow",ls="true",hs=z(us)+z(ls);async function fs({resource:e,data:t,mappedData:r,originalData:i}){const s=Y({s3Limit:Xi,systemConfig:{version:e.version,timestamps:e.config.timestamps,id:t.id}}),n=K(r),o=Object.entries(n).sort(([,e],[,t])=>e-t),a={},c={};let u=0,l=!1;r._v&&(a._v=r._v,u+=n._v);let h=s;for(const[e,t]of o)"_v"!==e&&(!l&&u+t>s&&(h-=hs,l=!0),!l&&u+t<=h?(a[e]=r[e],u+=t):(c[e]=r[e],l=!0));l&&(a[us]=ls);return{mappedData:a,body:Object.keys(c).length>0?JSON.stringify(c):""}}async function ds({resource:e,data:t,mappedData:r}){const i={_v:r._v||String(e.version)};i._map=JSON.stringify(e.schema.map);return{mappedData:i,body:JSON.stringify(r)}}const ps={"user-managed":ts,"enforce-limits":es,"truncate-data":cs,"body-overflow":Object.freeze({__proto__:null,handleGet:async function({resource:e,metadata:t,body:r}){let i={};if(r&&""!==r.trim()){const[e,t,s]=we(()=>JSON.parse(r));i=e?s:{}}const s={...i,...t};return delete s.$overflow,{metadata:s,body:r}},handleInsert:fs,handleUpdate:async function({resource:e,id:t,data:r,mappedData:i,originalData:s}){return fs({resource:e,data:r,mappedData:i,originalData:s})},handleUpsert:async function({resource:e,id:t,data:r,mappedData:i}){return fs({resource:e,data:r,mappedData:i})}}),"body-only":Object.freeze({__proto__:null,handleGet:async function({resource:e,metadata:t,body:r}){let i={};if(r&&""!==r.trim()){const[e,t,s]=we(()=>JSON.parse(r));i=e?s:{}}return{metadata:{...i,...t},body:r}},handleInsert:ds,handleUpdate:async function({resource:e,id:t,data:r,mappedData:i}){const s={_v:i._v||String(e.version)};return s._map=JSON.stringify(e.schema.map),{mappedData:s,body:JSON.stringify(i)}},handleUpsert:async function({resource:e,id:t,data:r,mappedData:i}){return ds({resource:e,data:r,mappedData:i})}})};function ms(e){const t=ps[e];if(!t)throw new Error(`Unknown behavior: ${e}. Available behaviors: ${Object.keys(ps).join(", ")}`);return t}const gs=Object.keys(ps),ys="user-managed";class bs extends $e{constructor(e={}){super(),this._instanceId=xe(7);const t=function(e){const t=[];e.name?"string"!=typeof e.name?t.push("Resource 'name' must be a string"):""===e.name.trim()&&t.push("Resource 'name' cannot be empty"):t.push("Resource 'name' is required");e.client||t.push("S3 'client' is required");e.attributes?"object"!=typeof e.attributes||Array.isArray(e.attributes)?t.push("Resource 'attributes' must be an object"):0===Object.keys(e.attributes).length&&t.push("Resource 'attributes' cannot be empty"):t.push("Resource 'attributes' are required");void 0!==e.version&&"string"!=typeof e.version&&t.push("Resource 'version' must be a string");void 0!==e.behavior&&"string"!=typeof e.behavior&&t.push("Resource 'behavior' must be a string");void 0!==e.passphrase&&"string"!=typeof e.passphrase&&t.push("Resource 'passphrase' must be a string");void 0!==e.parallelism&&("number"==typeof e.parallelism&&Number.isInteger(e.parallelism)?e.parallelism<1&&t.push("Resource 'parallelism' must be greater than 0"):t.push("Resource 'parallelism' must be an integer"));void 0===e.observers||Array.isArray(e.observers)||t.push("Resource 'observers' must be an array");const r=["cache","autoDecrypt","timestamps","paranoid","allNestedObjectsOptional"];for(const i of r)void 0!==e[i]&&"boolean"!=typeof e[i]&&t.push(`Resource '${i}' must be a boolean`);void 0!==e.idGenerator&&("function"!=typeof e.idGenerator&&"number"!=typeof e.idGenerator?t.push("Resource 'idGenerator' must be a function or a number (size)"):"number"==typeof e.idGenerator&&e.idGenerator<=0&&t.push("Resource 'idGenerator' size must be greater than 0"));void 0!==e.idSize&&("number"==typeof e.idSize&&Number.isInteger(e.idSize)?e.idSize<=0&&t.push("Resource 'idSize' must be greater than 0"):t.push("Resource 'idSize' must be an integer"));if(void 0!==e.partitions)if("object"!=typeof e.partitions||Array.isArray(e.partitions))t.push("Resource 'partitions' must be an object");else for(const[r,i]of Object.entries(e.partitions))if("object"!=typeof i||Array.isArray(i))t.push(`Partition '${r}' must be an object`);else if(i.fields)if("object"!=typeof i.fields||Array.isArray(i.fields))t.push(`Partition '${r}.fields' must be an object`);else for(const[e,s]of Object.entries(i.fields))"string"!=typeof s&&t.push(`Partition '${r}.fields.${e}' must be a string`);else t.push(`Partition '${r}' must have a 'fields' property`);if(void 0!==e.hooks)if("object"!=typeof e.hooks||Array.isArray(e.hooks))t.push("Resource 'hooks' must be an object");else{const r=["beforeInsert","afterInsert","beforeUpdate","afterUpdate","beforeDelete","afterDelete"];for(const[i,s]of Object.entries(e.hooks))if(r.includes(i))if(Array.isArray(s))for(let e=0;e<s.length;e++){const t=s[e];if("function"==typeof t);else if("string"==typeof t)continue}else t.push(`Resource 'hooks.${i}' must be an array`);else t.push(`Invalid hook event '${i}'. Valid events: ${r.join(", ")}`)}if(void 0!==e.events)if("object"!=typeof e.events||Array.isArray(e.events))t.push("Resource 'events' must be an object");else for(const[r,i]of Object.entries(e.events))if(Array.isArray(i))for(let e=0;e<i.length;e++){"function"!=typeof i[e]&&t.push(`Resource 'events.${r}[${e}]' must be a function`)}else"function"!=typeof i&&t.push(`Resource 'events.${r}' must be a function or array of functions`);return{isValid:0===t.length,errors:t}}(e);if(!t.isValid){const r=t.errors.map(e=>` • ${e}`).join("\n");throw new ge(`Invalid Resource ${e.name||"[unnamed]"} configuration:\n${r}`,{resourceName:e.name,validation:t.errors})}const{name:r,client:i,version:s="1",attributes:n={},behavior:o=ys,passphrase:a="secret",parallelism:c=10,observers:u=[],cache:l=!1,autoDecrypt:h=!0,timestamps:f=!1,partitions:d={},paranoid:p=!0,allNestedObjectsOptional:m=!0,hooks:g={},idGenerator:y,idSize:b=22,versioningEnabled:w=!1,events:v={}}=e;if(this.name=r,this.client=i,this.version=s,this.behavior=o,this.observers=u,this.parallelism=c,this.passphrase=a??"secret",this.versioningEnabled=w,this.idGenerator=this.configureIdGenerator(y,b),this.idSize="number"==typeof y&&y>0?y:"number"==typeof b&&b>0?b:22,this.idGeneratorType=this.getIdGeneratorType(y,this.idSize),this.config={cache:l,hooks:g,paranoid:p,timestamps:f,partitions:d,autoDecrypt:h,allNestedObjectsOptional:m},this.hooks={beforeInsert:[],afterInsert:[],beforeUpdate:[],afterUpdate:[],beforeDelete:[],afterDelete:[]},this.attributes=n||{},this.map=e.map,this.applyConfiguration({map:this.map}),g)for(const[e,t]of Object.entries(g))if(Array.isArray(t)&&this.hooks[e])for(const r of t)"function"==typeof r&&this.hooks[e].push(r.bind(this));if(v&&Object.keys(v).length>0)for(const[e,t]of Object.entries(v))if(Array.isArray(t))for(const r of t)"function"==typeof r&&this.on(e,r);else"function"==typeof t&&this.on(e,t);this._initMiddleware()}configureIdGenerator(r,i){return"function"==typeof r?()=>String(r()):"number"==typeof r&&r>0?e(t,r):"number"==typeof i&&i>0&&22!==i?e(t,i):xe}getIdGeneratorType(e,t){return"function"==typeof e?"custom_function":t}get options(){return{timestamps:this.config.timestamps,partitions:this.config.partitions||{},cache:this.config.cache,autoDecrypt:this.config.autoDecrypt,paranoid:this.config.paranoid,allNestedObjectsOptional:this.config.allNestedObjectsOptional}}export(){const e=this.schema.export();return e.behavior=this.behavior,e.timestamps=this.config.timestamps,e.partitions=this.config.partitions||{},e.paranoid=this.config.paranoid,e.allNestedObjectsOptional=this.config.allNestedObjectsOptional,e.autoDecrypt=this.config.autoDecrypt,e.cache=this.config.cache,e.hooks=this.hooks,e.map=this.map,e}applyConfiguration({map:e}={}){this.config.timestamps&&(this.attributes.createdAt||(this.attributes.createdAt="string|optional"),this.attributes.updatedAt||(this.attributes.updatedAt="string|optional"),this.config.partitions||(this.config.partitions={}),this.config.partitions.byCreatedDate||(this.config.partitions.byCreatedDate={fields:{createdAt:"date|maxlength:10"}}),this.config.partitions.byUpdatedDate||(this.config.partitions.byUpdatedDate={fields:{updatedAt:"date|maxlength:10"}})),this.setupPartitionHooks(),this.versioningEnabled&&(this.config.partitions.byVersion||(this.config.partitions.byVersion={fields:{_v:"string"}})),this.schema=new Zi({name:this.name,attributes:this.attributes,passphrase:this.passphrase,version:this.version,options:{autoDecrypt:this.config.autoDecrypt,allNestedObjectsOptional:this.config.allNestedObjectsOptional},map:e||this.map}),this.validatePartitions()}updateAttributes(e){const t=this.attributes;return this.attributes=e,this.applyConfiguration({map:this.schema?.map}),{oldAttributes:t,newAttributes:e}}addHook(e,t){this.hooks[e]&&this.hooks[e].push(t.bind(this))}async executeHooks(e,t){if(!this.hooks[e])return t;let r=t;for(const t of this.hooks[e])r=await t(r);return r}setupPartitionHooks(){if(!this.config.partitions)return;const e=this.config.partitions;0!==Object.keys(e).length&&(this.hooks.afterInsert||(this.hooks.afterInsert=[]),this.hooks.afterInsert.push(async e=>(await this.createPartitionReferences(e),e)),this.hooks.afterDelete||(this.hooks.afterDelete=[]),this.hooks.afterDelete.push(async e=>(await this.deletePartitionReferences(e),e)))}async validate(e){const t={original:w(e),isValid:!1,errors:[]},r=await this.schema.validate(e,{mutateOriginal:!1});return!0===r?t.isValid=!0:t.errors=r,t.data=e,t}validatePartitions(){if(!this.config.partitions)return;const e=this.config.partitions;if(0===Object.keys(e).length)return;const t=Object.keys(this.attributes||{});for(const[r,i]of Object.entries(e))if(i.fields)for(const e of Object.keys(i.fields))if(!this.fieldExistsInAttributes(e))throw new ye(`Partition '${r}' uses field '${e}' which does not exist in resource attributes. Available fields: ${t.join(", ")}.`,{resourceName:this.name,partitionName:r,fieldName:e,availableFields:t,operation:"validatePartitions"})}fieldExistsInAttributes(e){if(e.startsWith("_"))return!0;if(!e.includes("."))return Object.keys(this.attributes||{}).includes(e);const t=e.split(".");let r=this.attributes||{};for(const e of t){if(!r||"object"!=typeof r||!(e in r))return!1;r=r[e]}return!0}applyPartitionRule(e,t){if(null==e)return e;let r=e;if("string"==typeof t&&t.includes("maxlength:")){const e=t.match(/maxlength:(\d+)/);if(e){const t=parseInt(e[1]);"string"==typeof r&&r.length>t&&(r=r.substring(0,t))}}if(t.includes("date"))if(r instanceof Date)r=r.toISOString().split("T")[0];else if("string"==typeof r)if(r.includes("T")&&r.includes("Z"))r=r.split("T")[0];else{const e=new Date(r);isNaN(e.getTime())||(r=e.toISOString().split("T")[0])}return r}getResourceKey(e){return We("resource="+this.name,"data",`id=${e}`)}getPartitionKey({partitionName:e,id:t,data:r}){if(!this.config.partitions||!this.config.partitions[e])throw new ye(`Partition '${e}' not found`,{resourceName:this.name,partitionName:e,operation:"getPartitionKey"});const i=this.config.partitions[e],s=[],n=Object.entries(i.fields).sort(([e],[t])=>e.localeCompare(t));for(const[e,t]of n){const i=this.getNestedFieldValue(r,e),n=this.applyPartitionRule(i,t);if(null==n)return null;s.push(`${e}=${n}`)}if(0===s.length)return null;const o=t||r?.id;return o?We(`resource=${this.name}`,`partition=${e}`,...s,`id=${o}`):null}getNestedFieldValue(e,t){if(!t.includes("."))return e[t];const r=t.split(".");let i=e;for(const e of r){if(!i||"object"!=typeof i||!(e in i))return;i=i[e]}return i}calculateContentLength(e){return e?Buffer.isBuffer(e)?e.length:"string"==typeof e?Buffer.byteLength(e,"utf8"):"object"==typeof e?Buffer.byteLength(JSON.stringify(e),"utf8"):Buffer.byteLength(String(e),"utf8"):0}async insert({id:e,...t}){if(await this.exists(e))throw new Error(`Resource with id '${e}' already exists`);this.getResourceKey(e||"(auto)"),this.options.timestamps&&(t.createdAt=(new Date).toISOString(),t.updatedAt=(new Date).toISOString());const r={id:e,...this.applyDefaults(t)},i=await this.executeHooks("beforeInsert",r),s=Object.keys(i).filter(e=>!(e in r)||i[e]!==r[e]),n={};for(const e of s)n[e]=i[e];const{errors:o,isValid:a,data:c}=await this.validate(i);if(!a){const e=o&&o.length&&o[0].message?o[0].message:"Insert failed";throw new ue({bucket:this.client.config.bucket,resourceName:this.name,attributes:i,validation:o,message:e})}const{id:u,...l}=c;Object.assign(l,n);let h=u||e;if(!h&&(h=this.idGenerator(),!h||""===h.trim())){const{idGenerator:e}=await Promise.resolve().then(function(){return De});h=e()}const f=await this.schema.mapper(l);f._v=String(this.version);const d=ms(this.behavior),{mappedData:p,body:m}=await d.handleInsert({resource:this,data:l,mappedData:f,originalData:r}),g=p,y=this.getResourceKey(h);let b;if(m&&""!==m){const[e,t]=await ve(()=>Promise.resolve(JSON.parse(m)));e&&(b="application/json")}if("body-only"===this.behavior&&(!m||""===m))throw new Error(`[Resource.insert] Attempt to save object without body! Data: id=${h}, resource=${this.name}`);const[w,v,k]=await ve(()=>this.client.putObject({key:y,body:m,contentType:b,metadata:g}));if(!w){const e=v&&v.message?v.message:"";if(e.includes("metadata headers exceed")||e.includes("Insert failed")){const e=W(g),t=Y({s3Limit:2047,systemConfig:{version:this.version,timestamps:this.config.timestamps,id:h}}),r=e-t;throw v.totalSize=e,v.limit=2047,v.effectiveLimit=t,v.excess=r,new ge("metadata headers exceed",{resourceName:this.name,operation:"insert",id:h,totalSize:e,effectiveLimit:t,excess:r,suggestion:"Reduce metadata size or number of fields."})}throw v}const _=await this.get(h),S=await this.executeHooks("afterInsert",_);return this.emit("insert",S),S}async get(e){if(_(e))throw new Error("id cannot be an object");if(g(e))throw new Error("id cannot be empty");const t=this.getResourceKey(e),[r,i,s]=await ve(()=>this.client.getObject(t));if(!r)throw fe(i,{bucket:this.client.config.bucket,key:t,resourceName:this.name,operation:"get",id:e});const n=s.Metadata?._v||this.version,o="string"==typeof n&&n.startsWith("v")?n.slice(1):n,a=await this.getSchemaForVersion(o);let c=await a.unmapper(s.Metadata);const u=ms(this.behavior);let l="";if(s.ContentLength>0){const[e,r,i]=await ve(()=>this.client.getObject(t));l=e?await Ai(i.Body):""}const{metadata:h}=await u.handleGet({resource:this,metadata:c,body:l});let f=await this.composeFullObjectFromWrite({id:e,metadata:h,body:l,behavior:this.behavior});f._contentLength=s.ContentLength,f._lastModified=s.LastModified,f._hasContent=s.ContentLength>0,f._mimeType=s.ContentType||null,f._v=o,s.VersionId&&(f._versionId=s.VersionId),s.Expiration&&(f._expiresAt=s.Expiration),f._definitionHash=this.getDefinitionHash(),o!==this.version&&(f=await this.applyVersionMapping(f,o,this.version)),this.emit("get",f);return f}async exists(e){const t=this.getResourceKey(e),[r,i]=await ve(()=>this.client.headObject(t));return r}async update(e,t){if(g(e))throw new Error("id cannot be empty");if(!await this.exists(e))throw new Error(`Resource with id '${e}' does not exist`);const r=await this.get(e),i=w(t);let s=w(r);for(const[e,t]of Object.entries(i))if(e.includes(".")){let r=s;const i=e.split(".");for(let e=0;e<i.length-1;e++)"object"==typeof r[i[e]]&&null!==r[i[e]]||(r[i[e]]={}),r=r[i[e]];r[i[i.length-1]]=w(t)}else"object"!=typeof t||null===t||Array.isArray(t)?s[e]=w(t):s[e]=p({},s[e],t);if(this.config.timestamps){const e=(new Date).toISOString();s.updatedAt=e,s.metadata||(s.metadata={}),s.metadata.updatedAt=e}const n=await this.executeHooks("beforeUpdate",w(s)),o={...r,...n,id:e},{isValid:a,errors:c,data:u}=await this.validate(w(o));if(!a)throw new ue({bucket:this.client.config.bucket,resourceName:this.name,attributes:n,validation:c,message:"validation: "+(c&&c.length?JSON.stringify(c):"unknown")});await this.schema.mapper(u);const l=ms(this.behavior),h=await this.schema.mapper({...r,...n});h._v=String(this.version),await l.handleUpdate({resource:this,id:e,data:{...r,...n},mappedData:h,originalData:{...i,id:e}});const{id:f,...d}=u,m={...r,id:e},y={...d,id:e};await this.handlePartitionReferenceUpdates(m,y);const b=await this.schema.mapper(d);b._v=String(this.version);const v=ms(this.behavior),{mappedData:k,body:_}=await v.handleUpdate({resource:this,id:e,data:d,mappedData:b,originalData:{...i,id:e}}),S=k,O=this.getResourceKey(e);let R,j=_;if(""===_&&"body-overflow"!==this.behavior){const[e,t,r]=await ve(()=>this.client.getObject(O));if(e&&r.ContentLength>0){const e=Buffer.from(await r.Body.transformToByteArray()),t=e.toString(),[i,s]=await ve(()=>Promise.resolve(JSON.parse(t)));i||(j=e,R=r.ContentType)}}let x=R;if(j&&""!==j&&!x){const[e,t]=await ve(()=>Promise.resolve(JSON.parse(j)));e&&(x="application/json")}this.versioningEnabled&&r._v!==this.version&&await this.createHistoricalVersion(e,r);const[A,E]=await ve(()=>this.client.putObject({key:O,body:j,contentType:x,metadata:S}));if(!A&&E&&E.message&&E.message.includes("metadata headers exceed")){const t=W(S),r=Y({s3Limit:2047,systemConfig:{version:this.version,timestamps:this.config.timestamps,id:e}}),i=t-r;throw E.totalSize=t,E.limit=2047,E.effectiveLimit=r,E.excess=i,this.emit("exceedsLimit",{operation:"update",totalSize:t,limit:2047,effectiveLimit:r,excess:i,data:d}),new ge("metadata headers exceed",{resourceName:this.name,operation:"update",id:e,totalSize:t,effectiveLimit:r,excess:i,suggestion:"Reduce metadata size or number of fields."})}if(!A)throw fe(E,{bucket:this.client.config.bucket,key:O,resourceName:this.name,operation:"update",id:e});const D=await this.composeFullObjectFromWrite({id:e,metadata:S,body:j,behavior:this.behavior}),C=await this.executeHooks("afterUpdate",D);return this.emit("update",{...D,$before:{...r},$after:{...C}}),C}async delete(e){if(g(e))throw new Error("id cannot be empty");let t,r=null;const[i,s,n]=await ve(()=>this.get(e));i?t=n:(t={id:e},r=s),await this.executeHooks("beforeDelete",t);const o=this.getResourceKey(e),[a,c,u]=await ve(()=>this.client.deleteObject(o));if(this.emit("delete",{...t,$before:{...t},$after:null}),r)throw fe(r,{bucket:this.client.config.bucket,key:o,resourceName:this.name,operation:"delete",id:e});if(!a)throw fe(c,{key:o,resourceName:this.name,operation:"delete",id:e});return await this.executeHooks("afterDelete",t),u}async upsert({id:e,...t}){return await this.exists(e)?this.update(e,t):this.insert({id:e,...t})}async count({partition:e=null,partitionValues:t={}}={}){let r;if(e&&Object.keys(t).length>0){const i=this.config.partitions[e];if(!i)throw new ye(`Partition '${e}' not found`,{resourceName:this.name,partitionName:e,operation:"count"});const s=[],n=Object.entries(i.fields).sort(([e],[t])=>e.localeCompare(t));for(const[e,r]of n){const i=t[e];if(null!=i){const t=this.applyPartitionRule(i,r);s.push(`${e}=${t}`)}}r=s.length>0?`resource=${this.name}/partition=${e}/${s.join("/")}`:`resource=${this.name}/partition=${e}`}else r=`resource=${this.name}/data`;const i=await this.client.count({prefix:r});return this.emit("count",i),i}async insertMany(e){const{results:t}=await i.for(e).withConcurrency(this.parallelism).handleError(async(e,t)=>{this.emit("error",e,t),this.observers.map(r=>r.emit("error",this.name,e,t))}).process(async e=>await this.insert(e));return this.emit("insertMany",e.length),t}async deleteMany(e){const t=d(e.map(e=>this.getResourceKey(e)),1e3);e.map(e=>this.getResourceKey(e));const{results:r}=await i.for(t).withConcurrency(this.parallelism).handleError(async(e,t)=>{this.emit("error",e,t),this.observers.map(r=>r.emit("error",this.name,e,t))}).process(async e=>{const t=await this.client.deleteObjects(e);return e.forEach(e=>{const t=e.split("/").find(e=>e.startsWith("id=")),r=t?t.replace("id=",""):null;r&&(this.emit("deleted",r),this.observers.map(e=>e.emit("deleted",this.name,r)))}),t});return this.emit("deleteMany",e.length),r}async deleteAll(){if(!1!==this.config.paranoid)throw new ge("deleteAll() is a dangerous operation and requires paranoid: false option.",{resourceName:this.name,operation:"deleteAll",paranoid:this.config.paranoid,suggestion:"Set paranoid: false to allow deleteAll."});const e=`resource=${this.name}/data`,t=await this.client.deleteAll({prefix:e});return this.emit("deleteAll",{version:this.version,prefix:e,deletedCount:t}),{deletedCount:t,version:this.version}}async deleteAllData(){if(!1!==this.config.paranoid)throw new ge("deleteAllData() is a dangerous operation and requires paranoid: false option.",{resourceName:this.name,operation:"deleteAllData",paranoid:this.config.paranoid,suggestion:"Set paranoid: false to allow deleteAllData."});const e=`resource=${this.name}`,t=await this.client.deleteAll({prefix:e});return this.emit("deleteAllData",{resource:this.name,prefix:e,deletedCount:t}),{deletedCount:t,resource:this.name}}async listIds({partition:e=null,partitionValues:t={},limit:r,offset:i=0}={}){let s;if(e&&Object.keys(t).length>0){if(!this.config.partitions||!this.config.partitions[e])throw new ye(`Partition '${e}' not found`,{resourceName:this.name,partitionName:e,operation:"listIds"});const r=this.config.partitions[e],i=[],n=Object.entries(r.fields).sort(([e],[t])=>e.localeCompare(t));for(const[e,r]of n){const s=t[e];if(null!=s){const t=this.applyPartitionRule(s,r);i.push(`${e}=${t}`)}}s=i.length>0?`resource=${this.name}/partition=${e}/${i.join("/")}`:`resource=${this.name}/partition=${e}`}else s=`resource=${this.name}/data`;const n=(await this.client.getKeysPage({prefix:s,offset:i,amount:r||1e3})).map(e=>{const t=e.split("/").find(e=>e.startsWith("id="));return t?t.replace("id=",""):null}).filter(Boolean);return this.emit("listIds",n.length),n}async list({partition:e=null,partitionValues:t={},limit:r,offset:i=0}={}){const[s,n,o]=await ve(async()=>e?await this.listPartition({partition:e,partitionValues:t,limit:r,offset:i}):await this.listMain({limit:r,offset:i}));return s?o:this.handleListError(n,{partition:e,partitionValues:t})}async listMain({limit:e,offset:t=0}){const[r,i,s]=await ve(()=>this.listIds({limit:e,offset:t}));if(!r)throw i;const n=await this.processListResults(s,"main");return this.emit("list",{count:n.length,errors:0}),n}async listPartition({partition:e,partitionValues:t,limit:r,offset:i=0}){if(!this.config.partitions?.[e])return this.emit("list",{partition:e,partitionValues:t,count:0,errors:0}),[];const s=this.config.partitions[e],n=this.buildPartitionPrefix(e,s,t),[o,a,c]=await ve(()=>this.client.getAllKeys({prefix:n}));if(!o)throw a;const u=this.extractIdsFromKeys(c).slice(i),l=r?u.slice(0,r):u,h=await this.processPartitionResults(l,e,s,c);return this.emit("list",{partition:e,partitionValues:t,count:h.length,errors:0}),h}buildPartitionPrefix(e,t,r){const i=[],s=Object.entries(t.fields).sort(([e],[t])=>e.localeCompare(t));for(const[e,t]of s){const s=r[e];if(null!=s){const r=this.applyPartitionRule(s,t);i.push(`${e}=${r}`)}}return i.length>0?`resource=${this.name}/partition=${e}/${i.join("/")}`:`resource=${this.name}/partition=${e}`}extractIdsFromKeys(e){return e.map(e=>{const t=e.split("/").find(e=>e.startsWith("id="));return t?t.replace("id=",""):null}).filter(Boolean)}async processListResults(e,t="main"){const{results:r,errors:s}=await i.for(e).withConcurrency(this.parallelism).handleError(async(e,t)=>{this.emit("error",e,content),this.observers.map(t=>t.emit("error",this.name,e,content))}).process(async e=>{const[r,i,s]=await ve(()=>this.get(e));return r?s:this.handleResourceError(i,e,t)});return this.emit("list",{count:r.length,errors:0}),r}async processPartitionResults(e,t,r,s){const n=Object.entries(r.fields).sort(([e],[t])=>e.localeCompare(t)),{results:o,errors:a}=await i.for(e).withConcurrency(this.parallelism).handleError(async(e,t)=>{this.emit("error",e,content),this.observers.map(t=>t.emit("error",this.name,e,content))}).process(async e=>{const[r,i,o]=await ve(async()=>{const r=this.extractPartitionValuesFromKey(e,s,n);return await this.getFromPartition({id:e,partitionName:t,partitionValues:r})});return r?o:this.handleResourceError(i,e,"partition")});return o.filter(e=>null!==e)}extractPartitionValuesFromKey(e,t,r){const i=t.find(t=>t.includes(`id=${e}`));if(!i)throw new ye(`Partition key not found for ID ${e}`,{resourceName:this.name,id:e,operation:"extractPartitionValuesFromKey"});const s=i.split("/"),n={};for(const[e]of r){const t=s.find(t=>t.startsWith(`${e}=`));if(t){const r=t.replace(`${e}=`,"");n[e]=r}}return n}handleResourceError(e,t,r){if(e.message.includes("Cipher job failed")||e.message.includes("OperationError"))return{id:t,_decryptionFailed:!0,_error:e.message,..."partition"===r&&{_partition:r}};throw e}handleListError(e,{partition:t,partitionValues:r}){return e.message.includes("Partition '")&&e.message.includes("' not found"),this.emit("list",{partition:t,partitionValues:r,count:0,errors:1}),[]}async getMany(e){const{results:t,errors:r}=await i.for(e).withConcurrency(this.client.parallelism).handleError(async(e,t)=>(this.emit("error",e,content),this.observers.map(t=>t.emit("error",this.name,e,content)),{id:t,_error:e.message,_decryptionFailed:e.message.includes("Cipher job failed")||e.message.includes("OperationError")})).process(async e=>{const[t,r,i]=await ve(()=>this.get(e));if(t)return i;if(r.message.includes("Cipher job failed")||r.message.includes("OperationError"))return{id:e,_decryptionFailed:!0,_error:r.message};throw r});return this.emit("getMany",e.length),t}async getAll(){const[e,t,r]=await ve(()=>this.listIds());if(!e)throw t;const i=[];for(const e of r){const[t,r,s]=await ve(()=>this.get(e));t&&i.push(s)}return i}async page({offset:e=0,size:t=100,partition:r=null,partitionValues:i={},skipCount:s=!1}={}){const[n,o,a]=await ve(async()=>{let n=null,o=null;if(!s){const[e,s,a]=await ve(()=>this.count({partition:r,partitionValues:i}));e?(n=a,o=Math.ceil(n/t)):(n=null,o=null)}const a=Math.floor(e/t);let c=[];if(t<=0)c=[];else{const[s,n,o]=await ve(()=>this.list({partition:r,partitionValues:i,limit:t,offset:e}));c=s?o:[]}const u={items:c,totalItems:n,page:a,pageSize:t,totalPages:o,hasMore:c.length===t&&e+t<(n||1/0),_debug:{requestedSize:t,requestedOffset:e,actualItemsReturned:c.length,skipCount:s,hasTotalItems:null!==n}};return this.emit("page",u),u});return n?a:{items:[],totalItems:null,page:Math.floor(e/t),pageSize:t,totalPages:null,_debug:{requestedSize:t,requestedOffset:e,actualItemsReturned:0,skipCount:s,hasTotalItems:!1,error:o.message}}}readable(){return new ji({resource:this}).build()}writable(){return new xi({resource:this}).build()}async setContent({id:e,buffer:t,contentType:r="application/octet-stream"}){const[i,s,n]=await ve(()=>this.get(e));if(!i||!n)throw new ge(`Resource with id '${e}' not found`,{resourceName:this.name,id:e,operation:"setContent"});const o={...n,_hasContent:!0,_contentLength:t.length,_mimeType:r},a=await this.schema.mapper(o),[c,u]=await ve(()=>this.client.putObject({key:this.getResourceKey(e),metadata:a,body:t,contentType:r}));if(!c)throw u;return this.emit("setContent",{id:e,contentType:r,contentLength:t.length}),o}async content(e){const t=this.getResourceKey(e),[r,i,s]=await ve(()=>this.client.getObject(t));if(!r){if("NoSuchKey"===i.name)return{buffer:null,contentType:null};throw i}const n=Buffer.from(await s.Body.transformToByteArray()),o=s.ContentType||null;return this.emit("content",e,n.length,o),{buffer:n,contentType:o}}async hasContent(e){const t=this.getResourceKey(e),[r,i,s]=await ve(()=>this.client.headObject(t));return!!r&&s.ContentLength>0}async deleteContent(e){const t=this.getResourceKey(e),[r,i,s]=await ve(()=>this.client.headObject(t));if(!r)throw i;const n=s.Metadata||{},[o,a,c]=await ve(()=>this.client.putObject({key:t,body:"",metadata:n}));if(!o)throw a;return this.emit("deleteContent",e),c}getDefinitionHash(){const e={attributes:this.attributes,behavior:this.behavior},t=O(e);return`sha256:${f("sha256").update(t).digest("hex")}`}extractVersionFromKey(e){const t=e.split("/").find(e=>e.startsWith("v="));return t?t.replace("v=",""):null}async getSchemaForVersion(e){if(e===this.version)return this.schema;const[t,r,i]=await ve(()=>Promise.resolve(new Zi({name:this.name,attributes:this.attributes,passphrase:this.passphrase,version:e,options:{...this.config,autoDecrypt:!0,autoEncrypt:!0}})));return t?i:this.schema}async createPartitionReferences(e){const t=this.config.partitions;if(t&&0!==Object.keys(t).length)for(const[r,i]of Object.entries(t)){const t=this.getPartitionKey({partitionName:r,id:e.id,data:e});if(t){const e={_v:String(this.version)};await this.client.putObject({key:t,metadata:e,body:"",contentType:void 0})}}}async deletePartitionReferences(e){const t=this.config.partitions;if(!t||0===Object.keys(t).length)return;const r=[];for(const[i,s]of Object.entries(t)){const t=this.getPartitionKey({partitionName:i,id:e.id,data:e});t&&r.push(t)}if(r.length>0){const[e,t]=await ve(()=>this.client.deleteObjects(r))}}async query(e={},{limit:t=100,offset:r=0,partition:i=null,partitionValues:s={}}={}){if(0===Object.keys(e).length)return await this.list({partition:i,partitionValues:s,limit:t,offset:r});const n=[];let o=r;const a=Math.min(t,50);for(;n.length<t;){const t=await this.list({partition:i,partitionValues:s,limit:a,offset:o});if(0===t.length)break;const r=t.filter(t=>Object.entries(e).every(([e,r])=>t[e]===r));if(n.push(...r),o+=a,t.length<a)break}return n.slice(0,t)}async handlePartitionReferenceUpdates(e,t){const r=this.config.partitions;if(!r||0===Object.keys(r).length)return;for(const[i,s]of Object.entries(r)){const[r,n]=await ve(()=>this.handlePartitionReferenceUpdate(i,s,e,t))}const i=t.id||e.id;for(const[e,s]of Object.entries(r)){const r=`resource=${this.name}/partition=${e}`;let s=[];const[n,o,a]=await ve(()=>this.client.getAllKeys({prefix:r}));if(!n)continue;s=a;const c=this.getPartitionKey({partitionName:e,id:i,data:t});for(const e of s)if(e.endsWith(`/id=${i}`)&&e!==c){const[t,r]=await ve(()=>this.client.deleteObject(e))}}}async handlePartitionReferenceUpdate(e,t,r,i){const s=i.id||r.id,n=this.getPartitionKey({partitionName:e,id:s,data:r}),o=this.getPartitionKey({partitionName:e,id:s,data:i});if(n!==o){if(n){const[e,t]=await ve(async()=>{await this.client.deleteObject(n)})}if(o){const[e,t]=await ve(async()=>{const e={_v:String(this.version)};await this.client.putObject({key:o,metadata:e,body:"",contentType:void 0})})}}else if(o){const[e,t]=await ve(async()=>{const e={_v:String(this.version)};await this.client.putObject({key:o,metadata:e,body:"",contentType:void 0})})}}async updatePartitionReferences(e){const t=this.config.partitions;if(t&&0!==Object.keys(t).length)for(const[r,i]of Object.entries(t)){if(!i||!i.fields||"object"!=typeof i.fields)continue;const t=this.getPartitionKey({partitionName:r,id:e.id,data:e});if(t){const e={_v:String(this.version)},[r,i]=await ve(async()=>{await this.client.putObject({key:t,metadata:e,body:"",contentType:void 0})})}}}async getFromPartition({id:e,partitionName:t,partitionValues:r={}}){if(!this.config.partitions||!this.config.partitions[t])throw new ye(`Partition '${t}' not found`,{resourceName:this.name,partitionName:t,operation:"getFromPartition"});const i=this.config.partitions[t],s=[],n=Object.entries(i.fields).sort(([e],[t])=>e.localeCompare(t));for(const[e,t]of n){const i=r[e];if(null!=i){const r=this.applyPartitionRule(i,t);s.push(`${e}=${r}`)}}if(0===s.length)throw new ye(`No partition values provided for partition '${t}'`,{resourceName:this.name,partitionName:t,operation:"getFromPartition"});const o=We(`resource=${this.name}`,`partition=${t}`,...s,`id=${e}`),[a,c]=await ve(async()=>{await this.client.headObject(o)});if(!a)throw new ge(`Resource with id '${e}' not found in partition '${t}'`,{resourceName:this.name,id:e,partitionName:t,operation:"getFromPartition"});const u=await this.get(e);return u._partition=t,u._partitionValues=r,this.emit("getFromPartition",u),u}async createHistoricalVersion(e,t){const r=We(`resource=${this.name}`,"historical",`id=${e}`),i={...t,_v:t._v||this.version,_historicalTimestamp:(new Date).toISOString()},s=await this.schema.mapper(i),n=ms(this.behavior),{mappedData:o,body:a}=await n.handleInsert({resource:this,data:i,mappedData:s}),c={...o,_v:t._v||this.version,_historicalTimestamp:i._historicalTimestamp};let u;if(a&&""!==a){const[e,t]=await ve(()=>Promise.resolve(JSON.parse(a)));e&&(u="application/json")}await this.client.putObject({key:r,metadata:c,body:a,contentType:u})}async applyVersionMapping(e,t,r){if(t===r)return e;return{...e,_v:r,_originalVersion:t,_versionMapped:!0}}async composeFullObjectFromWrite({id:e,metadata:t,body:r,behavior:i}){const s={};t&&"true"===t.$truncated&&(s.$truncated="true"),t&&"true"===t.$overflow&&(s.$overflow="true");let n={};const[o,a,c]=await ve(()=>this.schema.unmapper(t));n=o?c:t;const u=e=>{if(!e||"object"!=typeof e)return e;const t={};for(const[r,i]of Object.entries(e))r.startsWith("_")||(t[r]=i);return t},l=e=>{if("object"==typeof e&&null!==e)return e;if("string"==typeof e){if("[object Object]"===e)return{};if(e.startsWith("{")||e.startsWith("[")){const[t,r,i]=we(()=>JSON.parse(e));return t?i:e}return e}return e};if("body-overflow"===i){const i=t&&"true"===t.$overflow;let s={};if(i&&r){const[e,t,i]=await ve(()=>Promise.resolve(JSON.parse(r)));if(e){const[e,t,r]=await ve(()=>this.schema.unmapper(i));s=e?r:{}}}const o={...n,...s,id:e};Object.keys(o).forEach(e=>{o[e]=l(o[e])});const a=u(o);return i&&(a.$overflow="true"),a}if("body-only"===i){const[i,s,n]=await ve(()=>Promise.resolve(r?JSON.parse(r):{}));let o=this.schema.map;if(t&&t._map){const[e,r,i]=await ve(()=>Promise.resolve("string"==typeof t._map?JSON.parse(t._map):t._map));o=e?i:this.schema.map}const[a,c,u]=await ve(()=>this.schema.unmapper(n,o)),h=a?{...u,id:e}:{id:e};return Object.keys(h).forEach(e=>{h[e]=l(h[e])}),h}if("user-managed"===i&&r&&""!==r.trim()){const[t,i,s]=await ve(()=>Promise.resolve(JSON.parse(r)));if(t){const[t,r,i]=await ve(()=>this.schema.unmapper(s)),o={...t?i:{},...n,id:e};return Object.keys(o).forEach(e=>{o[e]=l(o[e])}),u(o)}}const h={...n,id:e};Object.keys(h).forEach(e=>{h[e]=l(h[e])});const f=u(h);return s.$truncated&&(f.$truncated=s.$truncated),s.$overflow&&(f.$overflow=s.$overflow),f}emit(e,...t){return super.emit(e,...t)}async replace(e,t){await this.delete(e),await new Promise(e=>setTimeout(e,100));const r=Date.now();for(;Date.now()-r<5e3;){if(!await this.exists(e))break;await new Promise(e=>setTimeout(e,50))}try{return await this.insert({...t,id:e})}catch(r){if(r&&r.message&&r.message.includes("already exists")){return await this.update(e,t)}throw r}}_initMiddleware(){this._middlewares=new Map,this._middlewareMethods=["get","list","listIds","getAll","count","page","insert","update","delete","deleteMany","exists","getMany","content","hasContent","query","getFromPartition","setContent","deleteContent","replace"];for(const e of this._middlewareMethods)this._middlewares.set(e,[]),this[`_original_${e}`]||(this[`_original_${e}`]=this[e].bind(this),this[e]=async(...t)=>{const r={resource:this,args:t,method:e};let i=-1;const s=this._middlewares.get(e),n=async t=>{if(t<=i)throw new Error("next() called multiple times");return i=t,t<s.length?await s[t](r,()=>n(t+1)):await this[`_original_${e}`](...r.args)};return await n(0)})}useMiddleware(e,t){if(this._middlewares||this._initMiddleware(),!this._middlewares.has(e))throw new ge(`No such method for middleware: ${e}`,{operation:"useMiddleware",method:e});this._middlewares.get(e).push(t)}applyDefaults(e){const t={...e};for(const[e,r]of Object.entries(this.attributes))if(void 0===t[e]&&"string"==typeof r&&r.includes("default:")){const i=r.match(/default:([^|]+)/);if(i){let s=i[1];r.includes("boolean")?s="true"===s:r.includes("number")&&(s=Number(s)),t[e]=s}}return t}}var ws=bs;class vs extends $e{constructor(e){super(),this.id=xe(7),this.version="1",this.s3dbVersion=(()=>{const[e,t,r]=ve(()=>"8.1.1");return e?r:"latest"})(),this.resources={},this.savedMetadata=null,this.options=e,this.verbose=e.verbose||!1,this.parallelism=parseInt(e.parallelism+"")||10,this.plugins=e.plugins||[],this.pluginList=e.plugins||[],this.cache=e.cache,this.passphrase=e.passphrase||"secret",this.versioningEnabled=e.versioningEnabled||!1,this.persistHooks=e.persistHooks||!1,this._initHooks();let t=e.connectionString;if(!t&&(e.bucket||e.accessKeyId||e.secretAccessKey)){const{bucket:r,region:i,accessKeyId:s,secretAccessKey:n,endpoint:o,forcePathStyle:a}=e;if(o){const e=new URL(o);s&&(e.username=encodeURIComponent(s)),n&&(e.password=encodeURIComponent(n)),e.pathname=`/${r||"s3db"}`,a&&e.searchParams.set("forcePathStyle","true"),t=e.toString()}else if(s&&n){const e=new URLSearchParams;e.set("region",i||"us-east-1"),a&&e.set("forcePathStyle","true"),t=`s3://${encodeURIComponent(s)}:${encodeURIComponent(n)}@${r||"s3db"}?${e.toString()}`}}this.client=e.client||new Vi({verbose:this.verbose,parallelism:this.parallelism,connectionString:t}),this.bucket=this.client.bucket,this.keyPrefix=this.client.keyPrefix,this._exitListenerRegistered||(this._exitListenerRegistered=!0,"undefined"!=typeof process&&process.on("exit",async()=>{if(this.isConnected())try{await this.disconnect()}catch(e){}}))}async connect(){await this.startPlugins();let e=null,t=!1,r=[];if(await this.client.exists("s3db.json"))try{const i=await this.client.getObject("s3db.json"),s=await Ai(i?.Body);try{e=JSON.parse(s)}catch(i){r.push("JSON parsing failed - attempting recovery"),t=!0,e=await this._attemptJsonRecovery(s,r),e||(await this._createCorruptedBackup(s),r.push("Created backup of corrupted file - starting with blank metadata"),e=this.blankMetadataStructure())}const n=await this._validateAndHealMetadata(e,r);n!==e&&(e=n,t=!0)}catch(i){r.push(`Critical error reading s3db.json: ${i.message}`),await this._createCorruptedBackup(),e=this.blankMetadataStructure(),t=!0}else e=this.blankMetadataStructure(),await this.uploadMetadataFile();t&&await this._uploadHealedMetadata(e,r),this.savedMetadata=e;const i=this.detectDefinitionChanges(e);for(const[t,r]of Object.entries(e.resources||{})){const e=r.currentVersion||"v0",i=r.versions?.[e];if(i){let s,n;void 0!==i.idGenerator?"custom_function"===i.idGenerator?(s=void 0,n=i.idSize||22):"number"==typeof i.idGenerator&&(s=i.idGenerator,n=i.idSize||i.idGenerator):n=i.idSize||22,this.resources[t]=new ws({name:t,client:this.client,database:this,version:e,attributes:i.attributes,behavior:i.behavior||"user-managed",parallelism:this.parallelism,passphrase:this.passphrase,observers:[this],cache:this.cache,timestamps:void 0!==i.timestamps&&i.timestamps,partitions:r.partitions||i.partitions||{},paranoid:void 0===i.paranoid||i.paranoid,allNestedObjectsOptional:void 0===i.allNestedObjectsOptional||i.allNestedObjectsOptional,autoDecrypt:void 0===i.autoDecrypt||i.autoDecrypt,hooks:this.persistHooks?this._deserializeHooks(i.hooks||{}):i.hooks||{},versioningEnabled:this.versioningEnabled,map:i.map,idGenerator:s,idSize:n})}}i.length>0&&this.emit("resourceDefinitionsChanged",{changes:i,metadata:this.savedMetadata}),this.emit("connected",new Date)}detectDefinitionChanges(e){const t=[];for(const[r,i]of Object.entries(this.resources)){const s=this.generateDefinitionHash(i.export()),n=e.resources?.[r];if(n){const e=n.currentVersion||"v0",i=n.versions?.[e],o=i?.hash;o!==s&&t.push({type:"changed",resourceName:r,currentHash:s,savedHash:o,fromVersion:e,toVersion:this.getNextVersion(n.versions)})}else t.push({type:"new",resourceName:r,currentHash:s,savedHash:null})}for(const[r,i]of Object.entries(e.resources||{}))if(!this.resources[r]){const e=i.currentVersion||"v0",s=i.versions?.[e];t.push({type:"deleted",resourceName:r,currentHash:null,savedHash:s?.hash,deletedVersion:e})}return t}generateDefinitionHash(e,t=void 0){const r={...e.attributes};e.timestamps&&(delete r.createdAt,delete r.updatedAt);const i={attributes:r,behavior:t||e.behavior||"user-managed",partitions:e.partitions||{}},s=O(i);return`sha256:${f("sha256").update(s).digest("hex")}`}getNextVersion(e={}){const t=Object.keys(e).filter(e=>e.startsWith("v")).map(e=>parseInt(e.substring(1))).filter(e=>!isNaN(e));return`v${(t.length>0?Math.max(...t):-1)+1}`}_serializeHooks(e){if(!e||"object"!=typeof e)return e;const t={};for(const[r,i]of Object.entries(e))Array.isArray(i)?t[r]=i.map(e=>{if("function"==typeof e)try{return{__s3db_serialized_function:!0,code:e.toString(),name:e.name||"anonymous"}}catch(e){return this.verbose&&console.warn(`Failed to serialize hook for event '${r}':`,e.message),null}return e}):t[r]=i;return t}_deserializeHooks(e){if(!e||"object"!=typeof e)return e;const t={};for(const[r,i]of Object.entries(e))Array.isArray(i)?t[r]=i.map(e=>{if(e&&"object"==typeof e&&e.__s3db_serialized_function){try{const t=new Function("return "+e.code)();if("function"==typeof t)return t}catch(t){this.verbose&&console.warn(`Failed to deserialize hook '${e.name}' for event '${r}':`,t.message)}return null}return e}).filter(e=>null!==e):t[r]=i;return t}async startPlugins(){const e=this;if(!g(this.pluginList)){const t=this.pluginList.map(e=>S(e)?new e(this):e),r=t.map(async t=>{t.beforeSetup&&await t.beforeSetup(),await t.setup(e),t.afterSetup&&await t.afterSetup()});await Promise.all(r);const i=t.map(async e=>{e.beforeStart&&await e.beforeStart(),await e.start(),e.afterStart&&await e.afterStart()});await Promise.all(i)}}async usePlugin(e,t=null){const r=t||e.constructor.name.replace("Plugin","").toLowerCase();return this.plugins[r]=e,this.isConnected()&&(await e.setup(this),await e.start()),e}async uploadMetadataFile(){const e={version:this.version,s3dbVersion:this.s3dbVersion,lastUpdated:(new Date).toISOString(),resources:{}};Object.entries(this.resources).forEach(([t,r])=>{const i=r.export(),s=this.generateDefinitionHash(i),n=this.savedMetadata?.resources?.[t],o=n?.currentVersion||"v0",a=n?.versions?.[o];let c,u;a&&a.hash===s?(c=o,u=!1):(c=this.getNextVersion(n?.versions),u=!0),e.resources[t]={currentVersion:c,partitions:r.config.partitions||{},versions:{...n?.versions,[c]:{hash:s,attributes:i.attributes,behavior:i.behavior||"user-managed",timestamps:r.config.timestamps,partitions:r.config.partitions,paranoid:r.config.paranoid,allNestedObjectsOptional:r.config.allNestedObjectsOptional,autoDecrypt:r.config.autoDecrypt,cache:r.config.cache,hooks:this.persistHooks?this._serializeHooks(r.config.hooks):r.config.hooks,idSize:r.idSize,idGenerator:r.idGeneratorType,createdAt:u?(new Date).toISOString():a?.createdAt}}},r.version!==c&&(r.version=c,r.emit("versionUpdated",{oldVersion:o,newVersion:c}))}),await this.client.putObject({key:"s3db.json",body:JSON.stringify(e,null,2),contentType:"application/json"}),this.savedMetadata=e,this.emit("metadataUploaded",e)}blankMetadataStructure(){return{version:"1",s3dbVersion:this.s3dbVersion,lastUpdated:(new Date).toISOString(),resources:{}}}async _attemptJsonRecovery(e,t){if(!e||"string"!=typeof e)return t.push("Content is empty or not a string"),null;const r=[()=>e.replace(/,(\s*[}\]])/g,"$1"),()=>e.replace(/([{,]\s*)([a-zA-Z_$][a-zA-Z0-9_$]*)\s*:/g,'$1"$2":'),()=>{let t=0,r=0,i=!1,s=!1;for(let n=0;n<e.length;n++){const o=e[n];s?s=!1:"\\"!==o?'"'!==o?i||("{"===o?t++:"}"===o?t--:"["===o?r++:"]"===o&&r--):i=!i:s=!0}let n=e;for(;r>0;)n+="]",r--;for(;t>0;)n+="}",t--;return n}];for(const[e,i]of r.entries())try{const r=i(),s=JSON.parse(r);return t.push(`JSON recovery successful using fix #${e+1}`),s}catch(e){}return t.push("All JSON recovery attempts failed"),null}async _validateAndHealMetadata(e,t){if(!e||"object"!=typeof e)return t.push("Metadata is not an object - using blank structure"),this.blankMetadataStructure();let r={...e},i=!1;r.version&&"string"==typeof r.version||(r.version&&"number"==typeof r.version?(r.version=String(r.version),t.push("Converted version from number to string"),i=!0):(r.version="1",t.push("Added missing or invalid version field"),i=!0)),r.s3dbVersion&&"string"==typeof r.s3dbVersion||(r.s3dbVersion&&"string"!=typeof r.s3dbVersion?(r.s3dbVersion=String(r.s3dbVersion),t.push("Converted s3dbVersion to string"),i=!0):(r.s3dbVersion=this.s3dbVersion,t.push("Added missing s3dbVersion field"),i=!0)),r.resources&&"object"==typeof r.resources&&!Array.isArray(r.resources)||(r.resources={},t.push("Fixed invalid resources field"),i=!0),r.lastUpdated||(r.lastUpdated=(new Date).toISOString(),t.push("Added missing lastUpdated field"),i=!0);const s={};for(const[e,n]of Object.entries(r.resources)){const r=this._healResourceStructure(e,n,t);r?(s[e]=r,r!==n&&(i=!0)):(t.push(`Removed invalid resource: ${e}`),i=!0)}return r.resources=s,i?r:e}_healResourceStructure(e,t,r){if(!t||"object"!=typeof t)return r.push(`Resource ${e}: invalid structure`),null;let i={...t},s=!1;i.currentVersion||(i.currentVersion="v0",r.push(`Resource ${e}: added missing currentVersion`),s=!0),i.versions&&"object"==typeof i.versions&&!Array.isArray(i.versions)||(i.versions={},r.push(`Resource ${e}: fixed invalid versions object`),s=!0),i.partitions&&"object"==typeof i.partitions&&!Array.isArray(i.partitions)||(i.partitions={},r.push(`Resource ${e}: fixed invalid partitions object`),s=!0);const n=i.currentVersion;if(!i.versions[n]){const t=Object.keys(i.versions);if(!(t.length>0))return r.push(`Resource ${e}: no valid versions found - removing resource`),null;i.currentVersion=t[0],r.push(`Resource ${e}: changed currentVersion from ${n} to ${i.currentVersion}`),s=!0}const o=i.versions[i.currentVersion];if(!o||"object"!=typeof o)return r.push(`Resource ${e}: invalid version data - removing resource`),null;if(!o.attributes||"object"!=typeof o.attributes)return r.push(`Resource ${e}: missing or invalid attributes - removing resource`),null;if(o.hooks){const t=this._healHooksStructure(o.hooks,e,r);t!==o.hooks&&(i.versions[i.currentVersion].hooks=t,s=!0)}return s?i:t}_healHooksStructure(e,t,r){if(!e||"object"!=typeof e)return r.push(`Resource ${t}: invalid hooks structure - using empty hooks`),{};const i={};let s=!1;for(const[n,o]of Object.entries(e))if(Array.isArray(o)){const e=o.filter(e=>null!=e&&""!==e);i[n]=e,e.length!==o.length&&(r.push(`Resource ${t}: cleaned invalid hooks for event ${n}`),s=!0)}else r.push(`Resource ${t}: hooks for event ${n} is not an array - removing`),s=!0;return s?i:e}async _createCorruptedBackup(e=null){try{const t=`s3db.json.corrupted.${(new Date).toISOString().replace(/[:.]/g,"-")}.backup`;if(!e)try{const t=await this.client.getObject("s3db.json");e=await Ai(t?.Body)}catch(t){e="Unable to read corrupted file content"}await this.client.putObject({key:t,body:e,contentType:"application/json"}),this.verbose&&console.warn(`S3DB: Created backup of corrupted s3db.json as ${t}`)}catch(e){this.verbose&&console.warn(`S3DB: Failed to create backup: ${e.message}`)}}async _uploadHealedMetadata(e,t){try{this.verbose&&t.length>0&&(console.warn("S3DB Self-Healing Operations:"),t.forEach(e=>console.warn(` - ${e}`))),e.lastUpdated=(new Date).toISOString(),await this.client.putObject({key:"s3db.json",body:JSON.stringify(e,null,2),contentType:"application/json"}),this.emit("metadataHealed",{healingLog:t,metadata:e}),this.verbose&&console.warn("S3DB: Successfully uploaded healed metadata")}catch(e){throw this.verbose&&console.error(`S3DB: Failed to upload healed metadata: ${e.message}`),e}}resourceExists(e){return!!this.resources[e]}resourceExistsWithSameHash({name:e,attributes:t,behavior:r="user-managed",partitions:i={},options:s={}}){if(!this.resources[e])return{exists:!1,sameHash:!1,hash:null};const n=this.resources[e],o=this.generateDefinitionHash(n.export()),a=new ws({name:e,attributes:t,behavior:r,partitions:i,client:this.client,version:n.version,passphrase:this.passphrase,versioningEnabled:this.versioningEnabled,...s}),c=this.generateDefinitionHash(a.export());return{exists:!0,sameHash:o===c,hash:c,existingHash:o}}async createResource({name:e,attributes:t,behavior:r="user-managed",hooks:i,...s}){if(this.resources[e]){const n=this.resources[e];if(Object.assign(n.config,{cache:this.cache,...s}),r&&(n.behavior=r),n.versioningEnabled=this.versioningEnabled,n.updateAttributes(t),i)for(const[e,t]of Object.entries(i))if(Array.isArray(t)&&n.hooks[e])for(const r of t)"function"==typeof r&&n.hooks[e].push(r.bind(n));const o=this.generateDefinitionHash(n.export(),n.behavior),a=this.savedMetadata?.resources?.[e],c=a?.currentVersion||"v0",u=a?.versions?.[c];return u&&u.hash===o||await this.uploadMetadataFile(),this.emit("s3db.resourceUpdated",e),n}const n=this.savedMetadata?.resources?.[e],o=n?.currentVersion||"v0",a=new ws({name:e,client:this.client,version:void 0!==s.version?s.version:o,attributes:t,behavior:r,parallelism:this.parallelism,passphrase:void 0!==s.passphrase?s.passphrase:this.passphrase,observers:[this],cache:void 0!==s.cache?s.cache:this.cache,timestamps:void 0!==s.timestamps&&s.timestamps,partitions:s.partitions||{},paranoid:void 0===s.paranoid||s.paranoid,allNestedObjectsOptional:void 0===s.allNestedObjectsOptional||s.allNestedObjectsOptional,autoDecrypt:void 0===s.autoDecrypt||s.autoDecrypt,hooks:i||{},versioningEnabled:this.versioningEnabled,map:s.map,idGenerator:s.idGenerator,idSize:s.idSize,events:s.events||{}});return a.database=this,this.resources[e]=a,await this.uploadMetadataFile(),this.emit("s3db.resourceCreated",e),a}resource(e){return this.resources[e]?this.resources[e]:Promise.reject(`resource ${e} does not exist`)}async listResources(){return Object.keys(this.resources).map(e=>({name:e}))}async getResource(e){if(!this.resources[e])throw new se({bucket:this.client.config.bucket,resourceName:e,id:e});return this.resources[e]}get config(){return{version:this.version,s3dbVersion:this.s3dbVersion,bucket:this.bucket,keyPrefix:this.keyPrefix,parallelism:this.parallelism,verbose:this.verbose}}isConnected(){return!!this.savedMetadata}async disconnect(){try{if(this.pluginList&&this.pluginList.length>0){for(const e of this.pluginList)e&&"function"==typeof e.removeAllListeners&&e.removeAllListeners();const e=this.pluginList.map(async e=>{try{e&&"function"==typeof e.stop&&await e.stop()}catch(e){}});await Promise.all(e)}if(this.resources&&Object.keys(this.resources).length>0){for(const[e,t]of Object.entries(this.resources))try{t&&"function"==typeof t.removeAllListeners&&t.removeAllListeners(),t._pluginWrappers&&t._pluginWrappers.clear(),t._pluginMiddlewares&&(t._pluginMiddlewares={}),t.observers&&Array.isArray(t.observers)&&(t.observers=[])}catch(e){}Object.keys(this.resources).forEach(e=>delete this.resources[e])}this.client&&"function"==typeof this.client.removeAllListeners&&this.client.removeAllListeners(),this.removeAllListeners(),this.savedMetadata=null,this.plugins={},this.pluginList=[],this.emit("disconnected",new Date)}catch(e){}}_initHooks(){this._hooks=new Map,this._hookEvents=["beforeConnect","afterConnect","beforeCreateResource","afterCreateResource","beforeUploadMetadata","afterUploadMetadata","beforeDisconnect","afterDisconnect","resourceCreated","resourceUpdated"];for(const e of this._hookEvents)this._hooks.set(e,[]);this._wrapHookableMethods()}_wrapHookableMethods(){this._hooksInstalled||(this._originalConnect=this.connect.bind(this),this._originalCreateResource=this.createResource.bind(this),this._originalUploadMetadataFile=this.uploadMetadataFile.bind(this),this._originalDisconnect=this.disconnect.bind(this),this.connect=async(...e)=>{await this._executeHooks("beforeConnect",{args:e});const t=await this._originalConnect(...e);return await this._executeHooks("afterConnect",{result:t,args:e}),t},this.createResource=async e=>{await this._executeHooks("beforeCreateResource",{config:e});const t=await this._originalCreateResource(e);return await this._executeHooks("afterCreateResource",{resource:t,config:e}),t},this.uploadMetadataFile=async(...e)=>{await this._executeHooks("beforeUploadMetadata",{args:e});const t=await this._originalUploadMetadataFile(...e);return await this._executeHooks("afterUploadMetadata",{result:t,args:e}),t},this.disconnect=async(...e)=>{await this._executeHooks("beforeDisconnect",{args:e});const t=await this._originalDisconnect(...e);return await this._executeHooks("afterDisconnect",{result:t,args:e}),t},this._hooksInstalled=!0)}addHook(e,t){if(this._hooks||this._initHooks(),!this._hooks.has(e))throw new Error(`Unknown hook event: ${e}. Available events: ${this._hookEvents.join(", ")}`);if("function"!=typeof t)throw new Error("Hook function must be a function");this._hooks.get(e).push(t)}async _executeHooks(e,t={}){if(!this._hooks||!this._hooks.has(e))return;const r=this._hooks.get(e);for(const i of r)try{await i({database:this,...t})}catch(r){this.emit("hookError",{event:e,error:r,context:t})}}removeHook(e,t){if(!this._hooks||!this._hooks.has(e))return;const r=this._hooks.get(e),i=r.indexOf(t);i>-1&&r.splice(i,1)}getHooks(e){return this._hooks&&this._hooks.has(e)?[...this._hooks.get(e)]:[]}clearHooks(e){this._hooks&&this._hooks.has(e)&&(this._hooks.get(e).length=0)}}class ks extends vs{}function _s(e){return"string"==typeof e?e.trim().toLowerCase():e}var Ss=class extends Li{constructor(e={},t=[],r=null){super(e),this.instanceId=Math.random().toString(36).slice(2,10),this.client=r,this.connectionString=e.connectionString;let i=t;if(t)if(Array.isArray(t)){i={};for(const e of t)"string"==typeof e&&(i[_s(e)]=e)}else"string"==typeof t&&(i[_s(t)]=t);else i={};this.resourcesMap=this._normalizeResources(i)}_normalizeResources(e){if(!e)return{};if(Array.isArray(e)){const t={};for(const r of e)"string"==typeof r?t[_s(r)]=r:"object"==typeof r&&r.resource&&(t[_s(r.resource)]=r);return t}if("object"==typeof e){const t={};for(const[r,i]of Object.entries(e)){const e=_s(r);"string"==typeof i?t[e]=i:Array.isArray(i)?t[e]=i.map(e=>("string"==typeof e||"object"==typeof e&&e.resource,e)):("function"==typeof i||"object"==typeof i&&i.resource)&&(t[e]=i)}return t}return"function"==typeof e?e:{}}validateConfig(){const e=[];return this.client||this.connectionString||e.push("You must provide a client or a connectionString"),(!this.resourcesMap||"object"==typeof this.resourcesMap&&0===Object.keys(this.resourcesMap).length)&&e.push("You must provide a resources map or array"),{isValid:0===e.length,errors:e}}async initialize(e){await super.initialize(e);const[t,r]=await ve(async()=>{if(this.client)this.targetDatabase=this.client;else{if(!this.connectionString)throw new Error("S3dbReplicator: No client or connectionString provided");{const e={connectionString:this.connectionString,region:this.region,keyPrefix:this.keyPrefix,verbose:this.config.verbose||!1};this.targetDatabase=new ks(e),await this.targetDatabase.connect()}}this.emit("connected",{replicator:this.name,target:this.connectionString||"client-provided"})});if(!t)throw this.config.verbose&&console.warn(`[S3dbReplicator] Initialization failed: ${r.message}`),r}async replicate(e,t,r,i,s){let n,o,a,c;"object"==typeof e&&e.resource?(n=e.resource,o=e.operation,a=e.data,c=e.id):(n=e,o=t,a=r,c=i);const u=_s(n),l=this.resourcesMap[u];if(!l)throw new Error(`[S3dbReplicator] Resource not configured: ${n}`);if(Array.isArray(l)){const e=[];for(const t of l){const[r,i,s]=await ve(async()=>await this._replicateToSingleDestination(t,u,o,a,c));if(!r)throw this.config&&this.config.verbose&&console.warn(`[S3dbReplicator] Failed to replicate to destination ${JSON.stringify(t)}: ${i.message}`),i;e.push(s)}return e}{const[e,t,r]=await ve(async()=>await this._replicateToSingleDestination(l,u,o,a,c));if(!e)throw this.config&&this.config.verbose&&console.warn(`[S3dbReplicator] Failed to replicate to destination ${JSON.stringify(l)}: ${t.message}`),t;return r}}async _replicateToSingleDestination(e,t,r,i,s){let n;if(n="string"==typeof e?e:"object"==typeof e&&e.resource?e.resource:t,"object"==typeof e&&e.actions&&Array.isArray(e.actions)&&!e.actions.includes(r))return{skipped:!0,reason:"action_not_supported",action:r,destination:n};const o=this._getDestResourceObj(n);let a,c;if("object"==typeof e&&e.transform&&"function"==typeof e.transform?(a=e.transform(i),a&&i&&i.id&&!a.id&&(a.id=i.id)):"object"==typeof e&&e.transformer&&"function"==typeof e.transformer?(a=e.transformer(i),a&&i&&i.id&&!a.id&&(a.id=i.id)):a=i,!a&&i&&(a=i),"insert"===r)c=await o.insert(a);else if("update"===r)c=await o.update(s,a);else{if("delete"!==r)throw new Error(`Invalid operation: ${r}. Supported operations are: insert, update, delete`);c=await o.delete(s)}return c}_applyTransformer(e,t){let r=this._cleanInternalFields(t);const i=_s(e),s=this.resourcesMap[i];let n;if(!s)return r;if(Array.isArray(s)){for(const e of s){if("object"==typeof e&&e.transform&&"function"==typeof e.transform){n=e.transform(r);break}if("object"==typeof e&&e.transformer&&"function"==typeof e.transformer){n=e.transformer(r);break}}n||(n=r)}else"object"==typeof s?"function"==typeof s.transform?n=s.transform(r):"function"==typeof s.transformer&&(n=s.transformer(r)):n="function"==typeof s?s(r):r;return n&&r&&r.id&&!n.id&&(n.id=r.id),!n&&r&&(n=r),n}_cleanInternalFields(e){if(!e||"object"!=typeof e)return e;const t={...e};return Object.keys(t).forEach(e=>{(e.startsWith("$")||e.startsWith("_"))&&delete t[e]}),t}_resolveDestResource(e,t){const r=_s(e),i=this.resourcesMap[r];if(!i)return e;if(Array.isArray(i)){for(const e of i){if("string"==typeof e)return e;if("object"==typeof e&&e.resource)return e.resource}return e}return"string"==typeof i?i:"function"==typeof i?e:"object"==typeof i&&i.resource?i.resource:e}_getDestResourceObj(e){const t=Object.keys(this.client.resources||{}),r=_s(e),i=t.find(e=>_s(e)===r);if(!i)throw new Error(`[S3dbReplicator] Destination resource not found: ${e}. Available: ${t.join(", ")}`);return this.client.resources[i]}async replicateBatch(e,t){if(!this.enabled||!this.shouldReplicateResource(e))return{skipped:!0,reason:"resource_not_included"};const r=[],i=[];for(const s of t){const[t,n,o]=await ve(()=>this.replicate({resource:e,operation:s.operation,id:s.id,data:s.data,beforeData:s.beforeData}));t?r.push(o):(this.config.verbose&&console.warn(`[S3dbReplicator] Batch replication failed for record ${s.id}: ${n.message}`),i.push({id:s.id,error:n.message}))}return i.length>0&&console.warn(`[S3dbReplicator] Batch replication completed with ${i.length} error(s) for ${e}:`,i),this.emit("batch_replicated",{replicator:this.name,resourceName:e,total:t.length,successful:r.length,errors:i.length}),{success:0===i.length,results:r,errors:i,total:t.length}}async testConnection(){const[e,t]=await ve(async()=>{if(!this.targetDatabase)throw new Error("No target database configured");return"function"==typeof this.targetDatabase.connect&&await this.targetDatabase.connect(),!0});return!!e||(this.config.verbose&&console.warn(`[S3dbReplicator] Connection test failed: ${t.message}`),this.emit("connection_error",{replicator:this.name,error:t.message}),!1)}async getStatus(){return{...await super.getStatus(),connected:!!this.targetDatabase,targetDatabase:this.connectionString||"client-provided",resources:Object.keys(this.resourcesMap||{}),totalreplicators:this.listenerCount("replicated"),totalErrors:this.listenerCount("replicator_error")}}async cleanup(){this.targetDatabase&&this.targetDatabase.removeAllListeners(),await super.cleanup()}shouldReplicateResource(e,t){const r=_s(e),i=this.resourcesMap[r];if(!i)return!1;if(!t)return!0;if(Array.isArray(i)){for(const e of i)if("object"==typeof e&&e.resource){if(!e.actions||!Array.isArray(e.actions))return!0;if(e.actions.includes(t))return!0}else if("string"==typeof e)return!0;return!1}return"object"==typeof i&&i.resource?!i.actions||!Array.isArray(i.actions)||i.actions.includes(t):"string"==typeof i||"function"==typeof i}};var Os=class extends Li{constructor(e={},t=[],r=null){if(super(e),this.client=r,this.queueUrl=e.queueUrl,this.queues=e.queues||{},this.defaultQueue=e.defaultQueue||e.defaultQueueUrl||e.queueUrlDefault,this.region=e.region||"us-east-1",this.sqsClient=r||null,this.messageGroupId=e.messageGroupId,this.deduplicationId=e.deduplicationId,Array.isArray(t)){this.resources={};for(const e of t)"string"==typeof e?this.resources[e]=!0:"object"==typeof e&&e.name&&(this.resources[e.name]=e)}else if("object"==typeof t){this.resources=t;for(const[e,r]of Object.entries(t))r&&r.queueUrl&&(this.queues[e]=r.queueUrl)}else this.resources={}}validateConfig(){const e=[];return this.queueUrl||0!==Object.keys(this.queues).length||this.defaultQueue||this.resourceQueueMap||e.push("Either queueUrl, queues object, defaultQueue, or resourceQueueMap must be provided"),{isValid:0===e.length,errors:e}}getQueueUrlsForResource(e){if(this.resourceQueueMap&&this.resourceQueueMap[e])return this.resourceQueueMap[e];if(this.queues[e])return[this.queues[e]];if(this.queueUrl)return[this.queueUrl];if(this.defaultQueue)return[this.defaultQueue];throw new Error(`No queue URL found for resource '${e}'`)}_applyTransformer(e,t){let r=this._cleanInternalFields(t);const i=this.resources[e];let s=r;return i?("function"==typeof i.transform?s=i.transform(r):"function"==typeof i.transformer&&(s=i.transformer(r)),s||r):r}_cleanInternalFields(e){if(!e||"object"!=typeof e)return e;const t={...e};return Object.keys(t).forEach(e=>{(e.startsWith("$")||e.startsWith("_"))&&delete t[e]}),t}createMessage(e,t,r,i,s=null){const n={resource:e,action:t,timestamp:(new Date).toISOString(),source:"s3db-replicator"};switch(t){case"insert":case"delete":default:return{...n,data:r};case"update":return{...n,before:s,data:r}}}async initialize(e,t){if(await super.initialize(e),!this.sqsClient){const[e,r,i]=await ve(()=>import("@aws-sdk/client-sqs"));if(!e)throw this.config.verbose&&console.warn(`[SqsReplicator] Failed to import SQS SDK: ${r.message}`),this.emit("initialization_error",{replicator:this.name,error:r.message}),r;const{SQSClient:s}=i;this.sqsClient=t||new s({region:this.region,credentials:this.config.credentials}),this.emit("initialized",{replicator:this.name,queueUrl:this.queueUrl,queues:this.queues,defaultQueue:this.defaultQueue})}}async replicate(e,t,r,i,s=null){if(!this.enabled||!this.shouldReplicateResource(e))return{skipped:!0,reason:"resource_not_included"};const[n,o,a]=await ve(async()=>{const{SendMessageCommand:n}=await import("@aws-sdk/client-sqs"),o=this.getQueueUrlsForResource(e),a=this._applyTransformer(e,r),c=this.createMessage(e,t,a,i,s),u=[];for(const r of o){const s=new n({QueueUrl:r,MessageBody:JSON.stringify(c),MessageGroupId:this.messageGroupId,MessageDeduplicationId:this.deduplicationId?`${e}:${t}:${i}`:void 0}),o=await this.sqsClient.send(s);u.push({queueUrl:r,messageId:o.MessageId}),this.emit("replicated",{replicator:this.name,resource:e,operation:t,id:i,queueUrl:r,messageId:o.MessageId,success:!0})}return{success:!0,results:u}});return n?a:(this.config.verbose&&console.warn(`[SqsReplicator] Replication failed for ${e}: ${o.message}`),this.emit("replicator_error",{replicator:this.name,resource:e,operation:t,id:i,error:o.message}),{success:!1,error:o.message})}async replicateBatch(e,t){if(!this.enabled||!this.shouldReplicateResource(e))return{skipped:!0,reason:"resource_not_included"};const[r,i,s]=await ve(async()=>{const{SendMessageBatchCommand:r}=await import("@aws-sdk/client-sqs"),i=this.getQueueUrlsForResource(e),s=[];for(let e=0;e<t.length;e+=10)s.push(t.slice(e,e+10));const n=[],o=[];for(const t of s){const[s,a]=await ve(async()=>{const s=t.map((t,r)=>({Id:`${t.id}-${r}`,MessageBody:JSON.stringify(this.createMessage(e,t.operation,t.data,t.id,t.beforeData)),MessageGroupId:this.messageGroupId,MessageDeduplicationId:this.deduplicationId?`${e}:${t.operation}:${t.id}`:void 0})),o=new r({QueueUrl:i[0],Entries:s}),a=await this.sqsClient.send(o);n.push(a)});if(!s&&(o.push({batch:t.length,error:a.message}),a.message&&(a.message.includes("Batch error")||a.message.includes("Connection")||a.message.includes("Network"))))throw a}return o.length>0&&console.warn(`[SqsReplicator] Batch replication completed with ${o.length} error(s) for ${e}:`,o),this.emit("batch_replicated",{replicator:this.name,resource:e,queueUrl:i[0],total:t.length,successful:n.length,errors:o.length}),{success:0===o.length,results:n,errors:o,total:t.length,queueUrl:i[0]}});if(r)return s;const n=i?.message||i||"Unknown error";return this.config.verbose&&console.warn(`[SqsReplicator] Batch replication failed for ${e}: ${n}`),this.emit("batch_replicator_error",{replicator:this.name,resource:e,error:n}),{success:!1,error:n}}async testConnection(){const[e,t]=await ve(async()=>{this.sqsClient||await this.initialize(this.database);const{GetQueueAttributesCommand:e}=await import("@aws-sdk/client-sqs"),t=new e({QueueUrl:this.queueUrl,AttributeNames:["QueueArn"]});return await this.sqsClient.send(t),!0});return!!e||(this.config.verbose&&console.warn(`[SqsReplicator] Connection test failed: ${t.message}`),this.emit("connection_error",{replicator:this.name,error:t.message}),!1)}async getStatus(){return{...await super.getStatus(),connected:!!this.sqsClient,queueUrl:this.queueUrl,region:this.region,resources:Object.keys(this.resources||{}),totalreplicators:this.listenerCount("replicated"),totalErrors:this.listenerCount("replicator_error")}}async cleanup(){this.sqsClient&&this.sqsClient.destroy(),await super.cleanup()}shouldReplicateResource(e){return this.resourceQueueMap&&Object.keys(this.resourceQueueMap).includes(e)||this.queues&&Object.keys(this.queues).includes(e)||!(!this.defaultQueue&&!this.queueUrl)||this.resources&&Object.keys(this.resources).includes(e)||!1}};const Rs={s3db:Ss,sqs:Os,bigquery:Ui,postgres:Fi};function js(e){return"string"==typeof e?e.trim().toLowerCase():e}class xs extends Le{constructor(e={}){if(super(),!e.replicators||!Array.isArray(e.replicators))throw new Error("ReplicatorPlugin: replicators array is required");for(const t of e.replicators){if(!t.driver)throw new Error("ReplicatorPlugin: each replicator must have a driver");if(!t.resources||"object"!=typeof t.resources)throw new Error("ReplicatorPlugin: each replicator must have resources config");if(0===Object.keys(t.resources).length)throw new Error("ReplicatorPlugin: each replicator must have at least one resource configured")}this.config={replicators:e.replicators||[],logErrors:!1!==e.logErrors,replicatorLogResource:e.replicatorLogResource||"replicator_log",enabled:!1!==e.enabled,batchSize:e.batchSize||100,maxRetries:e.maxRetries||3,timeout:e.timeout||3e4,verbose:e.verbose||!1,...e},this.replicators=[],this.database=null,this.eventListenersInstalled=new Set}async decompressData(e){return e}filterInternalFields(e){if(!e||"object"!=typeof e)return e;const t={};for(const[r,i]of Object.entries(e))r.startsWith("_")||"$overflow"===r||"$before"===r||"$after"===r||(t[r]=i);return t}async getCompleteData(e,t){const[r,i,s]=await ve(()=>e.get(t.id));return r?s:t}installEventListeners(e,t,r){e&&!this.eventListenersInstalled.has(e.name)&&e.name!==this.config.replicatorLogResource&&(e.on("insert",async t=>{const[i,s]=await ve(async()=>{const i={...t,createdAt:(new Date).toISOString()};await r.processReplicatorEvent("insert",e.name,i.id,i)});i||(this.config.verbose&&console.warn(`[ReplicatorPlugin] Insert event failed for resource ${e.name}: ${s.message}`),this.emit("error",{operation:"insert",error:s.message,resource:e.name}))}),e.on("update",async(t,i)=>{const[s,n]=await ve(async()=>{const s=await r.getCompleteData(e,t),n={...s,updatedAt:(new Date).toISOString()};await r.processReplicatorEvent("update",e.name,s.id,n,i)});s||(this.config.verbose&&console.warn(`[ReplicatorPlugin] Update event failed for resource ${e.name}: ${n.message}`),this.emit("error",{operation:"update",error:n.message,resource:e.name}))}),e.on("delete",async t=>{const[i,s]=await ve(async()=>{await r.processReplicatorEvent("delete",e.name,t.id,t)});i||(this.config.verbose&&console.warn(`[ReplicatorPlugin] Delete event failed for resource ${e.name}: ${s.message}`),this.emit("error",{operation:"delete",error:s.message,resource:e.name}))}),this.eventListenersInstalled.add(e.name))}async setup(e){if(this.database=e,this.config.persistReplicatorLog){const[t,r,i]=await ve(()=>e.createResource({name:this.config.replicatorLogResource||"replicator_logs",attributes:{id:"string|required",resource:"string|required",action:"string|required",data:"json",timestamp:"number|required",createdAt:"string|required"},behavior:"truncate-data"}));this.replicatorLogResource=t?i:e.resources[this.config.replicatorLogResource||"replicator_logs"]}await this.initializeReplicators(e),this.installDatabaseHooks();for(const t of Object.values(e.resources))t.name!==(this.config.replicatorLogResource||"replicator_logs")&&this.installEventListeners(t,e,this)}async start(){}async stop(){for(const e of this.replicators||[])e&&"function"==typeof e.cleanup&&await e.cleanup();this.removeDatabaseHooks()}installDatabaseHooks(){this.database.addHook("afterCreateResource",e=>{e.name!==(this.config.replicatorLogResource||"replicator_logs")&&this.installEventListeners(e,this.database,this)})}removeDatabaseHooks(){this.database.removeHook("afterCreateResource",this.installEventListeners.bind(this))}createReplicator(e,t,r,i){return function(e,t={},r=[],i=null){const s=Rs[e];if(!s)throw new Error(`Unknown replicator driver: ${e}. Available drivers: ${Object.keys(Rs).join(", ")}`);return new s(t,r,i)}(e,t,r,i)}async initializeReplicators(e){for(const t of this.config.replicators){const{driver:r,config:i={},resources:s,client:n,...o}=t,a=s||i.resources||{},c={...i,...o},u=this.createReplicator(r,c,a,n);u&&(await u.initialize(e),this.replicators.push(u))}}async uploadMetadataFile(e){"function"==typeof e.uploadMetadataFile&&await e.uploadMetadataFile()}async retryWithBackoff(e,t=3){let r;for(let i=1;i<=t;i++){const[s,n]=await ve(e);if(s)return s;{if(r=n,this.config.verbose&&console.warn(`[ReplicatorPlugin] Retry attempt ${i}/${t} failed: ${n.message}`),i===t)throw n;const e=1e3*Math.pow(2,i-1);this.config.verbose&&console.warn(`[ReplicatorPlugin] Waiting ${e}ms before retry...`),await new Promise(t=>setTimeout(t,e))}}throw r}async logError(e,t,r,i,s,n){const[o,a]=await ve(async()=>{const o=this.config.replicatorLogResource;if(this.database&&this.database.resources&&this.database.resources[o]){const a=this.database.resources[o];await a.insert({replicator:e.name||e.id,resourceName:t,operation:r,recordId:i,data:JSON.stringify(s),error:n.message,timestamp:(new Date).toISOString(),status:"error"})}});o||(this.config.verbose&&console.warn(`[ReplicatorPlugin] Failed to log error for ${t}: ${a.message}`),this.emit("replicator_log_error",{replicator:e.name||e.id,resourceName:t,operation:r,recordId:i,originalError:n.message,logError:a.message}))}async processReplicatorEvent(e,t,r,i,s=null){if(!this.config.enabled)return;const n=this.replicators.filter(r=>r.shouldReplicateResource&&r.shouldReplicateResource(t,e));if(0===n.length)return;const o=n.map(async n=>{const[o,a,c]=await ve(async()=>{const o=await this.retryWithBackoff(()=>n.replicate(t,e,i,r,s),this.config.maxRetries);return this.emit("replicated",{replicator:n.name||n.id,resourceName:t,operation:e,recordId:r,result:o,success:!0}),o});if(o)return c;throw this.config.verbose&&console.warn(`[ReplicatorPlugin] Replication failed for ${n.name||n.id} on ${t}: ${a.message}`),this.emit("replicator_error",{replicator:n.name||n.id,resourceName:t,operation:e,recordId:r,error:a.message}),this.config.logErrors&&this.database&&await this.logError(n,t,e,r,i,a),a});return Promise.allSettled(o)}async processreplicatorItem(e){const t=this.replicators.filter(t=>t.shouldReplicateResource&&t.shouldReplicateResource(e.resourceName,e.operation));if(0===t.length)return;const r=t.map(async t=>{const[r,i]=await ve(async()=>{const[r,i,s]=await ve(()=>t.replicate(e.resourceName,e.operation,e.data,e.recordId,e.beforeData));return r?(this.emit("replicated",{replicator:t.name||t.id,resourceName:e.resourceName,operation:e.operation,recordId:e.recordId,result:s,success:!0}),{success:!0,result:s}):(this.config.verbose&&console.warn(`[ReplicatorPlugin] Replicator item processing failed for ${t.name||t.id} on ${e.resourceName}: ${i.message}`),this.emit("replicator_error",{replicator:t.name||t.id,resourceName:e.resourceName,operation:e.operation,recordId:e.recordId,error:i.message}),this.config.logErrors&&this.database&&await this.logError(t,e.resourceName,e.operation,e.recordId,e.data,i),{success:!1,error:i.message})});return r||(this.config.verbose&&console.warn(`[ReplicatorPlugin] Wrapper processing failed for ${t.name||t.id} on ${e.resourceName}: ${i.message}`),this.emit("replicator_error",{replicator:t.name||t.id,resourceName:e.resourceName,operation:e.operation,recordId:e.recordId,error:i.message}),this.config.logErrors&&this.database&&await this.logError(t,e.resourceName,e.operation,e.recordId,e.data,i),{success:!1,error:i.message})});return Promise.allSettled(r)}async logreplicator(e){const t=this.replicatorLog||this.database.resources[js(this.config.replicatorLogResource)];if(!t)return this.database&&this.database.options&&this.database.options.connectionString,void this.emit("replicator.log.failed",{error:"replicator log resource not found",item:e});const r={id:e.id||`repl-${Date.now()}-${Math.random().toString(36).slice(2)}`,resource:e.resource||e.resourceName||"",action:e.operation||e.action||"",data:e.data||{},timestamp:"number"==typeof e.timestamp?e.timestamp:Date.now(),createdAt:e.createdAt||(new Date).toISOString().slice(0,10)},[i,s]=await ve(async()=>{await t.insert(r)});i||(this.config.verbose&&console.warn(`[ReplicatorPlugin] Failed to log replicator item: ${s.message}`),this.emit("replicator.log.failed",{error:s,item:e}))}async updatereplicatorLog(e,t){if(!this.replicatorLog)return;const[r,i]=await ve(async()=>{await this.replicatorLog.update(e,{...t,lastAttempt:(new Date).toISOString()})});r||this.emit("replicator.updateLog.failed",{error:i.message,logId:e,updates:t})}async getreplicatorStats(){return{replicators:await Promise.all(this.replicators.map(async e=>{const t=await e.getStatus();return{id:e.id,driver:e.driver,config:e.config,status:t}})),queue:{length:this.queue.length,isProcessing:this.isProcessing},stats:this.stats,lastSync:this.stats.lastSync}}async getreplicatorLogs(e={}){if(!this.replicatorLog)return[];const{resourceName:t,operation:r,status:i,limit:s=100,offset:n=0}=e;let o={};t&&(o.resourceName=t),r&&(o.operation=r),i&&(o.status=i);return(await this.replicatorLog.list(o)).slice(n,n+s)}async retryFailedreplicators(){if(!this.replicatorLog)return{retried:0};const e=await this.replicatorLog.list({status:"failed"});let t=0;for(const r of e){const[e,i]=await ve(async()=>{await this.processReplicatorEvent(r.resourceName,r.operation,r.recordId,r.data)});e&&t++}return{retried:t}}async syncAllData(e){const t=this.replicators.find(t=>t.id===e);if(!t)throw new Error(`Replicator not found: ${e}`);this.stats.lastSync=(new Date).toISOString();for(const r in this.database.resources)if(js(r)!==js("replicator_logs")&&t.shouldReplicateResource(r)){this.emit("replicator.sync.resource",{resourceName:r,replicatorId:e});const i=this.database.resources[r],s=await i.getAll();for(const e of s)await t.replicate(r,"insert",e,e.id)}this.emit("replicator.sync.completed",{replicatorId:e,stats:this.stats})}async cleanup(){const[e,t]=await ve(async()=>{if(this.replicators&&this.replicators.length>0){const e=this.replicators.map(async e=>{const[t,r]=await ve(async()=>{e&&"function"==typeof e.cleanup&&await e.cleanup()});t||(this.config.verbose&&console.warn(`[ReplicatorPlugin] Failed to cleanup replicator ${e.name||e.id}: ${r.message}`),this.emit("replicator_cleanup_error",{replicator:e.name||e.id||"unknown",driver:e.driver||"unknown",error:r.message}))});await Promise.allSettled(e)}this.replicators=[],this.database=null,this.eventListenersInstalled.clear(),this.removeAllListeners()});e||(this.config.verbose&&console.warn(`[ReplicatorPlugin] Failed to cleanup plugin: ${t.message}`),this.emit("replicator_plugin_cleanup_error",{error:t.message}))}}export{gs as AVAILABLE_BEHAVIORS,Fe as AuditPlugin,te as AuthenticationError,Q as BaseError,Ii as CachePlugin,Hi as Client,zi as ConnectionString,de as ConnectionStringError,Pi as CostsPlugin,pe as CryptoError,ys as DEFAULT_BEHAVIOR,vs as Database,X as DatabaseError,ie as EncryptionError,he as ErrorMap,Ti as FullTextPlugin,ue as InvalidResourceItem,Mi as MetricsPlugin,ce as MissingMetadata,ne as NoSuchBucket,oe as NoSuchKey,ae as NotFound,ye as PartitionError,re as PermissionError,Le as Plugin,Ue as PluginObject,xs as ReplicatorPlugin,bs as Resource,ge as ResourceError,Ri as ResourceIdsPageReader,Si as ResourceIdsReader,se as ResourceNotFound,ji as ResourceReader,xi as ResourceWriter,vs as S3db,Z as S3dbError,Qi as Schema,me as SchemaError,le as UnknownError,ee as ValidationError,Ji as Validator,ps as behaviors,H as calculateAttributeNamesSize,K as calculateAttributeSizes,Y as calculateEffectiveLimit,G as calculateSystemOverhead,W as calculateTotalSize,z as calculateUTF8Bytes,F as decode,B as decodeDecimal,Oe as decrypt,ks as default,U as encode,q as encodeDecimal,Se as encrypt,ms as getBehavior,J as getSizeBreakdown,xe as idGenerator,fe as mapAwsError,Re as md5,Ae as passwordGenerator,_e as sha256,Ai as streamToString,V as transformValue,be as tryFn,we as tryFnSync};
|