@carno.js/core 1.0.5 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bun/index.js CHANGED
@@ -157,7 +157,7 @@ $`+Buffer.byteLength(this.name)+`\r
157
157
  `+arg+`\r
158
158
  `}}return result}stringifyArguments(){for(let i=0;i<this.args.length;++i){let arg=this.args[i];if(typeof arg==="string");else if(arg instanceof Buffer)this.bufferMode=!0;else this.args[i]=(0,utils_1.toArg)(arg)}}transformReply(result){if(this.replyEncoding)result=(0,utils_1.convertBufferToString)(result,this.replyEncoding);let transformer=Command._transformer.reply[this.name];if(transformer)result=transformer(result);return result}setTimeout(ms){if(!this._commandTimeoutTimer)this._commandTimeoutTimer=setTimeout(()=>{if(!this.isResolved)this.reject(Error("Command timed out"))},ms)}initPromise(){let promise=new Promise((resolve,reject)=>{if(!this.transformed){this.transformed=!0;let transformer=Command._transformer.argument[this.name];if(transformer)this.args=transformer(this.args);this.stringifyArguments()}if(this.resolve=this._convertValue(resolve),this.errorStack)this.reject=(err)=>{reject((0,utils_1.optimizeErrorStack)(err,this.errorStack.stack,__dirname))};else this.reject=reject});this.promise=(0,standard_as_callback_1.default)(promise,this.callback)}_iterateKeys(transform=(key)=>key){if(typeof this.keys>"u"){if(this.keys=[],(0,commands_1.exists)(this.name)){let keyIndexes=(0,commands_1.getKeyIndexes)(this.name,this.args);for(let index of keyIndexes)this.args[index]=transform(this.args[index]),this.keys.push(this.args[index])}}return this.keys}_convertValue(resolve){return(value)=>{try{let existingTimer=this._commandTimeoutTimer;if(existingTimer)clearTimeout(existingTimer),delete this._commandTimeoutTimer;resolve(this.transformReply(value)),this.isResolved=!0}catch(err){this.reject(err)}return this.promise}}}exports.default=Command;Command.FLAGS={VALID_IN_SUBSCRIBER_MODE:["subscribe","psubscribe","unsubscribe","punsubscribe","ssubscribe","sunsubscribe","ping","quit"],VALID_IN_MONITOR_MODE:["monitor","auth"],ENTER_SUBSCRIBER_MODE:["subscribe","psubscribe","ssubscribe"],EXIT_SUBSCRIBER_MODE:["unsubscribe","punsubscribe","sunsubscribe"],WILL_DISCONNECT:["quit"],HANDSHAKE_COMMANDS:["auth","select","client","readonly","info"],IGNORE_RECONNECT_ON_ERROR:["client"]};Command._transformer={argument:{},reply:{}};var msetArgumentTransformer=function(args){if(args.length===1){if(args[0]instanceof Map)return(0,utils_1.convertMapToArray)(args[0]);if(typeof args[0]==="object"&&args[0]!==null)return(0,utils_1.convertObjectToArray)(args[0])}return args},hsetArgumentTransformer=function(args){if(args.length===2){if(args[1]instanceof Map)return[args[0]].concat((0,utils_1.convertMapToArray)(args[1]));if(typeof args[1]==="object"&&args[1]!==null)return[args[0]].concat((0,utils_1.convertObjectToArray)(args[1]))}return args};Command.setArgumentTransformer("mset",msetArgumentTransformer);Command.setArgumentTransformer("msetnx",msetArgumentTransformer);Command.setArgumentTransformer("hset",hsetArgumentTransformer);Command.setArgumentTransformer("hmset",hsetArgumentTransformer);Command.setReplyTransformer("hgetall",function(result){if(Array.isArray(result)){let obj={};for(let i=0;i<result.length;i+=2){let key=result[i],value=result[i+1];if(key in obj)Object.defineProperty(obj,key,{value,configurable:!0,enumerable:!0,writable:!0});else obj[key]=value}return obj}return result});class MixedBuffers{constructor(){this.length=0,this.items=[]}push(x){this.length+=Buffer.byteLength(x),this.items.push(x)}toBuffer(){let result=Buffer.allocUnsafe(this.length),offset=0;for(let item of this.items){let length=Buffer.byteLength(item);Buffer.isBuffer(item)?item.copy(result,offset):result.write(item,offset,length),offset+=length}return result}}});var require_ClusterAllFailedError=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});var redis_errors_1=require_redis_errors();class ClusterAllFailedError extends redis_errors_1.RedisError{constructor(message,lastNodeError){super(message);this.lastNodeError=lastNodeError,Error.captureStackTrace(this,this.constructor)}get name(){return this.constructor.name}}exports.default=ClusterAllFailedError;ClusterAllFailedError.defaultMessage="Failed to refresh slots cache."});var require_ScanStream=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});var stream_1=__require("stream");class ScanStream extends stream_1.Readable{constructor(opt){super(opt);this.opt=opt,this._redisCursor="0",this._redisDrained=!1}_read(){if(this._redisDrained){this.push(null);return}let args=[this._redisCursor];if(this.opt.key)args.unshift(this.opt.key);if(this.opt.match)args.push("MATCH",this.opt.match);if(this.opt.type)args.push("TYPE",this.opt.type);if(this.opt.count)args.push("COUNT",String(this.opt.count));if(this.opt.noValues)args.push("NOVALUES");this.opt.redis[this.opt.command](args,(err,res)=>{if(err){this.emit("error",err);return}if(this._redisCursor=res[0]instanceof Buffer?res[0].toString():res[0],this._redisCursor==="0")this._redisDrained=!0;this.push(res[1])})}close(){this._redisDrained=!0}}exports.default=ScanStream});var require_autoPipelining=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});exports.executeWithAutoPipelining=exports.getFirstValueInFlattenedArray=exports.shouldUseAutoPipelining=exports.notAllowedAutoPipelineCommands=exports.kCallbacks=exports.kExec=void 0;var lodash_1=require_lodash3(),calculateSlot=require_lib(),standard_as_callback_1=require_built2();exports.kExec=Symbol("exec");exports.kCallbacks=Symbol("callbacks");exports.notAllowedAutoPipelineCommands=["auth","info","script","quit","cluster","pipeline","multi","subscribe","psubscribe","unsubscribe","unpsubscribe","select","client"];function executeAutoPipeline(client,slotKey){if(client._runningAutoPipelines.has(slotKey))return;if(!client._autoPipelines.has(slotKey))return;client._runningAutoPipelines.add(slotKey);let pipeline=client._autoPipelines.get(slotKey);client._autoPipelines.delete(slotKey);let callbacks=pipeline[exports.kCallbacks];pipeline[exports.kCallbacks]=null,pipeline.exec(function(err,results){if(client._runningAutoPipelines.delete(slotKey),err)for(let i=0;i<callbacks.length;i++)process.nextTick(callbacks[i],err);else for(let i=0;i<callbacks.length;i++)process.nextTick(callbacks[i],...results[i]);if(client._autoPipelines.has(slotKey))executeAutoPipeline(client,slotKey)})}function shouldUseAutoPipelining(client,functionName,commandName){return functionName&&client.options.enableAutoPipelining&&!client.isPipeline&&!exports.notAllowedAutoPipelineCommands.includes(commandName)&&!client.options.autoPipeliningIgnoredCommands.includes(commandName)}exports.shouldUseAutoPipelining=shouldUseAutoPipelining;function getFirstValueInFlattenedArray(args){for(let i=0;i<args.length;i++){let arg=args[i];if(typeof arg==="string")return arg;else if(Array.isArray(arg)||(0,lodash_1.isArguments)(arg)){if(arg.length===0)continue;return arg[0]}let flattened=[arg].flat();if(flattened.length>0)return flattened[0]}return}exports.getFirstValueInFlattenedArray=getFirstValueInFlattenedArray;function executeWithAutoPipelining(client,functionName,commandName,args,callback){if(client.isCluster&&!client.slots.length){if(client.status==="wait")client.connect().catch(lodash_1.noop);return(0,standard_as_callback_1.default)(new Promise(function(resolve,reject){client.delayUntilReady((err)=>{if(err){reject(err);return}executeWithAutoPipelining(client,functionName,commandName,args,null).then(resolve,reject)})}),callback)}let prefix=client.options.keyPrefix||"",slotKey=client.isCluster?client.slots[calculateSlot(`${prefix}${getFirstValueInFlattenedArray(args)}`)].join(","):"main";if(!client._autoPipelines.has(slotKey)){let pipeline2=client.pipeline();pipeline2[exports.kExec]=!1,pipeline2[exports.kCallbacks]=[],client._autoPipelines.set(slotKey,pipeline2)}let pipeline=client._autoPipelines.get(slotKey);if(!pipeline[exports.kExec])pipeline[exports.kExec]=!0,setImmediate(executeAutoPipeline,client,slotKey);let autoPipelinePromise=new Promise(function(resolve,reject){if(pipeline[exports.kCallbacks].push(function(err,value){if(err){reject(err);return}resolve(value)}),functionName==="call")args.unshift(commandName);pipeline[functionName](...args)});return(0,standard_as_callback_1.default)(autoPipelinePromise,callback)}exports.executeWithAutoPipelining=executeWithAutoPipelining});var require_Script=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});var crypto_1=__require("crypto"),Command_1=require_Command(),standard_as_callback_1=require_built2();class Script{constructor(lua,numberOfKeys=null,keyPrefix="",readOnly=!1){this.lua=lua,this.numberOfKeys=numberOfKeys,this.keyPrefix=keyPrefix,this.readOnly=readOnly,this.sha=(0,crypto_1.createHash)("sha1").update(lua).digest("hex");let sha=this.sha,socketHasScriptLoaded=new WeakSet;this.Command=class extends Command_1.default{toWritable(socket){let origReject=this.reject;if(this.reject=(err)=>{if(err.message.indexOf("NOSCRIPT")!==-1)socketHasScriptLoaded.delete(socket);origReject.call(this,err)},!socketHasScriptLoaded.has(socket))socketHasScriptLoaded.add(socket),this.name="eval",this.args[0]=lua;else if(this.name==="eval")this.name="evalsha",this.args[0]=sha;return super.toWritable(socket)}}}execute(container,args,options,callback){if(typeof this.numberOfKeys==="number")args.unshift(this.numberOfKeys);if(this.keyPrefix)options.keyPrefix=this.keyPrefix;if(this.readOnly)options.readOnly=!0;let evalsha=new this.Command("evalsha",[this.sha,...args],options);return evalsha.promise=evalsha.promise.catch((err)=>{if(err.message.indexOf("NOSCRIPT")===-1)throw err;let resend=new this.Command("evalsha",[this.sha,...args],options);return(container.isPipeline?container.redis:container).sendCommand(resend)}),(0,standard_as_callback_1.default)(evalsha.promise,callback),container.sendCommand(evalsha)}}exports.default=Script});var require_Commander=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});var commands_1=require_built(),autoPipelining_1=require_autoPipelining(),Command_1=require_Command(),Script_1=require_Script();class Commander{constructor(){this.options={},this.scriptsSet={},this.addedBuiltinSet=new Set}getBuiltinCommands(){return commands.slice(0)}createBuiltinCommand(commandName){return{string:generateFunction(null,commandName,"utf8"),buffer:generateFunction(null,commandName,null)}}addBuiltinCommand(commandName){this.addedBuiltinSet.add(commandName),this[commandName]=generateFunction(commandName,commandName,"utf8"),this[commandName+"Buffer"]=generateFunction(commandName+"Buffer",commandName,null)}defineCommand(name,definition){let script=new Script_1.default(definition.lua,definition.numberOfKeys,this.options.keyPrefix,definition.readOnly);this.scriptsSet[name]=script,this[name]=generateScriptingFunction(name,name,script,"utf8"),this[name+"Buffer"]=generateScriptingFunction(name+"Buffer",name,script,null)}sendCommand(command,stream,node){throw Error('"sendCommand" is not implemented')}}var commands=commands_1.list.filter((command)=>command!=="monitor");commands.push("sentinel");commands.forEach(function(commandName){Commander.prototype[commandName]=generateFunction(commandName,commandName,"utf8"),Commander.prototype[commandName+"Buffer"]=generateFunction(commandName+"Buffer",commandName,null)});Commander.prototype.call=generateFunction("call","utf8");Commander.prototype.callBuffer=generateFunction("callBuffer",null);Commander.prototype.send_command=Commander.prototype.call;function generateFunction(functionName,_commandName,_encoding){if(typeof _encoding>"u")_encoding=_commandName,_commandName=null;return function(...args){let commandName=_commandName||args.shift(),callback=args[args.length-1];if(typeof callback==="function")args.pop();else callback=void 0;let options={errorStack:this.options.showFriendlyErrorStack?Error():void 0,keyPrefix:this.options.keyPrefix,replyEncoding:_encoding};if(!(0,autoPipelining_1.shouldUseAutoPipelining)(this,functionName,commandName))return this.sendCommand(new Command_1.default(commandName,args,options,callback));return(0,autoPipelining_1.executeWithAutoPipelining)(this,functionName,commandName,args,callback)}}function generateScriptingFunction(functionName,commandName,script,encoding){return function(...args){let callback=typeof args[args.length-1]==="function"?args.pop():void 0,options={replyEncoding:encoding};if(this.options.showFriendlyErrorStack)options.errorStack=Error();if(!(0,autoPipelining_1.shouldUseAutoPipelining)(this,functionName,commandName))return script.execute(this,args,options,callback);return(0,autoPipelining_1.executeWithAutoPipelining)(this,functionName,commandName,args,callback)}}exports.default=Commander});var require_Pipeline=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});var calculateSlot=require_lib(),commands_1=require_built(),standard_as_callback_1=require_built2(),util_1=__require("util"),Command_1=require_Command(),utils_1=require_utils2(),Commander_1=require_Commander();function generateMultiWithNodes(redis,keys){let slot=calculateSlot(keys[0]),target=redis._groupsBySlot[slot];for(let i=1;i<keys.length;i++)if(redis._groupsBySlot[calculateSlot(keys[i])]!==target)return-1;return slot}class Pipeline extends Commander_1.default{constructor(redis){super();this.redis=redis,this.isPipeline=!0,this.replyPending=0,this._queue=[],this._result=[],this._transactions=0,this._shaToScript={},this.isCluster=this.redis.constructor.name==="Cluster"||this.redis.isCluster,this.options=redis.options,Object.keys(redis.scriptsSet).forEach((name)=>{let script=redis.scriptsSet[name];this._shaToScript[script.sha]=script,this[name]=redis[name],this[name+"Buffer"]=redis[name+"Buffer"]}),redis.addedBuiltinSet.forEach((name)=>{this[name]=redis[name],this[name+"Buffer"]=redis[name+"Buffer"]}),this.promise=new Promise((resolve,reject)=>{this.resolve=resolve,this.reject=reject});let _this=this;Object.defineProperty(this,"length",{get:function(){return _this._queue.length}})}fillResult(value,position){if(this._queue[position].name==="exec"&&Array.isArray(value[1])){let execLength=value[1].length;for(let i=0;i<execLength;i++){if(value[1][i]instanceof Error)continue;let cmd=this._queue[position-(execLength-i)];try{value[1][i]=cmd.transformReply(value[1][i])}catch(err){value[1][i]=err}}}if(this._result[position]=value,--this.replyPending)return;if(this.isCluster){let retriable=!0,commonError;for(let i=0;i<this._result.length;++i){let error=this._result[i][0],command=this._queue[i];if(error){if(command.name==="exec"&&error.message==="EXECABORT Transaction discarded because of previous errors.")continue;if(!commonError)commonError={name:error.name,message:error.message};else if(commonError.name!==error.name||commonError.message!==error.message){retriable=!1;break}}else if(!command.inTransaction){if(!((0,commands_1.exists)(command.name)&&(0,commands_1.hasFlag)(command.name,"readonly"))){retriable=!1;break}}}if(commonError&&retriable){let _this=this,errv=commonError.message.split(" "),queue=this._queue,inTransaction=!1;this._queue=[];for(let i=0;i<queue.length;++i){if(errv[0]==="ASK"&&!inTransaction&&queue[i].name!=="asking"&&(!queue[i-1]||queue[i-1].name!=="asking")){let asking=new Command_1.default("asking");asking.ignore=!0,this.sendCommand(asking)}queue[i].initPromise(),this.sendCommand(queue[i]),inTransaction=queue[i].inTransaction}let matched=!0;if(typeof this.leftRedirections>"u")this.leftRedirections={};let exec=function(){_this.exec()},cluster=this.redis;if(cluster.handleError(commonError,this.leftRedirections,{moved:function(_slot,key){_this.preferKey=key,cluster.slots[errv[1]]=[key],cluster._groupsBySlot[errv[1]]=cluster._groupsIds[cluster.slots[errv[1]].join(";")],cluster.refreshSlotsCache(),_this.exec()},ask:function(_slot,key){_this.preferKey=key,_this.exec()},tryagain:exec,clusterDown:exec,connectionClosed:exec,maxRedirections:()=>{matched=!1},defaults:()=>{matched=!1}}),matched)return}}let ignoredCount=0;for(let i=0;i<this._queue.length-ignoredCount;++i){if(this._queue[i+ignoredCount].ignore)ignoredCount+=1;this._result[i]=this._result[i+ignoredCount]}this.resolve(this._result.slice(0,this._result.length-ignoredCount))}sendCommand(command){if(this._transactions>0)command.inTransaction=!0;let position=this._queue.length;return command.pipelineIndex=position,command.promise.then((result)=>{this.fillResult([null,result],position)}).catch((error)=>{this.fillResult([error],position)}),this._queue.push(command),this}addBatch(commands){let command,commandName,args;for(let i=0;i<commands.length;++i)command=commands[i],commandName=command[0],args=command.slice(1),this[commandName].apply(this,args);return this}}exports.default=Pipeline;var multi=Pipeline.prototype.multi;Pipeline.prototype.multi=function(){return this._transactions+=1,multi.apply(this,arguments)};var execBuffer=Pipeline.prototype.execBuffer;Pipeline.prototype.execBuffer=(0,util_1.deprecate)(function(){if(this._transactions>0)this._transactions-=1;return execBuffer.apply(this,arguments)},"Pipeline#execBuffer: Use Pipeline#exec instead");Pipeline.prototype.exec=function(callback){if(this.isCluster&&!this.redis.slots.length){if(this.redis.status==="wait")this.redis.connect().catch(utils_1.noop);if(callback&&!this.nodeifiedPromise)this.nodeifiedPromise=!0,(0,standard_as_callback_1.default)(this.promise,callback);return this.redis.delayUntilReady((err)=>{if(err){this.reject(err);return}this.exec(callback)}),this.promise}if(this._transactions>0)return this._transactions-=1,execBuffer.apply(this,arguments);if(!this.nodeifiedPromise)this.nodeifiedPromise=!0,(0,standard_as_callback_1.default)(this.promise,callback);if(!this._queue.length)this.resolve([]);let pipelineSlot;if(this.isCluster){let sampleKeys=[];for(let i=0;i<this._queue.length;i++){let keys=this._queue[i].getKeys();if(keys.length)sampleKeys.push(keys[0]);if(keys.length&&calculateSlot.generateMulti(keys)<0)return this.reject(Error("All the keys in a pipeline command should belong to the same slot")),this.promise}if(sampleKeys.length){if(pipelineSlot=generateMultiWithNodes(this.redis,sampleKeys),pipelineSlot<0)return this.reject(Error("All keys in the pipeline should belong to the same slots allocation group")),this.promise}else pipelineSlot=Math.random()*16384|0}let _this=this;return execPipeline(),this.promise;function execPipeline(){let writePending=_this.replyPending=_this._queue.length,node;if(_this.isCluster)node={slot:pipelineSlot,redis:_this.redis.connectionPool.nodes.all[_this.preferKey]};let data="",buffers,stream={isPipeline:!0,destination:_this.isCluster?node:{redis:_this.redis},write(writable){if(typeof writable!=="string"){if(!buffers)buffers=[];if(data)buffers.push(Buffer.from(data,"utf8")),data="";buffers.push(writable)}else data+=writable;if(!--writePending){if(buffers){if(data)buffers.push(Buffer.from(data,"utf8"));stream.destination.redis.stream.write(Buffer.concat(buffers))}else stream.destination.redis.stream.write(data);writePending=_this._queue.length,data="",buffers=void 0}}};for(let i=0;i<_this._queue.length;++i)_this.redis.sendCommand(_this._queue[i],stream,node);return _this.promise}}});var require_transaction=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});exports.addTransactionSupport=void 0;var utils_1=require_utils2(),standard_as_callback_1=require_built2(),Pipeline_1=require_Pipeline();function addTransactionSupport(redis){redis.pipeline=function(commands){let pipeline=new Pipeline_1.default(this);if(Array.isArray(commands))pipeline.addBatch(commands);return pipeline};let{multi}=redis;redis.multi=function(commands,options){if(typeof options>"u"&&!Array.isArray(commands))options=commands,commands=null;if(options&&options.pipeline===!1)return multi.call(this);let pipeline=new Pipeline_1.default(this);if(pipeline.multi(),Array.isArray(commands))pipeline.addBatch(commands);let exec2=pipeline.exec;pipeline.exec=function(callback){if(this.isCluster&&!this.redis.slots.length){if(this.redis.status==="wait")this.redis.connect().catch(utils_1.noop);return(0,standard_as_callback_1.default)(new Promise((resolve,reject)=>{this.redis.delayUntilReady((err)=>{if(err){reject(err);return}this.exec(pipeline).then(resolve,reject)})}),callback)}if(this._transactions>0)exec2.call(pipeline);if(this.nodeifiedPromise)return exec2.call(pipeline);let promise=exec2.call(pipeline);return(0,standard_as_callback_1.default)(promise.then(function(result){let execResult=result[result.length-1];if(typeof execResult>"u")throw Error("Pipeline cannot be used to send any commands when the `exec()` has been called on it.");if(execResult[0]){execResult[0].previousErrors=[];for(let i=0;i<result.length-1;++i)if(result[i][0])execResult[0].previousErrors.push(result[i][0]);throw execResult[0]}return(0,utils_1.wrapMultiResult)(execResult[1])}),callback)};let{execBuffer}=pipeline;return pipeline.execBuffer=function(callback){if(this._transactions>0)execBuffer.call(pipeline);return pipeline.exec(callback)},pipeline};let{exec}=redis;redis.exec=function(callback){return(0,standard_as_callback_1.default)(exec.call(this).then(function(results){if(Array.isArray(results))results=(0,utils_1.wrapMultiResult)(results);return results}),callback)}}exports.addTransactionSupport=addTransactionSupport});var require_applyMixin=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});function applyMixin(derivedConstructor,mixinConstructor){Object.getOwnPropertyNames(mixinConstructor.prototype).forEach((name)=>{Object.defineProperty(derivedConstructor.prototype,name,Object.getOwnPropertyDescriptor(mixinConstructor.prototype,name))})}exports.default=applyMixin});var require_ClusterOptions=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});exports.DEFAULT_CLUSTER_OPTIONS=void 0;var dns_1=__require("dns");exports.DEFAULT_CLUSTER_OPTIONS={clusterRetryStrategy:(times)=>Math.min(100+times*2,2000),enableOfflineQueue:!0,enableReadyCheck:!0,scaleReads:"master",maxRedirections:16,retryDelayOnMoved:0,retryDelayOnFailover:100,retryDelayOnClusterDown:100,retryDelayOnTryAgain:100,slotsRefreshTimeout:1000,useSRVRecords:!1,resolveSrv:dns_1.resolveSrv,dnsLookup:dns_1.lookup,enableAutoPipelining:!1,autoPipeliningIgnoredCommands:[],shardedSubscribers:!1}});var require_util=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});exports.getConnectionName=exports.weightSrvRecords=exports.groupSrvRecords=exports.getUniqueHostnamesFromOptions=exports.normalizeNodeOptions=exports.nodeKeyToRedisOptions=exports.getNodeKey=void 0;var utils_1=require_utils2(),net_1=__require("net");function getNodeKey(node){return node.port=node.port||6379,node.host=node.host||"127.0.0.1",node.host+":"+node.port}exports.getNodeKey=getNodeKey;function nodeKeyToRedisOptions(nodeKey){let portIndex=nodeKey.lastIndexOf(":");if(portIndex===-1)throw Error(`Invalid node key ${nodeKey}`);return{host:nodeKey.slice(0,portIndex),port:Number(nodeKey.slice(portIndex+1))}}exports.nodeKeyToRedisOptions=nodeKeyToRedisOptions;function normalizeNodeOptions(nodes){return nodes.map((node)=>{let options={};if(typeof node==="object")Object.assign(options,node);else if(typeof node==="string")Object.assign(options,(0,utils_1.parseURL)(node));else if(typeof node==="number")options.port=node;else throw Error("Invalid argument "+node);if(typeof options.port==="string")options.port=parseInt(options.port,10);if(delete options.db,!options.port)options.port=6379;if(!options.host)options.host="127.0.0.1";return(0,utils_1.resolveTLSProfile)(options)})}exports.normalizeNodeOptions=normalizeNodeOptions;function getUniqueHostnamesFromOptions(nodes){let uniqueHostsMap={};return nodes.forEach((node)=>{uniqueHostsMap[node.host]=!0}),Object.keys(uniqueHostsMap).filter((host)=>!(0,net_1.isIP)(host))}exports.getUniqueHostnamesFromOptions=getUniqueHostnamesFromOptions;function groupSrvRecords(records){let recordsByPriority={};for(let record of records)if(!recordsByPriority.hasOwnProperty(record.priority))recordsByPriority[record.priority]={totalWeight:record.weight,records:[record]};else recordsByPriority[record.priority].totalWeight+=record.weight,recordsByPriority[record.priority].records.push(record);return recordsByPriority}exports.groupSrvRecords=groupSrvRecords;function weightSrvRecords(recordsGroup){if(recordsGroup.records.length===1)return recordsGroup.totalWeight=0,recordsGroup.records.shift();let random=Math.floor(Math.random()*(recordsGroup.totalWeight+recordsGroup.records.length)),total=0;for(let[i,record]of recordsGroup.records.entries())if(total+=1+record.weight,total>random)return recordsGroup.totalWeight-=record.weight,recordsGroup.records.splice(i,1),record}exports.weightSrvRecords=weightSrvRecords;function getConnectionName(component,nodeConnectionName){let prefix=`ioredis-cluster(${component})`;return nodeConnectionName?`${prefix}:${nodeConnectionName}`:prefix}exports.getConnectionName=getConnectionName});var require_ClusterSubscriber=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});var util_1=require_util(),utils_1=require_utils2(),Redis_1=require_Redis(),debug=(0,utils_1.Debug)("cluster:subscriber");class ClusterSubscriber{constructor(connectionPool,emitter,isSharded=!1){this.connectionPool=connectionPool,this.emitter=emitter,this.isSharded=isSharded,this.started=!1,this.subscriber=null,this.slotRange=[],this.onSubscriberEnd=()=>{if(!this.started){debug("subscriber has disconnected, but ClusterSubscriber is not started, so not reconnecting.");return}debug("subscriber has disconnected, selecting a new one..."),this.selectSubscriber()},this.connectionPool.on("-node",(_,key)=>{if(!this.started||!this.subscriber)return;if((0,util_1.getNodeKey)(this.subscriber.options)===key)debug("subscriber has left, selecting a new one..."),this.selectSubscriber()}),this.connectionPool.on("+node",()=>{if(!this.started||this.subscriber)return;debug("a new node is discovered and there is no subscriber, selecting a new one..."),this.selectSubscriber()})}getInstance(){return this.subscriber}associateSlotRange(range){if(this.isSharded)this.slotRange=range;return this.slotRange}start(){this.started=!0,this.selectSubscriber(),debug("started")}stop(){if(this.started=!1,this.subscriber)this.subscriber.disconnect(),this.subscriber=null}isStarted(){return this.started}selectSubscriber(){let lastActiveSubscriber=this.lastActiveSubscriber;if(lastActiveSubscriber)lastActiveSubscriber.off("end",this.onSubscriberEnd),lastActiveSubscriber.disconnect();if(this.subscriber)this.subscriber.off("end",this.onSubscriberEnd),this.subscriber.disconnect();let sampleNode=(0,utils_1.sample)(this.connectionPool.getNodes());if(!sampleNode){debug("selecting subscriber failed since there is no node discovered in the cluster yet"),this.subscriber=null;return}let{options}=sampleNode;debug("selected a subscriber %s:%s",options.host,options.port);let connectionPrefix="subscriber";if(this.isSharded)connectionPrefix="ssubscriber";this.subscriber=new Redis_1.default({port:options.port,host:options.host,username:options.username,password:options.password,enableReadyCheck:!0,connectionName:(0,util_1.getConnectionName)(connectionPrefix,options.connectionName),lazyConnect:!0,tls:options.tls,retryStrategy:null}),this.subscriber.on("error",utils_1.noop),this.subscriber.on("moved",()=>{this.emitter.emit("forceRefresh")}),this.subscriber.once("end",this.onSubscriberEnd);let previousChannels={subscribe:[],psubscribe:[],ssubscribe:[]};if(lastActiveSubscriber){let condition=lastActiveSubscriber.condition||lastActiveSubscriber.prevCondition;if(condition&&condition.subscriber)previousChannels.subscribe=condition.subscriber.channels("subscribe"),previousChannels.psubscribe=condition.subscriber.channels("psubscribe"),previousChannels.ssubscribe=condition.subscriber.channels("ssubscribe")}if(previousChannels.subscribe.length||previousChannels.psubscribe.length||previousChannels.ssubscribe.length){let pending=0;for(let type of["subscribe","psubscribe","ssubscribe"]){let channels=previousChannels[type];if(channels.length==0)continue;if(debug("%s %d channels",type,channels.length),type==="ssubscribe")for(let channel of channels)pending+=1,this.subscriber[type](channel).then(()=>{if(!--pending)this.lastActiveSubscriber=this.subscriber}).catch(()=>{debug("failed to ssubscribe to channel: %s",channel)});else pending+=1,this.subscriber[type](channels).then(()=>{if(!--pending)this.lastActiveSubscriber=this.subscriber}).catch(()=>{debug("failed to %s %d channels",type,channels.length)})}}else this.lastActiveSubscriber=this.subscriber;for(let event of["message","messageBuffer"])this.subscriber.on(event,(arg1,arg2)=>{this.emitter.emit(event,arg1,arg2)});for(let event of["pmessage","pmessageBuffer"])this.subscriber.on(event,(arg1,arg2,arg3)=>{this.emitter.emit(event,arg1,arg2,arg3)});if(this.isSharded==!0)for(let event of["smessage","smessageBuffer"])this.subscriber.on(event,(arg1,arg2)=>{this.emitter.emit(event,arg1,arg2)})}}exports.default=ClusterSubscriber});var require_ConnectionPool=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});var events_1=__require("events"),utils_1=require_utils2(),util_1=require_util(),Redis_1=require_Redis(),debug=(0,utils_1.Debug)("cluster:connectionPool");class ConnectionPool extends events_1.EventEmitter{constructor(redisOptions){super();this.redisOptions=redisOptions,this.nodes={all:{},master:{},slave:{}},this.specifiedOptions={}}getNodes(role="all"){let nodes=this.nodes[role];return Object.keys(nodes).map((key)=>nodes[key])}getInstanceByKey(key){return this.nodes.all[key]}getSampleInstance(role){let keys=Object.keys(this.nodes[role]),sampleKey=(0,utils_1.sample)(keys);return this.nodes[role][sampleKey]}addMasterNode(node){let key=(0,util_1.getNodeKey)(node.options),redis=this.createRedisFromOptions(node,node.options.readOnly);if(!node.options.readOnly)return this.nodes.all[key]=redis,this.nodes.master[key]=redis,!0;return!1}createRedisFromOptions(node,readOnly){return new Redis_1.default((0,utils_1.defaults)({retryStrategy:null,enableOfflineQueue:!0,readOnly},node,this.redisOptions,{lazyConnect:!0}))}findOrCreate(node,readOnly=!1){let key=(0,util_1.getNodeKey)(node);if(readOnly=Boolean(readOnly),this.specifiedOptions[key])Object.assign(node,this.specifiedOptions[key]);else this.specifiedOptions[key]=node;let redis;if(this.nodes.all[key]){if(redis=this.nodes.all[key],redis.options.readOnly!==readOnly)if(redis.options.readOnly=readOnly,debug("Change role of %s to %s",key,readOnly?"slave":"master"),redis[readOnly?"readonly":"readwrite"]().catch(utils_1.noop),readOnly)delete this.nodes.master[key],this.nodes.slave[key]=redis;else delete this.nodes.slave[key],this.nodes.master[key]=redis}else debug("Connecting to %s as %s",key,readOnly?"slave":"master"),redis=this.createRedisFromOptions(node,readOnly),this.nodes.all[key]=redis,this.nodes[readOnly?"slave":"master"][key]=redis,redis.once("end",()=>{if(this.removeNode(key),this.emit("-node",redis,key),!Object.keys(this.nodes.all).length)this.emit("drain")}),this.emit("+node",redis,key),redis.on("error",function(error){this.emit("nodeError",error,key)});return redis}reset(nodes){debug("Reset with %O",nodes);let newNodes={};nodes.forEach((node)=>{let key=(0,util_1.getNodeKey)(node);if(!(node.readOnly&&newNodes[key]))newNodes[key]=node}),Object.keys(this.nodes.all).forEach((key)=>{if(!newNodes[key])debug("Disconnect %s because the node does not hold any slot",key),this.nodes.all[key].disconnect(),this.removeNode(key)}),Object.keys(newNodes).forEach((key)=>{let node=newNodes[key];this.findOrCreate(node,node.readOnly)})}removeNode(key){let{nodes}=this;if(nodes.all[key])debug("Remove %s from the pool",key),delete nodes.all[key];delete nodes.master[key],delete nodes.slave[key]}}exports.default=ConnectionPool});var require_denque=__commonJS((exports,module)=>{function Denque(array,options){var options=options||{};if(this._capacity=options.capacity,this._head=0,this._tail=0,Array.isArray(array))this._fromArray(array);else this._capacityMask=3,this._list=[,,,,]}Denque.prototype.peekAt=function(index){var i=index;if(i!==(i|0))return;var len=this.size();if(i>=len||i<-len)return;if(i<0)i+=len;return i=this._head+i&this._capacityMask,this._list[i]};Denque.prototype.get=function(i){return this.peekAt(i)};Denque.prototype.peek=function(){if(this._head===this._tail)return;return this._list[this._head]};Denque.prototype.peekFront=function(){return this.peek()};Denque.prototype.peekBack=function(){return this.peekAt(-1)};Object.defineProperty(Denque.prototype,"length",{get:function(){return this.size()}});Denque.prototype.size=function(){if(this._head===this._tail)return 0;if(this._head<this._tail)return this._tail-this._head;else return this._capacityMask+1-(this._head-this._tail)};Denque.prototype.unshift=function(item){if(arguments.length===0)return this.size();var len=this._list.length;if(this._head=this._head-1+len&this._capacityMask,this._list[this._head]=item,this._tail===this._head)this._growArray();if(this._capacity&&this.size()>this._capacity)this.pop();if(this._head<this._tail)return this._tail-this._head;else return this._capacityMask+1-(this._head-this._tail)};Denque.prototype.shift=function(){var head=this._head;if(head===this._tail)return;var item=this._list[head];if(this._list[head]=void 0,this._head=head+1&this._capacityMask,head<2&&this._tail>1e4&&this._tail<=this._list.length>>>2)this._shrinkArray();return item};Denque.prototype.push=function(item){if(arguments.length===0)return this.size();var tail=this._tail;if(this._list[tail]=item,this._tail=tail+1&this._capacityMask,this._tail===this._head)this._growArray();if(this._capacity&&this.size()>this._capacity)this.shift();if(this._head<this._tail)return this._tail-this._head;else return this._capacityMask+1-(this._head-this._tail)};Denque.prototype.pop=function(){var tail=this._tail;if(tail===this._head)return;var len=this._list.length;this._tail=tail-1+len&this._capacityMask;var item=this._list[this._tail];if(this._list[this._tail]=void 0,this._head<2&&tail>1e4&&tail<=len>>>2)this._shrinkArray();return item};Denque.prototype.removeOne=function(index){var i=index;if(i!==(i|0))return;if(this._head===this._tail)return;var size=this.size(),len=this._list.length;if(i>=size||i<-size)return;if(i<0)i+=size;i=this._head+i&this._capacityMask;var item=this._list[i],k;if(index<size/2){for(k=index;k>0;k--)this._list[i]=this._list[i=i-1+len&this._capacityMask];this._list[i]=void 0,this._head=this._head+1+len&this._capacityMask}else{for(k=size-1-index;k>0;k--)this._list[i]=this._list[i=i+1+len&this._capacityMask];this._list[i]=void 0,this._tail=this._tail-1+len&this._capacityMask}return item};Denque.prototype.remove=function(index,count){var i=index,removed,del_count=count;if(i!==(i|0))return;if(this._head===this._tail)return;var size=this.size(),len=this._list.length;if(i>=size||i<-size||count<1)return;if(i<0)i+=size;if(count===1||!count)return removed=[,],removed[0]=this.removeOne(i),removed;if(i===0&&i+count>=size)return removed=this.toArray(),this.clear(),removed;if(i+count>size)count=size-i;var k;removed=Array(count);for(k=0;k<count;k++)removed[k]=this._list[this._head+i+k&this._capacityMask];if(i=this._head+i&this._capacityMask,index+count===size){this._tail=this._tail-count+len&this._capacityMask;for(k=count;k>0;k--)this._list[i=i+1+len&this._capacityMask]=void 0;return removed}if(index===0){this._head=this._head+count+len&this._capacityMask;for(k=count-1;k>0;k--)this._list[i=i+1+len&this._capacityMask]=void 0;return removed}if(i<size/2){this._head=this._head+index+count+len&this._capacityMask;for(k=index;k>0;k--)this.unshift(this._list[i=i-1+len&this._capacityMask]);i=this._head-1+len&this._capacityMask;while(del_count>0)this._list[i=i-1+len&this._capacityMask]=void 0,del_count--;if(index<0)this._tail=i}else{this._tail=i,i=i+count+len&this._capacityMask;for(k=size-(count+index);k>0;k--)this.push(this._list[i++]);i=this._tail;while(del_count>0)this._list[i=i+1+len&this._capacityMask]=void 0,del_count--}if(this._head<2&&this._tail>1e4&&this._tail<=len>>>2)this._shrinkArray();return removed};Denque.prototype.splice=function(index,count){var i=index;if(i!==(i|0))return;var size=this.size();if(i<0)i+=size;if(i>size)return;if(arguments.length>2){var k,temp,removed,arg_len=arguments.length,len=this._list.length,arguments_index=2;if(!size||i<size/2){temp=Array(i);for(k=0;k<i;k++)temp[k]=this._list[this._head+k&this._capacityMask];if(count===0){if(removed=[],i>0)this._head=this._head+i+len&this._capacityMask}else removed=this.remove(i,count),this._head=this._head+i+len&this._capacityMask;while(arg_len>arguments_index)this.unshift(arguments[--arg_len]);for(k=i;k>0;k--)this.unshift(temp[k-1])}else{temp=Array(size-(i+count));var leng=temp.length;for(k=0;k<leng;k++)temp[k]=this._list[this._head+i+count+k&this._capacityMask];if(count===0){if(removed=[],i!=size)this._tail=this._head+i+len&this._capacityMask}else removed=this.remove(i,count),this._tail=this._tail-leng+len&this._capacityMask;while(arguments_index<arg_len)this.push(arguments[arguments_index++]);for(k=0;k<leng;k++)this.push(temp[k])}return removed}else return this.remove(i,count)};Denque.prototype.clear=function(){this._list=Array(this._list.length),this._head=0,this._tail=0};Denque.prototype.isEmpty=function(){return this._head===this._tail};Denque.prototype.toArray=function(){return this._copyArray(!1)};Denque.prototype._fromArray=function(array){var length=array.length,capacity=this._nextPowerOf2(length);this._list=Array(capacity),this._capacityMask=capacity-1,this._tail=length;for(var i=0;i<length;i++)this._list[i]=array[i]};Denque.prototype._copyArray=function(fullCopy,size){var src=this._list,capacity=src.length,length=this.length;if(size=size|length,size==length&&this._head<this._tail)return this._list.slice(this._head,this._tail);var dest=Array(size),k=0,i;if(fullCopy||this._head>this._tail){for(i=this._head;i<capacity;i++)dest[k++]=src[i];for(i=0;i<this._tail;i++)dest[k++]=src[i]}else for(i=this._head;i<this._tail;i++)dest[k++]=src[i];return dest};Denque.prototype._growArray=function(){if(this._head!=0){var newList=this._copyArray(!0,this._list.length<<1);this._tail=this._list.length,this._head=0,this._list=newList}else this._tail=this._list.length,this._list.length<<=1;this._capacityMask=this._capacityMask<<1|1};Denque.prototype._shrinkArray=function(){this._list.length>>>=1,this._capacityMask>>>=1};Denque.prototype._nextPowerOf2=function(num){var log2=Math.log(num)/Math.log(2),nextPow2=1<<log2+1;return Math.max(nextPow2,4)};module.exports=Denque});var require_DelayQueue=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});var utils_1=require_utils2(),Deque=require_denque(),debug=(0,utils_1.Debug)("delayqueue");class DelayQueue{constructor(){this.queues={},this.timeouts={}}push(bucket,item,options){let callback=options.callback||process.nextTick;if(!this.queues[bucket])this.queues[bucket]=new Deque;if(this.queues[bucket].push(item),!this.timeouts[bucket])this.timeouts[bucket]=setTimeout(()=>{callback(()=>{this.timeouts[bucket]=null,this.execute(bucket)})},options.timeout)}execute(bucket){let queue=this.queues[bucket];if(!queue)return;let{length}=queue;if(!length)return;debug("send %d commands in %s queue",length,bucket),this.queues[bucket]=null;while(queue.length>0)queue.shift()()}}exports.default=DelayQueue});var require_ClusterSubscriberGroup=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});var utils_1=require_utils2(),ClusterSubscriber_1=require_ClusterSubscriber(),ConnectionPool_1=require_ConnectionPool(),util_1=require_util(),calculateSlot=require_lib(),debug=(0,utils_1.Debug)("cluster:subscriberGroup");class ClusterSubscriberGroup{constructor(cluster,refreshSlotsCacheCallback){this.cluster=cluster,this.shardedSubscribers=new Map,this.clusterSlots=[],this.subscriberToSlotsIndex=new Map,this.channels=new Map,cluster.on("+node",(redis)=>{this._addSubscriber(redis)}),cluster.on("-node",(redis)=>{this._removeSubscriber(redis)}),cluster.on("refresh",()=>{this._refreshSlots(cluster)}),cluster.on("forceRefresh",()=>{refreshSlotsCacheCallback()})}getResponsibleSubscriber(slot){let nodeKey=this.clusterSlots[slot][0];return this.shardedSubscribers.get(nodeKey)}addChannels(channels){let slot=calculateSlot(channels[0]);channels.forEach((c)=>{if(calculateSlot(c)!=slot)return-1});let currChannels=this.channels.get(slot);if(!currChannels)this.channels.set(slot,channels);else this.channels.set(slot,currChannels.concat(channels));return[...this.channels.values()].flatMap((v)=>v).length}removeChannels(channels){let slot=calculateSlot(channels[0]);channels.forEach((c)=>{if(calculateSlot(c)!=slot)return-1});let slotChannels=this.channels.get(slot);if(slotChannels){let updatedChannels=slotChannels.filter((c)=>!channels.includes(c));this.channels.set(slot,updatedChannels)}return[...this.channels.values()].flatMap((v)=>v).length}stop(){for(let s of this.shardedSubscribers.values())s.stop()}start(){for(let s of this.shardedSubscribers.values())if(!s.isStarted())s.start()}_addSubscriber(redis){let pool=new ConnectionPool_1.default(redis.options);if(pool.addMasterNode(redis)){let sub=new ClusterSubscriber_1.default(pool,this.cluster,!0),nodeKey=(0,util_1.getNodeKey)(redis.options);return this.shardedSubscribers.set(nodeKey,sub),sub.start(),this._resubscribe(),this.cluster.emit("+subscriber"),sub}return null}_removeSubscriber(redis){let nodeKey=(0,util_1.getNodeKey)(redis.options),sub=this.shardedSubscribers.get(nodeKey);if(sub)sub.stop(),this.shardedSubscribers.delete(nodeKey),this._resubscribe(),this.cluster.emit("-subscriber");return this.shardedSubscribers}_refreshSlots(cluster){if(this._slotsAreEqual(cluster.slots))debug("Nothing to refresh because the new cluster map is equal to the previous one.");else{debug("Refreshing the slots of the subscriber group."),this.subscriberToSlotsIndex=new Map;for(let slot=0;slot<cluster.slots.length;slot++){let node=cluster.slots[slot][0];if(!this.subscriberToSlotsIndex.has(node))this.subscriberToSlotsIndex.set(node,[]);this.subscriberToSlotsIndex.get(node).push(Number(slot))}return this._resubscribe(),this.clusterSlots=JSON.parse(JSON.stringify(cluster.slots)),this.cluster.emit("subscribersReady"),!0}return!1}_resubscribe(){if(this.shardedSubscribers)this.shardedSubscribers.forEach((s,nodeKey)=>{let subscriberSlots=this.subscriberToSlotsIndex.get(nodeKey);if(subscriberSlots)s.associateSlotRange(subscriberSlots),subscriberSlots.forEach((ss)=>{let redis=s.getInstance(),channels=this.channels.get(ss);if(channels&&channels.length>0){if(redis)redis.ssubscribe(channels),redis.on("ready",()=>{redis.ssubscribe(channels)})}})})}_slotsAreEqual(other){if(this.clusterSlots===void 0)return!1;else return JSON.stringify(this.clusterSlots)===JSON.stringify(other)}}exports.default=ClusterSubscriberGroup});var require_cluster=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});var commands_1=require_built(),events_1=__require("events"),redis_errors_1=require_redis_errors(),standard_as_callback_1=require_built2(),Command_1=require_Command(),ClusterAllFailedError_1=require_ClusterAllFailedError(),Redis_1=require_Redis(),ScanStream_1=require_ScanStream(),transaction_1=require_transaction(),utils_1=require_utils2(),applyMixin_1=require_applyMixin(),Commander_1=require_Commander(),ClusterOptions_1=require_ClusterOptions(),ClusterSubscriber_1=require_ClusterSubscriber(),ConnectionPool_1=require_ConnectionPool(),DelayQueue_1=require_DelayQueue(),util_1=require_util(),Deque=require_denque(),ClusterSubscriberGroup_1=require_ClusterSubscriberGroup(),debug=(0,utils_1.Debug)("cluster"),REJECT_OVERWRITTEN_COMMANDS=new WeakSet;class Cluster extends Commander_1.default{constructor(startupNodes,options={}){super();if(this.slots=[],this._groupsIds={},this._groupsBySlot=Array(16384),this.isCluster=!0,this.retryAttempts=0,this.delayQueue=new DelayQueue_1.default,this.offlineQueue=new Deque,this.isRefreshing=!1,this._refreshSlotsCacheCallbacks=[],this._autoPipelines=new Map,this._runningAutoPipelines=new Set,this._readyDelayedCallbacks=[],this.connectionEpoch=0,events_1.EventEmitter.call(this),this.startupNodes=startupNodes,this.options=(0,utils_1.defaults)({},options,ClusterOptions_1.DEFAULT_CLUSTER_OPTIONS,this.options),this.options.shardedSubscribers==!0)this.shardedSubscribers=new ClusterSubscriberGroup_1.default(this,this.refreshSlotsCache.bind(this));if(this.options.redisOptions&&this.options.redisOptions.keyPrefix&&!this.options.keyPrefix)this.options.keyPrefix=this.options.redisOptions.keyPrefix;if(typeof this.options.scaleReads!=="function"&&["all","master","slave"].indexOf(this.options.scaleReads)===-1)throw Error('Invalid option scaleReads "'+this.options.scaleReads+'". Expected "all", "master", "slave" or a custom function');if(this.connectionPool=new ConnectionPool_1.default(this.options.redisOptions),this.connectionPool.on("-node",(redis,key)=>{this.emit("-node",redis)}),this.connectionPool.on("+node",(redis)=>{this.emit("+node",redis)}),this.connectionPool.on("drain",()=>{this.setStatus("close")}),this.connectionPool.on("nodeError",(error,key)=>{this.emit("node error",error,key)}),this.subscriber=new ClusterSubscriber_1.default(this.connectionPool,this),this.options.scripts)Object.entries(this.options.scripts).forEach(([name,definition])=>{this.defineCommand(name,definition)});if(this.options.lazyConnect)this.setStatus("wait");else this.connect().catch((err)=>{debug("connecting failed: %s",err)})}connect(){return new Promise((resolve,reject)=>{if(this.status==="connecting"||this.status==="connect"||this.status==="ready"){reject(Error("Redis is already connecting/connected"));return}let epoch=++this.connectionEpoch;this.setStatus("connecting"),this.resolveStartupNodeHostnames().then((nodes)=>{if(this.connectionEpoch!==epoch){debug("discard connecting after resolving startup nodes because epoch not match: %d != %d",epoch,this.connectionEpoch),reject(new redis_errors_1.RedisError("Connection is discarded because a new connection is made"));return}if(this.status!=="connecting"){debug("discard connecting after resolving startup nodes because the status changed to %s",this.status),reject(new redis_errors_1.RedisError("Connection is aborted"));return}this.connectionPool.reset(nodes);let readyHandler=()=>{this.setStatus("ready"),this.retryAttempts=0,this.executeOfflineCommands(),this.resetNodesRefreshInterval(),resolve()},closeListener=void 0,refreshListener=()=>{if(this.invokeReadyDelayedCallbacks(void 0),this.removeListener("close",closeListener),this.manuallyClosing=!1,this.setStatus("connect"),this.options.enableReadyCheck)this.readyCheck((err,fail)=>{if(err||fail){if(debug("Ready check failed (%s). Reconnecting...",err||fail),this.status==="connect")this.disconnect(!0)}else readyHandler()});else readyHandler()};if(closeListener=()=>{let error=Error("None of startup nodes is available");this.removeListener("refresh",refreshListener),this.invokeReadyDelayedCallbacks(error),reject(error)},this.once("refresh",refreshListener),this.once("close",closeListener),this.once("close",this.handleCloseEvent.bind(this)),this.refreshSlotsCache((err)=>{if(err&&err.message===ClusterAllFailedError_1.default.defaultMessage)Redis_1.default.prototype.silentEmit.call(this,"error",err),this.connectionPool.reset([])}),this.subscriber.start(),this.options.shardedSubscribers)this.shardedSubscribers.start()}).catch((err)=>{this.setStatus("close"),this.handleCloseEvent(err),this.invokeReadyDelayedCallbacks(err),reject(err)})})}disconnect(reconnect=!1){let status=this.status;if(this.setStatus("disconnecting"),!reconnect)this.manuallyClosing=!0;if(this.reconnectTimeout&&!reconnect)clearTimeout(this.reconnectTimeout),this.reconnectTimeout=null,debug("Canceled reconnecting attempts");if(this.clearNodesRefreshInterval(),this.subscriber.stop(),this.options.shardedSubscribers)this.shardedSubscribers.stop();if(status==="wait")this.setStatus("close"),this.handleCloseEvent();else this.connectionPool.reset([])}quit(callback){let status=this.status;if(this.setStatus("disconnecting"),this.manuallyClosing=!0,this.reconnectTimeout)clearTimeout(this.reconnectTimeout),this.reconnectTimeout=null;if(this.clearNodesRefreshInterval(),this.subscriber.stop(),this.options.shardedSubscribers)this.shardedSubscribers.stop();if(status==="wait"){let ret=(0,standard_as_callback_1.default)(Promise.resolve("OK"),callback);return setImmediate(function(){this.setStatus("close"),this.handleCloseEvent()}.bind(this)),ret}return(0,standard_as_callback_1.default)(Promise.all(this.nodes().map((node)=>node.quit().catch((err)=>{if(err.message===utils_1.CONNECTION_CLOSED_ERROR_MSG)return"OK";throw err}))).then(()=>"OK"),callback)}duplicate(overrideStartupNodes=[],overrideOptions={}){let startupNodes=overrideStartupNodes.length>0?overrideStartupNodes:this.startupNodes.slice(0),options=Object.assign({},this.options,overrideOptions);return new Cluster(startupNodes,options)}nodes(role="all"){if(role!=="all"&&role!=="master"&&role!=="slave")throw Error('Invalid role "'+role+'". Expected "all", "master" or "slave"');return this.connectionPool.getNodes(role)}delayUntilReady(callback){this._readyDelayedCallbacks.push(callback)}get autoPipelineQueueSize(){let queued=0;for(let pipeline of this._autoPipelines.values())queued+=pipeline.length;return queued}refreshSlotsCache(callback){if(callback)this._refreshSlotsCacheCallbacks.push(callback);if(this.isRefreshing)return;this.isRefreshing=!0;let _this=this,wrapper=(error)=>{this.isRefreshing=!1;for(let callback2 of this._refreshSlotsCacheCallbacks)callback2(error);this._refreshSlotsCacheCallbacks=[]},nodes=(0,utils_1.shuffle)(this.connectionPool.getNodes()),lastNodeError=null;function tryNode(index){if(index===nodes.length){let error=new ClusterAllFailedError_1.default(ClusterAllFailedError_1.default.defaultMessage,lastNodeError);return wrapper(error)}let node=nodes[index],key=`${node.options.host}:${node.options.port}`;debug("getting slot cache from %s",key),_this.getInfoFromNode(node,function(err){switch(_this.status){case"close":case"end":return wrapper(Error("Cluster is disconnected."));case"disconnecting":return wrapper(Error("Cluster is disconnecting."))}if(err)_this.emit("node error",err,key),lastNodeError=err,tryNode(index+1);else _this.emit("refresh"),wrapper()})}tryNode(0)}sendCommand(command,stream,node){if(this.status==="wait")this.connect().catch(utils_1.noop);if(this.status==="end")return command.reject(Error(utils_1.CONNECTION_CLOSED_ERROR_MSG)),command.promise;let to=this.options.scaleReads;if(to!=="master"){if(!(command.isReadOnly||(0,commands_1.exists)(command.name)&&(0,commands_1.hasFlag)(command.name,"readonly")))to="master"}let targetSlot=node?node.slot:command.getSlot(),ttl={},_this=this;if(!node&&!REJECT_OVERWRITTEN_COMMANDS.has(command)){REJECT_OVERWRITTEN_COMMANDS.add(command);let reject=command.reject;command.reject=function(err){let partialTry=tryConnection.bind(null,!0);_this.handleError(err,ttl,{moved:function(slot,key){if(debug("command %s is moved to %s",command.name,key),targetSlot=Number(slot),_this.slots[slot])_this.slots[slot][0]=key;else _this.slots[slot]=[key];_this._groupsBySlot[slot]=_this._groupsIds[_this.slots[slot].join(";")],_this.connectionPool.findOrCreate(_this.natMapper(key)),tryConnection(),debug("refreshing slot caches... (triggered by MOVED error)"),_this.refreshSlotsCache()},ask:function(slot,key){debug("command %s is required to ask %s:%s",command.name,key);let mapped=_this.natMapper(key);_this.connectionPool.findOrCreate(mapped),tryConnection(!1,`${mapped.host}:${mapped.port}`)},tryagain:partialTry,clusterDown:partialTry,connectionClosed:partialTry,maxRedirections:function(redirectionError){reject.call(command,redirectionError)},defaults:function(){reject.call(command,err)}})}}tryConnection();function tryConnection(random,asking){if(_this.status==="end"){command.reject(new redis_errors_1.AbortError("Cluster is ended."));return}let redis;if(_this.status==="ready"||command.name==="cluster"){if(node&&node.redis)redis=node.redis;else if(Command_1.default.checkFlag("ENTER_SUBSCRIBER_MODE",command.name)||Command_1.default.checkFlag("EXIT_SUBSCRIBER_MODE",command.name)){if(_this.options.shardedSubscribers==!0&&(command.name=="ssubscribe"||command.name=="sunsubscribe")){let sub=_this.shardedSubscribers.getResponsibleSubscriber(targetSlot),status=-1;if(command.name=="ssubscribe")status=_this.shardedSubscribers.addChannels(command.getKeys());if(command.name=="sunsubscribe")status=_this.shardedSubscribers.removeChannels(command.getKeys());if(status!==-1)redis=sub.getInstance();else command.reject(new redis_errors_1.AbortError("Can't add or remove the given channels. Are they in the same slot?"))}else redis=_this.subscriber.getInstance();if(!redis){command.reject(new redis_errors_1.AbortError("No subscriber for the cluster"));return}}else{if(!random){if(typeof targetSlot==="number"&&_this.slots[targetSlot]){let nodeKeys=_this.slots[targetSlot];if(typeof to==="function"){let nodes=nodeKeys.map(function(key){return _this.connectionPool.getInstanceByKey(key)});if(redis=to(nodes,command),Array.isArray(redis))redis=(0,utils_1.sample)(redis);if(!redis)redis=nodes[0]}else{let key;if(to==="all")key=(0,utils_1.sample)(nodeKeys);else if(to==="slave"&&nodeKeys.length>1)key=(0,utils_1.sample)(nodeKeys,1);else key=nodeKeys[0];redis=_this.connectionPool.getInstanceByKey(key)}}if(asking)redis=_this.connectionPool.getInstanceByKey(asking),redis.asking()}if(!redis)redis=(typeof to==="function"?null:_this.connectionPool.getSampleInstance(to))||_this.connectionPool.getSampleInstance("all")}if(node&&!node.redis)node.redis=redis}if(redis)redis.sendCommand(command,stream);else if(_this.options.enableOfflineQueue)_this.offlineQueue.push({command,stream,node});else command.reject(Error("Cluster isn't ready and enableOfflineQueue options is false"))}return command.promise}sscanStream(key,options){return this.createScanStream("sscan",{key,options})}sscanBufferStream(key,options){return this.createScanStream("sscanBuffer",{key,options})}hscanStream(key,options){return this.createScanStream("hscan",{key,options})}hscanBufferStream(key,options){return this.createScanStream("hscanBuffer",{key,options})}zscanStream(key,options){return this.createScanStream("zscan",{key,options})}zscanBufferStream(key,options){return this.createScanStream("zscanBuffer",{key,options})}handleError(error,ttl,handlers){if(typeof ttl.value>"u")ttl.value=this.options.maxRedirections;else ttl.value-=1;if(ttl.value<=0){handlers.maxRedirections(Error("Too many Cluster redirections. Last error: "+error));return}let errv=error.message.split(" ");if(errv[0]==="MOVED"){let timeout=this.options.retryDelayOnMoved;if(timeout&&typeof timeout==="number")this.delayQueue.push("moved",handlers.moved.bind(null,errv[1],errv[2]),{timeout});else handlers.moved(errv[1],errv[2])}else if(errv[0]==="ASK")handlers.ask(errv[1],errv[2]);else if(errv[0]==="TRYAGAIN")this.delayQueue.push("tryagain",handlers.tryagain,{timeout:this.options.retryDelayOnTryAgain});else if(errv[0]==="CLUSTERDOWN"&&this.options.retryDelayOnClusterDown>0)this.delayQueue.push("clusterdown",handlers.connectionClosed,{timeout:this.options.retryDelayOnClusterDown,callback:this.refreshSlotsCache.bind(this)});else if(error.message===utils_1.CONNECTION_CLOSED_ERROR_MSG&&this.options.retryDelayOnFailover>0&&this.status==="ready")this.delayQueue.push("failover",handlers.connectionClosed,{timeout:this.options.retryDelayOnFailover,callback:this.refreshSlotsCache.bind(this)});else handlers.defaults()}resetOfflineQueue(){this.offlineQueue=new Deque}clearNodesRefreshInterval(){if(this.slotsTimer)clearTimeout(this.slotsTimer),this.slotsTimer=null}resetNodesRefreshInterval(){if(this.slotsTimer||!this.options.slotsRefreshInterval)return;let nextRound=()=>{this.slotsTimer=setTimeout(()=>{debug('refreshing slot caches... (triggered by "slotsRefreshInterval" option)'),this.refreshSlotsCache(()=>{nextRound()})},this.options.slotsRefreshInterval)};nextRound()}setStatus(status){debug("status: %s -> %s",this.status||"[empty]",status),this.status=status,process.nextTick(()=>{this.emit(status)})}handleCloseEvent(reason){if(reason)debug("closed because %s",reason);let retryDelay;if(!this.manuallyClosing&&typeof this.options.clusterRetryStrategy==="function")retryDelay=this.options.clusterRetryStrategy.call(this,++this.retryAttempts,reason);if(typeof retryDelay==="number")this.setStatus("reconnecting"),this.reconnectTimeout=setTimeout(()=>{this.reconnectTimeout=null,debug("Cluster is disconnected. Retrying after %dms",retryDelay),this.connect().catch(function(err){debug("Got error %s when reconnecting. Ignoring...",err)})},retryDelay);else this.setStatus("end"),this.flushQueue(Error("None of startup nodes is available"))}flushQueue(error){let item;while(item=this.offlineQueue.shift())item.command.reject(error)}executeOfflineCommands(){if(this.offlineQueue.length){debug("send %d commands in offline queue",this.offlineQueue.length);let offlineQueue=this.offlineQueue;this.resetOfflineQueue();let item;while(item=offlineQueue.shift())this.sendCommand(item.command,item.stream,item.node)}}natMapper(nodeKey){let key=typeof nodeKey==="string"?nodeKey:`${nodeKey.host}:${nodeKey.port}`,mapped=null;if(this.options.natMap&&typeof this.options.natMap==="function")mapped=this.options.natMap(key);else if(this.options.natMap&&typeof this.options.natMap==="object")mapped=this.options.natMap[key];if(mapped)return debug("NAT mapping %s -> %O",key,mapped),Object.assign({},mapped);return typeof nodeKey==="string"?(0,util_1.nodeKeyToRedisOptions)(nodeKey):nodeKey}getInfoFromNode(redis,callback){if(!redis)return callback(Error("Node is disconnected"));let duplicatedConnection=redis.duplicate({enableOfflineQueue:!0,enableReadyCheck:!1,retryStrategy:null,connectionName:(0,util_1.getConnectionName)("refresher",this.options.redisOptions&&this.options.redisOptions.connectionName)});duplicatedConnection.on("error",utils_1.noop),duplicatedConnection.cluster("SLOTS",(0,utils_1.timeout)((err,result)=>{if(duplicatedConnection.disconnect(),err)return debug("error encountered running CLUSTER.SLOTS: %s",err),callback(err);if(this.status==="disconnecting"||this.status==="close"||this.status==="end"){debug("ignore CLUSTER.SLOTS results (count: %d) since cluster status is %s",result.length,this.status),callback();return}let nodes=[];debug("cluster slots result count: %d",result.length);for(let i=0;i<result.length;++i){let items=result[i],slotRangeStart=items[0],slotRangeEnd=items[1],keys=[];for(let j2=2;j2<items.length;j2++){if(!items[j2][0])continue;let node=this.natMapper({host:items[j2][0],port:items[j2][1]});node.readOnly=j2!==2,nodes.push(node),keys.push(node.host+":"+node.port)}debug("cluster slots result [%d]: slots %d~%d served by %s",i,slotRangeStart,slotRangeEnd,keys);for(let slot=slotRangeStart;slot<=slotRangeEnd;slot++)this.slots[slot]=keys}this._groupsIds=Object.create(null);let j=0;for(let i=0;i<16384;i++){let target=(this.slots[i]||[]).join(";");if(!target.length){this._groupsBySlot[i]=void 0;continue}if(!this._groupsIds[target])this._groupsIds[target]=++j;this._groupsBySlot[i]=this._groupsIds[target]}this.connectionPool.reset(nodes),callback()},this.options.slotsRefreshTimeout))}invokeReadyDelayedCallbacks(err){for(let c of this._readyDelayedCallbacks)process.nextTick(c,err);this._readyDelayedCallbacks=[]}readyCheck(callback){this.cluster("INFO",(err,res)=>{if(err)return callback(err);if(typeof res!=="string")return callback();let state,lines=res.split(`\r
159
159
  `);for(let i=0;i<lines.length;++i){let parts=lines[i].split(":");if(parts[0]==="cluster_state"){state=parts[1];break}}if(state==="fail")debug("cluster state not ok (%s)",state),callback(null,state);else callback()})}resolveSrv(hostname){return new Promise((resolve,reject)=>{this.options.resolveSrv(hostname,(err,records)=>{if(err)return reject(err);let self=this,groupedRecords=(0,util_1.groupSrvRecords)(records),sortedKeys=Object.keys(groupedRecords).sort((a,b)=>parseInt(a)-parseInt(b));function tryFirstOne(err2){if(!sortedKeys.length)return reject(err2);let key=sortedKeys[0],group=groupedRecords[key],record=(0,util_1.weightSrvRecords)(group);if(!group.records.length)sortedKeys.shift();self.dnsLookup(record.name).then((host)=>resolve({host,port:record.port}),tryFirstOne)}tryFirstOne()})})}dnsLookup(hostname){return new Promise((resolve,reject)=>{this.options.dnsLookup(hostname,(err,address)=>{if(err)debug("failed to resolve hostname %s to IP: %s",hostname,err.message),reject(err);else debug("resolved hostname %s to IP %s",hostname,address),resolve(address)})})}async resolveStartupNodeHostnames(){if(!Array.isArray(this.startupNodes)||this.startupNodes.length===0)throw Error("`startupNodes` should contain at least one node.");let startupNodes=(0,util_1.normalizeNodeOptions)(this.startupNodes),hostnames=(0,util_1.getUniqueHostnamesFromOptions)(startupNodes);if(hostnames.length===0)return startupNodes;let configs=await Promise.all(hostnames.map((this.options.useSRVRecords?this.resolveSrv:this.dnsLookup).bind(this))),hostnameToConfig=(0,utils_1.zipMap)(hostnames,configs);return startupNodes.map((node)=>{let config=hostnameToConfig.get(node.host);if(!config)return node;if(this.options.useSRVRecords)return Object.assign({},node,config);return Object.assign({},node,{host:config})})}createScanStream(command,{key,options={}}){return new ScanStream_1.default({objectMode:!0,key,redis:this,command,...options})}}(0,applyMixin_1.default)(Cluster,events_1.EventEmitter);(0,transaction_1.addTransactionSupport)(Cluster.prototype);exports.default=Cluster});var require_AbstractConnector=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});var utils_1=require_utils2(),debug=(0,utils_1.Debug)("AbstractConnector");class AbstractConnector{constructor(disconnectTimeout){this.connecting=!1,this.disconnectTimeout=disconnectTimeout}check(info){return!0}disconnect(){if(this.connecting=!1,this.stream){let stream=this.stream,timeout=setTimeout(()=>{debug("stream %s:%s still open, destroying it",stream.remoteAddress,stream.remotePort),stream.destroy()},this.disconnectTimeout);stream.on("close",()=>clearTimeout(timeout)),stream.end()}}}exports.default=AbstractConnector});var require_StandaloneConnector=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});var net_1=__require("net"),tls_1=__require("tls"),utils_1=require_utils2(),AbstractConnector_1=require_AbstractConnector();class StandaloneConnector extends AbstractConnector_1.default{constructor(options){super(options.disconnectTimeout);this.options=options}connect(_){let{options}=this;this.connecting=!0;let connectionOptions;if("path"in options&&options.path)connectionOptions={path:options.path};else{if(connectionOptions={},"port"in options&&options.port!=null)connectionOptions.port=options.port;if("host"in options&&options.host!=null)connectionOptions.host=options.host;if("family"in options&&options.family!=null)connectionOptions.family=options.family}if(options.tls)Object.assign(connectionOptions,options.tls);return new Promise((resolve,reject)=>{process.nextTick(()=>{if(!this.connecting){reject(Error(utils_1.CONNECTION_CLOSED_ERROR_MSG));return}try{if(options.tls)this.stream=(0,tls_1.connect)(connectionOptions);else this.stream=(0,net_1.createConnection)(connectionOptions)}catch(err){reject(err);return}this.stream.once("error",(err)=>{this.firstError=err}),resolve(this.stream)})})}}exports.default=StandaloneConnector});var require_SentinelIterator=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});function isSentinelEql(a,b){return(a.host||"127.0.0.1")===(b.host||"127.0.0.1")&&(a.port||26379)===(b.port||26379)}class SentinelIterator{constructor(sentinels){this.cursor=0,this.sentinels=sentinels.slice(0)}next(){let done=this.cursor>=this.sentinels.length;return{done,value:done?void 0:this.sentinels[this.cursor++]}}reset(moveCurrentEndpointToFirst){if(moveCurrentEndpointToFirst&&this.sentinels.length>1&&this.cursor!==1)this.sentinels.unshift(...this.sentinels.splice(this.cursor-1));this.cursor=0}add(sentinel){for(let i=0;i<this.sentinels.length;i++)if(isSentinelEql(sentinel,this.sentinels[i]))return!1;return this.sentinels.push(sentinel),!0}toString(){return`${JSON.stringify(this.sentinels)} @${this.cursor}`}}exports.default=SentinelIterator});var require_FailoverDetector=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});exports.FailoverDetector=void 0;var utils_1=require_utils2(),debug=(0,utils_1.Debug)("FailoverDetector"),CHANNEL_NAME="+switch-master";class FailoverDetector{constructor(connector,sentinels){this.isDisconnected=!1,this.connector=connector,this.sentinels=sentinels}cleanup(){this.isDisconnected=!0;for(let sentinel of this.sentinels)sentinel.client.disconnect()}async subscribe(){debug("Starting FailoverDetector");let promises=[];for(let sentinel of this.sentinels){let promise=sentinel.client.subscribe(CHANNEL_NAME).catch((err)=>{debug("Failed to subscribe to failover messages on sentinel %s:%s (%s)",sentinel.address.host||"127.0.0.1",sentinel.address.port||26739,err.message)});promises.push(promise),sentinel.client.on("message",(channel)=>{if(!this.isDisconnected&&channel===CHANNEL_NAME)this.disconnect()})}await Promise.all(promises)}disconnect(){this.isDisconnected=!0,debug("Failover detected, disconnecting"),this.connector.disconnect()}}exports.FailoverDetector=FailoverDetector});var require_SentinelConnector=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});exports.SentinelIterator=void 0;var net_1=__require("net"),utils_1=require_utils2(),tls_1=__require("tls"),SentinelIterator_1=require_SentinelIterator();exports.SentinelIterator=SentinelIterator_1.default;var AbstractConnector_1=require_AbstractConnector(),Redis_1=require_Redis(),FailoverDetector_1=require_FailoverDetector(),debug=(0,utils_1.Debug)("SentinelConnector");class SentinelConnector extends AbstractConnector_1.default{constructor(options){super(options.disconnectTimeout);if(this.options=options,this.emitter=null,this.failoverDetector=null,!this.options.sentinels.length)throw Error("Requires at least one sentinel to connect to.");if(!this.options.name)throw Error("Requires the name of master.");this.sentinelIterator=new SentinelIterator_1.default(this.options.sentinels)}check(info){let roleMatches=!info.role||this.options.role===info.role;if(!roleMatches)debug("role invalid, expected %s, but got %s",this.options.role,info.role),this.sentinelIterator.next(),this.sentinelIterator.next(),this.sentinelIterator.reset(!0);return roleMatches}disconnect(){if(super.disconnect(),this.failoverDetector)this.failoverDetector.cleanup()}connect(eventEmitter){this.connecting=!0,this.retryAttempts=0;let lastError,connectToNext=async()=>{let endpoint=this.sentinelIterator.next();if(endpoint.done){this.sentinelIterator.reset(!1);let retryDelay=typeof this.options.sentinelRetryStrategy==="function"?this.options.sentinelRetryStrategy(++this.retryAttempts):null,errorMsg=typeof retryDelay!=="number"?"All sentinels are unreachable and retry is disabled.":`All sentinels are unreachable. Retrying from scratch after ${retryDelay}ms.`;if(lastError)errorMsg+=` Last error: ${lastError.message}`;debug(errorMsg);let error=Error(errorMsg);if(typeof retryDelay==="number")return eventEmitter("error",error),await new Promise((resolve)=>setTimeout(resolve,retryDelay)),connectToNext();else throw error}let resolved=null,err=null;try{resolved=await this.resolve(endpoint.value)}catch(error){err=error}if(!this.connecting)throw Error(utils_1.CONNECTION_CLOSED_ERROR_MSG);let endpointAddress=endpoint.value.host+":"+endpoint.value.port;if(resolved){if(debug("resolved: %s:%s from sentinel %s",resolved.host,resolved.port,endpointAddress),this.options.enableTLSForSentinelMode&&this.options.tls)Object.assign(resolved,this.options.tls),this.stream=(0,tls_1.connect)(resolved),this.stream.once("secureConnect",this.initFailoverDetector.bind(this));else this.stream=(0,net_1.createConnection)(resolved),this.stream.once("connect",this.initFailoverDetector.bind(this));return this.stream.once("error",(err2)=>{this.firstError=err2}),this.stream}else{let errorMsg=err?"failed to connect to sentinel "+endpointAddress+" because "+err.message:"connected to sentinel "+endpointAddress+" successfully, but got an invalid reply: "+resolved;if(debug(errorMsg),eventEmitter("sentinelError",Error(errorMsg)),err)lastError=err;return connectToNext()}};return connectToNext()}async updateSentinels(client){if(!this.options.updateSentinels)return;let result=await client.sentinel("sentinels",this.options.name);if(!Array.isArray(result))return;result.map(utils_1.packObject).forEach((sentinel)=>{if((sentinel.flags?sentinel.flags.split(","):[]).indexOf("disconnected")===-1&&sentinel.ip&&sentinel.port){let endpoint=this.sentinelNatResolve(addressResponseToAddress(sentinel));if(this.sentinelIterator.add(endpoint))debug("adding sentinel %s:%s",endpoint.host,endpoint.port)}}),debug("Updated internal sentinels: %s",this.sentinelIterator)}async resolveMaster(client){let result=await client.sentinel("get-master-addr-by-name",this.options.name);return await this.updateSentinels(client),this.sentinelNatResolve(Array.isArray(result)?{host:result[0],port:Number(result[1])}:null)}async resolveSlave(client){let result=await client.sentinel("slaves",this.options.name);if(!Array.isArray(result))return null;let availableSlaves=result.map(utils_1.packObject).filter((slave)=>slave.flags&&!slave.flags.match(/(disconnected|s_down|o_down)/));return this.sentinelNatResolve(selectPreferredSentinel(availableSlaves,this.options.preferredSlaves))}sentinelNatResolve(item){if(!item||!this.options.natMap)return item;let key=`${item.host}:${item.port}`,result=item;if(typeof this.options.natMap==="function")result=this.options.natMap(key)||item;else if(typeof this.options.natMap==="object")result=this.options.natMap[key]||item;return result}connectToSentinel(endpoint,options){return new Redis_1.default({port:endpoint.port||26379,host:endpoint.host,username:this.options.sentinelUsername||null,password:this.options.sentinelPassword||null,family:endpoint.family||("path"in this.options&&this.options.path?void 0:this.options.family),tls:this.options.sentinelTLS,retryStrategy:null,enableReadyCheck:!1,connectTimeout:this.options.connectTimeout,commandTimeout:this.options.sentinelCommandTimeout,...options})}async resolve(endpoint){let client=this.connectToSentinel(endpoint);client.on("error",noop);try{if(this.options.role==="slave")return await this.resolveSlave(client);else return await this.resolveMaster(client)}finally{client.disconnect()}}async initFailoverDetector(){var _a;if(!this.options.failoverDetector)return;this.sentinelIterator.reset(!0);let sentinels=[];while(sentinels.length<this.options.sentinelMaxConnections){let{done,value}=this.sentinelIterator.next();if(done)break;let client=this.connectToSentinel(value,{lazyConnect:!0,retryStrategy:this.options.sentinelReconnectStrategy});client.on("reconnecting",()=>{var _a2;(_a2=this.emitter)===null||_a2===void 0||_a2.emit("sentinelReconnecting")}),sentinels.push({address:value,client})}if(this.sentinelIterator.reset(!1),this.failoverDetector)this.failoverDetector.cleanup();this.failoverDetector=new FailoverDetector_1.FailoverDetector(this,sentinels),await this.failoverDetector.subscribe(),(_a=this.emitter)===null||_a===void 0||_a.emit("failoverSubscribed")}}exports.default=SentinelConnector;function selectPreferredSentinel(availableSlaves,preferredSlaves){if(availableSlaves.length===0)return null;let selectedSlave;if(typeof preferredSlaves==="function")selectedSlave=preferredSlaves(availableSlaves);else if(preferredSlaves!==null&&typeof preferredSlaves==="object"){let preferredSlavesArray=Array.isArray(preferredSlaves)?preferredSlaves:[preferredSlaves];preferredSlavesArray.sort((a,b)=>{if(!a.prio)a.prio=1;if(!b.prio)b.prio=1;if(a.prio<b.prio)return-1;if(a.prio>b.prio)return 1;return 0});for(let p=0;p<preferredSlavesArray.length;p++){for(let a=0;a<availableSlaves.length;a++){let slave=availableSlaves[a];if(slave.ip===preferredSlavesArray[p].ip){if(slave.port===preferredSlavesArray[p].port){selectedSlave=slave;break}}}if(selectedSlave)break}}if(!selectedSlave)selectedSlave=(0,utils_1.sample)(availableSlaves);return addressResponseToAddress(selectedSlave)}function addressResponseToAddress(input){return{host:input.ip,port:Number(input.port)}}function noop(){}});var require_connectors=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});exports.SentinelConnector=exports.StandaloneConnector=void 0;var StandaloneConnector_1=require_StandaloneConnector();exports.StandaloneConnector=StandaloneConnector_1.default;var SentinelConnector_1=require_SentinelConnector();exports.SentinelConnector=SentinelConnector_1.default});var require_MaxRetriesPerRequestError=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});var redis_errors_1=require_redis_errors();class MaxRetriesPerRequestError extends redis_errors_1.AbortError{constructor(maxRetriesPerRequest){let message=`Reached the max retries per request limit (which is ${maxRetriesPerRequest}). Refer to "maxRetriesPerRequest" option for details.`;super(message);Error.captureStackTrace(this,this.constructor)}get name(){return this.constructor.name}}exports.default=MaxRetriesPerRequestError});var require_errors=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});exports.MaxRetriesPerRequestError=void 0;var MaxRetriesPerRequestError_1=require_MaxRetriesPerRequestError();exports.MaxRetriesPerRequestError=MaxRetriesPerRequestError_1.default});var require_parser=__commonJS((exports,module)=>{var Buffer2=__require("buffer").Buffer,StringDecoder=__require("string_decoder").StringDecoder,decoder=new StringDecoder,errors=require_redis_errors(),ReplyError=errors.ReplyError,ParserError=errors.ParserError,bufferPool=Buffer2.allocUnsafe(32768),bufferOffset=0,interval=null,counter=0,notDecreased=0;function parseSimpleNumbers(parser){let length=parser.buffer.length-1;var offset=parser.offset,number=0,sign=1;if(parser.buffer[offset]===45)sign=-1,offset++;while(offset<length){let c1=parser.buffer[offset++];if(c1===13)return parser.offset=offset+1,sign*number;number=number*10+(c1-48)}}function parseStringNumbers(parser){let length=parser.buffer.length-1;var offset=parser.offset,number=0,res="";if(parser.buffer[offset]===45)res+="-",offset++;while(offset<length){var c1=parser.buffer[offset++];if(c1===13){if(parser.offset=offset+1,number!==0)res+=number;return res}else if(number>429496728)res+=number*10+(c1-48),number=0;else if(c1===48&&number===0)res+=0;else number=number*10+(c1-48)}}function parseSimpleString(parser){let{offset:start,buffer}=parser,length=buffer.length-1;var offset=start;while(offset<length)if(buffer[offset++]===13){if(parser.offset=offset+1,parser.optionReturnBuffers===!0)return parser.buffer.slice(start,offset-1);return parser.buffer.toString("utf8",start,offset-1)}}function parseLength(parser){let length=parser.buffer.length-1;var offset=parser.offset,number=0;while(offset<length){let c1=parser.buffer[offset++];if(c1===13)return parser.offset=offset+1,number;number=number*10+(c1-48)}}function parseInteger(parser){if(parser.optionStringNumbers===!0)return parseStringNumbers(parser);return parseSimpleNumbers(parser)}function parseBulkString(parser){let length=parseLength(parser);if(length===void 0)return;if(length<0)return null;let offset=parser.offset+length;if(offset+2>parser.buffer.length){parser.bigStrSize=offset+2,parser.totalChunkSize=parser.buffer.length,parser.bufferCache.push(parser.buffer);return}let start=parser.offset;if(parser.offset=offset+2,parser.optionReturnBuffers===!0)return parser.buffer.slice(start,offset);return parser.buffer.toString("utf8",start,offset)}function parseError(parser){var string=parseSimpleString(parser);if(string!==void 0){if(parser.optionReturnBuffers===!0)string=string.toString();return new ReplyError(string)}}function handleError(parser,type){let err=new ParserError("Protocol error, got "+JSON.stringify(String.fromCharCode(type))+" as reply type byte",JSON.stringify(parser.buffer),parser.offset);parser.buffer=null,parser.returnFatalError(err)}function parseArray(parser){let length=parseLength(parser);if(length===void 0)return;if(length<0)return null;let responses=Array(length);return parseArrayElements(parser,responses,0)}function pushArrayCache(parser,array,pos){parser.arrayCache.push(array),parser.arrayPos.push(pos)}function parseArrayChunks(parser){let tmp=parser.arrayCache.pop();var pos=parser.arrayPos.pop();if(parser.arrayCache.length){let res=parseArrayChunks(parser);if(res===void 0){pushArrayCache(parser,tmp,pos);return}tmp[pos++]=res}return parseArrayElements(parser,tmp,pos)}function parseArrayElements(parser,responses,i){let bufferLength=parser.buffer.length;while(i<responses.length){let offset=parser.offset;if(parser.offset>=bufferLength){pushArrayCache(parser,responses,i);return}let response=parseType(parser,parser.buffer[parser.offset++]);if(response===void 0){if(!(parser.arrayCache.length||parser.bufferCache.length))parser.offset=offset;pushArrayCache(parser,responses,i);return}responses[i]=response,i++}return responses}function parseType(parser,type){switch(type){case 36:return parseBulkString(parser);case 43:return parseSimpleString(parser);case 42:return parseArray(parser);case 58:return parseInteger(parser);case 45:return parseError(parser);default:return handleError(parser,type)}}function decreaseBufferPool(){if(bufferPool.length>51200)if(counter===1||notDecreased>counter*2){let minSliceLen=Math.floor(bufferPool.length/10),sliceLength=minSliceLen<bufferOffset?bufferOffset:minSliceLen;bufferOffset=0,bufferPool=bufferPool.slice(sliceLength,bufferPool.length)}else notDecreased++,counter--;else clearInterval(interval),counter=0,notDecreased=0,interval=null}function resizeBuffer(length){if(bufferPool.length<length+bufferOffset){let multiplier=length>78643200?2:3;if(bufferOffset>116391936)bufferOffset=52428800;if(bufferPool=Buffer2.allocUnsafe(length*multiplier+bufferOffset),bufferOffset=0,counter++,interval===null)interval=setInterval(decreaseBufferPool,50)}}function concatBulkString(parser){let{bufferCache:list,offset:oldOffset}=parser;var chunks=list.length,offset=parser.bigStrSize-parser.totalChunkSize;if(parser.offset=offset,offset<=2){if(chunks===2)return list[0].toString("utf8",oldOffset,list[0].length+offset-2);chunks--,offset=list[list.length-2].length+offset}var res=decoder.write(list[0].slice(oldOffset));for(var i=1;i<chunks-1;i++)res+=decoder.write(list[i]);return res+=decoder.end(list[i].slice(0,offset-2)),res}function concatBulkBuffer(parser){let{bufferCache:list,offset:oldOffset}=parser,length=parser.bigStrSize-oldOffset-2;var chunks=list.length,offset=parser.bigStrSize-parser.totalChunkSize;if(parser.offset=offset,offset<=2){if(chunks===2)return list[0].slice(oldOffset,list[0].length+offset-2);chunks--,offset=list[list.length-2].length+offset}resizeBuffer(length);let start=bufferOffset;list[0].copy(bufferPool,start,oldOffset,list[0].length),bufferOffset+=list[0].length-oldOffset;for(var i=1;i<chunks-1;i++)list[i].copy(bufferPool,bufferOffset),bufferOffset+=list[i].length;return list[i].copy(bufferPool,bufferOffset,0,offset-2),bufferOffset+=offset-2,bufferPool.slice(start,bufferOffset)}class JavascriptRedisParser{constructor(options){if(!options)throw TypeError("Options are mandatory.");if(typeof options.returnError!=="function"||typeof options.returnReply!=="function")throw TypeError("The returnReply and returnError options have to be functions.");this.setReturnBuffers(!!options.returnBuffers),this.setStringNumbers(!!options.stringNumbers),this.returnError=options.returnError,this.returnFatalError=options.returnFatalError||options.returnError,this.returnReply=options.returnReply,this.reset()}reset(){this.offset=0,this.buffer=null,this.bigStrSize=0,this.totalChunkSize=0,this.bufferCache=[],this.arrayCache=[],this.arrayPos=[]}setReturnBuffers(returnBuffers){if(typeof returnBuffers!=="boolean")throw TypeError("The returnBuffers argument has to be a boolean");this.optionReturnBuffers=returnBuffers}setStringNumbers(stringNumbers){if(typeof stringNumbers!=="boolean")throw TypeError("The stringNumbers argument has to be a boolean");this.optionStringNumbers=stringNumbers}execute(buffer){if(this.buffer===null)this.buffer=buffer,this.offset=0;else if(this.bigStrSize===0){let oldLength=this.buffer.length,remainingLength=oldLength-this.offset,newBuffer=Buffer2.allocUnsafe(remainingLength+buffer.length);if(this.buffer.copy(newBuffer,0,this.offset,oldLength),buffer.copy(newBuffer,remainingLength,0,buffer.length),this.buffer=newBuffer,this.offset=0,this.arrayCache.length){let arr=parseArrayChunks(this);if(arr===void 0)return;this.returnReply(arr)}}else if(this.totalChunkSize+buffer.length>=this.bigStrSize){this.bufferCache.push(buffer);var tmp=this.optionReturnBuffers?concatBulkBuffer(this):concatBulkString(this);if(this.bigStrSize=0,this.bufferCache=[],this.buffer=buffer,this.arrayCache.length){if(this.arrayCache[0][this.arrayPos[0]++]=tmp,tmp=parseArrayChunks(this),tmp===void 0)return}this.returnReply(tmp)}else{this.bufferCache.push(buffer),this.totalChunkSize+=buffer.length;return}while(this.offset<this.buffer.length){let offset=this.offset,type=this.buffer[this.offset++],response=parseType(this,type);if(response===void 0){if(!(this.arrayCache.length||this.bufferCache.length))this.offset=offset;return}if(type===45)this.returnError(response);else this.returnReply(response)}this.buffer=null}}module.exports=JavascriptRedisParser});var require_SubscriptionSet=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});class SubscriptionSet{constructor(){this.set={subscribe:{},psubscribe:{},ssubscribe:{}}}add(set,channel){this.set[mapSet(set)][channel]=!0}del(set,channel){delete this.set[mapSet(set)][channel]}channels(set){return Object.keys(this.set[mapSet(set)])}isEmpty(){return this.channels("subscribe").length===0&&this.channels("psubscribe").length===0&&this.channels("ssubscribe").length===0}}exports.default=SubscriptionSet;function mapSet(set){if(set==="unsubscribe")return"subscribe";if(set==="punsubscribe")return"psubscribe";if(set==="sunsubscribe")return"ssubscribe";return set}});var require_DataHandler=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});var Command_1=require_Command(),utils_1=require_utils2(),RedisParser=require_parser(),SubscriptionSet_1=require_SubscriptionSet(),debug=(0,utils_1.Debug)("dataHandler");class DataHandler{constructor(redis,parserOptions){this.redis=redis;let parser=new RedisParser({stringNumbers:parserOptions.stringNumbers,returnBuffers:!0,returnError:(err)=>{this.returnError(err)},returnFatalError:(err)=>{this.returnFatalError(err)},returnReply:(reply)=>{this.returnReply(reply)}});redis.stream.prependListener("data",(data)=>{parser.execute(data)}),redis.stream.resume()}returnFatalError(err){err.message+=". Please report this.",this.redis.recoverFromFatalError(err,err,{offlineQueue:!1})}returnError(err){let item=this.shiftCommand(err);if(!item)return;if(err.command={name:item.command.name,args:item.command.args},item.command.name=="ssubscribe"&&err.message.includes("MOVED")){this.redis.emit("moved");return}this.redis.handleReconnection(err,item)}returnReply(reply){if(this.handleMonitorReply(reply))return;if(this.handleSubscriberReply(reply))return;let item=this.shiftCommand(reply);if(!item)return;if(Command_1.default.checkFlag("ENTER_SUBSCRIBER_MODE",item.command.name)){if(this.redis.condition.subscriber=new SubscriptionSet_1.default,this.redis.condition.subscriber.add(item.command.name,reply[1].toString()),!fillSubCommand(item.command,reply[2]))this.redis.commandQueue.unshift(item)}else if(Command_1.default.checkFlag("EXIT_SUBSCRIBER_MODE",item.command.name)){if(!fillUnsubCommand(item.command,reply[2]))this.redis.commandQueue.unshift(item)}else item.command.resolve(reply)}handleSubscriberReply(reply){if(!this.redis.condition.subscriber)return!1;let replyType=Array.isArray(reply)?reply[0].toString():null;switch(debug('receive reply "%s" in subscriber mode',replyType),replyType){case"message":if(this.redis.listeners("message").length>0)this.redis.emit("message",reply[1].toString(),reply[2]?reply[2].toString():"");this.redis.emit("messageBuffer",reply[1],reply[2]);break;case"pmessage":{let pattern=reply[1].toString();if(this.redis.listeners("pmessage").length>0)this.redis.emit("pmessage",pattern,reply[2].toString(),reply[3].toString());this.redis.emit("pmessageBuffer",pattern,reply[2],reply[3]);break}case"smessage":{if(this.redis.listeners("smessage").length>0)this.redis.emit("smessage",reply[1].toString(),reply[2]?reply[2].toString():"");this.redis.emit("smessageBuffer",reply[1],reply[2]);break}case"ssubscribe":case"subscribe":case"psubscribe":{let channel=reply[1].toString();this.redis.condition.subscriber.add(replyType,channel);let item=this.shiftCommand(reply);if(!item)return;if(!fillSubCommand(item.command,reply[2]))this.redis.commandQueue.unshift(item);break}case"sunsubscribe":case"unsubscribe":case"punsubscribe":{let channel=reply[1]?reply[1].toString():null;if(channel)this.redis.condition.subscriber.del(replyType,channel);let count=reply[2];if(Number(count)===0)this.redis.condition.subscriber=!1;let item=this.shiftCommand(reply);if(!item)return;if(!fillUnsubCommand(item.command,count))this.redis.commandQueue.unshift(item);break}default:{let item=this.shiftCommand(reply);if(!item)return;item.command.resolve(reply)}}return!0}handleMonitorReply(reply){if(this.redis.status!=="monitoring")return!1;let replyStr=reply.toString();if(replyStr==="OK")return!1;let len=replyStr.indexOf(" "),timestamp=replyStr.slice(0,len),argIndex=replyStr.indexOf('"'),args=replyStr.slice(argIndex+1,-1).split('" "').map((elem)=>elem.replace(/\\"/g,'"')),dbAndSource=replyStr.slice(len+2,argIndex-2).split(" ");return this.redis.emit("monitor",timestamp,args,dbAndSource[1],dbAndSource[0]),!0}shiftCommand(reply){let item=this.redis.commandQueue.shift();if(!item){let error=Error("Command queue state error. If you can reproduce this, please report it."+(reply instanceof Error?` Last error: ${reply.message}`:` Last reply: ${reply.toString()}`));return this.redis.emit("error",error),null}return item}}exports.default=DataHandler;var remainingRepliesMap=new WeakMap;function fillSubCommand(command,count){let remainingReplies=remainingRepliesMap.has(command)?remainingRepliesMap.get(command):command.args.length;if(remainingReplies-=1,remainingReplies<=0)return command.resolve(count),remainingRepliesMap.delete(command),!0;return remainingRepliesMap.set(command,remainingReplies),!1}function fillUnsubCommand(command,count){let remainingReplies=remainingRepliesMap.has(command)?remainingRepliesMap.get(command):command.args.length;if(remainingReplies===0){if(Number(count)===0)return remainingRepliesMap.delete(command),command.resolve(count),!0;return!1}if(remainingReplies-=1,remainingReplies<=0)return command.resolve(count),!0;return remainingRepliesMap.set(command,remainingReplies),!1}});var require_event_handler=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});exports.readyHandler=exports.errorHandler=exports.closeHandler=exports.connectHandler=void 0;var redis_errors_1=require_redis_errors(),Command_1=require_Command(),errors_1=require_errors(),utils_1=require_utils2(),DataHandler_1=require_DataHandler(),debug=(0,utils_1.Debug)("connection");function connectHandler(self){return function(){var _a;self.setStatus("connect"),self.resetCommandQueue();let flushed=!1,{connectionEpoch}=self;if(self.condition.auth)self.auth(self.condition.auth,function(err){if(connectionEpoch!==self.connectionEpoch)return;if(err)if(err.message.indexOf("no password is set")!==-1)console.warn("[WARN] Redis server does not require a password, but a password was supplied.");else if(err.message.indexOf("without any password configured for the default user")!==-1)console.warn("[WARN] This Redis server's `default` user does not require a password, but a password was supplied");else if(err.message.indexOf("wrong number of arguments for 'auth' command")!==-1)console.warn(`[ERROR] The server returned "wrong number of arguments for 'auth' command". You are probably passing both username and password to Redis version 5 or below. You should only pass the 'password' option for Redis version 5 and under.`);else flushed=!0,self.recoverFromFatalError(err,err)});if(self.condition.select)self.select(self.condition.select).catch((err)=>{self.silentEmit("error",err)});new DataHandler_1.default(self,{stringNumbers:self.options.stringNumbers});let clientCommandPromises=[];if(self.options.connectionName)debug("set the connection name [%s]",self.options.connectionName),clientCommandPromises.push(self.client("setname",self.options.connectionName).catch(utils_1.noop));if(!self.options.disableClientInfo)debug("set the client info"),clientCommandPromises.push((0,utils_1.getPackageMeta)().then((packageMeta)=>{return self.client("SETINFO","LIB-VER",packageMeta.version).catch(utils_1.noop)}).catch(utils_1.noop)),clientCommandPromises.push(self.client("SETINFO","LIB-NAME",((_a=self.options)===null||_a===void 0?void 0:_a.clientInfoTag)?`ioredis(${self.options.clientInfoTag})`:"ioredis").catch(utils_1.noop));Promise.all(clientCommandPromises).catch(utils_1.noop).finally(()=>{if(!self.options.enableReadyCheck)exports.readyHandler(self)();if(self.options.enableReadyCheck)self._readyCheck(function(err,info){if(connectionEpoch!==self.connectionEpoch)return;if(err){if(!flushed)self.recoverFromFatalError(Error("Ready check failed: "+err.message),err)}else if(self.connector.check(info))exports.readyHandler(self)();else self.disconnect(!0)})})}}exports.connectHandler=connectHandler;function abortError(command){let err=new redis_errors_1.AbortError("Command aborted due to connection close");return err.command={name:command.name,args:command.args},err}function abortIncompletePipelines(commandQueue){var _a;let expectedIndex=0;for(let i=0;i<commandQueue.length;){let command=(_a=commandQueue.peekAt(i))===null||_a===void 0?void 0:_a.command,pipelineIndex=command.pipelineIndex;if(pipelineIndex===void 0||pipelineIndex===0)expectedIndex=0;if(pipelineIndex!==void 0&&pipelineIndex!==expectedIndex++){commandQueue.remove(i,1),command.reject(abortError(command));continue}i++}}function abortTransactionFragments(commandQueue){var _a;for(let i=0;i<commandQueue.length;){let command=(_a=commandQueue.peekAt(i))===null||_a===void 0?void 0:_a.command;if(command.name==="multi")break;if(command.name==="exec"){commandQueue.remove(i,1),command.reject(abortError(command));break}if(command.inTransaction)commandQueue.remove(i,1),command.reject(abortError(command));else i++}}function closeHandler(self){return function(){let prevStatus=self.status;if(self.setStatus("close"),self.commandQueue.length)abortIncompletePipelines(self.commandQueue);if(self.offlineQueue.length)abortTransactionFragments(self.offlineQueue);if(prevStatus==="ready"){if(!self.prevCondition)self.prevCondition=self.condition;if(self.commandQueue.length)self.prevCommandQueue=self.commandQueue}if(self.manuallyClosing)return self.manuallyClosing=!1,debug("skip reconnecting since the connection is manually closed."),close();if(typeof self.options.retryStrategy!=="function")return debug("skip reconnecting because `retryStrategy` is not a function"),close();let retryDelay=self.options.retryStrategy(++self.retryAttempts);if(typeof retryDelay!=="number")return debug("skip reconnecting because `retryStrategy` doesn't return a number"),close();debug("reconnect in %sms",retryDelay),self.setStatus("reconnecting",retryDelay),self.reconnectTimeout=setTimeout(function(){self.reconnectTimeout=null,self.connect().catch(utils_1.noop)},retryDelay);let{maxRetriesPerRequest}=self.options;if(typeof maxRetriesPerRequest==="number"){if(maxRetriesPerRequest<0)debug("maxRetriesPerRequest is negative, ignoring...");else if(self.retryAttempts%(maxRetriesPerRequest+1)===0)debug("reach maxRetriesPerRequest limitation, flushing command queue..."),self.flushQueue(new errors_1.MaxRetriesPerRequestError(maxRetriesPerRequest))}};function close(){self.setStatus("end"),self.flushQueue(Error(utils_1.CONNECTION_CLOSED_ERROR_MSG))}}exports.closeHandler=closeHandler;function errorHandler(self){return function(error){debug("error: %s",error),self.silentEmit("error",error)}}exports.errorHandler=errorHandler;function readyHandler(self){return function(){if(self.setStatus("ready"),self.retryAttempts=0,self.options.monitor){self.call("monitor").then(()=>self.setStatus("monitoring"),(error)=>self.emit("error",error));let{sendCommand}=self;self.sendCommand=function(command){if(Command_1.default.checkFlag("VALID_IN_MONITOR_MODE",command.name))return sendCommand.call(self,command);return command.reject(Error("Connection is in monitoring mode, can't process commands.")),command.promise},self.once("close",function(){delete self.sendCommand});return}let finalSelect=self.prevCondition?self.prevCondition.select:self.condition.select;if(self.options.readOnly)debug("set the connection to readonly mode"),self.readonly().catch(utils_1.noop);if(self.prevCondition){let condition=self.prevCondition;if(self.prevCondition=null,condition.subscriber&&self.options.autoResubscribe){if(self.condition.select!==finalSelect)debug("connect to db [%d]",finalSelect),self.select(finalSelect);let subscribeChannels=condition.subscriber.channels("subscribe");if(subscribeChannels.length)debug("subscribe %d channels",subscribeChannels.length),self.subscribe(subscribeChannels);let psubscribeChannels=condition.subscriber.channels("psubscribe");if(psubscribeChannels.length)debug("psubscribe %d channels",psubscribeChannels.length),self.psubscribe(psubscribeChannels);let ssubscribeChannels=condition.subscriber.channels("ssubscribe");if(ssubscribeChannels.length){debug("ssubscribe %s",ssubscribeChannels.length);for(let channel of ssubscribeChannels)self.ssubscribe(channel)}}}if(self.prevCommandQueue)if(self.options.autoResendUnfulfilledCommands){debug("resend %d unfulfilled commands",self.prevCommandQueue.length);while(self.prevCommandQueue.length>0){let item=self.prevCommandQueue.shift();if(item.select!==self.condition.select&&item.command.name!=="select")self.select(item.select);self.sendCommand(item.command,item.stream)}}else self.prevCommandQueue=null;if(self.offlineQueue.length){debug("send %d commands in offline queue",self.offlineQueue.length);let offlineQueue=self.offlineQueue;self.resetOfflineQueue();while(offlineQueue.length>0){let item=offlineQueue.shift();if(item.select!==self.condition.select&&item.command.name!=="select")self.select(item.select);self.sendCommand(item.command,item.stream)}}if(self.condition.select!==finalSelect)debug("connect to db [%d]",finalSelect),self.select(finalSelect)}}exports.readyHandler=readyHandler});var require_RedisOptions=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});exports.DEFAULT_REDIS_OPTIONS=void 0;exports.DEFAULT_REDIS_OPTIONS={port:6379,host:"localhost",family:0,connectTimeout:1e4,disconnectTimeout:2000,retryStrategy:function(times){return Math.min(times*50,2000)},keepAlive:0,noDelay:!0,connectionName:null,disableClientInfo:!1,clientInfoTag:void 0,sentinels:null,name:null,role:"master",sentinelRetryStrategy:function(times){return Math.min(times*10,1000)},sentinelReconnectStrategy:function(){return 60000},natMap:null,enableTLSForSentinelMode:!1,updateSentinels:!0,failoverDetector:!1,username:null,password:null,db:0,enableOfflineQueue:!0,enableReadyCheck:!0,autoResubscribe:!0,autoResendUnfulfilledCommands:!0,lazyConnect:!1,keyPrefix:"",reconnectOnError:null,readOnly:!1,stringNumbers:!1,maxRetriesPerRequest:20,maxLoadingRetryTime:1e4,enableAutoPipelining:!1,autoPipeliningIgnoredCommands:[],sentinelMaxConnections:10}});var require_Redis=__commonJS((exports)=>{Object.defineProperty(exports,"__esModule",{value:!0});var commands_1=require_built(),events_1=__require("events"),standard_as_callback_1=require_built2(),cluster_1=require_cluster(),Command_1=require_Command(),connectors_1=require_connectors(),SentinelConnector_1=require_SentinelConnector(),eventHandler=require_event_handler(),RedisOptions_1=require_RedisOptions(),ScanStream_1=require_ScanStream(),transaction_1=require_transaction(),utils_1=require_utils2(),applyMixin_1=require_applyMixin(),Commander_1=require_Commander(),lodash_1=require_lodash3(),Deque=require_denque(),debug=(0,utils_1.Debug)("redis");class Redis extends Commander_1.default{constructor(arg1,arg2,arg3){super();if(this.status="wait",this.isCluster=!1,this.reconnectTimeout=null,this.connectionEpoch=0,this.retryAttempts=0,this.manuallyClosing=!1,this._autoPipelines=new Map,this._runningAutoPipelines=new Set,this.parseOptions(arg1,arg2,arg3),events_1.EventEmitter.call(this),this.resetCommandQueue(),this.resetOfflineQueue(),this.options.Connector)this.connector=new this.options.Connector(this.options);else if(this.options.sentinels){let sentinelConnector=new SentinelConnector_1.default(this.options);sentinelConnector.emitter=this,this.connector=sentinelConnector}else this.connector=new connectors_1.StandaloneConnector(this.options);if(this.options.scripts)Object.entries(this.options.scripts).forEach(([name,definition])=>{this.defineCommand(name,definition)});if(this.options.lazyConnect)this.setStatus("wait");else this.connect().catch(lodash_1.noop)}static createClient(...args){return new Redis(...args)}get autoPipelineQueueSize(){let queued=0;for(let pipeline of this._autoPipelines.values())queued+=pipeline.length;return queued}connect(callback){let promise=new Promise((resolve,reject)=>{if(this.status==="connecting"||this.status==="connect"||this.status==="ready"){reject(Error("Redis is already connecting/connected"));return}this.connectionEpoch+=1,this.setStatus("connecting");let{options}=this;this.condition={select:options.db,auth:options.username?[options.username,options.password]:options.password,subscriber:!1};let _this=this;(0,standard_as_callback_1.default)(this.connector.connect(function(type,err){_this.silentEmit(type,err)}),function(err,stream){if(err){_this.flushQueue(err),_this.silentEmit("error",err),reject(err),_this.setStatus("end");return}let CONNECT_EVENT=options.tls?"secureConnect":"connect";if("sentinels"in options&&options.sentinels&&!options.enableTLSForSentinelMode)CONNECT_EVENT="connect";if(_this.stream=stream,options.noDelay)stream.setNoDelay(!0);if(typeof options.keepAlive==="number")if(stream.connecting)stream.once(CONNECT_EVENT,()=>{stream.setKeepAlive(!0,options.keepAlive)});else stream.setKeepAlive(!0,options.keepAlive);if(stream.connecting){if(stream.once(CONNECT_EVENT,eventHandler.connectHandler(_this)),options.connectTimeout){let connectTimeoutCleared=!1;stream.setTimeout(options.connectTimeout,function(){if(connectTimeoutCleared)return;stream.setTimeout(0),stream.destroy();let err2=Error("connect ETIMEDOUT");err2.errorno="ETIMEDOUT",err2.code="ETIMEDOUT",err2.syscall="connect",eventHandler.errorHandler(_this)(err2)}),stream.once(CONNECT_EVENT,function(){connectTimeoutCleared=!0,stream.setTimeout(0)})}}else if(stream.destroyed){let firstError=_this.connector.firstError;if(firstError)process.nextTick(()=>{eventHandler.errorHandler(_this)(firstError)});process.nextTick(eventHandler.closeHandler(_this))}else process.nextTick(eventHandler.connectHandler(_this));if(!stream.destroyed)stream.once("error",eventHandler.errorHandler(_this)),stream.once("close",eventHandler.closeHandler(_this));let connectionReadyHandler=function(){_this.removeListener("close",connectionCloseHandler),resolve()};var connectionCloseHandler=function(){_this.removeListener("ready",connectionReadyHandler),reject(Error(utils_1.CONNECTION_CLOSED_ERROR_MSG))};_this.once("ready",connectionReadyHandler),_this.once("close",connectionCloseHandler)})});return(0,standard_as_callback_1.default)(promise,callback)}disconnect(reconnect=!1){if(!reconnect)this.manuallyClosing=!0;if(this.reconnectTimeout&&!reconnect)clearTimeout(this.reconnectTimeout),this.reconnectTimeout=null;if(this.status==="wait")eventHandler.closeHandler(this)();else this.connector.disconnect()}end(){this.disconnect()}duplicate(override){return new Redis({...this.options,...override})}get mode(){var _a;return this.options.monitor?"monitor":((_a=this.condition)===null||_a===void 0?void 0:_a.subscriber)?"subscriber":"normal"}monitor(callback){let monitorInstance=this.duplicate({monitor:!0,lazyConnect:!1});return(0,standard_as_callback_1.default)(new Promise(function(resolve,reject){monitorInstance.once("error",reject),monitorInstance.once("monitoring",function(){resolve(monitorInstance)})}),callback)}sendCommand(command,stream){var _a,_b;if(this.status==="wait")this.connect().catch(lodash_1.noop);if(this.status==="end")return command.reject(Error(utils_1.CONNECTION_CLOSED_ERROR_MSG)),command.promise;if(((_a=this.condition)===null||_a===void 0?void 0:_a.subscriber)&&!Command_1.default.checkFlag("VALID_IN_SUBSCRIBER_MODE",command.name))return command.reject(Error("Connection in subscriber mode, only subscriber commands may be used")),command.promise;if(typeof this.options.commandTimeout==="number")command.setTimeout(this.options.commandTimeout);let writable=this.status==="ready"||!stream&&this.status==="connect"&&(0,commands_1.exists)(command.name)&&((0,commands_1.hasFlag)(command.name,"loading")||Command_1.default.checkFlag("HANDSHAKE_COMMANDS",command.name));if(!this.stream)writable=!1;else if(!this.stream.writable)writable=!1;else if(this.stream._writableState&&this.stream._writableState.ended)writable=!1;if(!writable){if(!this.options.enableOfflineQueue)return command.reject(Error("Stream isn't writeable and enableOfflineQueue options is false")),command.promise;if(command.name==="quit"&&this.offlineQueue.length===0)return this.disconnect(),command.resolve(Buffer.from("OK")),command.promise;if(debug.enabled)debug("queue command[%s]: %d -> %s(%o)",this._getDescription(),this.condition.select,command.name,command.args);this.offlineQueue.push({command,stream,select:this.condition.select})}else{if(debug.enabled)debug("write command[%s]: %d -> %s(%o)",this._getDescription(),(_b=this.condition)===null||_b===void 0?void 0:_b.select,command.name,command.args);if(stream)if("isPipeline"in stream&&stream.isPipeline)stream.write(command.toWritable(stream.destination.redis.stream));else stream.write(command.toWritable(stream));else this.stream.write(command.toWritable(this.stream));if(this.commandQueue.push({command,stream,select:this.condition.select}),Command_1.default.checkFlag("WILL_DISCONNECT",command.name))this.manuallyClosing=!0;if(this.options.socketTimeout!==void 0&&this.socketTimeoutTimer===void 0)this.setSocketTimeout()}if(command.name==="select"&&(0,utils_1.isInt)(command.args[0])){let db=parseInt(command.args[0],10);if(this.condition.select!==db)this.condition.select=db,this.emit("select",db),debug("switch to db [%d]",this.condition.select)}return command.promise}setSocketTimeout(){this.socketTimeoutTimer=setTimeout(()=>{this.stream.destroy(Error(`Socket timeout. Expecting data, but didn't receive any in ${this.options.socketTimeout}ms.`)),this.socketTimeoutTimer=void 0},this.options.socketTimeout),this.stream.once("data",()=>{if(clearTimeout(this.socketTimeoutTimer),this.socketTimeoutTimer=void 0,this.commandQueue.length===0)return;this.setSocketTimeout()})}scanStream(options){return this.createScanStream("scan",{options})}scanBufferStream(options){return this.createScanStream("scanBuffer",{options})}sscanStream(key,options){return this.createScanStream("sscan",{key,options})}sscanBufferStream(key,options){return this.createScanStream("sscanBuffer",{key,options})}hscanStream(key,options){return this.createScanStream("hscan",{key,options})}hscanBufferStream(key,options){return this.createScanStream("hscanBuffer",{key,options})}zscanStream(key,options){return this.createScanStream("zscan",{key,options})}zscanBufferStream(key,options){return this.createScanStream("zscanBuffer",{key,options})}silentEmit(eventName,arg){let error;if(eventName==="error"){if(error=arg,this.status==="end")return;if(this.manuallyClosing){if(error instanceof Error&&(error.message===utils_1.CONNECTION_CLOSED_ERROR_MSG||error.syscall==="connect"||error.syscall==="read"))return}}if(this.listeners(eventName).length>0)return this.emit.apply(this,arguments);if(error&&error instanceof Error)console.error("[ioredis] Unhandled error event:",error.stack);return!1}recoverFromFatalError(_commandError,err,options){this.flushQueue(err,options),this.silentEmit("error",err),this.disconnect(!0)}handleReconnection(err,item){var _a;let needReconnect=!1;if(this.options.reconnectOnError&&!Command_1.default.checkFlag("IGNORE_RECONNECT_ON_ERROR",item.command.name))needReconnect=this.options.reconnectOnError(err);switch(needReconnect){case 1:case!0:if(this.status!=="reconnecting")this.disconnect(!0);item.command.reject(err);break;case 2:if(this.status!=="reconnecting")this.disconnect(!0);if(((_a=this.condition)===null||_a===void 0?void 0:_a.select)!==item.select&&item.command.name!=="select")this.select(item.select);this.sendCommand(item.command);break;default:item.command.reject(err)}}_getDescription(){let description;if("path"in this.options&&this.options.path)description=this.options.path;else if(this.stream&&this.stream.remoteAddress&&this.stream.remotePort)description=this.stream.remoteAddress+":"+this.stream.remotePort;else if("host"in this.options&&this.options.host)description=this.options.host+":"+this.options.port;else description="";if(this.options.connectionName)description+=` (${this.options.connectionName})`;return description}resetCommandQueue(){this.commandQueue=new Deque}resetOfflineQueue(){this.offlineQueue=new Deque}parseOptions(...args){let options={},isTls=!1;for(let i=0;i<args.length;++i){let arg=args[i];if(arg===null||typeof arg>"u")continue;if(typeof arg==="object")(0,lodash_1.defaults)(options,arg);else if(typeof arg==="string"){if((0,lodash_1.defaults)(options,(0,utils_1.parseURL)(arg)),arg.startsWith("rediss://"))isTls=!0}else if(typeof arg==="number")options.port=arg;else throw Error("Invalid argument "+arg)}if(isTls)(0,lodash_1.defaults)(options,{tls:!0});if((0,lodash_1.defaults)(options,Redis.defaultOptions),typeof options.port==="string")options.port=parseInt(options.port,10);if(typeof options.db==="string")options.db=parseInt(options.db,10);this.options=(0,utils_1.resolveTLSProfile)(options)}setStatus(status,arg){if(debug.enabled)debug("status[%s]: %s -> %s",this._getDescription(),this.status||"[empty]",status);this.status=status,process.nextTick(this.emit.bind(this,status,arg))}createScanStream(command,{key,options={}}){return new ScanStream_1.default({objectMode:!0,key,redis:this,command,...options})}flushQueue(error,options){options=(0,lodash_1.defaults)({},options,{offlineQueue:!0,commandQueue:!0});let item;if(options.offlineQueue)while(item=this.offlineQueue.shift())item.command.reject(error);if(options.commandQueue){if(this.commandQueue.length>0){if(this.stream)this.stream.removeAllListeners("data");while(item=this.commandQueue.shift())item.command.reject(error)}}}_readyCheck(callback){let _this=this;this.info(function(err,res){if(err){if(err.message&&err.message.includes("NOPERM"))return console.warn(`Skipping the ready check because INFO command fails: "${err.message}". You can disable ready check with "enableReadyCheck". More: https://github.com/luin/ioredis/wiki/Disable-ready-check.`),callback(null,{});return callback(err)}if(typeof res!=="string")return callback(null,res);let info={},lines=res.split(`\r
160
- `);for(let i=0;i<lines.length;++i){let[fieldName,...fieldValueParts]=lines[i].split(":"),fieldValue=fieldValueParts.join(":");if(fieldValue)info[fieldName]=fieldValue}if(!info.loading||info.loading==="0")callback(null,info);else{let loadingEtaMs=(info.loading_eta_seconds||1)*1000,retryTime=_this.options.maxLoadingRetryTime&&_this.options.maxLoadingRetryTime<loadingEtaMs?_this.options.maxLoadingRetryTime:loadingEtaMs;debug("Redis server still loading, trying again in "+retryTime+"ms"),setTimeout(function(){_this._readyCheck(callback)},retryTime)}}).catch(lodash_1.noop)}}Redis.Cluster=cluster_1.default;Redis.Command=Command_1.default;Redis.defaultOptions=RedisOptions_1.DEFAULT_REDIS_OPTIONS;(0,applyMixin_1.default)(Redis,events_1.EventEmitter);(0,transaction_1.addTransactionSupport)(Redis.prototype);exports.default=Redis});var require_built3=__commonJS((exports,module)=>{Object.defineProperty(exports,"__esModule",{value:!0});exports.print=exports.ReplyError=exports.SentinelIterator=exports.SentinelConnector=exports.AbstractConnector=exports.Pipeline=exports.ScanStream=exports.Command=exports.Cluster=exports.Redis=exports.default=void 0;exports=module.exports=require_Redis().default;var Redis_1=require_Redis();Object.defineProperty(exports,"default",{enumerable:!0,get:function(){return Redis_1.default}});var Redis_2=require_Redis();Object.defineProperty(exports,"Redis",{enumerable:!0,get:function(){return Redis_2.default}});var cluster_1=require_cluster();Object.defineProperty(exports,"Cluster",{enumerable:!0,get:function(){return cluster_1.default}});var Command_1=require_Command();Object.defineProperty(exports,"Command",{enumerable:!0,get:function(){return Command_1.default}});var ScanStream_1=require_ScanStream();Object.defineProperty(exports,"ScanStream",{enumerable:!0,get:function(){return ScanStream_1.default}});var Pipeline_1=require_Pipeline();Object.defineProperty(exports,"Pipeline",{enumerable:!0,get:function(){return Pipeline_1.default}});var AbstractConnector_1=require_AbstractConnector();Object.defineProperty(exports,"AbstractConnector",{enumerable:!0,get:function(){return AbstractConnector_1.default}});var SentinelConnector_1=require_SentinelConnector();Object.defineProperty(exports,"SentinelConnector",{enumerable:!0,get:function(){return SentinelConnector_1.default}});Object.defineProperty(exports,"SentinelIterator",{enumerable:!0,get:function(){return SentinelConnector_1.SentinelIterator}});exports.ReplyError=require_redis_errors().ReplyError;Object.defineProperty(exports,"Promise",{get(){return console.warn("ioredis v5 does not support plugging third-party Promise library anymore. Native Promise will be used."),Promise},set(_lib){console.warn("ioredis v5 does not support plugging third-party Promise library anymore. Native Promise will be used.")}});function print(err,reply){if(err)console.log("Error: "+err);else console.log("Reply: "+reply)}exports.print=print});import"reflect-metadata";var CONTROLLER_META=Symbol("turbo:controller"),ROUTES_META=Symbol("turbo:routes"),PARAMS_META=Symbol("turbo:params"),MIDDLEWARE_META=Symbol("turbo:middleware"),SERVICE_META=Symbol("turbo:service"),INJECT_META=Symbol("turbo:inject");var ASYNC_REGEX=/^async\s|^\([^)]*\)\s*=>\s*\{[\s\S]*await\s|^function\s*\*|\.then\s*\(/;function isAsyncFunction(fn){if(fn.constructor.name==="AsyncFunction")return!0;let source=fn.toString();return ASYNC_REGEX.test(source)}function isStaticHandler(fn){let source=fn.toString();if(source.includes("this.")||source.includes("await"))return!1;return!!source.match(/=>\s*["'`]|return\s+["'`]|=>\s*\{|=>\s*\d/)}function compileHandler(instance,methodName,params){let method=instance[methodName],bound=method.bind(instance),async=isAsyncFunction(method);if(params.length===0){if(isStaticHandler(method)&&!async){let staticValue=bound();return{fn:bound,isAsync:!1,isStatic:!0,staticValue}}return{fn:bound,isAsync:async,isStatic:!1}}let argsCode=params.sort((a,b)=>a.index-b.index).map((p)=>buildArgExpression(p)).join(",");if(params.some((p)=>p.type==="body")){let code2=`return async function(c){
160
+ `);for(let i=0;i<lines.length;++i){let[fieldName,...fieldValueParts]=lines[i].split(":"),fieldValue=fieldValueParts.join(":");if(fieldValue)info[fieldName]=fieldValue}if(!info.loading||info.loading==="0")callback(null,info);else{let loadingEtaMs=(info.loading_eta_seconds||1)*1000,retryTime=_this.options.maxLoadingRetryTime&&_this.options.maxLoadingRetryTime<loadingEtaMs?_this.options.maxLoadingRetryTime:loadingEtaMs;debug("Redis server still loading, trying again in "+retryTime+"ms"),setTimeout(function(){_this._readyCheck(callback)},retryTime)}}).catch(lodash_1.noop)}}Redis.Cluster=cluster_1.default;Redis.Command=Command_1.default;Redis.defaultOptions=RedisOptions_1.DEFAULT_REDIS_OPTIONS;(0,applyMixin_1.default)(Redis,events_1.EventEmitter);(0,transaction_1.addTransactionSupport)(Redis.prototype);exports.default=Redis});var require_built3=__commonJS((exports,module)=>{Object.defineProperty(exports,"__esModule",{value:!0});exports.print=exports.ReplyError=exports.SentinelIterator=exports.SentinelConnector=exports.AbstractConnector=exports.Pipeline=exports.ScanStream=exports.Command=exports.Cluster=exports.Redis=exports.default=void 0;exports=module.exports=require_Redis().default;var Redis_1=require_Redis();Object.defineProperty(exports,"default",{enumerable:!0,get:function(){return Redis_1.default}});var Redis_2=require_Redis();Object.defineProperty(exports,"Redis",{enumerable:!0,get:function(){return Redis_2.default}});var cluster_1=require_cluster();Object.defineProperty(exports,"Cluster",{enumerable:!0,get:function(){return cluster_1.default}});var Command_1=require_Command();Object.defineProperty(exports,"Command",{enumerable:!0,get:function(){return Command_1.default}});var ScanStream_1=require_ScanStream();Object.defineProperty(exports,"ScanStream",{enumerable:!0,get:function(){return ScanStream_1.default}});var Pipeline_1=require_Pipeline();Object.defineProperty(exports,"Pipeline",{enumerable:!0,get:function(){return Pipeline_1.default}});var AbstractConnector_1=require_AbstractConnector();Object.defineProperty(exports,"AbstractConnector",{enumerable:!0,get:function(){return AbstractConnector_1.default}});var SentinelConnector_1=require_SentinelConnector();Object.defineProperty(exports,"SentinelConnector",{enumerable:!0,get:function(){return SentinelConnector_1.default}});Object.defineProperty(exports,"SentinelIterator",{enumerable:!0,get:function(){return SentinelConnector_1.SentinelIterator}});exports.ReplyError=require_redis_errors().ReplyError;Object.defineProperty(exports,"Promise",{get(){return console.warn("ioredis v5 does not support plugging third-party Promise library anymore. Native Promise will be used."),Promise},set(_lib){console.warn("ioredis v5 does not support plugging third-party Promise library anymore. Native Promise will be used.")}});function print(err,reply){if(err)console.log("Error: "+err);else console.log("Reply: "+reply)}exports.print=print});import"reflect-metadata";import"reflect-metadata";var CONTROLLER_META=Symbol("turbo:controller"),ROUTES_META=Symbol("turbo:routes"),PARAMS_META=Symbol("turbo:params"),MIDDLEWARE_META=Symbol("turbo:middleware"),SERVICE_META=Symbol("turbo:service"),INJECT_META=Symbol("turbo:inject");var ASYNC_REGEX=/^async\s|^\([^)]*\)\s*=>\s*\{[\s\S]*await\s|^function\s*\*|\.then\s*\(/;function isAsyncFunction(fn){if(fn.constructor.name==="AsyncFunction")return!0;let source=fn.toString();return ASYNC_REGEX.test(source)}function isStaticHandler(fn){let source=fn.toString();if(source.includes("this.")||source.includes("await"))return!1;return!!source.match(/=>\s*["'`]|return\s+["'`]|=>\s*\{|=>\s*\d/)}function compileHandler(instance,methodName,params){let method=instance[methodName],bound=method.bind(instance),async=isAsyncFunction(method);if(params.length===0){if(isStaticHandler(method)&&!async){let staticValue=bound();return{fn:bound,isAsync:!1,isStatic:!0,staticValue}}return{fn:bound,isAsync:async,isStatic:!1}}let argsCode=params.sort((a,b)=>a.index-b.index).map((p)=>buildArgExpression(p)).join(",");if(params.some((p)=>p.type==="body")){let code2=`return async function(c){
161
161
  await c.parseBody();
162
162
  return h(${argsCode});
163
163
  }`;return{fn:Function("h",code2)(bound),isAsync:!0,isStatic:!1}}if(async){let code2=`return async function(c){
@@ -166,5 +166,5 @@ return await h(${argsCode});
166
166
  return h(${argsCode});
167
167
  }`;return{fn:Function("h",code)(bound),isAsync:!1,isStatic:!1}}function escapeKey(key){return key.replace(/['\"\\]/g,"\\$&")}function buildArgExpression(param){let key=param.key?escapeKey(param.key):void 0;switch(param.type){case"param":return key?`c.params['${key}']`:"c.params";case"query":return key?`c.query['${key}']`:"c.query";case"body":return key?`c.body['${key}']`:"c.body";case"header":return key?`c.req.headers.get('${key}')`:"c.req.headers";case"req":return"c.req";case"ctx":return"c";case"locals":return key?`c.locals['${key}']`:"c.locals";default:return"undefined"}}function parseQueryFromURL(url){let queryStart=url.indexOf("?");if(queryStart===-1)return Object.create(null);let queryEnd=url.indexOf("#",queryStart);if(queryEnd===-1)queryEnd=url.length;return parseQuery(url,queryStart+1,queryEnd)}function parseQuery(input,startIndex,endIndex){let result=Object.create(null),flags=0,startingIndex=startIndex-1,equalityIndex=startingIndex;for(let i=startIndex;i<endIndex;i++)switch(input.charCodeAt(i)){case 38:processKeyValuePair(i),startingIndex=i,equalityIndex=i,flags=0;break;case 61:if(equalityIndex<=startingIndex)equalityIndex=i;else flags|=8;break;case 43:if(equalityIndex>startingIndex)flags|=4;else flags|=1;break;case 37:if(equalityIndex>startingIndex)flags|=8;else flags|=2;break}if(startingIndex<endIndex)processKeyValuePair(endIndex);return result;function processKeyValuePair(pairEndIndex){let hasBothKeyValuePair=equalityIndex>startingIndex,effectiveEqualityIndex=hasBothKeyValuePair?equalityIndex:pairEndIndex,keySlice=input.slice(startingIndex+1,effectiveEqualityIndex);if(!hasBothKeyValuePair&&keySlice.length===0)return;let finalKey=keySlice;if(flags&1)finalKey=finalKey.replace(/\+/g," ");if(flags&2)try{finalKey=decodeURIComponent(finalKey)}catch{}let finalValue="";if(hasBothKeyValuePair){let valueSlice=input.slice(equalityIndex+1,pairEndIndex);if(flags&4)valueSlice=valueSlice.replace(/\+/g," ");if(flags&8)try{finalValue=decodeURIComponent(valueSlice)}catch{finalValue=valueSlice}else finalValue=valueSlice}result[finalKey]=finalValue}}var EMPTY_PARAMS=Object.freeze({});class Context{req;params;locals={};_query=null;_body;_bodyParsed=!1;_url=null;_status=0;constructor(req,params=EMPTY_PARAMS){this.req=req,this.params=params}get status(){return this._status||200}set status(value){this._status=value}get url(){if(!this._url)this._url=new URL(this.req.url);return this._url}get query(){if(!this._query)this._query=parseQueryFromURL(this.req.url);return this._query}get body(){return this._body}async parseBody(){if(this._bodyParsed)return this._body;this._bodyParsed=!0;let contentType=this.req.headers.get("content-type")||"";if(contentType.includes("application/json"))this._body=await this.req.json();else if(contentType.includes("form")){let formData=await this.req.formData();this._body=Object.fromEntries(formData)}else if(contentType.includes("text"))this._body=await this.req.text();else this._body=await this.req.arrayBuffer();return this._body}get method(){return this.req.method}get headers(){return this.req.headers}get path(){return this.url.pathname}json(data,status){if(status)this.status=status;return Response.json(data,{status:this.status})}text(data,status){if(status)this.status=status;return new Response(data,{status:this.status,headers:{"Content-Type":"text/plain"}})}html(data,status){if(status)this.status=status;return new Response(data,{status:this.status,headers:{"Content-Type":"text/html"}})}redirect(url,status=302){return Response.redirect(url,status)}static createFromJob(job){let fakeRequest=new Request("http://localhost/job"),ctx=new Context(fakeRequest);return ctx.locals.job=job,ctx}}var Scope;((Scope2)=>{Scope2.SINGLETON="singleton";Scope2.REQUEST="request";Scope2.INSTANCE="instance"})(Scope||={});class Container{configs=new Map;instances=new Map;resolving=new Set;register(config){let normalized=this.normalizeConfig(config);if(this.configs.set(normalized.token,normalized),normalized.useValue!==void 0)this.instances.set(normalized.token,normalized.useValue);return this}get(token){let cached=this.instances.get(token);if(cached!==void 0)return cached;return this.resolveInternal(token).instance}has(token){return this.configs.has(token)}resolveInternal(token,requestLocals){if(requestLocals?.has(token))return{instance:requestLocals.get(token),scope:"request"};let cached=this.instances.get(token);if(cached!==void 0)return{instance:cached,scope:"singleton"};let config=this.configs.get(token);if(!config)throw Error(`Provider not found: ${token.name}`);let creation=this.createInstance(config,requestLocals);if(creation.scope==="singleton")this.instances.set(token,creation.instance);else if(creation.scope==="request"&&requestLocals)requestLocals.set(token,creation.instance);return creation}createInstance(config,requestLocals){let target=config.useClass??config.token;if(this.resolving.has(target))throw Error(`Circular dependency detected: ${target.name}`);this.resolving.add(target);try{let depsToken=this.getDependencies(target);if(depsToken.length===0)return{instance:new target,scope:config.scope||"singleton"};let args=[],effectiveScope=config.scope||"singleton";for(let depToken of depsToken){let depResult=this.resolveInternal(depToken,requestLocals);if(args.push(depResult.instance),depResult.scope==="request"&&effectiveScope==="singleton")effectiveScope="request"}return{instance:new target(...args),scope:effectiveScope}}finally{this.resolving.delete(target)}}getDependencies(target){return(Reflect.getMetadata("design:paramtypes",target)||[]).filter((t)=>t&&typeof t==="function"&&!this.isPrimitive(t))}isPrimitive(type){return type===String||type===Number||type===Boolean||type===Object||type===Array||type===Symbol}normalizeConfig(config){if(typeof config==="function")return{token:config,useClass:config,scope:"singleton"};return{...config,useClass:config.useClass??config.token,scope:config.scope??"singleton"}}clear(){this.configs.clear(),this.instances.clear()}}var DEFAULT_CORS_METHODS=["GET","HEAD","PUT","PATCH","POST","DELETE"],DEFAULT_CORS_HEADERS=["Content-Type","Authorization","X-Requested-With","Accept","Origin"];class CorsHandler{cache=new Map;methodsStr;headersStr;exposedStr;maxAgeStr;hasCredentials;isWildcard;matcher;preflightResponse=null;constructor(config){if(this.methodsStr=(config.methods||DEFAULT_CORS_METHODS).join(", "),this.headersStr=(config.allowedHeaders||DEFAULT_CORS_HEADERS).join(", "),this.exposedStr=config.exposedHeaders?.join(", ")||null,this.maxAgeStr=config.maxAge?.toString()||null,this.hasCredentials=!!config.credentials,this.isWildcard=config.origins==="*",this.matcher=this.buildMatcher(config.origins),this.isWildcard)this.preflightResponse=new Response(null,{status:204,headers:this.buildHeaders("*")})}preflight(origin){if(this.isWildcard&&this.preflightResponse)return this.preflightResponse.clone();if(!this.isAllowed(origin))return new Response(null,{status:403});return new Response(null,{status:204,headers:this.getHeaders(origin)})}apply(response,origin){if(!this.isAllowed(origin))return response;let headers=this.getHeaders(origin);for(let[key,value]of Object.entries(headers))response.headers.set(key,value);return response}isAllowed(origin){return this.matcher(origin)}getHeaders(origin){let key=this.isWildcard?"*":origin,headers=this.cache.get(key);if(!headers)headers=this.buildHeaders(origin),this.cache.set(key,headers);return headers}buildHeaders(origin){let headers={"Access-Control-Allow-Origin":this.isWildcard?"*":origin,"Access-Control-Allow-Methods":this.methodsStr,"Access-Control-Allow-Headers":this.headersStr};if(this.hasCredentials)headers["Access-Control-Allow-Credentials"]="true";if(this.exposedStr)headers["Access-Control-Expose-Headers"]=this.exposedStr;if(this.maxAgeStr)headers["Access-Control-Max-Age"]=this.maxAgeStr;return headers}buildMatcher(origins){if(origins==="*")return()=>!0;if(typeof origins==="string")return(o)=>o===origins;if(Array.isArray(origins)){let set=new Set(origins);return(o)=>set.has(o)}if(origins instanceof RegExp)return(o)=>origins.test(o);if(typeof origins==="function")return origins;return()=>!1}}class HttpException extends Error{statusCode;errors;constructor(statusCode,message,errors){super(message);this.statusCode=statusCode;this.errors=errors;this.name="HttpException"}toResponse(){let body={statusCode:this.statusCode,message:this.message,...this.errors&&{errors:this.errors}};return Response.json(body,{status:this.statusCode})}}class BadRequestException extends HttpException{constructor(message="Bad Request",errors){super(400,message,errors);this.name="BadRequestException"}}class UnauthorizedException extends HttpException{constructor(message="Unauthorized"){super(401,message);this.name="UnauthorizedException"}}class ForbiddenException extends HttpException{constructor(message="Forbidden"){super(403,message);this.name="ForbiddenException"}}class NotFoundException extends HttpException{constructor(message="Not Found"){super(404,message);this.name="NotFoundException"}}class MethodNotAllowedException extends HttpException{constructor(message="Method Not Allowed"){super(405,message);this.name="MethodNotAllowedException"}}class ConflictException extends HttpException{constructor(message="Conflict"){super(409,message);this.name="ConflictException"}}class UnprocessableEntityException extends HttpException{constructor(message="Unprocessable Entity",errors){super(422,message,errors);this.name="UnprocessableEntityException"}}class TooManyRequestsException extends HttpException{constructor(message="Too Many Requests"){super(429,message);this.name="TooManyRequestsException"}}class InternalServerErrorException extends HttpException{constructor(message="Internal Server Error"){super(500,message);this.name="InternalServerErrorException"}}class ServiceUnavailableException extends HttpException{constructor(message="Service Unavailable"){super(503,message);this.name="ServiceUnavailableException"}}var VALIDATION_SCHEMA=Symbol("turbo:validation");function Schema(schema){return(target)=>{Reflect.defineMetadata(VALIDATION_SCHEMA,schema,target)}}function getSchema(target){return Reflect.getMetadata(VALIDATION_SCHEMA,target)}class ZodAdapter{name="ZodAdapter";schemaCache=new Map;hasValidation(target){return getSchema(target)!==void 0}validate(target,value){let schema=this.getOrCacheSchema(target);if(!schema)return{success:!0,data:value};let result=schema.safeParse(value);if(result.success)return{success:!0,data:result.data};return{success:!1,errors:this.formatErrors(result.error)}}validateOrThrow(target,value){let schema=this.getOrCacheSchema(target);if(!schema)return value;let result=schema.safeParse(value);if(result.success)return result.data;let errors=this.formatErrors(result.error);throw new ValidationException(errors)}getOrCacheSchema(target){let schema=this.schemaCache.get(target);if(schema===void 0)schema=getSchema(target)??null,this.schemaCache.set(target,schema);return schema}formatErrors(zodError){return zodError.issues.map((issue)=>({path:issue.path.join("."),message:issue.message}))}}class ValidationException extends Error{errors;constructor(errors){super(`Validation failed: ${errors.map((e)=>`${e.path}: ${e.message}`).join(", ")}`);this.errors=errors;this.name="ValidationException"}toResponse(){return Response.json({statusCode:400,message:"Validation failed",errors:this.errors},{status:400})}}var EventType;((EventType2)=>{EventType2.INIT="onInit";EventType2.BOOT="onBoot";EventType2.SHUTDOWN="onShutdown"})(EventType||={});var EVENTS_META=Symbol("turbo:events"),eventRegistry=new Map;function registerEvent(type,target,methodName,priority=0){let handlers=eventRegistry.get(type);if(!handlers)handlers=[],eventRegistry.set(type,handlers);handlers.push({target,methodName,priority})}function getEventHandlers(type){return(eventRegistry.get(type)||[]).sort((a,b)=>b.priority-a.priority)}function hasEventHandlers(type){return(eventRegistry.get(type)?.length??0)>0}function OnApplicationInit(priority=0){return function(target,propertyKey){registerEvent("onInit",target.constructor,propertyKey,priority)}}function OnApplicationBoot(priority=0){return function(target,propertyKey){registerEvent("onBoot",target.constructor,propertyKey,priority)}}function OnApplicationShutdown(priority=0){return function(target,propertyKey){registerEvent("onShutdown",target.constructor,propertyKey,priority)}}class MemoryDriver{name="MemoryDriver";cache=new Map;cleanupInterval=null;constructor(cleanupIntervalMs=0){if(cleanupIntervalMs>0)this.cleanupInterval=setInterval(()=>this.cleanup(),cleanupIntervalMs)}async get(key){let entry=this.cache.get(key);if(!entry)return null;if(entry.expiresAt!==null&&Date.now()>entry.expiresAt)return this.cache.delete(key),null;return entry.value}async set(key,value,ttl){let expiresAt=ttl?Date.now()+ttl:null;return this.cache.set(key,{value,expiresAt}),!0}async del(key){return this.cache.delete(key)}async has(key){let entry=this.cache.get(key);if(!entry)return!1;if(entry.expiresAt!==null&&Date.now()>entry.expiresAt)return this.cache.delete(key),!1;return!0}async clear(){this.cache.clear()}async close(){if(this.cleanupInterval)clearInterval(this.cleanupInterval),this.cleanupInterval=null;this.cache.clear()}cleanup(){let now=Date.now();for(let[key,entry]of this.cache)if(entry.expiresAt!==null&&now>entry.expiresAt)this.cache.delete(key)}stats(){return{size:this.cache.size}}}class CacheService{driver;prefix;defaultTtl;constructor(config={}){this.driver=config.driver||new MemoryDriver,this.prefix=config.prefix||"",this.defaultTtl=config.defaultTtl}key(key){return this.prefix?`${this.prefix}:${key}`:key}async get(key){return this.driver.get(this.key(key))}async set(key,value,ttl){return this.driver.set(this.key(key),value,ttl??this.defaultTtl)}async del(key){return this.driver.del(this.key(key))}async has(key){return this.driver.has(this.key(key))}async clear(){return this.driver.clear()}async getOrSet(key,cb,ttl){let cached=await this.get(key);if(cached!==null)return cached;let value=await cb();return await this.set(key,value,ttl),value}async getMany(keys){return Promise.all(keys.map((key)=>this.get(key)))}async setMany(entries){return Promise.all(entries.map((entry)=>this.set(entry.key,entry.value,entry.ttl)))}async delMany(keys){return Promise.all(keys.map((key)=>this.del(key)))}async close(){await this.driver.close?.()}getDriver(){return this.driver}}function normalizeOptions(pathOrOptions){if(!pathOrOptions)return{};if(typeof pathOrOptions==="string")return{path:pathOrOptions};return pathOrOptions}function normalizePath(path){if(!path)return"";let normalized=path.startsWith("/")?path:"/"+path;if(normalized!=="/"&&normalized.endsWith("/"))normalized=normalized.slice(0,-1);return normalized}function Controller(pathOrOptions){return(target)=>{let options=normalizeOptions(pathOrOptions),meta={path:normalizePath(options.path||""),scope:options.scope,children:options.children};if(Reflect.defineMetadata(CONTROLLER_META,meta,target),!Reflect.hasMetadata(ROUTES_META,target))Reflect.defineMetadata(ROUTES_META,[],target)}}function createMethodDecorator(method){return function(path=""){return function(targetOrMethod,contextOrPropertyKey,descriptor){if(contextOrPropertyKey&&typeof contextOrPropertyKey==="object"&&"kind"in contextOrPropertyKey){let context=contextOrPropertyKey;return context.addInitializer(function(){let constructor2=this.constructor,routes2=Reflect.getMetadata(ROUTES_META,constructor2)||[];routes2.push({method,path:path.startsWith("/")?path:"/"+path,handlerName:String(context.name)}),Reflect.defineMetadata(ROUTES_META,routes2,constructor2)}),targetOrMethod}let constructor=targetOrMethod.constructor,propertyKey=contextOrPropertyKey,routes=Reflect.getMetadata(ROUTES_META,constructor)||[];routes.push({method,path:path.startsWith("/")?path:"/"+path,handlerName:String(propertyKey)}),Reflect.defineMetadata(ROUTES_META,routes,constructor)}}}var Get=createMethodDecorator("get"),Post=createMethodDecorator("post"),Put=createMethodDecorator("put"),Delete=createMethodDecorator("delete"),Patch=createMethodDecorator("patch"),Head=createMethodDecorator("head"),Options=createMethodDecorator("options");class DefaultRoutes{favicon(){return new Response(null,{status:204})}}__legacyDecorateClassTS([Get("/favicon.ico"),__legacyMetadataTS("design:type",Function),__legacyMetadataTS("design:paramtypes",[]),__legacyMetadataTS("design:returntype",void 0)],DefaultRoutes.prototype,"favicon",null),DefaultRoutes=__legacyDecorateClassTS([Controller()],DefaultRoutes);var DEFAULT_STATIC_ROUTES={"/health":new Response('{"status":"ok"}',{status:200,headers:{"Content-Type":"application/json"}}),"/ready":new Response('{"ready":true}',{status:200,headers:{"Content-Type":"application/json"}}),"/favicon.ico":new Response(null,{status:204})};var NOT_FOUND_RESPONSE=new Response("Not Found",{status:404}),TEXT_OPTS=Object.freeze({status:200,headers:{"Content-Type":"text/plain"}}),JSON_OPTS=Object.freeze({status:200,headers:{"Content-Type":"application/json"}}),INTERNAL_ERROR_RESPONSE=new Response('{"statusCode":500,"message":"Internal Server Error"}',{status:500,headers:{"Content-Type":"application/json"}});class Carno{config;_controllers=[];_services=[];_middlewares=[];routes={};container=new Container;corsHandler=null;hasCors=!1;validator=null;server;hasInitHooks=!1;hasBootHooks=!1;hasShutdownHooks=!1;constructor(config={}){this.config=config;if(this.config.exports=this.config.exports||[],this.config.globalMiddlewares=this.config.globalMiddlewares||[],this.config.cors)this.corsHandler=new CorsHandler(this.config.cors),this.hasCors=!0;if(this.config.validation===void 0||this.config.validation===!0)this.validator=new ZodAdapter;else if(typeof this.config.validation==="function"){let AdapterClass=this.config.validation;this.validator=new AdapterClass}else if(this.config.validation)this.validator=this.config.validation}use(plugin){if(plugin._controllers.length>0)this._controllers.push(...plugin._controllers);for(let exported of plugin.config.exports||[]){let existingService=this.findServiceInPlugin(plugin,exported),serviceToAdd=this.shouldCloneService(existingService)?{...existingService}:exported;this._services.push(serviceToAdd)}if(plugin._services.length>0)this._services.push(...plugin._services);if(plugin.config.globalMiddlewares)this._middlewares.push(...plugin.config.globalMiddlewares);if(plugin._middlewares.length>0)this._middlewares.push(...plugin._middlewares);return this}findServiceInPlugin(plugin,exported){return plugin._services.find((s)=>this.getServiceToken(s)===this.getServiceToken(exported))}getServiceToken(service){return service?.token||service}shouldCloneService(service){return!!(service?.useValue!==void 0||service?.useClass)}services(serviceClass){let items=Array.isArray(serviceClass)?serviceClass:[serviceClass];return this._services.push(...items),this}middlewares(handler){let items=Array.isArray(handler)?handler:[handler];return this._middlewares.push(...items),this}controllers(controllerClass){let items=Array.isArray(controllerClass)?controllerClass:[controllerClass];return this._controllers.push(...items),this}get(token){return this.container.get(token)}listen(port=3000){this.bootstrap(),this.compileRoutes();let config={port,fetch:this.handleNotFound.bind(this),error:this.handleError.bind(this),routes:{...DEFAULT_STATIC_ROUTES,...this.routes}};if(this.server=Bun.serve(config),this.hasBootHooks)this.executeLifecycleHooks("onBoot");if(this.hasShutdownHooks)this.registerShutdownHandlers();if(!this.config.disableStartupLog)console.log(`Carno running on port ${port}`)}bootstrap(){this.hasInitHooks=hasEventHandlers("onInit"),this.hasBootHooks=hasEventHandlers("onBoot"),this.hasShutdownHooks=hasEventHandlers("onShutdown"),this.container.register({token:Container,useValue:this.container});let cacheConfig=typeof this.config.cache==="object"?this.config.cache:{};this.container.register({token:CacheService,useValue:new CacheService(cacheConfig)});for(let service of this._services)this.container.register(service);for(let ControllerClass of this._controllers)this.container.register(ControllerClass);if(this.hasInitHooks)this.executeLifecycleHooks("onInit");for(let service of this._services){let token=typeof service==="function"?service:service.token,serviceConfig=typeof service==="function"?null:service;if(!serviceConfig||serviceConfig.scope!=="request")this.container.get(token)}}compileRoutes(){for(let ControllerClass of this._controllers)this.compileController(ControllerClass)}compileController(ControllerClass,parentPath="",inheritedMiddlewares=[]){let meta=Reflect.getMetadata(CONTROLLER_META,ControllerClass)||{path:""},basePath=parentPath+(meta.path||""),routes=Reflect.getMetadata(ROUTES_META,ControllerClass)||[],middlewares=Reflect.getMetadata(MIDDLEWARE_META,ControllerClass)||[],instance=this.container.get(ControllerClass),controllerMiddlewares=middlewares.filter((m)=>!m.target).map((m)=>m.handler),scopedMiddlewares=[...inheritedMiddlewares,...controllerMiddlewares];for(let route of routes){let fullPath=this.normalizePath(basePath+route.path),params=Reflect.getMetadata(PARAMS_META,ControllerClass,route.handlerName)||[],routeMiddlewares=middlewares.filter((m)=>m.target===route.handlerName).map((m)=>m.handler),paramTypes=Reflect.getMetadata("design:paramtypes",ControllerClass.prototype,route.handlerName)||[],bodyDtoType=null;for(let param of params)if(param.type==="body"&&!param.key){let dtoType=paramTypes[param.index];if(dtoType&&this.validator?.hasValidation(dtoType))bodyDtoType=dtoType}let compiled=compileHandler(instance,route.handlerName,params),resolvedMiddlewares=[...this.config.globalMiddlewares||[],...this._middlewares,...scopedMiddlewares,...routeMiddlewares].map((m)=>this.resolveMiddleware(m)),hasMiddlewares=resolvedMiddlewares.length>0,method=route.method.toUpperCase();if(compiled.isStatic&&!hasMiddlewares)this.registerRoute(fullPath,method,this.createStaticResponse(compiled.staticValue));else this.registerRoute(fullPath,method,this.createHandler(compiled,params,resolvedMiddlewares,bodyDtoType))}if(meta.children)for(let ChildController of meta.children){if(!this.container.has(ChildController))this.container.register(ChildController);this.compileController(ChildController,basePath,scopedMiddlewares)}}registerRoute(path,method,handler){if(!this.routes[path])this.routes[path]={};this.routes[path][method]=handler}createStaticResponse(value){let isString=typeof value==="string",body=isString?value:JSON.stringify(value);return new Response(body,isString?TEXT_OPTS:JSON_OPTS)}createHandler(compiled,params,middlewares,bodyDtoType){let handler=compiled.fn,hasMiddlewares=middlewares.length>0,hasParams=params.length>0,applyCors=this.hasCors?this.applyCors.bind(this):null,validator=bodyDtoType?this.validator:null,hasMiddlewaresOrValidation=hasMiddlewares||!!validator;if(!hasMiddlewaresOrValidation&&!hasParams){if(compiled.isAsync)return async(req)=>{let ctx=new Context(req),result=await handler(ctx),response=this.buildResponse(result);return applyCors?applyCors(response,req):response};return(req)=>{let ctx=new Context(req),result=handler(ctx),response=this.buildResponse(result);return applyCors?applyCors(response,req):response}}if(!hasMiddlewaresOrValidation&&hasParams){if(compiled.isAsync)return async(req)=>{let ctx=new Context(req,req.params),result=await handler(ctx),response=this.buildResponse(result);return applyCors?applyCors(response,req):response};return(req)=>{let ctx=new Context(req,req.params),result=handler(ctx),response=this.buildResponse(result);return applyCors?applyCors(response,req):response}}return async(req)=>{let ctx=new Context(req,req.params||{});for(let middleware of middlewares){let result2=await middleware(ctx);if(result2 instanceof Response)return applyCors?applyCors(result2,req):result2}if(validator&&bodyDtoType)await ctx.parseBody(),validator.validateOrThrow(bodyDtoType,ctx.body);let result=compiled.isAsync?await handler(ctx):handler(ctx),response=this.buildResponse(result);return applyCors?applyCors(response,req):response}}resolveMiddleware(middleware){if(typeof middleware==="function"&&middleware.prototype?.handle){let instance=this.container.get(middleware);return(ctx)=>instance.handle(ctx,()=>{})}return middleware}applyCors(response,req){let origin=req.headers.get("origin");if(origin&&this.corsHandler)return this.corsHandler.apply(response,origin);return response}handleNotFound(req){if(this.hasCors&&req.method==="OPTIONS"){let origin=req.headers.get("origin");if(origin)return this.corsHandler.preflight(origin)}return NOT_FOUND_RESPONSE}buildResponse(result){if(result instanceof Response)return result;if(typeof result==="string")return new Response(result,TEXT_OPTS);if(result===void 0)return new Response(null,{status:204});return Response.json(result)}normalizePath(path){if(!path.startsWith("/"))path="/"+path;if(path!=="/"&&path.endsWith("/"))path=path.slice(0,-1);return path.replace(/\/+/g,"/")}hasParams(path){return path.includes(":")||path.includes("*")}stop(){this.server?.stop?.()}handleError(error){let response;if(error instanceof HttpException)response=error.toResponse();else if(error instanceof ValidationException)response=error.toResponse();else console.error("Unhandled error:",error),response=INTERNAL_ERROR_RESPONSE;if(this.hasCors&&this.corsHandler)return this.corsHandler.apply(response,"*");return response}executeLifecycleHooks(type){let handlers=getEventHandlers(type);for(let handler of handlers)try{let instance=this.container.has(handler.target)?this.container.get(handler.target):null;if(instance&&typeof instance[handler.methodName]==="function"){let result=instance[handler.methodName]();if(result instanceof Promise)result.catch((err)=>console.error(`Error in ${type} hook ${handler.methodName}:`,err))}}catch(err){console.error(`Error in ${type} hook ${handler.methodName}:`,err)}}registerShutdownHandlers(){let shutdown=()=>{this.executeLifecycleHooks("onShutdown"),this.stop(),process.exit(0)};process.on("SIGTERM",shutdown),process.on("SIGINT",shutdown)}}function createParamDecorator(type,key){return function(target,propertyKey,index){let params=Reflect.getMetadata(PARAMS_META,target.constructor,propertyKey)||[];params.push({type,key,index}),Reflect.defineMetadata(PARAMS_META,params,target.constructor,propertyKey)}}function Param(key){return createParamDecorator("param",key)}function Query(key){return createParamDecorator("query",key)}function Body(key){return createParamDecorator("body",key)}function Header(key){return createParamDecorator("header",key)}function Req(){return createParamDecorator("req")}function Ctx(){return createParamDecorator("ctx")}function Locals(key){return createParamDecorator("locals",key)}function Use(...middlewares){return function(target,propertyKey){let isMethod=propertyKey!==void 0,metaTarget=isMethod?target.constructor:target,existing=Reflect.getMetadata(MIDDLEWARE_META,metaTarget)||[];for(let handler of middlewares)existing.push({handler,target:isMethod?propertyKey:void 0});Reflect.defineMetadata(MIDDLEWARE_META,existing,metaTarget)}}function Service(options={}){return(target)=>{Reflect.defineMetadata(SERVICE_META,{scope:options.scope??"singleton"},target)}}function Inject(token){return(target,propertyKey,parameterIndex)=>{let existing=Reflect.getMetadata(INJECT_META,target)||new Map;existing.set(parameterIndex,token),Reflect.defineMetadata(INJECT_META,existing,target)}}var EMPTY_PARAMS2=Object.freeze({});function createNode(part){return{part,store:null,children:null,paramChild:null,wildcardStore:null}}class RadixRouter{roots={};add(method,path,store){if(path==="")path="/";if(path[0]!=="/")path="/"+path;let isWildcard=path.endsWith("*");if(isWildcard)path=path.slice(0,-1);let node=this.roots[method];if(!node)node=this.roots[method]=createNode("/");let i=0,len=path.length;while(i<len){if(path.charCodeAt(i)===58){let paramStart=i+1,paramEnd=paramStart;while(paramEnd<len&&path.charCodeAt(paramEnd)!==47)paramEnd++;let paramName=path.slice(paramStart,paramEnd);if(!node.paramChild)node.paramChild={name:paramName,store:null,child:null};if(paramEnd>=len){node.paramChild.store=store;return}if(!node.paramChild.child)node.paramChild.child=createNode(path.slice(paramEnd));node=node.paramChild.child,i=paramEnd;continue}let segmentEnd=i;while(segmentEnd<len&&path.charCodeAt(segmentEnd)!==47&&path.charCodeAt(segmentEnd)!==58)segmentEnd++;if(segmentEnd<len&&path.charCodeAt(segmentEnd)===47)segmentEnd++;let segment=path.slice(i,segmentEnd);if(segment===node.part){i=segmentEnd;continue}if(!node.children)node.children=new Map;let firstChar=segment.charCodeAt(0),child=node.children.get(firstChar);if(!child)child=createNode(segment),node.children.set(firstChar,child);node=child,i=segmentEnd}if(isWildcard)node.wildcardStore=store;else node.store=store}find(method,path){let root=this.roots[method];if(!root)return null;return this.matchPath(root,path,0,path.length)}matchPath(node,path,start,len){let partLen=node.part.length,end=start+partLen;if(partLen>1){if(end>len)return null;for(let i=1,j=start+1;i<partLen;i++,j++)if(node.part.charCodeAt(i)!==path.charCodeAt(j))return null}if(end===len){if(node.store!==null)return{store:node.store,params:EMPTY_PARAMS2};if(node.wildcardStore!==null)return{store:node.wildcardStore,params:{"*":""}};return null}if(node.children){let child=node.children.get(path.charCodeAt(end));if(child){let result=this.matchPath(child,path,end,len);if(result)return result}}if(node.paramChild){let param=node.paramChild,paramEnd=end;while(paramEnd<len&&path.charCodeAt(paramEnd)!==47)paramEnd++;if(paramEnd===end)return null;let paramValue=path.slice(end,paramEnd);if(paramEnd>=len){if(param.store!==null)return{store:param.store,params:{[param.name]:paramValue}}}else if(param.child){let result=this.matchPath(param.child,path,paramEnd,len);if(result){if(result.params===EMPTY_PARAMS2)result.params={[param.name]:paramValue};else result.params[param.name]=paramValue;return result}}}if(node.wildcardStore!==null)return{store:node.wildcardStore,params:{"*":path.slice(end)}};return null}}class ValibotAdapter{name="ValibotAdapter";schemaCache=new Map;valibot=null;constructor(){try{this.valibot=__require("valibot")}catch{}}ensureValibot(){if(!this.valibot)this.valibot=__require("valibot");return this.valibot}hasValidation(target){return getSchema(target)!==void 0}validate(target,value){let schema=this.getOrCacheSchema(target);if(!schema)return{success:!0,data:value};let result=this.ensureValibot().safeParse(schema,value);if(result.success)return{success:!0,data:result.output};return{success:!1,errors:this.formatErrors(result.issues)}}validateOrThrow(target,value){let result=this.validate(target,value);if(result.success)return result.data;throw new ValidationException(result.errors)}getOrCacheSchema(target){let schema=this.schemaCache.get(target);if(schema===void 0)schema=getSchema(target)??null,this.schemaCache.set(target,schema);return schema}formatErrors(issues){return issues.map((issue)=>({path:issue.path?.map((p)=>p.key).join(".")||"",message:issue.message}))}}class RedisDriver{config;name="RedisDriver";client=null;connected=!1;constructor(config={}){this.config=config}async ensureConnected(){if(this.connected)return;let url=this.config.url||`redis://${this.config.host||"localhost"}:${this.config.port||6379}`;if(typeof Bun<"u"&&Bun.redis)this.client=new Bun.redis(url);else try{let Redis=require_built3();this.client=new Redis({host:this.config.host||"localhost",port:this.config.port||6379,password:this.config.password,db:this.config.db||0})}catch{throw Error("Redis client not available. Install ioredis or use Bun with Redis support.")}this.connected=!0}async get(key){await this.ensureConnected();let value=await this.client.get(key);if(value===null)return null;try{return JSON.parse(value)}catch{return value}}async set(key,value,ttl){await this.ensureConnected();let serialized=typeof value==="string"?value:JSON.stringify(value);if(ttl)await this.client.setex(key,ttl,serialized);else await this.client.set(key,serialized);return!0}async del(key){return await this.ensureConnected(),await this.client.del(key)>0}async has(key){return await this.ensureConnected(),await this.client.exists(key)>0}async clear(){await this.ensureConnected(),await this.client.flushdb()}async close(){if(this.client&&this.connected)await this.client.quit?.(),this.connected=!1}}async function createTestHarness(options={}){let config={...options.config,disableStartupLog:!0},app=new Carno(config);if(options.plugins)for(let plugin of options.plugins)app.use(plugin);if(options.controllers)app.controllers(options.controllers);if(options.services)app.services(options.services);let port=resolvePort(options),server;if(shouldListen(options.listen))app.listen(port),server=app.server;let actualPort=server?.port??port,container=app.container,baseUrl=`http://127.0.0.1:${actualPort}`,request=async(path,init)=>{if(!server)throw Error("Server not running. Set listen: true in options.");let url=path.startsWith("http")?path:`${baseUrl}${path.startsWith("/")?path:"/"+path}`;return fetch(url,init)};return{app,container,server,port:actualPort,resolve:(token)=>container.get(token),request,get:(path,init)=>request(path,{...init,method:"GET"}),post:(path,body,init)=>request(path,{...init,method:"POST",body:body?JSON.stringify(body):void 0,headers:{"Content-Type":"application/json",...init?.headers}}),put:(path,body,init)=>request(path,{...init,method:"PUT",body:body?JSON.stringify(body):void 0,headers:{"Content-Type":"application/json",...init?.headers}}),delete:(path,init)=>request(path,{...init,method:"DELETE"}),close:async()=>{app.stop()}}}async function withTestApp(routine,options={}){let harness=await createTestHarness(options);try{await routine(harness)}finally{await harness.close()}}function shouldListen(value){return typeof value==="number"||Boolean(value)}function resolvePort(options){if(typeof options.listen==="number")return options.listen;if(typeof options.port==="number")return options.port;return 0}class Metadata{static get(key,target){return Reflect.getMetadata(key,target)}static set(key,value,target){Reflect.defineMetadata(key,value,target)}static has(key,target){return Reflect.hasMetadata(key,target)}static delete(key,target){return Reflect.deleteMetadata(key,target)}static keys(target){return Reflect.getMetadataKeys(target)}static getType(target,propertyKey){return Reflect.getMetadata("design:type",target,propertyKey)}}function isObject(value){return typeof value==="object"&&value!==null&&!Array.isArray(value)}function isString(value){return typeof value==="string"}export{withTestApp,isString,isObject,getSchema,createTestHarness,ZodAdapter,ValidationException,ValibotAdapter,VALIDATION_SCHEMA,Use,UnprocessableEntityException,UnauthorizedException,TooManyRequestsException,ServiceUnavailableException,Service,Scope,Schema,Req,RedisDriver,RadixRouter,Query,Put,Post,Patch,Param,Options,OnApplicationShutdown,OnApplicationInit,OnApplicationBoot,NotFoundException,Use as Middleware,MethodNotAllowedException,Metadata,MemoryDriver,Locals,InternalServerErrorException,Inject,HttpException,Header,Head,Get,ForbiddenException,EventType,Delete,Ctx,CorsHandler,Controller,Context,Container,ConflictException,Carno,CacheService,Body,BadRequestException};
168
168
 
169
- //# debugId=6D339FEBFBD0367364756E2164756E21
169
+ //# debugId=1C9F2BA5F42CBA7A64756E2164756E21
170
170
  //# sourceMappingURL=index.js.map