harperdb 4.5.34 → 4.5.35

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/bin/lite.js CHANGED
@@ -21,9 +21,9 @@ Caused by:`));else if(typeof u=="object")try{n+=JSON.stringify(u)}catch{n+="Obje
21
21
  `,""));return r.replace(`
22
22
  `,"")}a(xk,"runCommand");async function qse(){try{await gse.access(wO)}catch{return!1}let e=await xk(`${wO} --version`,void 0),t=e.substring(e.lastIndexOf("v")+1,e.length);return Sse.eq(t,Fse)}a(qse,"checkNATSServerInstalled");async function LO(e,t,r,n=!0,s="127.0.0.1"){if(!t&&!r){let o=await vk.getClusterUser();if(ll(o))throw new Error("Unable to get nats connection. Cluster user is undefined.");t=o.username,r=o.decrypt_hash}js.trace("create nats connection called");let i=await Dse({name:s,port:e,user:t,pass:r,maxReconnectAttempts:-1,waitOnFirstConnect:n,timeout:2e5,tls:{keyFile:Ir.get(Qe.CONFIG_PARAMS.CLUSTERING_TLS_PRIVATEKEY),certFile:Ir.get(Qe.CONFIG_PARAMS.CLUSTERING_TLS_CERTIFICATE),caFile:Ir.get(Qe.CONFIG_PARAMS.CLUSTERING_TLS_CERT_AUTH),rejectUnauthorized:!1}});return i.protocol.transport.socket.unref(),js.trace("create connection established a nats client connection with id",i?.info?.client_id),i.closed().then(o=>{o&&js.error("Error with Nats client connection, connection closed",o),i===Jr&&Bk()}),i}a(LO,"createConnection");function Bk(){Jr=void 0,ol=void 0,al=void 0,cl=void 0}a(Bk,"clearClientCache");async function $se(){Jr&&(await Jr.drain(),Jr=void 0,ol=void 0,al=void 0,cl=void 0)}a($se,"closeConnection");var Jr,cl;async function rh(){return cl||(cl=LO(Ir.get(Qe.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_NETWORK_PORT),void 0,void 0),Jr=await cl),Jr||cl}a(rh,"getConnection");async function nh(){if(ol)return ol;ll(Jr)&&await rh();let{domain:e}=$u(Qe.PROCESS_DESCRIPTORS.CLUSTERING_LEAF);if(ll(e))throw new Error("Error getting JetStream domain. Unable to get JetStream manager.");return ol=await Jr.jetstreamManager({domain:e,timeout:6e4}),ol}a(nh,"getJetStreamManager");async function Hk(){if(al)return al;ll(Jr)&&await rh();let{domain:e}=$u(Qe.PROCESS_DESCRIPTORS.CLUSTERING_LEAF);if(ll(e))throw new Error("Error getting JetStream domain. Unable to get JetStream manager.");return al=Jr.jetstream({domain:e,timeout:6e4}),al}a(Hk,"getJetStream");async function xi(){let e=Jr||await rh(),t=ol||await nh(),r=al||await Hk();return{connection:e,jsm:t,js:r}}a(xi,"getNATSReferences");async function Vse(e){let t=Ir.get(Qe.CONFIG_PARAMS.CLUSTERING_HUBSERVER_NETWORK_PORT),{sys_name:r,decrypt_hash:n}=await vk.getClusterUser(),s=await LO(t,r,n),i=DO(),o=s.subscribe(i),c=[],l,u=(async()=>{for await(let f of o){let d=Uk.decode(f.data);d.response_time=Date.now()-l,c.push(d)}})();return l=Date.now(),await s.publish("$SYS.REQ.SERVER.PING.VARZ",void 0,{reply:i}),await s.publish("$SYS.REQ.SERVER.PING",void 0,{reply:i}),await s.flush(),await pg.async_set_timeout(e),await o.drain(),await s.close(),await u,c}a(Vse,"getServerList");async function MO(e,t){let{jsm:r}=await xi(),n=Ir.get(Qe.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_STREAMS_MAXAGE);n=n===null?0:n*1e9;let s=Ir.get(Qe.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_STREAMS_MAXMSGS);s=s===null?-1:s;let i=Ir.get(Qe.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_STREAMS_MAXBYTES);i=i===null?-1:i,await r.streams.add({name:e,storage:Lse.File,retention:Mse.Limits,subjects:t,discard:vse.Old,max_msgs:s,max_bytes:i,max_age:n})}a(MO,"createLocalStream");async function kk(){let{jsm:e}=await xi(),t=await e.streams.list().next(),r=[];return t.forEach(n=>{r.push(n)}),r}a(kk,"listStreams");async function Kse(e){let{jsm:t}=await xi();await t.streams.delete(e)}a(Kse,"deleteLocalStream");async function Yse(e){let{connection:t}=await xi(),r=[],n=DO(),s=t.subscribe(n),i=(async()=>{for await(let o of s)r.push(Uk.decode(o.data))})();return await t.publish(`$JS.${e}.API.STREAM.LIST`,void 0,{reply:n}),await t.flush(),await s.drain(),await i,r}a(Yse,"listRemoteStreams");async function Wse(e,t=void 0,r=void 0){let{jsm:n,js:s}=await xi(),i=Pk(),o={durable_name:i,ack_policy:CO.Explicit};t&&(o.deliver_policy=PO.StartTime,o.opt_start_time=new Date(t).toISOString()),await n.consumers.add(e,o);let c=await s.consumers.get(e,i),l=r?await c.fetch({max_messages:r,expires:2e3}):await c.consume();if(c._info.num_pending===0)return[];let u=[];for await(let f of l){let d=IO(f.data),_={nats_timestamp:f.info.timestampNanos,nats_sequence:f.info.streamSequence,entry:d};if(f.headers&&(_.origin=f.headers.get(Hr.MSG_HEADERS.ORIGIN)),u.push(_),f.ack(),f.info.pending===0)break}return await c.delete(),u}a(Wse,"viewStream");async function*zse(e,t=void 0,r=void 0){let{jsm:n,js:s}=await xi(),i=Pk(),o={durable_name:i,ack_policy:CO.Explicit};t&&(o.deliver_policy=PO.StartTime,o.opt_start_time=new Date(t).toISOString()),await n.consumers.add(e,o);let c=await s.consumers.get(e,i),l=r?await c.fetch({max_messages:r,expires:2e3}):await c.consume();if(c._info.num_pending===0)return[];for await(let u of l){let f=IO(u.data);f[0]||(f=[f]);for(let d of f){let _={nats_timestamp:u.info.timestampNanos,nats_sequence:u.info.streamSequence,entry:d};u.headers&&(_.origin=u.headers.get(Hr.MSG_HEADERS.ORIGIN)),yield _}if(u.ack(),u.info.pending===0)break}await c.delete()}a(zse,"viewStreamIterator");async function Qse(e,t,r,n){js.trace(`publishToStream called with subject: ${e}, stream: ${t}, entries:`,n.operation),r=Fk(n,r);let{js:s}=await xi(),i=await gg(),o=`${e}.${i}`,c=await Hse(()=>n instanceof Uint8Array?n:Mk.encode(n));try{js.trace(`publishToStream publishing to subject: ${o}`),Bse(c.length,"bytes-sent",e,n.operation,"replication"),await s.publish(o,c,{headers:r})}catch(l){if(l.code&&l.code.toString()==="503")return qk(async()=>{try{await s.publish(o,c,{headers:r})}catch{if(l.code&&l.code.toString()==="503"){js.trace(`publishToStream creating stream: ${t}`);let f=o.split(".");f[2]="*",await MO(t,[o]),await s.publish(o,c,{headers:r})}else throw l}});throw l}}a(Qse,"publishToStream");function Fk(e,t){t===void 0&&(t=xse());let r=Ir.get(Qe.CONFIG_PARAMS.CLUSTERING_NODENAME);return!t.has(Hr.MSG_HEADERS.ORIGIN)&&r&&t.append(Hr.MSG_HEADERS.ORIGIN,r),t}a(Fk,"addNatsMsgHeader");function $u(e){e=e.toLowerCase();let t=th.join(Ir.get(Qe.CONFIG_PARAMS.ROOTPATH),kse);if(e===Qe.PROCESS_DESCRIPTORS.CLUSTERING_HUB.toLowerCase())return ll(NO)&&(NO={port:Z_.getConfigFromFile(Qe.CONFIG_PARAMS.CLUSTERING_HUBSERVER_NETWORK_PORT),server_name:Z_.getConfigFromFile(Qe.CONFIG_PARAMS.CLUSTERING_NODENAME)+Hr.SERVER_SUFFIX.HUB,config_file:Hr.NATS_CONFIG_FILES.HUB_SERVER,pid_file_path:th.join(t,Hr.PID_FILES.HUB),hdb_nats_path:t}),NO;if(e===Qe.PROCESS_DESCRIPTORS.CLUSTERING_LEAF.toLowerCase())return ll(OO)&&(OO={port:Z_.getConfigFromFile(Qe.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_NETWORK_PORT),server_name:Z_.getConfigFromFile(Qe.CONFIG_PARAMS.CLUSTERING_NODENAME)+Hr.SERVER_SUFFIX.LEAF,config_file:Hr.NATS_CONFIG_FILES.LEAF_SERVER,domain:Z_.getConfigFromFile(Qe.CONFIG_PARAMS.CLUSTERING_NODENAME)+Hr.SERVER_SUFFIX.LEAF,pid_file_path:th.join(t,Hr.PID_FILES.LEAF),hdb_nats_path:t}),OO;js.error(`Unable to get Nats server config. Unrecognized process: ${e}`)}a($u,"getServerConfig");async function Gk(e,t,r,n){try{await e.consumers.add(t,{ack_policy:CO.Explicit,durable_name:r,deliver_policy:PO.StartTime,opt_start_time:n})}catch(s){if(s.message!=="consumer already exists")throw s}}a(Gk,"createConsumer");async function jse(e,t,r){await e.consumers.delete(t,r)}a(jse,"removeConsumer");function Jse(e){return e.split(".")[1]}a(Jse,"extractServerName");async function Xse(e,t,r=6e4,n=DO()){if(!pg.isObject(t))throw new Error("data param must be an object");let s=Mk.encode(t),{connection:i}=await xi(),o={timeout:r};n&&(o.reply=n,o.noMux=!0);let c=await i.request(e,s,o);return IO(c.data)}a(Xse,"request");function vO(e){return new Promise(async(t,r)=>{let n=yse(wO,["--signal",`reload=${e}`],{cwd:__dirname}),s,i;n.on("error",o=>{r(o)}),n.stdout.on("data",o=>{i+=o.toString()}),n.stderr.on("data",o=>{s+=o.toString()}),n.stderr.on("close",o=>{s&&r(s),t(i)})})}a(vO,"reloadNATS");async function Zse(){let{pid_file_path:e}=$u(Qe.PROCESS_DESCRIPTORS.CLUSTERING_HUB);await vO(e)}a(Zse,"reloadNATSHub");async function eie(){let{pid_file_path:e}=$u(Qe.PROCESS_DESCRIPTORS.CLUSTERING_LEAF);await vO(e)}a(eie,"reloadNATSLeaf");function tie(e,t,r){let n;switch(e.code){case Ck.NoResponders:n=`Unable to ${t}, node '${r}' is not listening.`;break;case Ck.Timeout:n=`Unable to ${t}, node '${r}' is listening but did not respond.`;break;default:n=e.message;break}return n}a(tie,"requestErrorHandler");async function rie(e,t){let r=t+Hr.SERVER_SUFFIX.LEAF,{connection:n}=await xi(),{jsm:s}=await uie(r),{schema:i,table:o}=e,c=Eg.createNatsTableStreamName(i,o),l=e.start_time?e.start_time:new Date(Date.now()).toISOString();await qk(async()=>{if(e.subscribe===!0)await Gk(s,c,n.info.server_name,l);else try{await jse(s,c,n.info.server_name)}catch(u){js.trace(u)}})}a(rie,"updateRemoteConsumer");async function nie(e,t,r,n){let s=Eg.createNatsTableStreamName(e,t),i=r+Hr.SERVER_SUFFIX.LEAF,o={type:Qe.ITC_EVENT_TYPES.NATS_CONSUMER_UPDATE,status:n,stream_name:s,node_domain_name:i};if(!Lk&&Cse()<Ir.get(Qe.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_STREAMS_MAXINGESTTHREADS)){let{updateConsumer:c}=bO();await c(o)}await wse(o),n==="stop"&&await pg.async_set_timeout(1e3)}a(nie,"updateConsumerIterator");function qk(e){return Nse.writeTransaction(Qe.SYSTEM_SCHEMA_NAME,Qe.SYSTEM_TABLE_NAMES.NODE_TABLE_NAME,e)}a(qk,"exclusiveLock");async function $k(e,t){let r=Eg.createNatsTableStreamName(e,t),n=await gg(),s=aie(e,t,n);await MO(r,[s])}a($k,"createLocalTableStream");async function sie(e){for(let t=0,r=e.length;t<r;t++){let n=e[t].schema,s=e[t].table;await $k(n,s)}}a(sie,"createTableStreams");async function Vk(e,t,r=void 0){if(Ir.get(Qe.CONFIG_PARAMS.CLUSTERING_ENABLED))try{let n=Eg.createNatsTableStreamName(e,t),{domain:s}=$u(Qe.PROCESS_DESCRIPTORS.CLUSTERING_LEAF);await(await(await rh()).jetstreamManager({domain:s,timeout:24e4})).streams.purge(n,r)}catch(n){if(n.message==="stream not found")js.warn(n);else throw n}}a(Vk,"purgeTableStream");async function iie(e,t){if(Ir.get(Qe.CONFIG_PARAMS.CLUSTERING_ENABLED))for(let r=0,n=t.length;r<n;r++)await Vk(e,t[r])}a(iie,"purgeSchemaTableStreams");async function oie(e){return(await nh()).streams.info(e)}a(oie,"getStreamInfo");function aie(e,t,r){return`${Hr.SUBJECT_PREFIXES.TXN}.${e}${t?"."+t:""}.${r}`}a(aie,"createSubjectName");async function gg(){if(eh)return eh;if(eh=(await nh())?.nc?.info?.server_name,eh===void 0)throw new Error("Unable to get jetstream manager server name");return eh}a(gg,"getJsmServerName");async function cie(){let e=await nh(),t=await gg(),r=await kk();for(let n of r){let s=n.config,i=s.subjects[0];if(!i)continue;let o=lie(n),c=i.split(".");if(c[c.length-1]===t&&!o||s.name==="__HARPERDB_WORK_QUEUE__")continue;let u=i.split(".");u[u.length-1]=t;let f=u.join(".");js.trace(`Updating stream subject name from: ${i} to: ${f}`),s.subjects[0]=f,await e.streams.update(s.name,s)}}a(cie,"updateLocalStreams");function lie(e){let{config:t}=e,r=!1,n=Ir.get(Qe.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_STREAMS_MAXAGE);n=n===null?0:n*1e9;let s=Ir.get(Qe.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_STREAMS_MAXBYTES);s=s===null?-1:s;let i=Ir.get(Qe.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_STREAMS_MAXMSGS);return i=i===null?-1:i,n!==t.max_age&&(t.max_age=n,r=!0),s!==t.max_bytes&&(t.max_bytes=s,r=!0),i!==t.max_msgs&&(t.max_msgs=i,r=!0),r}a(lie,"updateStreamLimits");async function uie(e){let t,r;try{t=await Jr.jetstream({domain:e}),r=await Jr.jetstreamManager({domain:e,checkAPI:!1})}catch(n){throw js.error("Unable to connect to:",e),n}return{js:t,jsm:r}}a(uie,"connectToRemoteJS")});function UO(e){let t=e.get(Sg),r=t?(0,Vu.unpack)(t):null;r||(r={remoteNameToId:{}});let n=et(),s=!1;r.nodeName=et();let i=r.remoteNameToId;if(i[n]!==0){let o=0,c;for(let l in i){let u=i[l];u===0?c=l:u>o&&(o=u)}if(c){o++,i[c]=o;let l=[Symbol.for("seq"),o];e.rootStore.dbisDb.transactionSync(()=>{e.rootStore.dbisDb.get(l)||e.rootStore.dbisDb.putSync(l,{seqId:ih(e)??1,nodes:[]})})}i[n]=0,e.putSync(Sg,(0,Vu.pack)(r))}return r}function sh(e){return UO(e).remoteNameToId}function Wk(e,t){let r=UO(t),n=r.remoteNameToId,s=new Map,i=!1;for(let o in e){let c=e[o],l=n[o];if(l==null){let u=0;for(let f in n){let d=n[f];d>u&&(u=d)}l=u+1,n[o]=l,i=!0}s.set(c,l)}return i&&t.putSync(Sg,(0,Vu.pack)(r)),s}function Tg(e,t){let r=UO(t),n=r.remoteNameToId,s=n[e];if(s==null){let i=0;for(let o in n){let c=n[o];c>i&&(i=c)}s=i+1,n[e]=s,t.putSync(Sg,(0,Vu.pack)(r))}return Yk.trace?.("The remote node name map",e,n,s),s}var Yk,Vu,Sg,xO=Re(()=>{Yk=M(ks());gs();Vu=require("msgpackr"),Sg=Symbol.for("remote-ids");a(UO,"getIdMappingRecord");a(sh,"exportIdMapping");a(Wk,"remoteToLocalNodeId");a(Tg,"getIdOfRemoteNode")});var BO={};Ue(BO,{commits_awaiting_replication:()=>Ku,getHDBNodeTable:()=>ir,getReplicationSharedStatus:()=>Ag,iterateRoutes:()=>ah,shouldReplicateToNode:()=>oh,subscribeToNodeUpdates:()=>Yu});function ir(){return zk||(zk=_t({table:"hdb_nodes",database:"system",attributes:[{name:"name",isPrimaryKey:!0},{attribute:"subscriptions"},{attribute:"system_info"},{attribute:"url"},{attribute:"routes"},{attribute:"ca"},{attribute:"ca_info"},{attribute:"replicates"},{attribute:"revoked_certificates"},{attribute:"__createdtime__"},{attribute:"__updatedtime__"}]}))}function Ag(e,t,r,n){return new Float64Array(e.getUserSharedBuffer(["replicated",t,r],new ArrayBuffer(48),n&&{callback:n}))}function Yu(e){ir().subscribe({}).then(async t=>{for await(let r of t){let n=r?.value?.name;Xk.debug?.("adding node",n,"on node",et()," on process",process.pid),server.nodes=server.nodes.filter(i=>i.name!==n),r.type==="put"&&n!==et()&&(r.value?server.nodes.push(r.value):console.error("Invalid node update event",r));let s=new Map;for await(let i of ir().search({}))if(i.shard!=null){let o=s.get(i.shard);o||s.set(i.shard,o=[]),o.push(i)}server.shards=s,(r.type==="put"||r.type==="delete")&&e(r.value,r.id)}})}function oh(e,t){let r=Ra.default.get(x.REPLICATION_DATABASES);return(e.replicates===!0||e.replicates?.sends)&&databases[t]&&(r==="*"||r?.find?.(n=>n.name===t&&(!n.sharded||e.shard===Ra.default.get(x.REPLICATION_SHARD))))&&ir().primaryStore.get(et())?.replicates||e.subscriptions?.some(n=>(n.database||n.schema)===t&&n.subscribe)}function die(){Yu(e=>{ya({},(t,r)=>{let n=e.name,s=Qk.get(n);if(s||Qk.set(n,s=new Map),s.has(r))return;let i;for(let o in t)if(i=t[o].auditStore,i)break;if(i){let o=Ag(i,r,n,()=>{let c=o[0],l=o.lastTime;for(let{txnTime:u,onConfirm:f}of Ku.get(r)||[])u>l&&u<=c&&f();o.lastTime=c});o.lastTime=0,s.set(r,o)}})})}function*ah(e){for(let t of e.routes||[]){let r=t.url,n;if(typeof t=="string"?t.includes("://")?r=t:n=t:n=t.hostname??t.host,n&&!r){let s=Ra.default.get(x.REPLICATION_SECUREPORT)??(!Ra.default.get(x.REPLICATION_PORT)&&Ra.default.get(x.OPERATIONSAPI_NETWORK_SECUREPORT)),i;(i=n.match(/:(\d+)$/)?.[1])?n=n.slice(0,-i[0].length-1):t.port?i=t.port:i=s||Ra.default.get(x.REPLICATION_PORT)||Ra.default.get(x.OPERATIONSAPI_NETWORK_PORT);let o=i?.lastIndexOf?.(":");o>0&&(i=+i.slice(o+1).replace(/[\[\]]/g,"")),r=(s?"wss://":"ws://")+n+":"+i}if(!r){jk.isMainThread&&console.error("Invalid route, must specify a url or host (with port)");continue}yield{replicates:!t.subscriptions,url:r,subscription:t.subscriptions,routes:t.routes,start_time:t.startTime,revoked_certificates:t.revokedCertificates}}}var jk,Jk,Ra,Xk,zk,Qk,Ku,ul=Re(()=>{xe();gs();jm();jk=require("worker_threads"),Jk=M(he()),Ra=M(le());k();Xk=M(ks());server.nodes=[];a(ir,"getHDBNodeTable");a(Ag,"getReplicationSharedStatus");a(Yu,"subscribeToNodeUpdates");a(oh,"shouldReplicateToNode");Qk=new Map;ID((e,t,r)=>{if(r>server.nodes.length)throw new Jk.ClientError(`Cannot confirm replication to more nodes (${r}) than are in the network (${server.nodes.length})`);Ku||(Ku=new Map,die());let n=Ku.get(e);return n||(n=[],Ku.set(e,n)),new Promise(s=>{let i=0;n.push({txnTime:t,onConfirm:a(()=>{++i===r&&s()},"onConfirm")})})});a(die,"startSubscriptionToReplications");a(ah,"iterateRoutes")});var tF={};Ue(tF,{connectedToNode:()=>dl,disconnectedFromNode:()=>zu,ensureNode:()=>Ao,requestClusterStatus:()=>eF,startOnMainThread:()=>FO});async function FO(e){let t=0,r=Je();for(let i of Object.getOwnPropertyNames(r)){let o=r[i];for(let c in o){let l=o[c];if(l.auditStore){Rg.set(i,ih(l.auditStore));break}}}Hi.whenThreadsStarted.then(async()=>{let i=[];for await(let o of r.system.hdb_nodes?.search([])||[])i.push(o);for(let o of ah(e))try{let c=!o.subscriptions;if(c){let u=et(),f=ir().primaryStore.get(u);if(f!==null){let d=e.url??ba();(f===void 0||f.url!==d||f.shard!==e.shard)&&await Ao(u,{name:u,url:d,shard:e.shard,replicates:!0})}}let l=o.trusted!==!1;if(c&&o.replicates==null&&(o.replicates=!0),i.find(u=>u.url===o.url))continue;s(o)}catch(c){console.error(c)}Yu(s)});let n;function s(i,o=i?.name){let c=et()&&o===et()||ba()&&i?.url===ba();if(c){let d=!!i?.replicates;if(n!==void 0&&n!==d)for(let _ of ir().search([]))_.replicates&&_.name!==o&&s(_,_.name);n=d}if(nt.trace("Setting up node replication for",i),!i){for(let[d,_]of Bi){let h;for(let[m,{worker:S,nodes:g}]of _){let R=g[0];if(R&&R.name==o){h=!0;for(let[E,{worker:T}]of _)_.delete(E),nt.warn("Node was deleted, unsubscribing from node",o,E,d),T?.postMessage({type:"unsubscribe-from-node",node:o,database:E,url:d});break}}if(h){Bi.get(d).iterator.remove(),Bi.delete(d);return}}return}if(c)return;if(!i.url){nt.info(`Node ${i.name} is missing url`);return}let l=Bi.get(i.url);if(l&&l.iterator.remove(),!(i.replicates===!0||i.replicates?.sends)&&!i.subscriptions?.length&&!l)return;if(nt.info(`Added node ${i.name} at ${i.url} for process ${et()}`),i.replicates&&i.subscriptions&&(i={...i,subscriptions:null}),i.name){for(let[d,_]of Wu)if(i.url===_.url){Wu.delete(d);break}Wu.set(i.name,i)}let u=Je();if(l||(l=new Map,Bi.set(i.url,l)),l.iterator=ya(e,(d,_,h)=>{h?f(_,!0):f(_,!1)}),i.subscriptions)for(let d of i.subscriptions){let _=d.database||d.schema;u[_]||(nt.warn(`Database ${_} not found for node ${i.name}, making a subscription anyway`),f(_,!1))}function f(d,_){nt.trace("Setting up replication for database",d,"on node",i.name);let h=l.get(d),m,S=[{replicateByDefault:_,...i}];Rg.has(d)&&(S.push({replicateByDefault:_,name:et(),start_time:Rg.get(d),end_time:Date.now(),replicates:!0}),Rg.delete(d));let g=oh(i,d),R=Hi.workers.filter(E=>E.name==="http");if(h?(m=h.worker,h.nodes=S):g&&(t=t%R.length,m=R[t++],l.set(d,{worker:m,nodes:S,url:i.url}),m?.on("exit",()=>{l.get(d)?.worker===m&&(l.delete(d),f(d,_))})),g)setTimeout(()=>{let E={type:"subscribe-to-node",database:d,nodes:S};m?m.postMessage(E):ch(E)},fie);else{nt.info("Node no longer should be used, unsubscribing from node",i.replicates,!!u[d],ir().primaryStore.get(et())?.replicates),ir().primaryStore.get(et())?.replicates||(n=!1);let E={type:"unsubscribe-from-node",database:d,url:i.url,name:i.name};m?m.postMessage(E):bg(E)}}a(f,"onDatabase")}a(s,"onNodeUpdate"),zu=a(function(i){try{nt.info("Disconnected from node",i.name,i.url,"finished",!!i.finished);let o=Array.from(Wu.keys()),c=o.sort(),l=c.indexOf(i.name||Js(i.url));if(l===-1){nt.warn("Disconnected node not found in node map",i.name,o);return}let u=Bi.get(i.url),f=u?.get(i.database);if(!f){nt.warn("Disconnected node not found in replication map",i.database,u);return}if(f.connected=!1,i.finished||!kO.default.get(x.REPLICATION_FAILOVER))return;let d=f.nodes[0];if(!(d.replicates===!0||d.replicates?.sends||d.subscriptions?.length))return;let _=d.shard,h=(l+1)%c.length;for(;l!==h;){let m=c[h],S=Wu.get(m);u=Bi.get(S.url);let g=u?.get(i.database);if(!g||g.connected===!1||g.nodes[0].shard!==_){h=(h+1)%c.length;continue}let{worker:R,nodes:E}=g,T=!1;for(let N of f.nodes){if(E.some(v=>v.name===N.name)){nt.info(`Disconnected node is already failing over to ${m} for ${i.database}`);continue}N.end_time<Date.now()||(E.push(N),T=!0)}if(f.nodes=[f.nodes[0]],!T){nt.info(`Disconnected node ${i.name} has no nodes to fail over to ${m}`);return}nt.info(`Failing over ${i.database} from ${i.name} to ${m}`),R?R.postMessage({type:"subscribe-to-node",database:i.database,nodes:E}):ch({database:i.database,nodes:E});return}nt.warn("Unable to find any other node to fail over to",i.name,i.url)}catch(o){nt.error("Error failing over node",o)}},"disconnectedFromNode"),dl=a(function(i){let o=Bi.get(i.url),c=o?.get(i.database);if(!c){nt.warn("Connected node not found in replication map, this may be because the node is being removed",i.database,o);return}c.connected=!0,c.latency=i.latency;let l=c.nodes[0];if(!l){nt.info("Connected node has no nodes",i.database,c);return}if(!l.name){nt.debug("Connected node is not named yet",i.database,c);return}c.nodes=[l];let u=!1;for(let f of Bi.values()){let d=f.get(i.database);if(!d||d==c)continue;let{worker:_,nodes:h,connected:m}=d;if(h)if(m===!1&&h[0].shard===l.shard)u=!0,c.nodes.push(h[0]);else{let S=h.filter(g=>g.name!==l.name);S.length<h.length&&(d.nodes=S,_.postMessage({type:"subscribe-to-node",database:i.database,nodes:h}))}}u&&c.worker&&c.worker.postMessage({type:"subscribe-to-node",database:i.database,nodes:c.nodes})},"connectedToNode"),(0,Hi.onMessageByType)("disconnected-from-node",zu),(0,Hi.onMessageByType)("connected-to-node",dl),(0,Hi.onMessageByType)("request-cluster-status",eF)}function eF(e,t){let r=[];for(let[n,s]of Wu)try{let i=Bi.get(s.url);nt.info("Getting cluster status for",n,s.url,"has dbs",i?.size);let o=[];if(i){for(let[l,{worker:u,connected:f,nodes:d,latency:_}]of i)o.push({database:l,connected:f,latency:_,thread_id:u?.threadId,nodes:d.filter(h=>!(h.end_time<Date.now())).map(h=>h.name)});let c=(0,HO.cloneDeep)(s);c.database_sockets=o,delete c.ca,delete c.node_name,delete c.__updatedtime__,delete c.__createdtime__,r.push(c)}}catch(i){nt.warn("Error getting cluster status for",s?.url,i)}return t?.postMessage({type:"cluster-status",connections:r}),{connections:r}}async function Ao(e,t){let r=ir();e=e??Js(t.url),t.name=e;try{if(t.ca){let s=new Zk.X509Certificate(t.ca);t.ca_info={issuer:s.issuer.replace(/\n/g," "),subject:s.subject.replace(/\n/g," "),subject_alt_name:s.subjectAltName,serial_number:s.serialNumber,valid_from:s.validFrom,valid_to:s.validTo}}}catch(s){nt.error("Error parsing replication CA info for hdb_nodes table",s.message)}let n=r.primaryStore.get(e);if(nt.debug(`Ensuring node ${e} at ${t.url}, existing record:`,n,"new record:",t),!n)await r.patch(t);else{t.replicates&&!kO.default.get(x.CLUSTERING_ENABLED)&&(t.subscriptions=null);for(let s in t)if(n[s]!==t[s]&&s==="subscriptions"&&t[s]&&n[s]){let i=[],o=(0,HO.cloneDeep)(n[s]);for(let c of t[s]){let l=!1;for(let u of o)if((c.database??c.schema)===(u.database??u.schema)&&c.table===u.table){u.publish=c.publish,u.subscribe=c.subscribe,l=!0;break}l||i.push(c)}t.subscriptions=[...o,...i];break}if(Array.isArray(t.revoked_certificates)){let s=n.revoked_certificates||[];t.revoked_certificates=[...new Set([...s,...t.revoked_certificates])]}nt.info(`Updating node ${e} at ${t.url}`),await r.patch(t)}}var Hi,yg,nt,HO,kO,Zk,fie,Bi,zu,dl,Wu,Rg,lh=Re(()=>{xe();Hi=M(it());gs();yg=require("worker_threads");ul();nt=M(ee()),HO=require("lodash"),kO=M(le());k();Zk=require("crypto"),fie=200,Bi=new Map,Wu=new Map,Rg=new Map;a(FO,"startOnMainThread");a(eF,"requestClusterStatus");yg.parentPort&&(zu=a(e=>{yg.parentPort.postMessage({type:"disconnected-from-node",...e})},"disconnectedFromNode"),dl=a(e=>{yg.parentPort.postMessage({type:"connected-to-node",...e})},"connectedToNode"),(0,Hi.onMessageByType)("subscribe-to-node",e=>{ch(e)}),(0,Hi.onMessageByType)("unsubscribe-from-node",e=>{bg(e)}));a(Ao,"ensureNode")});var ei=C(bF=>{"use strict";var or=require("path"),{watch:_ie}=require("chokidar"),On=require("fs-extra"),Qu=require("node-forge"),aF=require("net"),{generateKeyPair:qO,X509Certificate:Ro,createPrivateKey:cF}=require("crypto"),hie=require("util");qO=hie.promisify(qO);var bt=Qu.pki,Xs=require("joi"),{v4:lF}=require("uuid"),{validateBySchema:YO}=ot(),Tt=ee(),Zn=le(),Ss=(k(),P(q)),{CONFIG_PARAMS:_l}=Ss,Zs=ab(),{ClientError:Na}=he(),Og=require("node:tls"),{relative:uF,join:mie}=require("node:path"),{CERT_PREFERENCE_APP:nCe,CERTIFICATE_VALUES:rF}=Zs,pie=_c(),$O=Lt(),{table:Eie,getDatabases:gie,databases:GO}=(xe(),P(ct)),{getJWTRSAKeys:nF}=(ku(),P(J_));Object.assign(bF,{generateKeys:QO,updateConfigCert:gF,createCsr:Oie,signCertificate:Nie,setCertTable:ju,loadCertificates:mF,reviewSelfSignedCert:JO,createTLSSelector:TF,listCertificates:RF,addCertificate:Lie,removeCertificate:vie,createNatsCerts:Cie,generateCertsKeys:Iie,getReplicationCert:dh,getReplicationCertAuth:bie,renewSelfSigned:Pie,hostnamesFromCert:XO,getKey:Uie});var{urlToNodeName:dF,getThisNodeUrl:Sie,getThisNodeName:wg,clearThisNodeName:Tie}=(gs(),P(Ca)),{readFileSync:Aie,statSync:fF}=require("node:fs"),sCe=le(),{getTicketKeys:Rie,onMessageFromWorkers:yie}=it(),Oa=ee(),{isMainThread:_F}=require("worker_threads"),{TLSSocket:hF,createSecureContext:iCe}=require("node:tls"),WO=3650,uh=["127.0.0.1","localhost","::1"],zO=[{name:"countryName",value:"USA"},{name:"stateOrProvinceName",value:"Colorado"},{name:"localityName",value:"Denver"},{name:"organizationName",value:"HarperDB, Inc."}];yie(async e=>{e.type===Ss.ITC_EVENT_TYPES.RESTART&&(Zn.initSync(!0),await JO())});var kr;function Ia(){return kr||(kr=gie().system.hdb_certificate,kr||(kr=Eie({table:"hdb_certificate",database:"system",attributes:[{name:"name",isPrimaryKey:!0},{attribute:"uses"},{attribute:"certificate"},{attribute:"is_authority"},{attribute:"private_key_name"},{attribute:"details"},{attribute:"is_self_signed"},{attribute:"__updatedtime__"}]}))),kr}a(Ia,"getCertTable");async function dh(){let e=TF("operations-api"),t={secureContexts:null,setSecureContext:a(s=>{},"setSecureContext")};await e.initialize(t);let r=t.secureContexts.get(wg());if(!r)return;let n=new Ro(r.options.cert);return r.cert_parsed=n,r.issuer=n.issuer,r}a(dh,"getReplicationCert");async function bie(){Ia();let e=(await dh()).options.cert,r=new Ro(e).issuer.match(/CN=(.*)/)?.[1];return kr.get(r)}a(bie,"getReplicationCertAuth");var sF,wa=new Map;function mF(){if(sF)return;sF=!0;let e=[{configKey:_l.TLS},{configKey:_l.OPERATIONSAPI_TLS}];Ia();let t=or.dirname($O.getConfigFilePath()),r;for(let{configKey:n}of e){let s=$O.getConfigFromFile(n);if(s){Array.isArray(s)||(s=[s]);for(let i of s){let o=i.privateKey,c=o&&uF(mie(t,"keys"),o);c&&iF(o,l=>{wa.set(c,l)},"private key");for(let l of[!1,!0]){let u=i[l?"certificateAuthority":"certificate"];if(u&&_F){let f;iF(u,d=>{if(rF.cert===d)return;let _=i.hostname??i.hostnames??i.host??i.hosts;_&&!Array.isArray(_)&&(_=[_]);let h=SF(u),m=new Ro(h),S;try{S=yF(m)}catch(T){logger.error("error extracting host name from certificate",T);return}if(S==null){logger.error("No host name found on certificate");return}if(m.checkIssued(new Ro(rF.cert)))return;let g=kr.primaryStore.get(S),R=fF(u).mtimeMs,E=!g||g.is_self_signed?1:g.file_timestamp??g.__updatedtime__;if(g&&R<=E){R<E&&Tt.info(`Certificate ${S} at ${u} is older (${new Date(R)}) than the certificate in the database (${E>1?new Date(E):"only self signed certificate available"})`);return}r=kr.put({name:S,uses:["https",...n.includes("operations")?["operations"]:[]],ciphers:i.ciphers,certificate:h,private_key_name:c,is_authority:l,hostnames:_,file_timestamp:R,details:{issuer:m.issuer.replace(/\n/g," "),subject:m.subject?.replace(/\n/g," "),subject_alt_name:m.subjectAltName,serial_number:m.serialNumber,valid_from:m.validFrom,valid_to:m.validTo}})},l?"certificate authority":"certificate")}}}}}return r}a(mF,"loadCertificates");function iF(e,t,r){let n,s=a((i,o)=>{try{let c=o.mtimeMs;c&&c!==n&&(n&&_F&&Tt.warn(`Reloading ${r}:`,i),n=c,t(SF(i)))}catch(c){Tt.error(`Error loading ${r}:`,i,c)}},"loadFile");On.existsSync(e)?s(e,fF(e)):Tt.error(`${r} file not found:`,e),_ie(e,{persistent:!1}).on("change",s)}a(iF,"loadAndWatch");function VO(){let e=Sie();if(e==null){let t=uh[0];return Tt.info("replication url is missing from harperdb-config.yaml, using default host"+t),t}return dF(e)}a(VO,"getHost");function Ng(){let e=wg();if(e==null){let t=uh[0];return Tt.info("replication url is missing from harperdb-config.yaml, using default host"+t),t}return e}a(Ng,"getCommonName");async function Oie(){let e=await dh(),t=bt.certificateFromPem(e.options.cert),r=bt.privateKeyFromPem(e.options.key);Tt.info("Creating CSR with cert named:",e.name);let n=bt.createCertificationRequest();n.publicKey=t.publicKey;let s=[{name:"commonName",value:Ng()},...zO];Tt.info("Creating CSR with subject",s),n.setSubject(s);let i=[{name:"unstructuredName",value:"HarperDB, Inc."},{name:"extensionRequest",extensions:pF()}];return Tt.info("Creating CSR with attributes",i),n.setAttributes(i),n.sign(r),Qu.pki.certificationRequestToPem(n)}a(Oie,"createCsr");function pF(){let e=uh.includes(Ng())?uh:[...uh,Ng()];return e.includes(VO())||e.push(VO()),[{name:"basicConstraints",cA:!1,critical:!0},{name:"keyUsage",digitalSignature:!0,keyEncipherment:!0,critical:!0},{name:"extKeyUsage",serverAuth:!0,clientAuth:!0},{name:"nsCertType",client:!0,server:!0},{name:"subjectAltName",altNames:e.map(t=>aF.isIP(t)?{type:7,ip:t}:{type:2,value:t})}]}a(pF,"certExtensions");async function Nie(e){let t={},r=or.join(Zn.getHdbBasePath(),Ss.LICENSE_KEY_DIR_NAME);if(e.csr){let n,s;Ia();for await(let f of kr.search([]))if(f.is_authority&&!f.details.issuer.includes("HarperDB-Certificate-Authority")){if(wa.has(f.private_key_name)){n=wa.get(f.private_key_name),s=f;break}else if(f.private_key_name&&await On.exists(or.join(r,f.private_key_name))){n=On.readFile(or.join(r,f.private_key_name)),s=f;break}}if(!n){let f=await KO();s=f.ca,n=f.private_key}n=bt.privateKeyFromPem(n),t.signingCA=s.certificate;let i=bt.certificateFromPem(s.certificate);Tt.info("Signing CSR with cert named",s.name);let o=bt.certificationRequestFromPem(e.csr);try{o.verify()}catch(f){return Tt.error(f),new Error("Error verifying CSR: "+f.message)}let c=Qu.pki.createCertificate();c.serialNumber=Math.random().toString().slice(2,10),c.validity.notBefore=new Date;let l=new Date;c.validity.notAfter=l,c.validity.notAfter.setDate(l.getDate()+WO),Tt.info("sign cert setting validity:",c.validity),Tt.info("sign cert setting subject from CSR:",o.subject.attributes),c.setSubject(o.subject.attributes),Tt.info("sign cert setting issuer:",i.subject.attributes),c.setIssuer(i.subject.attributes);let u=o.getAttribute({name:"extensionRequest"}).extensions;Tt.info("sign cert adding extensions from CSR:",u),c.setExtensions(u),c.publicKey=o.publicKey,c.sign(n,Qu.md.sha256.create()),t.certificate=bt.certificateToPem(c)}else Tt.info("Sign cert did not receive a CSR from:",e.url,"only the CA will be returned");return t}a(Nie,"signCertificate");async function wie(e,t){await ju({name:wg(),uses:["https","wss"],certificate:e,private_key_name:"privateKey.pem",is_authority:!1,is_self_signed:!0}),await ju({name:t.subject.getField("CN").value,uses:["https","wss"],certificate:bt.certificateToPem(t),private_key_name:"privateKey.pem",is_authority:!0,is_self_signed:!0})}a(wie,"createCertificateTable");async function ju(e){let t=new Ro(e.certificate);e.details={issuer:t.issuer.replace(/\n/g," "),subject:t.subject?.replace(/\n/g," "),subject_alt_name:t.subjectAltName,serial_number:t.serialNumber,valid_from:t.validFrom,valid_to:t.validTo},Ia(),await kr.patch(e)}a(ju,"setCertTable");async function QO(){let e=await qO("rsa",{modulusLength:4096,publicKeyEncoding:{type:"spki",format:"pem"},privateKeyEncoding:{type:"pkcs8",format:"pem"}});return{public_key:bt.publicKeyFromPem(e.publicKey),private_key:bt.privateKeyFromPem(e.privateKey)}}a(QO,"generateKeys");async function jO(e,t,r){let n=bt.createCertificate();if(!t){let o=await dh();t=bt.certificateFromPem(o.options.cert).publicKey}n.publicKey=t,n.serialNumber=Math.random().toString().slice(2,10),n.validity.notBefore=new Date;let s=new Date;n.validity.notAfter=s,n.validity.notAfter.setDate(s.getDate()+WO);let i=[{name:"commonName",value:Ng()},...zO];return n.setSubject(i),n.setIssuer(r.subject.attributes),n.setExtensions(pF()),n.sign(e,Qu.md.sha256.create()),bt.certificateToPem(n)}a(jO,"generateCertificates");async function KO(){let e=await RF(),t;for(let r of e){if(!r.is_authority)continue;let n=await AF(r.private_key_name);if(r.private_key_name&&n&&new Ro(r.certificate).checkPrivateKey(cF(n))){Tt.trace(`CA named: ${r.name} found with matching private key`),t={ca:r,private_key:n};break}}if(t)return t;Tt.trace("No CA found with matching private key")}a(KO,"getCertAuthority");async function EF(e,t,r=!0){let n=bt.createCertificate();n.publicKey=t,n.serialNumber=Math.random().toString().slice(2,10),n.validity.notBefore=new Date;let s=new Date;n.validity.notAfter=s,n.validity.notAfter.setDate(s.getDate()+WO);let i=[{name:"commonName",value:`HarperDB-Certificate-Authority-${Zn.get(_l.REPLICATION_HOSTNAME)??dF(Zn.get(_l.REPLICATION_URL))??lF().split("-")[0]}`},...zO];n.setSubject(i),n.setIssuer(i),n.setExtensions([{name:"basicConstraints",cA:!0,critical:!0},{name:"keyUsage",keyCertSign:!0,critical:!0}]),n.sign(e,Qu.md.sha256.create());let o=or.join(Zn.getHdbBasePath(),Ss.LICENSE_KEY_DIR_NAME),c=or.join(o,Zs.PRIVATEKEY_PEM_NAME);return r&&await On.writeFile(c,bt.privateKeyToPem(e)),n}a(EF,"generateCertAuthority");async function Iie(){let{private_key:e,public_key:t}=await QO(),r=await EF(e,t),n=await jO(e,t,r);await wie(n,r),gF()}a(Iie,"generateCertsKeys");async function Cie(){let e=await jO(bt.privateKeyFromPem(Zs.CERTIFICATE_VALUES.key),void 0,bt.certificateFromPem(Zs.CERTIFICATE_VALUES.cert)),t=or.join(Zn.getHdbBasePath(),Ss.LICENSE_KEY_DIR_NAME),r=or.join(t,Zs.NATS_CERTIFICATE_PEM_NAME);await On.exists(r)||await On.writeFile(r,e);let n=or.join(t,Zs.NATS_CA_PEM_NAME);await On.exists(n)||await On.writeFile(n,Zs.CERTIFICATE_VALUES.cert)}a(Cie,"createNatsCerts");async function Pie(){Ia();for await(let e of kr.search([{attribute:"is_self_signed",value:!0}]))await kr.delete(e.name);await JO()}a(Pie,"renewSelfSigned");async function JO(){Tie(),await mF(),Ia();let e=await KO();if(!e){Tt.notify("A matching Certificate Authority and key was not found. A new CA will be created in advance, so it's available if needed.");let r=a(u=>{try{return{key:bt.privateKeyFromPem(On.readFileSync(u)),keyPath:u}}catch(f){return Tt.warn(`Failed to parse private key from ${u}:`,f.message),{key:null,keyPath:u}}},"tryToParseKey"),n=Zn.get(_l.TLS),s,i;if(Array.isArray(n)){for(let u of n)if(u.privateKey){let f=r(u.privateKey);if(s=f.key,i=f.keyPath,f.key)break}}else{let u=Zn.get(_l.TLS_PRIVATEKEY),f=r(u);s=f.key,i=f.keyPath}let o=or.join(Zn.getHdbBasePath(),Ss.LICENSE_KEY_DIR_NAME),c=uF(o,i);s||(Tt.warn("Unable to parse the TLS key",i,"A new key will be generated and used to create Certificate Authority"),{private_key:s}=await QO(),On.existsSync(or.join(o,Zs.PRIVATEKEY_PEM_NAME))&&(c=`privateKey${lF().split("-")[0]}.pem`),await On.writeFile(or.join(o,c),bt.privateKeyToPem(s)));let l=await EF(s,bt.setRsaPublicKey(s.n,s.e),!1);await ju({name:l.subject.getField("CN").value,uses:["https"],certificate:bt.certificateToPem(l),private_key_name:c,is_authority:!0,is_self_signed:!0})}if(!await dh()){let r=wg();Tt.notify(`A suitable replication certificate was not found, creating new self singed cert named: ${r}`),e=e??await KO();let n=bt.certificateFromPem(e.ca.certificate),s=n.publicKey,i=await jO(bt.privateKeyFromPem(e.private_key),s,n);await ju({name:r,uses:["https","operations","wss"],certificate:i,is_authority:!1,private_key_name:e.ca.private_key_name,is_self_signed:!0})}}a(JO,"reviewSelfSignedCert");function gF(){let e=pie(Object.keys(Ss.CONFIG_PARAM_MAP),!0),t=or.join(Zn.getHdbBasePath(),Ss.LICENSE_KEY_DIR_NAME),r=or.join(t,Zs.PRIVATEKEY_PEM_NAME),n=or.join(t,Zs.NATS_CERTIFICATE_PEM_NAME),s=or.join(t,Zs.NATS_CA_PEM_NAME),i=Ss.CONFIG_PARAMS,o={[i.TLS_PRIVATEKEY]:e[i.TLS_PRIVATEKEY.toLowerCase()]?e[i.TLS_PRIVATEKEY.toLowerCase()]:r};e[i.TLS_CERTIFICATE.toLowerCase()]&&(o[i.TLS_CERTIFICATE]=e[i.TLS_CERTIFICATE.toLowerCase()]),e[i.TLS_CERTIFICATEAUTHORITY.toLowerCase()]&&(o[i.TLS_CERTIFICATEAUTHORITY]=e[i.TLS_CERTIFICATEAUTHORITY.toLowerCase()]),e[i.OPERATIONSAPI_TLS_CERTIFICATE.toLowerCase()]&&(o[i.OPERATIONSAPI_TLS_CERTIFICATE]=e[i.OPERATIONSAPI_TLS_CERTIFICATE.toLowerCase()]),e[i.OPERATIONSAPI_TLS_PRIVATEKEY.toLowerCase()]&&(o[i.OPERATIONSAPI_TLS_PRIVATEKEY]=e[i.OPERATIONSAPI_TLS_PRIVATEKEY.toLowerCase()]),e[i.OPERATIONSAPI_TLS_CERTIFICATEAUTHORITY.toLowerCase()]&&(o[i.OPERATIONSAPI_TLS_CERTIFICATEAUTHORITY]=e[i.OPERATIONSAPI_TLS_CERTIFICATEAUTHORITY.toLowerCase()]),(e[i.CLUSTERING_ENABLED.toLowerCase()]||e.clustering)&&(o[i.CLUSTERING_TLS_CERTIFICATE]=e[i.CLUSTERING_TLS_CERTIFICATE.toLowerCase()]??n,o[i.CLUSTERING_TLS_CERT_AUTH]=e[i.CLUSTERING_TLS_CERT_AUTH.toLowerCase()]??s,o[i.CLUSTERING_TLS_PRIVATEKEY]=e[i.CLUSTERING_TLS_PRIVATEKEY.toLowerCase()]??r),$O.updateConfigValue(void 0,void 0,o,!1,!0)}a(gF,"updateConfigCert");function SF(e){return e.startsWith("-----BEGIN")?e:Aie(e,"utf8")}a(SF,"readPEM");var oF=Og.createSecureContext;Og.createSecureContext=function(e){if(!e.cert||!e.key)return oF(e);let t={...e};delete t.key,delete t.cert;let r=oF(t);return r.context.setCert(e.cert),r.context.setKey(e.key,void 0),r};var Die=hF.prototype._init;hF.prototype._init=function(e,t){Die.call(this,e,t);let r=this;this._handle.oncertcb=function(n){let s=n.servername;r._SNICallback(s,(i,o)=>{this.sni_context=o?.context||o,this.certCbDone()})}};var fl=new Map;function TF(e,t){let r=new Map,n,s=!1;return i.initialize=o=>i.ready?i.ready:(o&&(o.secureContexts=r,o.secureContextsListeners=[]),i.ready=new Promise((c,l)=>{async function u(){try{r.clear(),fl.clear();let f=0;for await(let d of GO.system.hdb_certificate.search([])){let _=d.certificate,h=new Ro(_);d.is_authority&&(h.asString=_,fl.set(h.subject,_))}for await(let d of GO.system.hdb_certificate.search([]))try{if(d.is_authority)continue;let _=e==="operations-api",h=d.is_self_signed?1:2;_&&d.uses?.includes?.("operations")&&(h+=1);let m=await AF(d.private_key_name),S=d.certificate,g=new Ro(S);if(fl.has(g.issuer)&&(S+=`
23
23
  `+fl.get(g.issuer)),!m||!S)throw new Error("Missing private key or certificate for secure server");let R={ciphers:d.ciphers,ticketKeys:Rie(),availableCAs:fl,ca:t&&Array.from(fl.values()),cert:S,key:m,key_file:d.private_key_name,is_self_signed:d.is_self_signed};o&&(R.sessionIdContext=o.sessionIdContext);let E=Og.createSecureContext(R);E.name=d.name,E.options=R,E.quality=h,E.certificateAuthorities=Array.from(fl),E.certStart=S.toString().slice(0,100);let T=d.hostnames??XO(g);Array.isArray(T)||(T=[T]);let N;for(let v of T)if(v){v[0]==="*"&&(s=!0,v=v.slice(1)),v===VO()&&(h+=2),aF.isIP(v)&&(N=!0);let H=r.get(v)?.quality??0;h>H&&r.set(v,E)}else Oa.error("No hostname found for certificate at",Og.certificate);Oa.trace("Adding TLS",E.name,"for",o.ports||"client","cert named",d.name,"hostnames",T,"quality",h,"best quality",f),h>f&&(i.defaultContext=n=E,f=h,o&&(o.defaultContext=E))}catch(_){Oa.error("Error applying TLS for",d.name,_)}o?.secureContextsListeners.forEach(d=>d()),c(n)}catch(f){l(f)}}a(u,"updateTLS"),GO.system.hdb_certificate.subscribe({listener:a(()=>setTimeout(()=>u(),1500).unref(),"listener"),omitCurrent:!0}),u()})),i;function i(o,c){Oa.info("TLS requested for",o||"(no SNI)");let l=o;for(;;){let f=r.get(l);if(f)return Oa.debug("Found certificate for",o,f.certStart),f.updatedContext&&(f=f.updatedContext),c(null,f);if(s&&l){let d=l.indexOf(".",1);d<0?l="":l=l.slice(d)}else break}o?Oa.debug("No certificate found to match",o,"using the default certificate"):Oa.debug("No SNI, using the default certificate",n?.name);let u=n;u?u.updatedContext&&(u=u.updatedContext):Oa.info("No default certificate found"),c(null,u)}a(i,"SNICallback")}a(TF,"createTLSSelector");async function AF(e){let t=wa.get(e);return!t&&e?await On.readFile(or.join(Zn.get(_l.ROOTPATH),Ss.LICENSE_KEY_DIR_NAME,e),"utf8"):t}a(AF,"getPrivateKeyByName");async function RF(){Ia();let e=[];for await(let t of kr.search([]))e.push(t);return e}a(RF,"listCertificates");async function Lie(e){let t=YO(e,Xs.object({name:Xs.string().required(),certificate:Xs.string().required(),is_authority:Xs.boolean().required(),private_key:Xs.string(),hosts:Xs.array(),uses:Xs.array()}));if(t)throw new Na(t.message);let{name:r,certificate:n,private_key:s,is_authority:i}=e,o=new Ro(n),c=!1,l=!1,u;for(let[h,m]of wa)!s&&!c&&o.checkPrivateKey(cF(m))&&(c=!0,u=h),s&&s===m&&(l=!0,u=h);if(!i&&!s&&!c)throw new Na("A suitable private key was not found for this certificate");let f;if(!r){try{f=yF(o)}catch(h){Tt.error(h)}if(f==null)throw new Na("Error extracting certificate common name, please provide a name parameter")}let d=Mie(r??f);s&&!c&&!l&&(await On.writeFile(or.join(Zn.getHdbBasePath(),Ss.LICENSE_KEY_DIR_NAME,d+".pem"),s),wa.set(d,s));let _={name:r??f,certificate:n,is_authority:i,hosts:e.hosts,uses:e.uses};return(!i||i&&u||i&&s)&&(_.private_key_name=u??d+".pem"),e.ciphers&&(_.ciphers=e.ciphers),await ju(_),"Successfully added certificate: "+d}a(Lie,"addCertificate");function Mie(e){return e.replace(/[^a-z0-9\.]/gi,"-")}a(Mie,"sanitizeName");async function vie(e){let t=YO(e,Xs.object({name:Xs.string().required()}));if(t)throw new Na(t.message);let{name:r}=e;Ia();let n=await kr.get(r);if(!n)throw new Na(r+" not found");let{private_key_name:s}=n;if(s){let i=Array.from(await kr.search([{attribute:"private_key_name",value:s}]));i.length===1&&i[0].name===r&&(Tt.info("Removing private key named",s),await On.remove(or.join(Zn.getHdbBasePath(),Ss.LICENSE_KEY_DIR_NAME,s)))}return await kr.delete(r),"Successfully removed "+r}a(vie,"removeCertificate");function yF(e){let t=e.subject?.match(/CN=(.*)/)?.[1];return t||XO(e)[0]}a(yF,"getPrimaryHostName");function XO(e){if(e.subjectAltName)return e.subjectAltName.split(",").map(r=>{let n=r.indexOf(":");if(r=r.slice(n+1),r=r.trim(),r[0]==='"')try{r=JSON.parse(r)}catch{}return r.indexOf("=")>-1?r.match(/CN=([^,]*)/)?.[1]:r}).filter(r=>r);let t=certObj.subject?.match(/CN=(.*)/)?.[1];return t?[t]:[]}a(XO,"hostnamesFromCert");async function Uie(e){if(e.bypass_auth!==!0)throw new Na("Unauthorized","401");let t=YO(e,Xs.object({name:Xs.string().required()}));if(t)throw new Na(t.message);let{name:r}=e;if(r===".jwtPrivate")return(await nF()).privateKey;if(r===".jwtPublic")return(await nF()).publicKey;if(wa.get(r))return wa.get(e.name);throw new Na("Key not found")}a(Uie,"getKey")});var YF={};Ue(YF,{CONFIRMATION_STATUS_POSITION:()=>$F,NodeReplicationConnection:()=>Xu,OPERATION_REQUEST:()=>rN,RECEIVED_TIME_POSITION:()=>sN,RECEIVED_VERSION_POSITION:()=>nN,RECEIVING_STATUS_POSITION:()=>iN,RECEIVING_STATUS_RECEIVING:()=>KF,RECEIVING_STATUS_WAITING:()=>VF,SENDING_TIME_POSITION:()=>fh,createWebSocket:()=>vg,database_subscriptions:()=>Da,replicateOverWS:()=>_h,table_update_listeners:()=>aN});async function vg(e,t){let{authorization:r,rejectUnauthorized:n}=t||{},s=et(),i;if(e==null)throw new TypeError(`Invalid URL: Expected a string URL for node "${s}" but received ${e}`);if(e.includes("wss://")){if(!eN){let l=(0,kF.createTLSSelector)("operations-api"),u={secureContexts:null};await l.initialize(u),eN=u.secureContexts}if(i=eN.get(s),i&&ce.debug?.("Creating web socket for URL",e,"with certificate named:",i.name),!i&&n!==!1)throw new Error("Unable to find a valid certificate to use for replication to connect to "+e)}let o={};r&&(o.Authorization=r);let c={headers:o,localAddress:s?.startsWith("127.0")?s:void 0,servername:(0,GF.isIP)(t?.serverName)?void 0:t?.serverName,noDelay:!0,highWaterMark:128*1024,rejectUnauthorized:n!==!1,secureContext:void 0};return i&&(Mg?.caCount!==yo.size&&(Mg=FF.createSecureContext({...i.options,ca:[...yo,...i.options.availableCAs.values()]}),Mg.caCount=yo.size),c.secureContext=Mg),new BF.WebSocket(e,"harperdb-replication-v1",c)}function _h(e,t,r){let n=t.port||t.securePort,s=hl.pid%1e3+"-"+HF.threadId+(n?"s:"+n:"c:"+t.url?.slice(-4))+" "+Math.random().toString().slice(2,3),i=0,o=Buffer.allocUnsafeSlow(1024),c=0,l=new DataView(o.buffer,0,1024),u=t.database,f=t.databaseSubscriptions||Da,d,_,h=!1,m=t.subscription;m?.then&&m.then(A=>m=A);let S=t.tables||u&&Je()[u];if(!r){ce.error?.("No authorization provided"),cn(1008,"Unauthorized");return}let g=new Map,R=[],E=r.name;E&&t.connection&&(t.connection.nodeName=E);let T,N,v,H,X,W,$,se=6e4,z,fe=0,ue=0,Z=0,Ae=xF.default.get(x.REPLICATION_BLOBTIMEOUT)??12e4,me=new Map,ye=[],Ht=0,dt;if(t.url){let A=a(()=>{X&&ue===e._socket?.bytesRead&&Z===e._socket?.bytesWritten?e.terminate():(X=performance.now(),e.ping(),ue=e._socket?.bytesRead,Z=e._socket?.bytesWritten)},"send_ping");v=setInterval(A,vF).unref(),A()}else Ln();e._socket?.setMaxListeners(200);function Ln(){clearTimeout(H),ue=e._socket?.bytesRead,Z=e._socket?.bytesWritten,H=setTimeout(()=>{ue===e._socket?.bytesRead&&Z===e._socket?.bytesWritten&&(ce.warn?.(`Timeout waiting for ping from ${E}, terminating connection and reconnecting`),e.terminate())},vF*2).unref()}a(Ln,"resetPingTimer");function an(){return _||(_=Ag(d,u,E)),_}a(an,"getSharedStatus"),u&&jo(u);let Cr,Qd,oc=[],ZT=[],eA,kt=[],jd=[],Jd=[],tA=150,wm=25,Xd=0,Ce=0,Zd=!1,Ji,Pr,Mn,ac;e.on("message",A=>{fe=performance.now();try{let y=A.dataView=new Lc(A.buffer,A.byteOffset,A.byteLength);if(A[0]>127){let B=(0,Ze.decode)(A),[w,D,G]=B;switch(w){case NF:{if(D){if(E){if(E!==D){ce.error?.(s,`Node name mismatch, expecting to connect to ${E}, but peer reported name as ${D}, disconnecting`),e.send((0,Ze.encode)([Ju])),cn(1008,"Node name mismatch");return}}else if(E=D,t.connection?.tentativeNode){let oe=t.connection.tentativeNode;oe.name=E,t.connection.tentativeNode=null,Ao(E,oe)}if(t.connection&&(t.connection.nodeName=E),ce.debug?.(s,"received node name:",E,"db:",u),!u)try{jo(u=B[2]),u==="system"&&(Cr=ya(t,(oe,V)=>{Qo(V)&&rf(V)}),e.on("close",()=>{Cr?.remove()}))}catch(oe){ce.warn?.(s,"Error setting database",oe),e.send((0,Ze.encode)([Ju])),cn(1008,oe.message);return}zo()}break}case LF:{ce.debug?.(s,"Received table definitions for",D.map(oe=>oe.table));for(let oe of D){let V=B[2];oe.database=V;let J;Qo(V)&&(V==="system"?We[V]?.[oe.table]||(J=L(oe,We[V]?.[oe.table])):J=L(oe,We[V]?.[oe.table]),d||(d=J?.auditStore),S||(S=Je()?.[V]))}break}case Ju:cn();break;case rN:try{let oe=r?.replicates||r?.subscribers||r?.name;server.operation(D,{user:r},!oe).then(V=>{Array.isArray(V)&&(V={results:V}),V.requestId=D.requestId,e.send((0,Ze.encode)([Cg,V]))},V=>{e.send((0,Ze.encode)([Cg,{requestId:D.requestId,error:V instanceof Error?V.toString():V}]))})}catch(oe){e.send((0,Ze.encode)([Cg,{requestId:D.requestId,error:oe instanceof Error?oe.toString():oe}]))}break;case Cg:let{resolve:j,reject:Q}=g.get(D.requestId);D.error?Q(new Error(D.error)):j(D),g.delete(D.requestId);break;case ZO:let F=B[3];S||(u?ce.error?.(s,"No tables found for",u):ce.error?.(s,"Database name never received"));let ve=S[F];ve=L({table:F,database:u,attributes:D.attributes,schemaDefined:D.schemaDefined},ve),oc[G]={name:F,decoder:new Ze.Packr({useBigIntExtension:!0,randomAccessStructure:!0,freezeData:!0,typedStructs:D.typedStructs,structures:D.structures}),getEntry(oe){return ve.primaryStore.getEntry(oe)},rootStore:ve.primaryStore.rootStore};break;case wF:ac=d?Wk(D,d):new Map,eA=B[2],ce.debug?.(s,`Acknowledged subscription request, receiving messages for nodes: ${eA}`);break;case IF:let Ee=G;Jd[Ee]=D;break;case DF:an()[$F]=D,ce.trace?.(s,"received and broadcasting committed update",D),an().buffer.notify();break;case PF:T=D,m.send({type:"end_txn",localTime:T,remoteNodeIds:R});break;case Pg:{let oe=B[1],{fileId:V,size:J,finished:de,error:pe}=oe,ae=me.get(V);ce.debug?.("Received blob",V,"has stream",!!ae,"connectedToBlob",!!ae?.connectedToBlob,"length",B[2].length,"finished",de),ae||(ae=new tN.PassThrough,ae.expectedSize=J,me.set(V,ae)),ae.lastChunk=Date.now();let Ie=B[2];Mt(Ie.byteLength,"bytes-received",`${E}.${u}`,"replication","blob");try{de?(pe?(ae.on("error",()=>{}),ae.destroy(new Error("Blob error: "+pe+" for record "+(ae.recordId??"unknown")+" from "+E))):ae.end(Ie),ae.connectedToBlob&&me.delete(V)):ae.write(Ie)}catch(He){ce.error?.(`Error receiving blob for ${ae.recordId} from ${E} and streaming to storage`,He),me.delete(V)}break}case CF:{let oe=D,V;try{let J=B[3],de=ZT[G]||(ZT[G]=S[B[4]]);if(!de)return ce.warn?.("Unknown table id trying to handle record request",G);let pe=de.primaryStore.getBinaryFast(Symbol.for("structures")),ae=pe?.length;if(ae>0&&ae!==Ce){Ce=ae;let He=(0,Ze.decode)(pe);e.send((0,Ze.encode)([ZO,{typedStructs:He.typed,structures:He.named},G,de.tableName]))}let Ie=de.primaryStore.getBinaryFast(J);if(Ie){let He=de.primaryStore.decoder.decode(Ie,{valueAsBuffer:!0}),De=He.value;He[Nc]&Ur&&(De=Buffer.from(De),vf(()=>de.primaryStore.decoder.decode(Ie),rt=>cc(rt,J),de.primaryStore.rootStore)),V=(0,Ze.encode)([Ig,oe,{value:De,expiresAt:He.expiresAt,version:He.version,residencyId:He.residencyId,nodeId:He.nodeId,user:He.user}])}else V=(0,Ze.encode)([Ig,oe])}catch(J){V=(0,Ze.encode)([Ig,oe,{error:J.message}])}e.send(V);break}case Ig:{let{resolve:oe,reject:V,tableId:J,key:de}=g.get(B[1]),pe=B[2];if(pe?.error)V(new Error(pe.error));else if(pe){let ae;hp(()=>{let Ie=oc[J].decoder.decode(pe.value);pe.value=Ie,pe.key=de,oe(pe)||ae&&setTimeout(()=>ae.forEach(dp),6e4).unref()},d?.rootStore,Ie=>{let He=ef(Ie,de);return ae||(ae=[]),ae.push(He),He})}else oe();g.delete(B[1]);break}case OF:{Mn=D;let oe,V,J=!1;if(m){if(u!==m.databaseName&&!m.then){ce.error?.("Subscription request for wrong database",u,m.databaseName);return}}else m=f.get(u);if(ce.debug?.(s,"received subscription request for",u,"at",Mn),!m){let Oe;m=new Promise(Ft=>{ce.debug?.("Waiting for subscription to database "+u),Oe=Ft}),m.ready=Oe,Da.set(u,m)}if(r.name)V=ir().subscribe(r.name),V.then(async Oe=>{oe=Oe;for await(let Ft of oe){let Nt=Ft.value;if(!(Nt?.replicates===!0||Nt?.replicates?.receives||Nt?.subscriptions?.some(yr=>(yr.database||yr.schema)===u&&yr.publish!==!1))){J=!0,e.send((0,Ze.encode)([Ju])),cn(1008,`Unauthorized database subscription to ${u}`);return}}},Oe=>{ce.error?.(s,"Error subscribing to HDB nodes",Oe)});else if(!(r?.role?.permission?.super_user||r.replicates)){e.send((0,Ze.encode)([Ju])),cn(1008,`Unauthorized database subscription to ${u}`);return}if(Pr&&(ce.debug?.(s,"stopping previous subscription",u),Pr.emit("close")),Mn.length===0)return;let de=Mn[0],pe=a(Oe=>{if(Oe&&(de.replicateByDefault?!de.tables.includes(Oe.tableName):de.tables.includes(Oe.tableName)))return{table:Oe}},"tableToTableEntry"),ae={txnTime:0},Ie,He,De=1/0,rt,vn=a((Oe,Ft)=>{if(Oe.type==="end_txn"){ae.txnTime&&(o[i]!==66&&ce.error?.("Invalid encoding of message"),Xi(9),Xi(Mp),p(rt=Ft),di()),i=c,ae.txnTime=0;return}let Nt=Oe.nodeId,yr=Oe.tableId,Rt=He[yr];if(!Rt&&(Rt=He[yr]=pe(m.tableById[yr]),!Rt))return ce.debug?.("Not subscribed to table",yr);let ls=Rt.table,wt=ls.primaryStore,vs=wt.encoder;(Oe.extendedType&Tp||!vs.typedStructs)&&(vs._mergeStructures(vs.getStructures()),vs.typedStructs&&(vs.lastTypedStructuresLength=vs.typedStructs.length));let Kl=Ie[Nt];if(!(Kl&&Kl.startTime<Ft&&(!Kl.endTime||Kl.endTime>Ft)))return Lg&&ce.trace?.(s,"skipping replication update",Oe.recordId,"to:",E,"from:",Nt,"subscribed:",Ie),uP();Lg&&ce.trace?.(s,"sending replication update",Oe.recordId,"to:",E,"from:",Nt,"subscribed:",Ie);let rA=Oe.version;ae.txnTime!==rA&&(ae.txnTime&&(Lg&&ce.trace?.(s,"new txn time, sending queued txn",ae.txnTime),o[i]!==66&&ce.error?.("Invalid encoding of message"),di()),ae.txnTime=rA,i=c,p(rA));let dc=Oe.residencyId,nA=tf(dc,ls),Cm;if(nA&&!nA.includes(E)){let Us=tf(Oe.previousResidencyId,ls);if(Us&&!Us.includes(E)&&(Oe.type==="put"||Oe.type==="patch")||ls.getResidencyById)return uP();let nf=Oe.recordId;ce.trace?.(s,"sending invalidation",nf,E,"from",Nt);let sf=0;dc&&(sf|=Cc),Oe.previousResidencyId&&(sf|=Pc);let oA,Pm=null;for(let dP in ls.indices){if(!Pm){if(oA=Oe.getValue(wt,!0),!oA)break;Pm={}}Pm[dP]=oA[dP]}Cm=wc(Oe.version,yr,nf,null,Nt,Oe.user,Oe.type==="put"||Oe.type==="patch"?"invalidate":Oe.type,vs.encode(Pm),sf,dc,Oe.previousResidencyId,Oe.expiresAt)}function uP(){return ce.trace?.(s,"skipping audit record",Oe.recordId),W||(W=setTimeout(()=>{W=null,(rt||0)+MF/2<De&&(Lg&&ce.trace?.(s,"sending skipped sequence update",De),e.send((0,Ze.encode)([PF,De])))},MF).unref()),new Promise(setImmediate)}a(uP,"skipAuditRecord");let sA=vs.typedStructs,iA=vs.structures;if((sA?.length!=Rt.typed_length||iA?.length!=Rt.structure_length)&&(Rt.typed_length=sA?.length,Rt.structure_length=iA.length,ce.debug?.(s,"send table struct",Rt.typed_length,Rt.structure_length),Rt.sentName||(Rt.sentName=!0),e.send((0,Ze.encode)([ZO,{typedStructs:sA,structures:iA,attributes:ls.attributes,schemaDefined:ls.schemaDefined},yr,Rt.table.tableName]))),dc&&!jd[dc]&&(e.send((0,Ze.encode)([IF,nA,dc])),jd[dc]=!0),Cm)Xi(Cm.length),K(Cm);else{let Us=Oe.encoded;Oe.extendedType&Ur&&vf(()=>Oe.getValue(wt),sf=>cc(sf,Oe.recordId),wt.rootStore);let nf=Us[0]===66?8:0;Xi(Us.length-nf),K(Us,nf),ce.trace?.("wrote record",Oe.recordId,"length:",Us.length)}return e._socket.writableNeedDrain?new Promise(Us=>{ce.debug?.(`Waiting for remote node ${E} to allow more commits ${e._socket.writableNeedDrain?"due to network backlog":"due to requested flow directive"}`),e._socket.once("drain",Us)}):Ht>wm?new Promise(Us=>{dt=Us}):new Promise(setImmediate)},"sendAuditRecord"),di=a(()=>{c-i>8?(e.send(o.subarray(i,c)),ce.debug?.(s,"Sent message, size:",c-i),Mt(c-i,"bytes-sent",`${E}.${u}`,"replication","egress")):ce.debug?.(s,"skipping empty transaction")},"sendQueuedData");Pr=new oN.EventEmitter,Pr.once("close",()=>{J=!0,oe?.end()});for(let{startTime:Oe}of Mn)Oe<De&&(De=Oe);(V||Promise.resolve()).then(async()=>{m=await m,d=m.auditStore,He=m.tableById.map(pe),Ie=[];for(let{name:Ft,startTime:Nt,endTime:yr}of Mn){let Rt=Tg(Ft,d);ce.debug?.("subscription to",Ft,"using local id",Rt,"starting",Nt),Ie[Rt]={startTime:Nt,endTime:yr}}rf(u),Cr||(Cr=nl(Ft=>{Ft.databaseName===u&&rf(u)}),Qd=G_(Ft=>{Ft===u&&(e.send((0,Ze.encode)([Ju])),cn())}),e.on("close",()=>{Cr?.remove(),Qd?.remove()})),e.send((0,Ze.encode)([wF,sh(m.auditStore),Mn.map(({name:Ft})=>Ft)]));let Oe=!0;do{isFinite(De)||(ce.warn?.("Invalid sequence id "+De),cn(1008,"Invalid sequence id"+De));let Ft;if(Oe&&!J&&(Oe=!1,De===0)){let Nt=De,yr=Ug(d);for(let Rt in S){if(!pe(Rt))continue;let ls=S[Rt];ce.warn?.(`Fully copying ${Rt} table to ${E}`);for(let wt of ls.primaryStore.getRange({snapshot:!1,versions:!0})){if(J)return;if(wt.localTime>=De){ce.trace?.(s,"Copying record from",u,Rt,wt.key,wt.localTime),Nt=Math.max(wt.localTime,Nt),Ft=!0,an()[fh]=1;let vs=wc(wt.version,ls.tableId,wt.key,null,yr,null,"put",vf(()=>ls.primaryStore.encoder.encode(wt.value),Kl=>cc(Kl,wt.key)),wt.metadataFlags&-256,wt.residencyId,null,wt.expiresAt);await vn({recordId:wt.key,tableId:ls.tableId,type:"put",getValue(){return wt.value},encoded:vs,version:wt.version,residencyId:wt.residencyId,nodeId:yr,extendedType:wt.metadataFlags},wt.localTime)}}}Ft&&vn({type:"end_txn"},De),an()[fh]=0,De=Nt}for(let{key:Nt,value:yr}of d.getRange({start:De||1,exclusiveStart:!0,snapshot:!1})){if(J)return;let Rt=St(yr);ce.debug?.("sending audit record",new Date(Nt)),an()[fh]=Nt,De=Nt,await vn(Rt,Nt),Pr.startTime=Nt,Ft=!0}Ft&&vn({type:"end_txn"},De),an()[fh]=0,await GL(d)}while(!J)}).catch(Oe=>{ce.error?.(s,"Error handling subscription to node",Oe),cn(1008,"Error handling subscription to node")});break}}return}y.position=8;let I=!0,b,U;do{an();let B=y.readInt();if(B===9&&y.getUint8(y.position)==Mp){y.position++,T=U=y.readFloat64(),_[nN]=T,_[sN]=Date.now(),_[iN]=VF,ce.trace?.("received remote sequence update",T,u);break}let w=y.position,D=St(A,w,w+B),G=oc[D.tableId];G||ce.error?.(`No table found with an id of ${D.tableId}`);let j;D.residencyId&&(j=Jd[D.residencyId],ce.trace?.(s,"received residency list",j,D.type,D.recordId));try{let Q=D.recordId;hp(()=>{b={table:G.name,id:Q,type:D.type,nodeId:ac.get(D.nodeId),residencyList:j,timestamp:D.version,value:D.getValue(G),user:D.user,beginTxn:I,expiresAt:D.expiresAt}},d?.rootStore,F=>ef(F,Q))}catch(Q){throw Q.message+="typed structures for current decoder"+JSON.stringify(G.decoder.typedStructs),Q}I=!1,ce.trace?.(s,"received replication message",D.type,"id",b.id,"version",new Date(D.version),"nodeId",b.nodeId),_[nN]=D.version,_[sN]=Date.now(),_[iN]=KF,m.send(b),y.position=w+B}while(y.position<A.byteLength);Xd++,Mt(A.byteLength,"bytes-received",`${E}.${u}.${b?.table||"unknown_table"}`,"replication","ingest"),Xd>tA&&!Zd&&(Zd=!0,e.pause(),ce.debug?.(`Commit backlog causing replication back-pressure, requesting that ${E} pause replication`)),m.send({type:"end_txn",localTime:T,remoteNodeIds:R,async onCommit(){if(b){let B=Date.now()-b.timestamp;Mt(B,"replication-latency",E+"."+u+"."+b.table,b.type,"ingest")}Xd--,Zd&&(Zd=!1,e.resume(),ce.debug?.(`Replication resuming ${E}`)),ye.length>0&&await Promise.all(ye),ce.trace?.("All blobs finished"),!N&&U&&(ce.trace?.(s,"queuing confirmation of a commit at",U),setTimeout(()=>{e.send((0,Ze.encode)([DF,N])),ce.trace?.(s,"sent confirmation of a commit at",N),N=null},Bie)),N=U,ce.debug?.("last sequence committed",new Date(U),u)}})}catch(y){ce.error?.(s,"Error handling incoming replication message",y)}}),e.on("ping",Ln),e.on("pong",()=>{t.connection&&(t.connection.latency=performance.now()-X,t.isSubscriptionConnection&&dl({name:E,database:u,url:t.url,latency:t.connection.latency})),X=null}),e.on("close",(A,y)=>{clearInterval(v),clearTimeout(H),clearInterval($),Pr&&Pr.emit("close"),Ji&&Ji.end();for(let[I,{reject:b}]of g)b(new Error(`Connection closed ${y?.toString()} ${A}`));ce.debug?.(s,"closed",A,y?.toString())});function cn(A,y){e.isFinished=!0,e.close(A,y),t.connection?.emit("finished")}a(cn,"close");let Dr=new Set;async function cc(A,y){let I=fp(A);if(Dr.has(I)){ce.debug?.("Blob already being sent",I);return}Dr.add(I);try{let b;Ht++;for await(let U of A.stream())b&&(ce.debug?.("Sending blob chunk",I,"length",b.length),e.send((0,Ze.encode)([Pg,{fileId:I,size:A.size},b]))),b=U,e._socket.writableNeedDrain&&(ce.debug?.("draining",I),await new Promise(B=>e._socket.once("drain",B)),ce.debug?.("drained",I)),Mt(U.length,"bytes-sent",`${E}.${u}`,"replication","blob");ce.debug?.("Sending final blob chunk",I,"length",b.length),e.send((0,Ze.encode)([Pg,{fileId:I,size:A.size,finished:!0},b]))}catch(b){ce.warn?.("Error sending blob",b,"blob id",I,"for record",y),e.send((0,Ze.encode)([Pg,{fileId:I,finished:!0,error:b.toString()},Buffer.alloc(0)]))}finally{Dr.delete(I),Ht--,Ht<wm&&dt?.()}}a(cc,"sendBlobs");function ef(A,y){let I=fp(A),b=me.get(I);ce.debug?.("Received transaction for record",y,"with blob",I,"has stream",!!b,"ended",!!b?.writableEnded),b?b.writableEnded&&me.delete(I):(b=new tN.PassThrough,me.set(I,b)),b.connectedToBlob=!0,b.lastChunk=Date.now(),b.recordId=y,A.size===void 0&&b.expectedSize&&(A.size=b.expectedSize);let U=b.blob??createBlob(b,A);b.blob=U;let B=oo(()=>Mf(U).saving,m.auditStore?.rootStore);return B&&(B.blobId=I,ye.push(B),B.finally(()=>{ce.debug?.(`Finished receiving blob stream ${I}`),ye.splice(ye.indexOf(B),1)})),U}a(ef,"receiveBlobs");function zo(){if(h||(h=!0,t.connection?.on("subscriptions-updated",zo)),t.connection?.isFinished)throw new Error("Can not make a subscription request on a connection that is already closed");let A=new Map;d||(d=m?.auditStore);try{for(let b of m?.dbisDB?.getRange({start:Symbol.for("seq"),end:[Symbol.for("seq"),Buffer.from([255])]})||[])for(let U of b.value.nodes||[])U.lastTxnTime>(A.get(U.id)??0)&&A.set(U.id,U.lastTxnTime)}catch(b){if(!b.message.includes("Can not re"))throw b}let y=t.connection?.nodeSubscriptions?.[0];R=[];let I=t.connection?.nodeSubscriptions?.map((b,U)=>{let B=[],{replicateByDefault:w}=b;if(b.subscriptions){for(let Q of b.subscriptions)if(Q.subscribe&&(Q.schema||Q.database)===u){let F=Q.table;S?.[F]?.replicate!==!1&&B.push(F)}w=!1}else for(let Q in S)(w?S[Q].replicate===!1:S[Q].replicate)&&B.push(Q);let D=d&&Tg(b.name,d),G=m?.dbisDB?.get([Symbol.for("seq"),D])??1,j=Math.max(G?.seqId??1,(typeof b.start_time=="string"?new Date(b.start_time).getTime():b.start_time)??1);if(ce.debug?.("Starting time recorded in db",b.name,D,u,G?.seqId,"start time:",j,new Date(j)),y!==b){let Q=d&&Tg(y.name,d),F=m?.dbisDB?.get([Symbol.for("seq"),Q])??1;for(let ve of F?.nodes||[])ve.name===b.name&&(j=ve.seqId,ce.debug?.("Using sequence id from proxy node",y.name,j))}if(D===void 0?ce.warn("Starting subscription request from node",b,"but no node id found"):R.push(D),A.get(D)>j&&(j=A.get(D),ce.debug?.("Updating start time from more recent txn recorded",y.name,j)),j===1&&Dg)try{new URL(Dg).hostname===b.name&&E===b.name?(ce.warn?.(`Requesting full copy of database ${u} from ${Dg}`),j=0):j=Date.now()-6e4}catch(Q){ce.error?.("Error parsing leader URL",Dg,Q)}return ce.trace?.(s,"defining subscription request",b.name,u,new Date(j)),{name:b.name,replicateByDefault:w,tables:B,startTime:j,endTime:b.end_time}});if(I)if(ce.debug?.(s,"sending subscription request",I,m?.dbisDB?.path),clearTimeout(z),I.length>0)e.send((0,Ze.encode)([OF,I]));else{let b=a(()=>{let U=performance.now();z=setTimeout(()=>{fe<=U?cn(1008,"Connection has no subscriptions and is no longer used"):b()},se).unref()},"schedule_close");b()}}a(zo,"sendSubscriptionRequestUpdate");function tf(A,y){if(!A)return;let I=kt[A];return I||(I=y.getResidencyRecord(A),kt[A]=I),I}a(tf,"getResidence");function Qo(A){return!(Pa&&Pa!="*"&&!Pa[A]&&!Pa.includes?.(A)&&!Pa.some?.(y=>y.name===A))}a(Qo,"checkDatabaseAccess");function jo(A){if(m=m||f.get(A),!Qo(A))throw new Error(`Access to database "${A}" is not permitted`);m||ce.warn?.(`No database named "${A}" was declared and registered`),d=m?.auditStore,S||(S=Je()?.[A]);let y=et();if(y===E)throw y?new Error("Should not connect to self",y):new Error("Node name not defined");return Im(y,A),!0}a(jo,"setDatabase");function Im(A,y){let I=Je()?.[y],b=[];for(let U in I){let B=I[U];b.push({table:U,schemaDefined:B.schemaDefined,attributes:B.attributes.map(w=>({name:w.name,type:w.type,isPrimaryKey:w.isPrimaryKey}))})}ce.trace?.("Sending database info for node",A,"database name",y),e.send((0,Ze.encode)([NF,A,y,b]))}a(Im,"sendNodeDBName");function rf(A){let y=Je()?.[A],I=[];for(let b in y){if(Mn&&!Mn.some(B=>B.replicateByDefault?!B.tables.includes(b):B.tables.includes(b)))continue;let U=y[b];I.push({table:b,schemaDefined:U.schemaDefined,attributes:U.attributes.map(B=>({name:B.name,type:B.type,isPrimaryKey:B.isPrimaryKey}))})}e.send((0,Ze.encode)([LF,I,A]))}a(rf,"sendDBSchema"),$=setInterval(()=>{for(let[A,y]of me)y.lastChunk+Ae<Date.now()&&(ce.warn?.(`Timeout waiting for blob stream to finish ${A} for record ${y.recordId??"unknown"} from ${E}`),me.delete(A),y.end())},Ae).unref();let lc=1,uc=[];return{end(){Ji&&Ji.end(),Pr&&Pr.emit("close")},getRecord(A){let y=lc++;return new Promise((I,b)=>{let U=[CF,y,A.table.tableId,A.id];uc[A.table.tableId]||(U.push(A.table.tableName),uc[A.table.tableId]=!0),e.send((0,Ze.encode)(U)),fe=performance.now(),g.set(y,{tableId:A.table.tableId,key:A.id,resolve(B){let{table:w,entry:D}=A;if(I(B),B)return w._recordRelocate(D,B)},reject:b})})},sendOperation(A){let y=lc++;return A.requestId=y,e.send((0,Ze.encode)([rN,A])),new Promise((I,b)=>{g.set(y,{resolve:I,reject:b})})}};function Xi(A){O(5),A<128?o[c++]=A:A<16384?(l.setUint16(c,A|32768),c+=2):A<1056964608?(l.setUint32(c,A|3221225472),c+=4):(o[c]=255,l.setUint32(c+1,A),c+=5)}function K(A,y=0,I=A.length){let b=I-y;O(b),A.copy(o,c,y,I),c+=b}function p(A){O(8),l.setFloat64(c,A),c+=8}function O(A){if(A+16>o.length-c){let y=Buffer.allocUnsafeSlow(c+A-i+65536>>10<<11);o.copy(y,0,i,c),c=c-i,i=0,o=y,l=new DataView(o.buffer,0,o.length)}}function L(A,y){let I=A.database??"data";if(I!=="data"&&!We[I]){ce.warn?.("Database not found",A.database);return}y||(y={});let b=y.schemaDefined,U=!1,B=A.schemaDefined,w=y.attributes||[];for(let D=0;D<A.attributes?.length;D++){let G=A.attributes[D],j=w.find(Q=>Q.name===G.name);(!j||j.type!==G.type)&&(b?ce.error?.(`Schema for '${u}.${A.table}' is defined locally, but attribute '${G.name}: ${G.type}' from '${E}' does not match local attribute ${j?"'"+j.name+": "+j.type+"'":"which does not exist"}`):(U=!0,B||(G.indexed=!0),j?w[w.indexOf(j)]=G:w.push(G)))}return U?(ce.debug?.("(Re)creating",A),_t({table:A.table,database:A.database,schemaDefined:A.schemaDefined,attributes:w,...y})):y}}var xF,Ze,BF,HF,ce,oN,kF,FF,hl,GF,tN,qF,OF,NF,wF,Ju,IF,ZO,CF,Ig,rN,Cg,PF,DF,LF,Pg,$F,nN,sN,fh,iN,VF,KF,xie,Dg,aN,Da,Lg,MF,Bie,vF,eN,Mg,UF,Xu,cN=Re(()=>{xe();Ai();xO();TR();gs();xF=M(le());k();cu();Ze=require("msgpackr"),BF=require("ws"),HF=require("worker_threads"),ce=M(ks());lh();oN=require("events"),kF=M(ei()),FF=M(require("node:tls"));ul();hl=M(require("node:process")),GF=require("node:net");Di();hn();tN=require("node:stream"),qF=M(require("minimist")),OF=129,NF=140,wF=141,Ju=142,IF=130,ZO=132,CF=133,Ig=134,rN=136,Cg=137,PF=143,DF=144,LF=145,Pg=146,$F=0,nN=1,sN=2,fh=3,iN=4,VF=0,KF=1,xie=(0,qF.default)(hl.argv),Dg=xie.HDB_LEADER_URL??hl.env.HDB_LEADER_URL,aN=new Map,Da=new Map,Lg=!0,MF=300,Bie=2,vF=3e4;a(vg,"createWebSocket");UF=500,Xu=class extends oN.EventEmitter{constructor(r,n,s,i,o){super();this.url=r;this.subscription=n;this.databaseName=s;this.nodeName=i;this.authorization=o;this.nodeName=this.nodeName??Js(r)}static{a(this,"NodeReplicationConnection")}socket;startTime;retryTime=UF;retries=0;isConnected=!0;isFinished=!1;nodeSubscriptions;latency=0;replicateTablesByDefault;session;sessionResolve;sessionReject;async connect(){this.session||this.resetSession();let r=[];this.socket=await vg(this.url,{serverName:this.nodeName,authorization:this.authorization});let n;ce.debug?.(`Connecting to ${this.url}, db: ${this.databaseName}, process ${hl.pid}`),this.socket.on("open",()=>{this.socket._socket.unref(),ce[this.isConnected?"info":"warn"]?.(`Connected to ${this.url}, db: ${this.databaseName}`),this.retries=0,this.retryTime=UF,this.nodeSubscriptions&&dl({name:this.nodeName,database:this.databaseName,url:this.url}),this.isConnected=!0,n=_h(this.socket,{database:this.databaseName,subscription:this.subscription,url:this.url,connection:this,isSubscriptionConnection:this.nodeSubscriptions!==void 0},{replicates:!0}),this.sessionResolve(n)}),this.socket.on("error",s=>{s.code==="SELF_SIGNED_CERT_IN_CHAIN"?(ce.warn?.(`Can not connect to ${this.url}, this server does not have a certificate authority for the certificate provided by ${this.url}`),s.isHandled=!0):s.code!=="ECONNREFUSED"&&(s.code==="UNABLE_TO_VERIFY_LEAF_SIGNATURE"?ce.error?.(`Can not connect to ${this.url}, the certificate provided by ${this.url} is not trusted, this node needs to be added to the cluster, or a certificate authority needs to be added`):ce.error?.(`Error in connection to ${this.url} due to ${s.message}`)),this.sessionReject(s)}),this.socket.on("close",(s,i)=>{if(this.isConnected&&(this.nodeSubscriptions&&zu({name:this.nodeName,database:this.databaseName,url:this.url,finished:this.socket.isFinished}),this.isConnected=!1),this.removeAllListeners("subscriptions-updated"),this.socket.isFinished){this.isFinished=!0,n?.end(),this.emit("finished");return}if(++this.retries%20===1){let o=i?.toString();ce.warn?.(`${n?"Disconnected from":"Failed to connect to"} ${this.url} (db: "${this.databaseName}"), due to ${o?'"'+o+'" ':""}(code: ${s})`)}n=null,this.resetSession(),setTimeout(()=>{this.connect()},this.retryTime).unref(),this.retryTime+=this.retryTime>>8})}resetSession(){this.session=new Promise((r,n)=>{this.sessionResolve=r,this.sessionReject=n})}subscribe(r,n){this.nodeSubscriptions=r,this.replicateTablesByDefault=n,this.emit("subscriptions-updated",r)}unsubscribe(){this.socket.isFinished=!0,this.socket.close(1008,"No longer subscribed")}getRecord(r){return this.session.then(n=>n.getRecord(r))}};a(_h,"replicateOverWS")});var Ca={};Ue(Ca,{clearThisNodeName:()=>Yie,disableReplication:()=>Gie,enabled_databases:()=>Pa,forEachReplicatedDatabase:()=>ya,getThisNodeId:()=>Ug,getThisNodeName:()=>et,getThisNodeUrl:()=>ba,hostnameToUrl:()=>Fg,lastTimeInAuditStore:()=>ih,monitorNodeCAs:()=>eG,replicateOperation:()=>zie,replication_certificate_authorities:()=>yo,sendOperationToNode:()=>hh,servers:()=>kie,setReplicator:()=>rG,start:()=>Fie,startOnMainThread:()=>FO,subscribeToNode:()=>ch,unsubscribeFromNode:()=>bg,urlToNodeName:()=>Js});function Fie(e){if(e.port||(e.port=Ts.default.get(x.OPERATIONSAPI_NETWORK_PORT)),e.securePort||(e.securePort=Ts.default.get(x.OPERATIONSAPI_NETWORK_SECUREPORT)),!et())throw new Error("Can not load replication without a url (see replication.url in the config)");let t=new Map;for(let s of ah(e))t.set(Js(s.url),s);qie(e),e={mtls:!0,isOperationsServer:!0,maxPayload:10*1024*1024*1024,...e};let r=Ye.ws(async(s,i,o,c)=>{if(i.headers.get("sec-websocket-protocol")!=="harperdb-replication-v1")return c(s,i,o);await o,s._socket.unref(),_h(s,e,i?.user),s.on("error",l=>{l.code!=="ECONNREFUSED"&&ar.error("Error in connection to "+this.url,l.message)})},e);e.runFirst=!0,Ye.http((s,i)=>{if(s.isWebSocket&&s.headers.get("Sec-WebSocket-Protocol")==="harperdb-replication-v1"){!s.authorized&&s._nodeRequest.socket.authorizationError&&ar.error(`Incoming client connection from ${s.ip} did not have valid certificate, you may need turn on enableRootCAs in the config if you are using a publicly signed certificate, or add the CA to the server's trusted CAs`,s._nodeRequest.socket.authorizationError);let o=ir().primaryStore;if(s.authorized&&s.peerCertificate.subject){let c=s.peerCertificate.subject,l=c&&(o.get(c.CN)||t.get(c.CN));if(l)if(l?.revoked_certificates?.includes(s.peerCertificate.serialNumber)){ar.warn("Revoked certificate used in attempt to connect to node",l.name,"certificate serial number",s.peerCertificate.serialNumber);return}else s.user=l;else ar.warn(`No node found for certificate common name ${c.CN}, available nodes are ${Array.from(o.getRange({}).filter(({value:u})=>u).map(({key:u})=>u)).join(", ")} and routes ${Array.from(t.keys()).join(", ")}, connection will require credentials.`)}else{let c=o.get(s.ip)||t.get(s.ip);c?s.user=c:ar.warn(`No node found for IP address ${s.ip}, available nodes are ${Array.from(new Set([...o.getKeys(),...t.keys()])).join(", ")}, connection will require credentials.`)}}return i(s)},e);let n=[];for(let s of r)if(s.secureContexts){let i=a(()=>{let o=new Set(s.secureContexts.values());s.defaultContext&&o.add(s.defaultContext);for(let c of o)try{let l=Array.from(yo);c.options.availableCAs&&l.push(...c.options.availableCAs.values());let u={...c.options,ca:l};c.updatedContext=kg.createSecureContext(u)}catch(l){ar.error("Error creating replication TLS config",l)}},"updateContexts");s.secureContextsListeners.push(i),n.push(i),Ts.default.get(x.REPLICATION_ENABLEROOTCAS)!==!1&&i()}eG(()=>{for(let s of n)s()})}function eG(e){let t=0;Yu(r=>{r?.ca&&(yo.add(r.ca),yo.size!==t&&(t=yo.size,e?.()))})}function Gie(e=!0){ZF=e}function qie(e){ZF||(Je(),Pa=e.databases,ya(e,(t,r)=>{if(!t){let n=e.databaseSubscriptions||Da;for(let[s,i]of Bg){let o=i.get(r);o&&(o.subscribe([],!1),i.delete(r))}n.delete(r);return}for(let n in t){let s=t[n];rG(r,s,e),aN.get(s)?.forEach(i=>i(s))}}))}function rG(e,t,r){if(!t)return console.error(`Attempt to replicate non-existent table ${t.name} from database ${e}`);if(t.replicate===!1||t.sources?.some(s=>s.isReplicator))return;let n;t.sourcedFrom(class tG extends Vr{static{a(this,"Replicator")}static connection;static subscription;static async subscribe(){let i=r.databaseSubscriptions||Da,o=i.get(e),c=o?.tableById||[];c[t.tableId]=t;let l=o?.ready;if(ar.trace("Setting up replicator subscription to database",e),!o?.auditStore)return this.subscription=o=new xn,i.set(e,o),o.tableById=c,o.auditStore=t.auditStore,o.dbisDB=t.dbisDB,o.databaseName=e,l&&l(o),o;this.subscription=o}static subscribeOnThisThread(i,o){return!0}static async load(i){if(i){let o=i.residencyId,c=i.residency||t.dbisDB.get([Symbol.for("residency_by_id"),o]);if(c){let l,u=new Set;do{let f;for(let _ of c){if(_===Ye.hostname)continue;let h=Vie(_,tG.subscription,e);h?.isConnected&&!u.has(h)&&(!f||h.latency<f.latency)&&(f=h)}if(!f)throw l||new JF.ServerError("No connection to any other nodes are available",502);let d={requestId:Hie++,table:t,entry:i,id:i.key};u.add(f);try{return await f.getRecord(d)}catch(_){if(f.isConnected)throw _;ar.warn("Error in load from node",Hg,_),l||(l=_)}}while(!0)}}}static isReplicator=!0},{intermediateSource:!0})}function $ie(e,t,r,n,s){let i=Bg.get(e);i||(i=new Map,Bg.set(e,i));let o=i.get(r);if(o)return o;if(t)return i.set(r,o=new Xu(e,t,r,n,s)),o.connect(),o.once("finished",()=>i.delete(r)),o}function Vie(e,t,r){let n=WF.get(e);n||(n=new Map,WF.set(e,n));let s=n.get(r);if(s)return s;let i=ir().primaryStore.get(e);return i?.url&&(s=new Xu(i.url,t,r,e,i.authorization),n.set(r,s),s.connect(),s.once("finished",()=>n.delete(r))),s}async function hh(e,t,r){r||(r={}),r.serverName=e.name;let n=await vg(e.url,r),s=_h(n,{},{});return new Promise((i,o)=>{n.on("open",()=>{i(s.sendOperation(t))}),n.on("error",c=>{o(c)}),n.on("close",c=>{ar.info("Sending operation connection to "+e.url+" closed",c)})}).finally(()=>{n.close()})}function ch(e){try{XF.isMainThread&&ar.trace("Subscribing on main thread (should not happen in multi-threaded instance)",e.nodes[0].url,e.database);let t=Da.get(e.database);if(!t){let n;t=new Promise(s=>{ar.info("Waiting for subscription to database "+e.database),n=s}),t.ready=n,Da.set(e.database,t)}let r=$ie(e.nodes[0].url,t,e.database,e.nodes[0].name,e.nodes[0].authorization);e.nodes[0].name===void 0?r.tentativeNode=e.nodes[0]:r.nodeName=e.nodes[0].name,r.subscribe(e.nodes.filter(n=>oh(n,e.database)),e.replicateByDefault)}catch(t){ar.error("Error in subscription to node",e.nodes[0]?.url,t)}}async function bg({name:e,url:t,database:r}){ar.trace("Unsubscribing from node",e,t,r,"nodes",Array.from(ir().primaryStore.getRange({})));let n=Bg.get(t);if(n){let s=n.get(r);s&&(s.unsubscribe(),n.delete(r))}}function Kie(){if(lN!==void 0)return lN;let e=Ts.default.get(x.OPERATIONSAPI_TLS_CERTIFICATE)||Ts.default.get(x.TLS_CERTIFICATE);if(e)return lN=new QF.X509Certificate((0,jF.readFileSync)(e)).subject?.match(/CN=(.*)/)?.[1]??null}function et(){return Hg||(Hg=Ts.default.get("replication_hostname")??Js(Ts.default.get("replication_url"))??Kie()??zF("operationsapi_network_secureport")??zF("operationsapi_network_port")??"127.0.0.1")}function Yie(){Hg=void 0}function zF(e){let t=Ts.default.get(e),r=t?.lastIndexOf?.(":");if(r>0)return t.slice(0,r)}function xg(e){let t=Ts.default.get(e),r=t?.lastIndexOf?.(":");return r>0?+t.slice(r+1).replace(/[\[\]]/g,""):+t}function Ug(e){return sh(e)?.[et()]}function ba(){let e=Ts.default.get("replication_url");return e||Fg(et())}function Fg(e){let t=xg("replication_port");if(t)return`ws://${e}:${t}`;if(t=xg("replication_secureport"),t)return`wss://${e}:${t}`;if(t=xg("operationsapi_network_port"),t)return`ws://${e}:${t}`;if(t=xg("operationsapi_network_secureport"),t)return`wss://${e}:${t}`}function Js(e){if(e)return new URL(e).hostname}function ya(e,t){for(let n of Object.getOwnPropertyNames(We))r(n);return G_(n=>{r(n)}),nl((n,s)=>{r(n.databaseName)});function r(n){let s=We[n];ar.trace("Checking replication status of ",n,e?.databases),e?.databases===void 0||e.databases==="*"||e.databases.includes(n)||e.databases.some?.(i=>i.name===n)||!s?t(s,n,!0):Wie(n)&&t(s,n,!1)}a(r,"forDatabase")}function Wie(e){let t=We[e];for(let r in t)if(t[r].replicate)return!0}function ih(e){for(let t of e.getKeys({limit:1,reverse:!0}))return t}async function zie(e){let t={message:""};if(e.replicated){e.replicated=!1,ar.trace?.("Replicating operation",e.operation,"to nodes",Ye.nodes.map(n=>n.name));let r=await Promise.allSettled(Ye.nodes.map(n=>hh(n,e)));t.replicated=r.map((n,s)=>{let i=n.status==="rejected"?{status:"failed",reason:n.reason.toString()}:n.value;return i.node=Ye.nodes[s]?.name,i})}return t}var Ts,ar,QF,jF,kg,JF,XF,ZF,Hie,kie,yo,Pa,Bg,WF,lN,Hg,gs=Re(()=>{xe();na();Ql();cN();Lr();Ts=M(le()),ar=M(ee()),QF=require("crypto"),jF=require("fs");lh();ul();k();xO();kg=M(require("node:tls")),JF=M(he()),XF=require("worker_threads"),Hie=1,kie=[],yo=Ts.default.get(x.REPLICATION_ENABLEROOTCAS)!==!1?new Set(kg.rootCertificates):new Set;a(Fie,"start");a(eG,"monitorNodeCAs");a(Gie,"disableReplication");a(qie,"assignReplicationSource");a(rG,"setReplicator");Bg=new Map;a($ie,"getSubscriptionConnection");WF=new Map;a(Vie,"getRetrievalConnectionByName");a(hh,"sendOperationToNode");a(ch,"subscribeToNode");a(bg,"unsubscribeFromNode");a(Kie,"getCommonNameFromCert");a(et,"getThisNodeName");a(Yie,"clearThisNodeName");Object.defineProperty(Ye,"hostname",{get(){return et()}});a(zF,"getHostFromListeningPort");a(xg,"getPortFromListeningPort");a(Ug,"getThisNodeId");Ye.replication={getThisNodeId:Ug,exportIdMapping:sh};a(ba,"getThisNodeUrl");a(Fg,"hostnameToUrl");a(Js,"urlToNodeName");a(ya,"forEachReplicatedDatabase");a(Wie,"hasExplicitlyReplicatedTable");a(ih,"lastTimeInAuditStore");a(zie,"replicateOperation")});var ph=C((LCe,aG)=>{"use strict";var Zu=pk(),{validateBySchema:mh}=ot(),{common_validators:ed,schema_regex:uN}=bi(),cr=require("joi"),Qie=ee(),jie=require("uuid").v4,$g=uo(),td=(k(),P(q)),Jie=require("util"),La=$n(),{handleHDBError:bo,hdb_errors:Xie,ClientError:ml}=he(),{HDB_ERROR_MSGS:Gg,HTTP_STATUS_CODES:Oo}=Xie,{SchemaEventMsg:Vg}=qs(),nG=Sr(),{getDatabases:Zie}=(xe(),P(ct)),{transformReq:rd}=ie(),{replicateOperation:sG}=(gs(),P(Ca)),{cleanupOrphans:DCe}=(hn(),P(au)),qg=cr.string().min(1).max(ed.schema_length.maximum).pattern(uN).messages({"string.pattern.base":"{:#label} "+ed.schema_format.message}),eoe=cr.string().min(1).max(ed.schema_length.maximum).pattern(uN).messages({"string.pattern.base":"{:#label} "+ed.schema_format.message}).required(),toe=cr.string().min(1).max(ed.schema_length.maximum).pattern(uN).messages({"string.pattern.base":"{:#label} "+ed.schema_format.message,"any.required":"'primary_key' is required","string.base":"'primary_key' must be a string"}).required();aG.exports={createSchema:roe,createSchemaStructure:iG,createTable:noe,createTableStructure:oG,createAttribute:coe,dropSchema:soe,dropTable:ioe,dropAttribute:ooe,getBackup:loe,cleanupOrphanBlobs:uoe};async function roe(e){let t=await iG(e);return $g.signalSchemaChange(new Vg(process.pid,e.operation,e.schema)),t}a(roe,"createSchema");async function iG(e){let t=mh(e,cr.object({database:qg,schema:qg}));if(t)throw new ml(t.message);if(rd(e),!await Zu.checkSchemaExists(e.schema))throw bo(new Error,Gg.SCHEMA_EXISTS_ERR(e.schema),Oo.BAD_REQUEST,td.LOG_LEVELS.ERROR,Gg.SCHEMA_EXISTS_ERR(e.schema),!0);return await La.createSchema(e),`database '${e.schema}' successfully created`}a(iG,"createSchemaStructure");async function noe(e){return rd(e),e.hash_attribute=e.primary_key??e.hash_attribute,await oG(e)}a(noe,"createTable");async function oG(e){let t=mh(e,cr.object({database:qg,schema:qg,table:eoe,residence:cr.array().items(cr.string().min(1)).optional(),hash_attribute:toe}));if(t)throw new ml(t.message);if(!await Zu.checkSchemaTableExists(e.schema,e.table))throw bo(new Error,Gg.TABLE_EXISTS_ERR(e.schema,e.table),Oo.BAD_REQUEST,td.LOG_LEVELS.ERROR,Gg.TABLE_EXISTS_ERR(e.schema,e.table),!0);let n={name:e.table,schema:e.schema,id:jie(),hash_attribute:e.hash_attribute};try{if(e.residence)if(global.clustering_on)n.residence=e.residence,await La.createTable(n,e);else throw bo(new Error,"Clustering does not appear to be enabled. Cannot insert table with property 'residence'.",Oo.BAD_REQUEST);else await La.createTable(n,e);return`table '${e.schema}.${e.table}' successfully created.`}catch(s){throw s}}a(oG,"createTableStructure");async function soe(e){let t=mh(e,cr.object({database:cr.string(),schema:cr.string()}).or("database","schema").messages({"object.missing":"'database' is required"}));if(t)throw new ml(t.message);rd(e);let r=await Zu.checkSchemaExists(e.schema);if(r)throw bo(new Error,r,Oo.NOT_FOUND,td.LOG_LEVELS.ERROR,r,!0);let n=await Zu.schema_describe.describeSchema({schema:e.schema}),s=Object.keys(global.hdb_schema[e.schema]);await La.dropSchema(e),$g.signalSchemaChange(new Vg(process.pid,e.operation,e.schema)),await nG.purgeSchemaTableStreams(e.schema,s);let i=await sG(e);return i.message=`successfully deleted '${e.schema}'`,i}a(soe,"dropSchema");async function ioe(e){let t=mh(e,cr.object({database:cr.string(),schema:cr.string(),table:cr.string().required()}));if(t)throw new ml(t.message);rd(e);let r=await Zu.checkSchemaTableExists(e.schema,e.table);if(r)throw bo(new Error,r,Oo.NOT_FOUND,td.LOG_LEVELS.ERROR,r,!0);await La.dropTable(e),await nG.purgeTableStream(e.schema,e.table);let n=await sG(e);return n.message=`successfully deleted table '${e.schema}.${e.table}'`,n}a(ioe,"dropTable");async function ooe(e){let t=mh(e,cr.object({database:cr.string(),schema:cr.string(),table:cr.string().required(),attribute:cr.string().required()}));if(t)throw new ml(t.message);rd(e);let r=await Zu.checkSchemaTableExists(e.schema,e.table);if(r)throw bo(new Error,r,Oo.NOT_FOUND,td.LOG_LEVELS.ERROR,r,!0);if(e.attribute===global.hdb_schema[e.schema][e.table].hash_attribute)throw bo(new Error,"You cannot drop a hash attribute",Oo.BAD_REQUEST,void 0,void 0,!0);if(td.TIME_STAMP_NAMES.indexOf(e.attribute)>=0)throw bo(new Error,`cannot drop internal timestamp attribute: ${e.attribute}`,Oo.BAD_REQUEST,void 0,void 0,!0);try{return await La.dropAttribute(e),aoe(e),$g.signalSchemaChange(new Vg(process.pid,e.operation,e.schema,e.table,e.attribute)),`successfully deleted attribute '${e.attribute}'`}catch(n){throw Qie.error(`Got an error deleting attribute ${Jie.inspect(e)}.`),n}}a(ooe,"dropAttribute");function aoe(e){let t=Object.values(global.hdb_schema[e.schema][e.table].attributes);for(let r=0;r<t.length;r++)t[r].attribute===e.attribute&&global.hdb_schema[e.schema][e.table].attributes.splice(r,1)}a(aoe,"dropAttributeFromGlobal");async function coe(e){rd(e);let t=Zie()[e.schema][e.table].attributes;for(let{name:r}of t)if(r===e.attribute)throw bo(new Error,`attribute '${e.attribute}' already exists in ${e.schema}.${e.table}`,Oo.BAD_REQUEST,void 0,void 0,!0);return await La.createAttribute(e),$g.signalSchemaChange(new Vg(process.pid,e.operation,e.schema,e.table,e.attribute)),`attribute '${e.schema}.${e.table}.${e.attribute}' successfully created.`}a(coe,"createAttribute");function loe(e){return La.getBackup(e)}a(loe,"getBackup");function uoe(e){if(!e.database)throw new ml('Must provide "database" name for search for orphaned blobs');if(!databases[e.database])throw new ml(`Unknown database '${e.database}'`);let{cleanupOrphans:r}=(hn(),P(au));return r(databases[e.database],e.database),{message:"Orphaned blobs cleanup started, check logs for progress"}}a(uoe,"cleanupOrphanBlobs")});var lG=C((vCe,cG)=>{"use strict";var{OPERATIONS_ENUM:doe}=(k(),P(q)),dN=class{static{a(this,"ReadAuditLogObject")}constructor(t,r,n=void 0,s=void 0){this.operation=doe.READ_AUDIT_LOG,this.schema=t,this.table=r,this.search_type=n,this.search_values=s}};cG.exports=dN});var fN=C((BCe,hG)=>{"use strict";var foe=$n(),xCe=lG(),Kg=ie(),Yg=(k(),P(q)),_oe=le(),{handleHDBError:uG,hdb_errors:hoe}=he(),{HDB_ERROR_MSGS:dG,HTTP_STATUS_CODES:fG}=hoe,moe=Object.values(Yg.READ_AUDIT_LOG_SEARCH_TYPES_ENUM),_G="To use this operation audit log must be enabled in harperdb-config.yaml";hG.exports=poe;async function poe(e){if(Kg.isEmpty(e.schema))throw new Error(dG.SCHEMA_REQUIRED_ERR);if(Kg.isEmpty(e.table))throw new Error(dG.TABLE_REQUIRED_ERR);if(!_oe.get(Yg.CONFIG_PARAMS.LOGGING_AUDITLOG))throw uG(new Error,_G,fG.BAD_REQUEST,Yg.LOG_LEVELS.ERROR,_G,!0);let t=Kg.checkSchemaTableExist(e.schema,e.table);if(t)throw uG(new Error,t,fG.NOT_FOUND,Yg.LOG_LEVELS.ERROR,t,!0);if(!Kg.isEmpty(e.search_type)&&moe.indexOf(e.search_type)<0)throw new Error(`Invalid search_type '${e.search_type}'`);return await foe.readAuditLog(e)}a(poe,"readAuditLog")});var pG=C((kCe,mG)=>{"use strict";var{OPERATIONS_ENUM:Eoe}=(k(),P(q)),_N=class{static{a(this,"GetBackupObject")}constructor(t,r,n=void 0,s=void 0){this.operation=Eoe.GET_BACKUP,this.schema=t,this.table=r}};mG.exports=_N});var SG=C(($Ce,gG)=>{"use strict";var goe=$n(),GCe=pG(),hN=ie(),Soe=(k(),P(q)),qCe=le(),{handleHDBError:Toe,hdb_errors:Aoe}=he(),{HDB_ERROR_MSGS:EG,HTTP_STATUS_CODES:Roe}=Aoe;gG.exports=yoe;async function yoe(e){if(hN.isEmpty(e.schema))throw new Error(EG.SCHEMA_REQUIRED_ERR);if(hN.isEmpty(e.table))throw new Error(EG.TABLE_REQUIRED_ERR);let t=hN.checkSchemaTableExist(e.schema,e.table);if(t)throw Toe(new Error,t,Roe.NOT_FOUND,Soe.LOG_LEVELS.ERROR,t,!0);return await goe.getBackup(read_audit_log_object)}a(yoe,"getBackup")});var yG=C((KCe,RG)=>{"use strict";var boe=le(),Ma=require("joi"),Ooe=ot(),TG=require("moment"),Noe=require("fs-extra"),mN=require("path"),woe=require("lodash"),Eh=(k(),P(q)),{LOG_LEVELS:pl}=(k(),P(q)),Ioe="YYYY-MM-DD hh:mm:ss",Coe=mN.resolve(__dirname,"../logs");RG.exports=function(e){return Ooe.validateBySchema(e,Poe)};var Poe=Ma.object({from:Ma.custom(AG),until:Ma.custom(AG),level:Ma.valid(pl.NOTIFY,pl.FATAL,pl.ERROR,pl.WARN,pl.INFO,pl.DEBUG,pl.TRACE),order:Ma.valid("asc","desc"),limit:Ma.number().min(1),start:Ma.number().min(0),log_name:Ma.custom(Doe)});function AG(e,t){if(TG(e,TG.ISO_8601).format(Ioe)==="Invalid date")return t.message(`'${t.state.path[0]}' date '${e}' is invalid.`)}a(AG,"validateDatetime");function Doe(e,t){if(woe.invert(Eh.LOG_NAMES)[e]===void 0)return t.message(`'log_name' '${e}' is invalid.`);let n=boe.get(Eh.HDB_SETTINGS_NAMES.LOG_PATH_KEY),s=e===void 0?Eh.LOG_NAMES.HDB:e,i=s===Eh.LOG_NAMES.INSTALL?mN.join(Coe,Eh.LOG_NAMES.INSTALL):mN.join(n,s);return Noe.existsSync(i)?null:t.message(`'log_name' '${e}' does not exist.`)}a(Doe,"validateReadLogPath")});var EN=C((WCe,OG)=>{"use strict";var Wg=(k(),P(q)),Loe=ee(),Moe=le(),voe=yG(),pN=require("path"),bG=require("fs-extra"),{once:Uoe}=require("events"),{handleHDBError:xoe,hdb_errors:Boe}=he(),{PACKAGE_ROOT:Hoe}=Et(),koe=pN.join(Hoe,"logs"),Foe=1e3,Goe=200;OG.exports=qoe;async function qoe(e){let t=voe(e);if(t)throw xoe(t,t.message,Boe.HTTP_STATUS_CODES.BAD_REQUEST,void 0,void 0,!0);let r=Moe.get(Wg.HDB_SETTINGS_NAMES.LOG_PATH_KEY),n=e.log_name===void 0?Wg.LOG_NAMES.HDB:e.log_name,s=n===Wg.LOG_NAMES.INSTALL?pN.join(koe,Wg.LOG_NAMES.INSTALL):pN.join(r,n),i=e.level!==void 0,o=i?e.level:void 0,c=e.from!==void 0,l=c?new Date(e.from):void 0,u=e.until!==void 0,f=u?new Date(e.until):void 0,d=e.limit===void 0?Foe:e.limit,_=e.order===void 0?void 0:e.order,h=e.start===void 0?0:e.start,m=h+d,S=0;_==="desc"&&!l&&!f&&(S=Math.max(bG.statSync(s).size-(m+5)*Goe,0));let g=bG.createReadStream(s,{start:S});g.on("error",H=>{Loe.error(H)});let R=0,E=[],T="",N;g.on("data",H=>{let X=/(?:^|\n)(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:[\d\.]+Z) \[(.+?)]: /g;H=T+H;let W=0,$;for(;($=X.exec(H))&&!g.destroyed;){N&&(N.message=H.slice(W,$.index),v(N));let[se,z,fe]=$,ue=fe.split("] ["),Z=ue[0],Ae=ue[1];ue.splice(0,2),N={timestamp:z,thread:Z,level:Ae,tags:ue,message:""},W=$.index+se.length}T=H.slice(W)}),g.on("end",H=>{g.destroyed||N&&(N.message=T.trim(),v(N))}),g.resume();function v(H){let X,W,$;switch(!0){case(i&&c&&u):X=new Date(H.timestamp),W=new Date(l),$=new Date(f),H.level===o&&X>=W&&X<=$&&R<h?R++:H.level===o&&X>=W&&X<=$&&(va(H,_,E),R++,R===m&&g.destroy());break;case(i&&c):X=new Date(H.timestamp),W=new Date(l),H.level===o&&X>=W&&R<h?R++:H.level===o&&X>=W&&(va(H,_,E),R++,R===m&&g.destroy());break;case(i&&u):X=new Date(H.timestamp),$=new Date(f),H.level===o&&X<=$&&R<h?R++:H.level===o&&X<=$&&(va(H,_,E),R++,R===m&&g.destroy());break;case(c&&u):X=new Date(H.timestamp),W=new Date(l),$=new Date(f),X>=W&&X<=$&&R<h?R++:X>=W&&X<=$&&(va(H,_,E),R++,R===m&&g.destroy());break;case i:H.level===o&&R<h?R++:H.level===o&&(va(H,_,E),R++,R===m&&g.destroy());break;case c:X=new Date(H.timestamp),W=new Date(l),X>=W&&R<h?R++:X>=W&&R>=h&&(va(H,_,E),R++,R===m&&g.destroy());break;case u:X=new Date(H.timestamp),$=new Date(f),X<=$&&R<h?R++:X<=$&&R>=h&&(va(H,_,E),R++,R===m&&g.destroy());break;default:R<h?R++:(va(H,_,E),R++,R===m&&g.destroy())}}return a(v,"onLogMessage"),await Uoe(g,"close"),E}a(qoe,"readLog");function va(e,t,r){t==="desc"?$oe(e,r):t==="asc"?Voe(e,r):r.push(e)}a(va,"pushLineToResult");function $oe(e,t){let r=new Date(e.timestamp),n=0,s=t.length;for(;n<s;){let i=n+s>>>1;new Date(t[i].timestamp)>r?n=i+1:s=i}t.splice(n,0,e)}a($oe,"insertDescending");function Voe(e,t){let r=new Date(e.timestamp),n=0,s=t.length;for(;n<s;){let i=n+s>>>1;new Date(t[i].timestamp)<r?n=i+1:s=i}t.splice(n,0,e)}a(Voe,"insertAscending")});var zg=C((ZCe,CG)=>{"use strict";var gN=require("joi"),{string:nd,boolean:NG,date:Koe}=gN.types(),Yoe=ot(),{validateSchemaExists:QCe,validateTableExists:jCe,validateSchemaName:JCe}=bi(),Woe=(k(),P(q)),zoe=Pt(),wG=le();wG.initSync();var XCe=nd.invalid(wG.get(Woe.CONFIG_PARAMS.CLUSTERING_NODENAME)??"node_name").pattern(zoe.NATS_TERM_CONSTRAINTS_RX).messages({"string.pattern.base":"{:#label} invalid, must not contain ., * or >","any.invalid":"'node_name' cannot be this nodes name"}).empty(null),IG={operation:nd.valid("add_node","update_node","set_node_replication"),node_name:nd.optional(),subscriptions:gN.array().items({table:nd.optional(),schema:nd.optional(),database:nd.optional(),subscribe:NG.required(),publish:NG.required().custom(joe),start_time:Koe.iso()})};function Qoe(e){return Yoe.validateBySchema(e,gN.object(IG))}a(Qoe,"addUpdateNodeValidator");function joe(e,t){if(t.state.ancestors[2].operation==="add_node"&&e===!1&&t.state.ancestors[0].subscribe===!1)return t.message(`'subscriptions[${t.state.path[1]}]' subscribe and/or publish must be set to true when adding a node`)}a(joe,"checkForFalsy");CG.exports={addUpdateNodeValidator:Qoe,validation_schema:IG}});var sd=C((tPe,PG)=>{"use strict";var SN=class{static{a(this,"Node")}constructor(t,r,n){this.name=t,this.subscriptions=r,this.system_info=n}},TN=class{static{a(this,"NodeSubscription")}constructor(t,r,n,s){this.schema=t,this.table=r,this.publish=n,this.subscribe=s}};PG.exports={Node:SN,NodeSubscription:TN}});var LG=C((nPe,DG)=>{"use strict";var Joe=(k(),P(q)).OPERATIONS_ENUM,AN=class{static{a(this,"UpsertObject")}constructor(t,r,n,s=void 0){this.operation=Joe.UPSERT,this.schema=t,this.table=r,this.records=n,this.__origin=s}};DG.exports=AN});var gh=C((iPe,MG)=>{"use strict";var RN=class{static{a(this,"RemotePayloadObject")}constructor(t,r,n,s){this.operation=t,this.node_name=r,this.subscriptions=n,this.system_info=s}},yN=class{static{a(this,"RemotePayloadSubscription")}constructor(t,r,n,s,i,o,c){this.schema=t,this.table=r,this.hash_attribute=n,this.publish=s,this.subscribe=i,this.start_time=o,c!==void 0&&(this.attributes=c)}};MG.exports={RemotePayloadObject:RN,RemotePayloadSubscription:yN}});var UG=C((aPe,vG)=>{"use strict";var bN=class{static{a(this,"TableSizeObject")}constructor(t,r,n=0,s=0,i=0,o=0){this.schema=t,this.table=r,this.table_size=n,this.record_count=s,this.transaction_log_size=i,this.transaction_log_record_count=o}};vG.exports=bN});var BG=C((_Pe,xG)=>{"use strict";var Xoe=UG(),lPe=Gt(),uPe=ft(),Zoe=ee(),{getSchemaPath:dPe,getTransactionAuditStorePath:fPe}=gt(),{getDatabases:eae}=(xe(),P(ct));xG.exports=tae;async function tae(e){let t=new Xoe;try{let r=eae()[e.schema]?.[e.name],n=r.primaryStore.getStats(),s=r.auditStore?.getStats();t.schema=e.schema,t.table=e.name,t.record_count=n.entryCount,t.transaction_log_record_count=s.entryCount}catch(r){Zoe.warn(`unable to stat table dbi due to ${r}`)}return t}a(tae,"lmdbGetTableSize")});var kG=C((mPe,HG)=>{"use strict";var ON=class{static{a(this,"SystemInformationObject")}constructor(t,r,n,s,i,o,c){this.system=t,this.time=r,this.cpu=n,this.memory=s,this.disk=i,this.network=o,this.harperdb_processes=c}};HG.exports=ON});var od=C((APe,$G)=>{"use strict";var rae=require("fs-extra"),nae=require("path"),Xr=require("systeminformation"),Ua=ee(),FG=Sr(),EPe=Pt(),id=(k(),P(q)),sae=BG(),iae=po(),{getThreadInfo:GG}=it(),Sh=le();Sh.initSync();var oae=kG(),{openEnvironment:gPe}=ft(),{getSchemaPath:SPe}=gt(),{database:TPe,databases:NN}=(xe(),P(ct)),Qg;$G.exports={getHDBProcessInfo:PN,getNetworkInfo:LN,getDiskInfo:DN,getMemoryInfo:CN,getCPUInfo:IN,getTimeInfo:wN,getSystemInformation:MN,systemInformation:aae,getTableSize:vN,getMetrics:UN};function wN(){return Xr.time()}a(wN,"getTimeInfo");async function IN(){try{let{family:e,model:t,stepping:r,revision:n,voltage:s,speedmin:i,speedmax:o,governor:c,socket:l,cache:u,...f}=await Xr.cpu();f.cpu_speed=await Xr.cpuCurrentSpeed();let{raw_currentload:d,raw_currentload_idle:_,raw_currentload_irq:h,raw_currentload_nice:m,raw_currentload_system:S,raw_currentload_user:g,cpus:R,...E}=await Xr.currentLoad();return E.cpus=[],R.forEach(T=>{let{raw_load:N,raw_load_idle:v,raw_load_irq:H,raw_load_nice:X,raw_load_system:W,raw_load_user:$,...se}=T;E.cpus.push(se)}),f.current_load=E,f}catch(e){return Ua.error(`error in getCPUInfo: ${e}`),{}}}a(IN,"getCPUInfo");async function CN(){try{let{buffers:e,cached:t,slab:r,buffcache:n,...s}=await Xr.mem();return Object.assign(s,process.memoryUsage())}catch(e){return Ua.error(`error in getMemoryInfo: ${e}`),{}}}a(CN,"getMemoryInfo");async function PN(){let e={core:[],clustering:[]};try{let t=await Xr.processes(),r;try{r=Number.parseInt(await rae.readFile(nae.join(Sh.get(id.CONFIG_PARAMS.ROOTPATH),id.HDB_PID_FILE),"utf8"))}catch(n){if(n.code===id.NODE_ERROR_CODES.ENOENT)Ua.warn("Unable to locate 'hdb.pid' file, try stopping and starting HarperDB. This could be because HarperDB is not running.");else throw n}t.list.forEach(n=>{n.pid===r?e.core.push(n):n.name==="nats-server"&&e.clustering.push(n)});for(let n of e.core)for(let s of t.list)s.pid===n.parentPid&&(s.name==="PM2"||s.command==="PM2")&&(n.parent="PM2");return e}catch(t){return Ua.error(`error in getHDBProcessInfo: ${t}`),e}}a(PN,"getHDBProcessInfo");async function DN(){let e={};try{if(!Sh.get(id.CONFIG_PARAMS.OPERATIONSAPI_SYSINFO_DISK))return e;let{rIO_sec:t,wIO_sec:r,tIO_sec:n,ms:s,...i}=await Xr.disksIO();e.io=i;let{rx_sec:o,tx_sec:c,wx_sec:l,...u}=await Xr.fsStats();return e.read_write=u,e.size=await Xr.fsSize(),e}catch(t){return Ua.error(`error in getDiskInfo: ${t}`),e}}a(DN,"getDiskInfo");async function LN(){let e={default_interface:null,latency:{},interfaces:[],stats:[],connections:[]};try{return Sh.get(id.CONFIG_PARAMS.OPERATIONSAPI_SYSINFO_NETWORK)&&(e.default_interface=await Xr.networkInterfaceDefault(),e.latency=await Xr.inetChecksite("google.com"),(await Xr.networkInterfaces()).forEach(n=>{let{internal:s,virtual:i,mtu:o,dhcp:c,dnsSuffix:l,ieee8021xAuth:u,ieee8021xState:f,carrier_changes:d,..._}=n;e.interfaces.push(_)}),(await Xr.networkStats()).forEach(n=>{let{rx_sec:s,tx_sec:i,ms:o,...c}=n;e.stats.push(c)})),e}catch(t){return Ua.error(`error in getNetworkInfo: ${t}`),e}}a(LN,"getNetworkInfo");async function MN(){if(Qg!==void 0)return Qg;let e={};try{let{codepage:t,logofile:r,serial:n,build:s,servicepack:i,uefi:o,...c}=await Xr.osInfo();e=c;let l=await Xr.versions("node, npm");return e.node_version=l.node,e.npm_version=l.npm,Qg=e,Qg}catch(t){return Ua.error(`error in getSystemInformation: ${t}`),e}}a(MN,"getSystemInformation");async function vN(){let e=[],t=await iae.describeAll();for(let r of Object.values(t))for(let n of Object.values(r))e.push(await sae(n));return e}a(vN,"getTableSize");async function UN(){let e={};for(let t in NN){let r=e[t]={},n=r.tables={};for(let s in NN[t])try{let i=NN[t][s];if(!r.readers&&(Object.assign(r,i.primaryStore.rootStore.getStats()),delete r.root,r.readers=i.primaryStore.rootStore.readerList().split(/\n\s+/).slice(1).map(l=>{let[u,f,d]=l.trim().split(" ");return{pid:u,thread:f,txnid:d}}),i.auditStore)){let{treeDepth:l,treeBranchPageCount:u,treeLeafPageCount:f,entryCount:d,overflowPages:_}=i.auditStore.getStats();r.audit={treeDepth:l,treeBranchPageCount:u,treeLeafPageCount:f,entryCount:d,overflowPages:_}}let o=i.primaryStore.getStats(),c={};for(let l of["treeDepth","treeBranchPageCount","treeLeafPageCount","entryCount","overflowPages"])c[l]=o[l];n[s]=c}catch(i){Ua.notify(`Error getting stats for table ${s}: ${i}`)}}return e}a(UN,"getMetrics");async function qG(){if(Sh.get(id.CONFIG_PARAMS.CLUSTERING_ENABLED)){let{jsm:e}=await FG.getNATSReferences(),t=await FG.listStreams(),r=[];for(let n of t){let s=[],i=await e.consumers.list(n.config.name);for await(let c of i)s.push({name:c.name,created:c.created,num_ack_pending:c.num_ack_pending,num_redelivered:c.num_redelivered,num_waiting:c.num_waiting,num_pending:c.num_pending});let o={stream_name:n.config.name,database:n.config.subjects[0].split(".")[1],table:n.config.subjects[0].split(".")[2],state:n.state,consumers:s};r.push(o)}return r}}a(qG,"getNatsStreamInfo");async function aae(e){let t=new oae;if(!Array.isArray(e.attributes)||e.attributes.length===0)return t.system=await MN(),t.time=wN(),t.cpu=await IN(),t.memory=await CN(),t.disk=await DN(),t.network=await LN(),t.harperdb_processes=await PN(),t.table_size=await vN(),t.metrics=await UN(),t.threads=await GG(),t.replication=await qG(),t;for(let r=0;r<e.attributes.length;r++)switch(e.attributes[r]){case"system":t.system=await MN();break;case"time":t.time=wN();break;case"cpu":t.cpu=await IN();break;case"memory":t.memory=await CN();break;case"disk":t.disk=await DN();break;case"network":t.network=await LN();break;case"harperdb_processes":t.harperdb_processes=await PN();break;case"table_size":t.table_size=await vN();break;case"database_metrics":case"metrics":t.metrics=await UN();break;case"threads":t.threads=await GG();break;case"replication":t.replication=await qG();break;default:break}return t}a(aae,"systemInformation")});var No=C((NPe,WG)=>{"use strict";var cae=Rn(),xN=ie(),lae=require("util"),El=(k(),P(q)),VG=le();VG.initSync();var uae=mO(),KG=Wr(),{Node:yPe,NodeSubscription:bPe}=sd(),dae=pu(),fae=LG(),{RemotePayloadObject:_ae,RemotePayloadSubscription:hae}=gh(),{handleHDBError:mae,hdb_errors:pae}=he(),{HTTP_STATUS_CODES:Eae,HDB_ERROR_MSGS:gae}=pae,Sae=$s(),Tae=od(),{packageJson:Aae}=Et(),{getDatabases:Rae}=(xe(),P(ct)),OPe=lae.promisify(uae.authorize),yae=KG.searchByHash,bae=KG.searchByValue;WG.exports={isEmpty:Oae,getNodeRecord:Nae,upsertNodeRecord:wae,buildNodePayloads:Iae,checkClusteringEnabled:Cae,getAllNodeRecords:Pae,getSystemInfo:Dae,reverseSubscription:YG};function Oae(e){return e==null}a(Oae,"isEmpty");async function Nae(e){let t=new dae(El.SYSTEM_SCHEMA_NAME,El.SYSTEM_TABLE_NAMES.NODE_TABLE_NAME,[e],["*"]);return yae(t)}a(Nae,"getNodeRecord");async function wae(e){let t=new fae(El.SYSTEM_SCHEMA_NAME,El.SYSTEM_TABLE_NAMES.NODE_TABLE_NAME,[e]);return cae.upsert(t)}a(wae,"upsertNodeRecord");function YG(e){if(xN.isEmpty(e.subscribe)||xN.isEmpty(e.publish))throw new Error("Received invalid subscription object");let{schema:t,table:r,hash_attribute:n}=e,s={schema:t,table:r,hash_attribute:n};return e.subscribe===!0&&e.publish===!1?(s.subscribe=!1,s.publish=!0):e.subscribe===!1&&e.publish===!0?(s.subscribe=!0,s.publish=!1):(s.subscribe=e.subscribe,s.publish=e.publish),s}a(YG,"reverseSubscription");function Iae(e,t,r,n){let s=[];for(let i=0,o=e.length;i<o;i++){let c=e[i],{schema:l,table:u}=c,f=xN.getTableHashAttribute(l,u),{subscribe:d,publish:_}=YG(c),h=Rae()[l]?.[u],m=new hae(l,u,f,_,d,c.start_time,h.schemaDefined?h.attributes:void 0);s.push(m)}return new _ae(r,t,s,n)}a(Iae,"buildNodePayloads");function Cae(){if(!VG.get(El.CONFIG_PARAMS.CLUSTERING_ENABLED))throw mae(new Error,gae.CLUSTERING_NOT_ENABLED,Eae.BAD_REQUEST,void 0,void 0,!0)}a(Cae,"checkClusteringEnabled");async function Pae(){let e=new Sae(El.SYSTEM_SCHEMA_NAME,El.SYSTEM_TABLE_NAMES.NODE_TABLE_NAME,"name","*",void 0,["*"]);return Array.from(await bae(e))}a(Pae,"getAllNodeRecords");async function Dae(){let e=await Tae.getSystemInformation();return{hdb_version:Aae.version,node_version:e.node_version,platform:e.platform}}a(Dae,"getSystemInfo")});var BN=C((IPe,tq)=>{"use strict";var jg=Sr(),zG=ie(),QG=Pt(),jG=(k(),P(q)),Jg=ee(),JG=ph(),Lae=o_(),{RemotePayloadObject:Mae}=gh(),{handleHDBError:XG,hdb_errors:vae}=he(),{HTTP_STATUS_CODES:ZG}=vae,{NodeSubscription:eq}=sd();tq.exports=Uae;async function Uae(e,t){let r;try{r=await jg.request(`${t}.${QG.REQUEST_SUFFIX}`,new Mae(jG.OPERATIONS_ENUM.DESCRIBE_ALL,t,void 0,void 0)),Jg.trace("Response from remote describe all request:",r)}catch(o){Jg.error(`addNode received error from describe all request to remote node: ${o}`);let c=jg.requestErrorHandler(o,"add_node",t);throw XG(new Error,c,ZG.INTERNAL_SERVER_ERROR,"error",c)}if(r.status===QG.UPDATE_REMOTE_RESPONSE_STATUSES.ERROR){let o=`Error returned from remote node ${t}: ${r.message}`;throw XG(new Error,o,ZG.INTERNAL_SERVER_ERROR,"error",o)}let n=r.message,s=[],i=[];for(let o of e){let{table:c}=o,l=o.database??o.schema??"data";if(l===jG.SYSTEM_SCHEMA_NAME){await jg.createLocalTableStream(l,c);let m=new eq(l,c,o.publish,o.subscribe);m.start_time=o.start_time,i.push(m);continue}let u=zG.doesSchemaExist(l),f=n[l]!==void 0,d=c?zG.doesTableExist(l,c):!0,_=c?n?.[l]?.[c]!==void 0:!0;if(!u&&!f||!d&&!_){s.push(o);continue}if(!u&&f&&(Jg.trace(`addNode creating schema: ${l}`),await JG.createSchema({operation:"create_schema",schema:l})),!d&&_){Jg.trace(`addNode creating table: ${c} in schema: ${l} with attributes ${JSON.stringify(n[l][c].attributes)}`);let m=new Lae(l,c,n[l][c].hash_attribute);n[l][c].attributes&&(m.attributes=n[l][c].attributes),await JG.createTable(m)}await jg.createLocalTableStream(l,c);let h=new eq(l,c,o.publish,o.subscribe);h.start_time=o.start_time,i.push(h)}return{added:i,skipped:s}}a(Uae,"reviewSubscriptions")});var gl={};Ue(gl,{addNodeBack:()=>Fae,removeNodeBack:()=>Gae,setNode:()=>kae});async function kae(e){e.node_name&&!e.hostname&&(e.hostname=e.node_name),e.verify_tls!==void 0&&(e.rejectUnauthorized=e.verify_tls);let{url:t,hostname:r}=e;t?r||(r=e.hostname=Js(t)):t=Fg(r);let n=(0,nq.validateBySchema)(e,Hae);if(n)throw(0,wo.handleHDBError)(n,n.message,Bae.BAD_REQUEST,void 0,void 0,!0);if(e.operation==="remove_node"){if(!t&&!r)throw new wo.ClientError("url or hostname is required for remove_node operation");let h=r,m=ir(),S=await m.get(h);if(!S)throw new wo.ClientError(h+" does not exist");try{await hh({url:S.url},{operation:Wt.REMOVE_NODE_BACK,name:S?.subscriptions?.length>0?et():h},void 0)}catch(g){es.warn(`Error removing node from target node ${h}, if it is offline and we be online in the future, you may need to clean up this node manually, or retry:`,g)}return await m.delete(h),`Successfully removed '${h}' from cluster`}if(!t)throw new wo.ClientError("url required for this operation");let s=ba();if(s==null)throw new wo.ClientError("replication url is missing from harperdb-config.yaml");let i,o,c;if(t?.startsWith("wss:")){i=await(0,As.getReplicationCert)();let h=await(0,As.getReplicationCertAuth)();if(!i)throw new Error("Unable to find a certificate to use for replication");i.options.is_self_signed?(o=await(0,As.createCsr)(),es.info("Sending CSR to target node:",t)):h&&(c=h.certificate,es.info("Sending CA named",h.name,"to target node",t))}let l={operation:Wt.ADD_NODE_BACK,hostname:(0,Ba.get)(x.REPLICATION_HOSTNAME),target_hostname:r,url:s,csr:o,cert_auth:c,authorization:e.retain_authorization?e.authorization:null};if((0,Ba.get)(x.REPLICATION_SHARD)!==void 0&&(l.shard=(0,Ba.get)(x.REPLICATION_SHARD)),e.subscriptions?l.subscriptions=e.subscriptions.map(rq):l.subscriptions=null,e.hasOwnProperty("subscribe")||e.hasOwnProperty("publish")){let h=rq(e);l.subscribe=h.subscribe,l.publish=h.publish}e?.authorization?.username&&e?.authorization?.password&&(e.authorization="Basic "+Buffer.from(e.authorization.username+":"+e.authorization.password).toString("base64"));let u,f;try{u=await hh({url:t},l,e)}catch(h){h.message=`Error returned from ${t}: `+h.message,es.warn("Error adding node:",t,"to cluster:",h),f=h}if(o&&(!u?.certificate||!u?.certificate?.includes?.("BEGIN CERTIFICATE")))throw f?(f.message+=" and connection was required to sign certificate",f):new Error(`Unexpected certificate signature response from node ${t} response: ${JSON.stringify(u)}`);o&&(es.info("CSR response received from node:",t,"saving certificate and CA in hdb_certificate"),await(0,As.setCertTable)({name:xae.certificateFromPem(u.signingCA).issuer.getField("CN").value,certificate:u.signingCA,is_authority:!0}),u.certificate&&await(0,As.setCertTable)({name:et(),uses:["https","operations","wss"],certificate:u.certificate,private_key_name:i?.options?.key_file,is_authority:!1,is_self_signed:!1}),c=u.signingCA);let d={url:t,ca:u?.usingCA};if(e.hostname&&(d.name=e.hostname),e.subscriptions?d.subscriptions=e.subscriptions:d.replicates=!0,e.start_time&&(d.start_time=typeof e.start_time=="string"?new Date(e.start_time).getTime():e.start_time),e.retain_authorization&&(d.authorization=e.authorization),e.revoked_certificates&&(d.revoked_certificates=e.revoked_certificates),u?.shard!==void 0?d.shard=u.shard:e.shard!==void 0&&(d.shard=e.shard),d.replicates){let h={url:s,ca:c,replicates:!0,subscriptions:null};(0,Ba.get)(x.REPLICATION_SHARD)!==void 0&&(h.shard=(0,Ba.get)(x.REPLICATION_SHARD)),e.retain_authorization&&(h.authorization=e.authorization),e.start_time&&(h.start_time=e.start_time),await Ao(et(),h)}await Ao(u?u.nodeName:d.name??Js(t),d);let _;return e.operation==="update_node"?_=`Successfully updated '${t}'`:_=`Successfully added '${t}' to cluster`,f&&(_+=" but there was an error updating target node: "+f.message),_}async function Fae(e){es.trace("addNodeBack received request:",e);let t=await(0,As.signCertificate)(e),r;e.csr?(r=t.signingCA,es.info("addNodeBack received CSR from node:",e.url,"this node will use and respond with CA that was used to issue CSR")):(r=e?.cert_auth,es.info("addNodeBack received CA from node:",e.url));let n={url:e.url,ca:r};e.subscriptions?n.subscriptions=e.subscriptions:(n.replicates=!0,n.subscriptions=null),e.start_time&&(n.start_time=e.start_time),e.authorization&&(n.authorization=e.authorization),e.shard!==void 0&&(n.shard=e.shard);let s=await(0,As.getReplicationCertAuth)();if(n.replicates){let i={url:ba(),ca:s?.certificate,replicates:!0,subscriptions:null};(0,Ba.get)(x.REPLICATION_SHARD)!==void 0&&(i.shard=(0,Ba.get)(x.REPLICATION_SHARD),t.shard=i.shard),e.start_time&&(i.start_time=e.start_time),e.authorization&&(i.authorization=e.authorization),await Ao(et(),i)}return await Ao(e.hostname,n),t.nodeName=et(),t.usingCA=s?.certificate,es.info("addNodeBack responding to:",e.url,"with CA named:",s?.name),t}async function Gae(e){es.trace("removeNodeBack received request:",e),await ir().delete(e.name)}function rq(e){let{subscribe:t,publish:r}=e;return{...e,subscribe:r,publish:t}}var As,nq,xa,Ba,es,wo,xae,Bae,Hae,Sl=Re(()=>{As=M(ei()),nq=M(ot()),xa=M(require("joi")),Ba=M(le());k();lh();ul();gs();es=M(ee()),wo=M(he()),{pki:xae}=require("node-forge"),{HTTP_STATUS_CODES:Bae}=wo.hdb_errors,Hae=xa.default.object({hostname:xa.default.string(),verify_tls:xa.default.boolean(),replicates:xa.default.boolean(),subscriptions:xa.default.array(),revoked_certificates:xa.default.array(),shard:xa.default.number()});a(kae,"setNode");a(Fae,"addNodeBack");a(Gae,"removeNodeBack");a(rq,"reverseSubscription")});var rS=C((BPe,iq)=>{"use strict";var{handleHDBError:Xg,hdb_errors:qae}=he(),{HTTP_STATUS_CODES:Zg}=qae,{addUpdateNodeValidator:$ae}=zg(),eS=ee(),tS=(k(),P(q)),sq=Pt(),Vae=ie(),Th=Sr(),Ah=No(),HN=le(),Kae=BN(),{Node:Yae,NodeSubscription:Wae}=sd(),{broadcast:zae}=it(),{setNode:Qae}=(Sl(),P(gl)),UPe=le(),xPe=(k(),P(q)),jae="Unable to create subscriptions due to schema and/or tables not existing on the local or remote node",Jae="Some subscriptions were unsuccessful due to schema and/or tables not existing on the local or remote node",Xae=HN.get(tS.CONFIG_PARAMS.CLUSTERING_NODENAME);iq.exports=Zae;async function Zae(e,t=!1){if(eS.trace("addNode called with:",e),HN.get(tS.CONFIG_PARAMS.REPLICATION_URL)||HN.get(tS.CONFIG_PARAMS.REPLICATION_HOSTNAME))return Qae(e);Ah.checkClusteringEnabled();let r=$ae(e);if(r)throw Xg(r,r.message,Zg.BAD_REQUEST,void 0,void 0,!0);let n=e.node_name;if(!t){let d=await Ah.getNodeRecord(n);if(!Vae.isEmptyOrZeroLength(d))throw Xg(new Error,`Node '${n}' has already been added, perform update_node to proceed.`,Zg.BAD_REQUEST,void 0,void 0,!0)}let{added:s,skipped:i}=await Kae(e.subscriptions,n),o={message:void 0,added:s,skipped:i};if(s.length===0)return o.message=jae,o;let c=Ah.buildNodePayloads(s,Xae,tS.OPERATIONS_ENUM.ADD_NODE,await Ah.getSystemInfo()),l=[];for(let d=0,_=s.length;d<_;d++){let h=s[d];s[d].start_time===void 0&&delete s[d].start_time,l.push(new Wae(h.schema,h.table,h.publish,h.subscribe))}eS.trace("addNode sending remote payload:",c);let u;try{u=await Th.request(`${n}.${sq.REQUEST_SUFFIX}`,c)}catch(d){eS.error(`addNode received error from request: ${d}`);for(let h=0,m=s.length;h<m;h++){let S=s[h];S.publish=!1,S.subscribe=!1,await Th.updateRemoteConsumer(S,n)}let _=Th.requestErrorHandler(d,"add_node",n);throw Xg(new Error,_,Zg.INTERNAL_SERVER_ERROR,"error",_)}if(u.status===sq.UPDATE_REMOTE_RESPONSE_STATUSES.ERROR){let d=`Error returned from remote node ${n}: ${u.message}`;throw Xg(new Error,d,Zg.INTERNAL_SERVER_ERROR,"error",d)}eS.trace(u);for(let d=0,_=s.length;d<_;d++){let h=s[d];await Th.updateRemoteConsumer(h,n),h.subscribe===!0&&await Th.updateConsumerIterator(h.schema,h.table,n,"start")}let f=new Yae(n,l,u.system_info);return await Ah.upsertNodeRecord(f),zae({type:"nats_update"}),i.length>0?o.message=Jae:o.message=`Successfully added '${n}' to manifest`,o}a(Zae,"addNode")});var qN=C((FPe,aq)=>{"use strict";var{handleHDBError:kN,hdb_errors:ece}=he(),{HTTP_STATUS_CODES:FN}=ece,{addUpdateNodeValidator:tce}=zg(),Rh=ee(),nS=(k(),P(q)),oq=Pt(),kPe=ie(),yh=Sr(),bh=No(),GN=le(),{cloneDeep:rce}=require("lodash"),nce=BN(),{Node:sce,NodeSubscription:ice}=sd(),{broadcast:oce}=it(),{setNode:ace}=(Sl(),P(gl)),cce="Unable to update subscriptions due to schema and/or tables not existing on the local or remote node",lce="Some subscriptions were unsuccessful due to schema and/or tables not existing on the local or remote node",uce=GN.get(nS.CONFIG_PARAMS.CLUSTERING_NODENAME);aq.exports=dce;async function dce(e){if(Rh.trace("updateNode called with:",e),GN.get(nS.CONFIG_PARAMS.REPLICATION_URL)??GN.get(nS.CONFIG_PARAMS.REPLICATION_HOSTNAME))return ace(e);bh.checkClusteringEnabled();let t=tce(e);if(t)throw kN(t,t.message,FN.BAD_REQUEST,void 0,void 0,!0);let r=e.node_name,n,s=await bh.getNodeRecord(r);s.length>0&&(n=rce(s));let{added:i,skipped:o}=await nce(e.subscriptions,r),c={message:void 0,updated:i,skipped:o};if(i.length===0)return c.message=cce,c;let l=bh.buildNodePayloads(i,uce,nS.OPERATIONS_ENUM.UPDATE_NODE,await bh.getSystemInfo());for(let f=0,d=i.length;f<d;f++){let _=i[f];Rh.trace(`updateNode updating work stream for node: ${r} subscription:`,_),i[f].start_time===void 0&&delete i[f].start_time}Rh.trace("updateNode sending remote payload:",l);let u;try{u=await yh.request(`${r}.${oq.REQUEST_SUFFIX}`,l)}catch(f){Rh.error(`updateNode received error from request: ${f}`);let d=yh.requestErrorHandler(f,"update_node",r);throw kN(new Error,d,FN.INTERNAL_SERVER_ERROR,"error",d)}if(u.status===oq.UPDATE_REMOTE_RESPONSE_STATUSES.ERROR){let f=`Error returned from remote node ${r}: ${u.message}`;throw kN(new Error,f,FN.INTERNAL_SERVER_ERROR,"error",f)}Rh.trace(u);for(let f=0,d=i.length;f<d;f++){let _=i[f];await yh.updateRemoteConsumer(_,r),_.subscribe===!0?await yh.updateConsumerIterator(_.schema,_.table,r,"start"):await yh.updateConsumerIterator(_.schema,_.table,r,"stop")}return n||(n=[new sce(r,[],u.system_info)]),await fce(n[0],i,u.system_info),o.length>0?c.message=lce:c.message=`Successfully updated '${r}'`,c}a(dce,"updateNode");async function fce(e,t,r){let n=e;for(let s=0,i=t.length;s<i;s++){let o=t[s],c=!1;for(let l=0,u=e.subscriptions.length;l<u;l++){let f=n.subscriptions[l];if(f.schema===o.schema&&f.table===o.table){f.publish=o.publish,f.subscribe=o.subscribe,c=!0;break}}c||n.subscriptions.push(new ice(o.schema,o.table,o.publish,o.subscribe))}n.system_info=r,await bh.upsertNodeRecord(n),oce({type:"nats_update"})}a(fce,"updateNodeTable")});var fq=C((qPe,dq)=>{"use strict";var uq=require("joi"),{string:cq}=uq.types(),_ce=ot(),lq=(k(),P(q)),hce=le(),mce=Pt();dq.exports=pce;function pce(e){let t=cq.invalid(hce.get(lq.CONFIG_PARAMS.CLUSTERING_NODENAME)).pattern(mce.NATS_TERM_CONSTRAINTS_RX).messages({"string.pattern.base":"{:#label} invalid, must not contain ., * or >","any.invalid":"'node_name' cannot be this nodes name"}).empty(null),r=uq.object({operation:cq.valid(lq.OPERATIONS_ENUM.REMOVE_NODE).required(),node_name:t});return _ce.validateBySchema(e,r)}a(pce,"removeNodeValidator")});var sS=C((VPe,Eq)=>{"use strict";var{handleHDBError:_q,hdb_errors:Ece}=he(),{HTTP_STATUS_CODES:hq}=Ece,gce=fq(),Oh=ee(),mq=No(),Sce=ie(),ad=(k(),P(q)),pq=Pt(),$N=Sr(),VN=le(),{RemotePayloadObject:Tce}=gh(),{NodeSubscription:Ace}=sd(),Rce=i_(),yce=Yc(),{broadcast:bce}=it(),{setNode:Oce}=(Sl(),P(gl)),Nce=VN.get(ad.CONFIG_PARAMS.CLUSTERING_NODENAME);Eq.exports=wce;async function wce(e){if(Oh.trace("removeNode called with:",e),VN.get(ad.CONFIG_PARAMS.REPLICATION_URL)??VN.get(ad.CONFIG_PARAMS.REPLICATION_HOSTNAME))return Oce(e);mq.checkClusteringEnabled();let t=gce(e);if(t)throw _q(t,t.message,hq.BAD_REQUEST,void 0,void 0,!0);let r=e.node_name,n=await mq.getNodeRecord(r);if(Sce.isEmptyOrZeroLength(n))throw _q(new Error,`Node '${r}' was not found.`,hq.BAD_REQUEST,void 0,void 0,!0);n=n[0];let s=new Tce(ad.OPERATIONS_ENUM.REMOVE_NODE,Nce,[]),i,o=!1;for(let l=0,u=n.subscriptions.length;l<u;l++){let f=n.subscriptions[l];f.subscribe===!0&&await $N.updateConsumerIterator(f.schema,f.table,r,"stop");try{await $N.updateRemoteConsumer(new Ace(f.schema,f.table,!1,!1),r)}catch(d){Oh.error(d)}}try{i=await $N.request(`${r}.${pq.REQUEST_SUFFIX}`,s),Oh.trace("Remove node reply from remote node:",r,i)}catch(l){Oh.error("removeNode received error from request:",l),o=!0}let c=new Rce(ad.SYSTEM_SCHEMA_NAME,ad.SYSTEM_TABLE_NAMES.NODE_TABLE_NAME,[r]);return await yce.deleteRecord(c),bce({type:"nats_update"}),i?.status===pq.UPDATE_REMOTE_RESPONSE_STATUSES.ERROR||o?(Oh.error("Error returned from remote node:",r,i?.message),`Successfully removed '${r}' from local manifest, however there was an error reaching remote node. Check the logs for more details.`):`Successfully removed '${r}' from manifest`}a(wce,"removeNode")});var Tq=C((YPe,Sq)=>{"use strict";var gq=require("joi"),{string:Ice,array:Cce}=gq.types(),Pce=ot(),Dce=zg();Sq.exports=Lce;function Lce(e){let t=gq.object({operation:Ice.valid("configure_cluster").required(),connections:Cce.items(Dce.validation_schema).required()});return Pce.validateBySchema(e,t)}a(Lce,"configureClusterValidator")});var KN=C((zPe,Oq)=>{"use strict";var Aq=(k(),P(q)),iS=ee(),Mce=ie(),vce=le(),Uce=sS(),xce=rS(),Bce=No(),Hce=Tq(),{handleHDBError:Rq,hdb_errors:kce}=he(),{HTTP_STATUS_CODES:yq}=kce,Fce="Configure cluster complete.",Gce="Failed to configure the cluster. Check the logs for more details.",qce="Configure cluster was partially successful. Errors occurred when attempting to configure the following nodes. Check the logs for more details.";Oq.exports=$ce;async function $ce(e){iS.trace("configure cluster called with:",e);let t=Hce(e);if(t)throw Rq(t,t.message,yq.BAD_REQUEST,void 0,void 0,!0);let r=await Bce.getAllNodeRecords(),n=[];if(vce.get(Aq.CONFIG_PARAMS.CLUSTERING_ENABLED)){for(let f=0,d=r.length;f<d;f++){let _=await bq(Uce,{operation:Aq.OPERATIONS_ENUM.REMOVE_NODE,node_name:r[f].name},r[f].name);n.push(_)}iS.trace("All results from configure_cluster remove node:",n)}let s=[],i=e.connections.length;for(let f=0;f<i;f++){let d=e.connections[f],_=await bq(xce,d,d.node_name);s.push(_)}iS.trace("All results from configure_cluster add node:",s);let o=[],c=[],l=!1,u=n.concat(s);for(let f=0,d=u.length;f<d;f++){let _=u[f];_.status==="rejected"&&(iS.error(_.node_name,_?.error?.message,_?.error?.stack),o.includes(_.node_name)||o.push(_.node_name)),(_?.result?.message?.includes?.("Successfully")||_?.result?.includes?.("Successfully"))&&(l=!0),!(typeof _.result=="string"&&_.result.includes("Successfully removed")||_.status==="rejected")&&c.push({node_name:_?.node_name,response:_?.result})}if(Mce.isEmptyOrZeroLength(o))return{message:Fce,connections:c};if(l)return{message:qce,failed_nodes:o,connections:c};throw Rq(new Error,Gce,yq.INTERNAL_SERVER_ERROR,void 0,void 0,!0)}a($ce,"configureCluster");async function bq(e,t,r){try{return{node_name:r,result:await e(t)}}catch(n){return{node_name:r,error:n,status:"rejected"}}}a(bq,"functionWrapper")});var Cq=C((jPe,Iq)=>{"use strict";var Nh=require("joi"),Vce=ot(),{validateSchemaExists:Nq,validateTableExists:Kce,validateSchemaName:wq}=bi(),Yce=Nh.object({operation:Nh.string().valid("purge_stream"),schema:Nh.string().custom(Nq).custom(wq).optional(),database:Nh.string().custom(Nq).custom(wq).optional(),table:Nh.string().custom(Kce).required()});function Wce(e){return Vce.validateBySchema(e,Yce)}a(Wce,"purgeStreamValidator");Iq.exports=Wce});var YN=C((XPe,Pq)=>{"use strict";var{handleHDBError:zce,hdb_errors:Qce}=he(),{HTTP_STATUS_CODES:jce}=Qce,Jce=Cq(),Xce=Sr(),Zce=No();Pq.exports=ele;async function ele(e){e.schema=e.schema??e.database;let t=Jce(e);if(t)throw zce(t,t.message,jce.BAD_REQUEST,void 0,void 0,!0);Zce.checkClusteringEnabled();let{schema:r,table:n,options:s}=e;return await Xce.purgeTableStream(r,n,s),`Successfully purged table '${r}.${n}'`}a(ele,"purgeStream")});var QN=C((eDe,Bq)=>{"use strict";var zN=No(),tle=Sr(),aS=le(),cd=(k(),P(q)),Tl=Pt(),rle=ie(),WN=ee(),{RemotePayloadObject:nle}=gh(),{ErrorCode:Dq}=require("nats"),{parentPort:Lq}=require("worker_threads"),{onMessageByType:sle}=it(),{getThisNodeName:ile}=(gs(),P(Ca)),{requestClusterStatus:ole}=(lh(),P(tF)),{getReplicationSharedStatus:ale,getHDBNodeTable:cle}=(ul(),P(BO)),{CONFIRMATION_STATUS_POSITION:lle,RECEIVED_VERSION_POSITION:ule,RECEIVED_TIME_POSITION:dle,SENDING_TIME_POSITION:fle,RECEIVING_STATUS_POSITION:_le,RECEIVING_STATUS_RECEIVING:hle}=(cN(),P(YF)),Mq=aS.get(cd.CONFIG_PARAMS.CLUSTERING_ENABLED),vq=aS.get(cd.CONFIG_PARAMS.CLUSTERING_NODENAME);Bq.exports={clusterStatus:mle,buildNodeStatus:xq};var Uq;sle("cluster-status",async e=>{Uq(e)});async function mle(){if(aS.get(cd.CONFIG_PARAMS.REPLICATION_URL)||aS.get(cd.CONFIG_PARAMS.REPLICATION_HOSTNAME)){let n;if(Lq){Lq.postMessage({type:"request-cluster-status"}),n=await new Promise(i=>{Uq=i});for(let i of n.connections){let o=i.name;for(let c of i.database_sockets){let l=c.database,u;for(let d of Object.values(databases[l]||{}))if(u=d.auditStore,u)break;if(!u)continue;let f=ale(u,l,o);c.lastCommitConfirmed=oS(f[lle]),c.lastReceivedRemoteTime=oS(f[ule]),c.lastReceivedLocalTime=oS(f[dle]),c.sendingMessage=oS(f[fle]),c.lastReceivedStatus=f[_le]===hle?"Receiving":"Waiting"}}}else n=ole();n.node_name=ile();let s=cle().primaryStore.get(n.node_name);return s?.shard&&(n.shard=s.shard),s?.url&&(n.url=s.url),n.is_enabled=!0,n}let e={node_name:vq,is_enabled:Mq,connections:[]};if(!Mq)return e;let t=await zN.getAllNodeRecords();if(rle.isEmptyOrZeroLength(t))return e;let r=[];for(let n=0,s=t.length;n<s;n++)r.push(xq(t[n],e.connections));return await Promise.allSettled(r),e}a(mle,"clusterStatus");function oS(e){return e?e===1?"Copying":new Date(e).toUTCString():void 0}a(oS,"asDate");async function xq(e,t){let r=e.name,n=new nle(cd.OPERATIONS_ENUM.CLUSTER_STATUS,vq,void 0,await zN.getSystemInfo()),s,i,o=Tl.CLUSTER_STATUS_STATUSES.OPEN;try{let l=Date.now();s=await tle.request(Tl.REQUEST_SUBJECT(r),n),i=Date.now()-l,s.status===Tl.UPDATE_REMOTE_RESPONSE_STATUSES.ERROR&&(o=Tl.CLUSTER_STATUS_STATUSES.CLOSED,WN.error(`Error getting node status from ${r} `,s))}catch(l){WN.warn(`Error getting node status from ${r}`,l),l.code===Dq.NoResponders?o=Tl.CLUSTER_STATUS_STATUSES.NO_RESPONDERS:l.code===Dq.Timeout?o=Tl.CLUSTER_STATUS_STATUSES.TIMEOUT:o=Tl.CLUSTER_STATUS_STATUSES.CLOSED}let c=new ple(r,o,s?.message?.ports?.clustering,s?.message?.ports?.operations_api,i,s?.message?.uptime,e.subscriptions,s?.message?.system_info);try{let l={name:r,system_info:s?.message?.system_info};e.system_info?.hdb_version!==cd.PRE_4_0_0_VERSION&&await zN.upsertNodeRecord(l)}catch(l){WN.error("Cluster status encountered an error updating system info for node:",r,l)}t.push(c)}a(xq,"buildNodeStatus");function ple(e,t,r,n,s,i,o,c){this.node_name=e,this.status=t,this.ports={clustering:r,operations_api:n},this.latency_ms=s,this.uptime=i,this.subscriptions=o,this.system_info=c}a(ple,"NodeStatusObject")});var JN=C((rDe,Hq)=>{"use strict";var{handleHDBError:Ele,hdb_errors:gle}=he(),{HTTP_STATUS_CODES:Sle}=gle,Tle=Sr(),Ale=No(),jN=ie(),cS=require("joi"),Rle=ot(),yle=2e3,ble=cS.object({timeout:cS.number().min(1),connected_nodes:cS.boolean(),routes:cS.boolean()});Hq.exports=Ole;async function Ole(e){Ale.checkClusteringEnabled();let t=Rle.validateBySchema(e,ble);if(t)throw Ele(t,t.message,Sle.BAD_REQUEST,void 0,void 0,!0);let{timeout:r,connected_nodes:n,routes:s}=e,i=n===void 0||jN.autoCastBoolean(n),o=s===void 0||jN.autoCastBoolean(s),c={nodes:[]},l=await Tle.getServerList(r??yle),u={};if(i)for(let f=0,d=l.length;f<d;f++){let _=l[f].statsz;_&&(u[l[f].server.name]=_.routes)}for(let f=0,d=l.length;f<d;f++){if(l[f].statsz)continue;let _=l[f].server,h=l[f].data;if(_.name.endsWith("-hub")){let m={name:_.name.slice(0,-4),response_time:l[f].response_time};i&&(m.connected_nodes=[],u[_.name]&&u[_.name].forEach(S=>{m.connected_nodes.includes(S.name.slice(0,-4))||m.connected_nodes.push(S.name.slice(0,-4))})),o&&(m.routes=h.cluster?.urls?h.cluster?.urls.map(S=>({host:S.split(":")[0],port:jN.autoCast(S.split(":")[1])})):[]),c.nodes.push(m)}}return c}a(Ole,"clusterNetwork")});var qq=C((sDe,Gq)=>{"use strict";var XN=require("joi"),kq=ot(),{route_constraints:Fq}=lb();Gq.exports={setRoutesValidator:Nle,deleteRoutesValidator:wle};function Nle(e){let t=XN.object({server:XN.valid("hub","leaf"),routes:Fq.required()});return kq.validateBySchema(e,t)}a(Nle,"setRoutesValidator");function wle(e){let t=XN.object({routes:Fq.required()});return kq.validateBySchema(e,t)}a(wle,"deleteRoutesValidator")});var lS=C((oDe,Qq)=>{"use strict";var Io=Lt(),ZN=ie(),Rs=(k(),P(q)),ld=le(),$q=qq(),{handleHDBError:Vq,hdb_errors:Ile}=he(),{HTTP_STATUS_CODES:Kq}=Ile,Yq="cluster routes successfully set",Wq="cluster routes successfully deleted";Qq.exports={setRoutes:Ple,getRoutes:Dle,deleteRoutes:Lle};function Cle(e){let t=Io.getClusteringRoutes(),r=e.server==="hub"?t.hub_routes:t.leaf_routes,n=e.server==="hub"?t.leaf_routes:t.hub_routes,s=[],i=[];for(let o=0,c=e.routes.length;o<c;o++){let l=e.routes[o];l.port=ZN.autoCast(l.port);let u=r.some(d=>d.host===l.host&&d.port===l.port),f=n.some(d=>d.host===l.host&&d.port===l.port);u||f?s.push(l):(r.push(l),i.push(l))}return e.server==="hub"?Io.updateConfigValue(Rs.CONFIG_PARAMS.CLUSTERING_HUBSERVER_CLUSTER_NETWORK_ROUTES,r):Io.updateConfigValue(Rs.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_NETWORK_ROUTES,r),{message:Yq,set:i,skipped:s}}a(Cle,"setRoutesNats");function Ple(e){let t=$q.setRoutesValidator(e);if(t)throw Vq(t,t.message,Kq.BAD_REQUEST,void 0,void 0,!0);if(ld.get(Rs.CONFIG_PARAMS.CLUSTERING_ENABLED))return Cle(e);let r=[],n=[],s=ld.get(Rs.CONFIG_PARAMS.REPLICATION_ROUTES)??[];return e.routes.forEach(i=>{zq(s,i)?n.push(i):(s.push(i),r.push(i))}),Io.updateConfigValue(Rs.CONFIG_PARAMS.REPLICATION_ROUTES,s),{message:Yq,set:r,skipped:n}}a(Ple,"setRoutes");function zq(e,t){return typeof t=="string"?e.includes(t):typeof t=="object"&&t!==null?e.some(r=>(r.host===t.host||r.hostname===t.hostname)&&r.port===t.port):!1}a(zq,"existsInArray");function Dle(){if(ld.get(Rs.CONFIG_PARAMS.CLUSTERING_ENABLED)){let e=Io.getClusteringRoutes();return{hub:e.hub_routes,leaf:e.leaf_routes}}else return ld.get(Rs.CONFIG_PARAMS.REPLICATION_ROUTES)??[]}a(Dle,"getRoutes");function Lle(e){let t=$q.deleteRoutesValidator(e);if(t)throw Vq(t,t.message,Kq.BAD_REQUEST,void 0,void 0,!0);if(ld.get(Rs.CONFIG_PARAMS.CLUSTERING_ENABLED))return Mle(e);let r=[],n=[],s=ld.get(Rs.CONFIG_PARAMS.REPLICATION_ROUTES)??[],i=[];return s.forEach(o=>{zq(e.routes,o)?r.push(o):(i.push(o),n.push(o))}),Io.updateConfigValue(Rs.CONFIG_PARAMS.REPLICATION_ROUTES,i),{message:Wq,deleted:r,skipped:n}}a(Lle,"deleteRoutes");function Mle(e){let t=Io.getClusteringRoutes(),r=t.hub_routes,n=t.leaf_routes,s=[],i=[],o=!1,c=!1;for(let l=0,u=e.routes.length;l<u;l++){let f=e.routes[l],d=!1;for(let _=0,h=r.length;_<h;_++){let m=r[_];if(f.host===m.host&&f.port===m.port){r.splice(_,1),d=!0,o=!0,s.push(f);break}}if(!d){let _=!0;for(let h=0,m=n.length;h<m;h++){let S=n[h];if(f.host===S.host&&f.port===S.port){n.splice(h,1),c=!0,_=!1,s.push(f);break}}_&&i.push(f)}}return o&&(r=ZN.isEmptyOrZeroLength(r)?null:r,Io.updateConfigValue(Rs.CONFIG_PARAMS.CLUSTERING_HUBSERVER_CLUSTER_NETWORK_ROUTES,r)),c&&(n=ZN.isEmptyOrZeroLength(n)?null:n,Io.updateConfigValue(Rs.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_NETWORK_ROUTES,n)),{message:Wq,deleted:s,skipped:i}}a(Mle,"deleteRoutesNats")});var Jq=C((cDe,jq)=>{"use strict";var wh=require("alasql"),Al=require("recursive-iterator"),ti=ee(),vle=ie(),Ih=(k(),P(q)),ew=class{static{a(this,"sql_statement_bucket")}constructor(t){this.ast=t,this.affected_attributes=new Map,this.table_lookup=new Map,this.schema_lookup=new Map,this.table_to_schema_lookup=new Map,xle(this.ast,this.affected_attributes,this.table_lookup,this.schema_lookup,this.table_to_schema_lookup)}getAttributesBySchemaTableName(t,r){if(!t||!r||!this.affected_attributes)return[];if(this.affected_attributes.has(t))return!this.affected_attributes.get(t).has(r)&&(r=this.table_lookup.get(r),!r)?[]:this.affected_attributes.get(t).get(r)}getAllTables(){let t=[];if(!this.affected_attributes)return t;for(let r of this.affected_attributes.keys())t.push(Array.from(this.affected_attributes.get(r).keys()));return t}getTablesBySchemaName(t){return!t||!this.affected_attributes?[]:Array.from(this.affected_attributes.get(t).keys())}getSchemas(){return this.affected_attributes?Array.from(this.affected_attributes.keys()):[]}getAst(){return this.ast}updateAttributeWildcardsForRolePerms(t){let r=this.ast.columns.filter(s=>Ih.SEARCH_WILDCARDS.includes(s.columnid));if(r.length===0)return this.ast;let n=this.ast.from[0].databaseid;return this.ast.columns=this.ast.columns.filter(s=>!Ih.SEARCH_WILDCARDS.includes(s.columnid)),r.forEach(s=>{let i=this.table_to_schema_lookup.has(s.tableid)?this.table_to_schema_lookup.get(s.tableid):n,o=this.table_lookup.has(s.tableid)?this.table_lookup.get(s.tableid):this.ast.from[0].tableid;if(t[i]&&t[i].tables[o]&&t[i].tables[o][Ih.PERMS_CRUD_ENUM.READ]){let c;t[i].tables[o].attribute_permissions.length>0?c=Ule(t[i].tables[o].attribute_permissions):c=global.hdb_schema[i][o].attributes.map(u=>({attribute_name:u.attribute}));let l=this.affected_attributes.get(i).get(o).filter(u=>!Ih.SEARCH_WILDCARDS.includes(u));c.forEach(({attribute_name:u})=>{let f=new wh.yy.Column({columnid:u});s.tableid&&(f.tableid=s.tableid),this.ast.columns.push(f),l.includes(u)||l.push(u)}),this.affected_attributes.get(i).set(o,l)}}),this.ast}};function Ule(e){return e.filter(t=>t[Ih.PERMS_CRUD_ENUM.READ])}a(Ule,"filterReadRestrictedAttrs");function xle(e,t,r,n,s){Ble(e,t,r,n,s)}a(xle,"interpretAST");function Ch(e,t,r,n,s){if(!(!e||!e.databaseid)&&(t.has(e.databaseid)||t.set(e.databaseid,new Map),t.get(e.databaseid).has(e.tableid)||t.get(e.databaseid).set(e.tableid,[]),e.as&&(r.has(e.as)||r.set(e.as,e.tableid),n&&!n.has(e.as)&&n.set(e.as,e.databaseid)),s)){let i=e.databaseid,o=e.tableid;e.as&&(o=e.as),s.set(o,i)}}a(Ch,"addSchemaTableToMap");function Ble(e,t,r,n,s){if(!e){ti.info("getRecordAttributesAST: invalid SQL syntax tree");return}e instanceof wh.yy.Insert?Gle(e,t,r):e instanceof wh.yy.Select?Hle(e,t,r,n,s):e instanceof wh.yy.Update?kle(e,t,r):e instanceof wh.yy.Delete?Fle(e,t,r):ti.error("AST in getRecordAttributesAST() is not a valid SQL type.")}a(Ble,"getRecordAttributesAST");function Hle(e,t,r,n,s){if(!e){ti.info("getSelectAttributes: invalid SQL syntax tree");return}if(!e.from||e.from[0]===void 0)return;let i=e.from[0].databaseid;if(vle.isEmptyOrZeroLength(i)){ti.error("No schema specified");return}e.from.forEach(c=>{Ch(c,t,r,n,s)}),e.joins&&e.joins.forEach(c=>{c.as&&(c.table.as=c.as),Ch(c.table,t,r,n,s)});let o=new Al(e.columns);for(let{node:c}of o)if(c&&c.columnid){let l=c.tableid,u=n.has(l)?n.get(l):i;if(l||(l=e.from[0].tableid),!t.get(u).has(l))if(r.has(l))l=r.get(l);else{ti.info(`table specified as ${l} not found.`);return}t.get(u).get(l).indexOf(c.columnid)<0&&t.get(u).get(l).push(c.columnid)}if(e.where){let c=new Al(e.where),l=e.from[0].tableid;for(let{node:u}of c)if(u&&u.columnid){let f=u.tableid?u.tableid:l;if(!t.get(i).has(f))if(r.has(f))f=r.get(f);else{ti.info(`table specified as ${f} not found.`);continue}t.get(i).get(f).indexOf(u.columnid)<0&&t.get(i).get(f).push(u.columnid)}}if(e.joins&&e.joins.forEach(c=>{let l=new Al(c.on);for(let{node:u}of l)if(u&&u.columnid){let f=u.tableid,d=s.get(f);if(!t.get(d).has(f))if(r.has(f))f=r.get(f);else{ti.info(`table specified as ${f} not found.`);continue}t.get(d).get(f).indexOf(u.columnid)<0&&t.get(d).get(f).push(u.columnid)}}),e.order){let c=new Al(e.order);for(let{node:l}of c)if(l&&l.columnid){let u=l.tableid,f=n.has(u)?n.get(u):i;if(u||(u=e.from[0].tableid),!t.get(f).has(u))if(r.has(u))u=r.get(u);else{ti.info(`table specified as ${u} not found.`);return}t.get(f).get(u).indexOf(l.columnid)<0&&t.get(f).get(u).push(l.columnid)}}}a(Hle,"getSelectAttributes");function kle(e,t,r){if(!e){ti.info("getUpdateAttributes: invalid SQL syntax tree");return}let n=new Al(e.columns),s=e.table.databaseid;Ch(e.table,t,r);for(let{node:i}of n)i&&i.columnid&&tw(e.table.tableid,s,i.columnid,t,r)}a(kle,"getUpdateAttributes");function Fle(e,t,r){if(!e){ti.info("getDeleteAttributes: invalid SQL syntax tree");return}let n=new Al(e.where),s=e.table.databaseid;Ch(e.table,t,r);for(let{node:i}of n)i&&i.columnid&&tw(e.table.tableid,s,i.columnid,t,r)}a(Fle,"getDeleteAttributes");function Gle(e,t,r){if(!e){ti.info("getInsertAttributes: invalid SQL syntax tree");return}let n=new Al(e.columns),s=e.into.databaseid;Ch(e.into,t,r);for(let{node:i}of n)i&&i.columnid&&tw(e.into.tableid,s,i.columnid,t,r)}a(Gle,"getInsertAttributes");function tw(e,t,r,n,s){if(!n.get(t))return;let i=e;n.get(t).has(i)||(i=s.get(i)),n.get(t).get(i).push(r)}a(tw,"pushAttribute");jq.exports=ew});var Zq=C((uDe,Xq)=>{"use strict";var uS=(k(),P(q)),dS=class{static{a(this,"BaseLicense")}constructor(t=0,r=uS.RAM_ALLOCATION_ENUM.DEFAULT,n=uS.LICENSE_VALUES.VERSION_DEFAULT,s){this.exp_date=t,this.ram_allocation=r,this.version=n,this.fingerprint=s}},rw=class extends dS{static{a(this,"ExtendedLicense")}constructor(t=0,r=uS.RAM_ALLOCATION_ENUM.DEFAULT,n=uS.LICENSE_VALUES.VERSION_DEFAULT,s,i=!1){super(t,r,n,s),this.enterprise=i}};Xq.exports={BaseLicense:dS,ExtendedLicense:rw}});var fd=C((fDe,i$)=>{"use strict";var dd=require("fs-extra"),fS=(gE(),P(EE)),t$=require("crypto"),qle=require("moment"),$le=require("uuid").v4,Zr=ee(),sw=require("path"),Vle=ie(),Rl=(k(),P(q)),{totalmem:e$}=require("os"),Kle=Zq().ExtendedLicense,ud="invalid license key format",Yle="061183",Wle="mofi25",zle="aes-256-cbc",Qle=16,jle=32,r$=le(),{resolvePath:n$}=Lt();r$.initSync();var nw;i$.exports={validateLicense:s$,generateFingerPrint:Xle,licenseSearch:aw,getLicense:tue,checkMemoryLimit:rue};function iw(){return sw.join(r$.getHdbBasePath(),Rl.LICENSE_KEY_DIR_NAME,Rl.LICENSE_FILE_NAME)}a(iw,"getLicenseDirPath");function Jle(){let e=iw();return n$(sw.join(e,Rl.LICENSE_FILE_NAME))}a(Jle,"getLicenseFilePath");function ow(){let e=iw();return n$(sw.join(e,Rl.REG_KEY_FILE_NAME))}a(ow,"getFingerPrintFilePath");async function Xle(){let e=ow();try{return await dd.readFile(e,"utf8")}catch(t){if(t.code==="ENOENT")return await Zle();throw Zr.error(`Error writing fingerprint file to ${e}`),Zr.error(t),new Error("There was an error generating the fingerprint")}}a(Xle,"generateFingerPrint");async function Zle(){let e=$le(),t=fS.hash(e,fS.HASH_FUNCTION.MD5),r=ow();try{await dd.mkdirp(iw()),await dd.writeFile(r,t)}catch(n){if(n.code==="EEXIST")return t;throw Zr.error(`Error writing fingerprint file to ${r}`),Zr.error(n),new Error("There was an error generating the fingerprint")}return t}a(Zle,"writeFingerprint");function s$(e,t){let r={valid_license:!1,valid_date:!1,valid_machine:!1,exp_date:null,ram_allocation:Rl.RAM_ALLOCATION_ENUM.DEFAULT,version:Rl.LICENSE_VALUES.VERSION_DEFAULT};if(!e)return Zr.error("empty license key passed to validate."),r;let n=ow(),s=!1;try{s=dd.statSync(n)}catch(i){Zr.error(i)}if(s){let i;try{i=dd.readFileSync(n,"utf8")}catch{Zr.error("error validating this machine in the license"),r.valid_machine=!1;return}let o=e.split(Wle),c=o[1];c=Buffer.concat([Buffer.from(c)],Qle);let l=Buffer.concat([Buffer.from(i)],jle),u=t$.createDecipheriv(zle,l,c);r.valid_date=!0,r.valid_license=!0,r.valid_machine=!0;let f=null;try{f=u.update(o[0],"hex","utf8"),f.trim(),f+=u.final("utf8")}catch{let h=eue(o[0],i);if(h)f=h;else throw r.valid_license=!1,r.valid_machine=!1,console.error(ud),Zr.error(ud),new Error(ud)}let d;if(isNaN(f))try{d=JSON.parse(f),r.version=d.version,r.exp_date=d.exp_date,isNaN(r.exp_date)&&(r.exp_date=new Date(r.exp_date).getTime()),d.ram_allocation&&(r.ram_allocation=d.ram_allocation)}catch{throw console.error(ud),Zr.error(ud),new Error(ud)}else r.exp_date=f;r.exp_date<qle().valueOf()&&(r.valid_date=!1),fS.validate(o[1],`${Yle}${i}${t}`,fS.HASH_FUNCTION.MD5)||(r.valid_license=!1)}else r.valid_license=!1,r.valid_machine=!1;return r.valid_license&&r.valid_machine&&r.valid_date||Zr.error("Invalid licence"),r}a(s$,"validateLicense");function eue(e,t){try{let r=t$.createDecipher("aes192",t),n=r.update(e,"hex","utf8");return n.trim(),n+=r.final("utf8"),n}catch{Zr.warn("Check old license failed")}}a(eue,"checkOldLicense");function aw(){let e=new Kle,t=[];try{t=dd.readFileSync(Jle(),"utf-8").split(`\r
24
- `)}catch(r){r.code==="ENOENT"?Zr.debug("no license file found"):Zr.error(`could not search for licenses due to: '${r.message}`)}for(let r=0;r<t.length;++r){let n=t[r];try{if(Vle.isEmptyOrZeroLength(n))continue;let s=JSON.parse(n),i=s$(s.license_key,s.company);i.valid_machine===!0&&i.valid_date===!0&&i.valid_machine===!0&&(e.exp_date=i.exp_date>e.exp_date?i.exp_date:e.exp_date,e.ram_allocation=i.ram_allocation,e.enterprise=!0)}catch(s){Zr.error("There was an error parsing the license string."),Zr.error(s),e.ram_allocation=Rl.RAM_ALLOCATION_ENUM.DEFAULT,e.enterprise=!1}}return nw=e,e}a(aw,"licenseSearch");async function tue(){return nw||await aw(),nw}a(tue,"getLicense");function rue(){let e=aw().ram_allocation,t=process.constrainedMemory?.()||e$();if(t=Math.round(Math.min(t,e$())/2**20),t>e)return`This server has more memory (${t}MB) than HarperDB is licensed for (${e}MB), this should only be used for educational and development purposes.`}a(rue,"checkMemoryLimit")});var uw=C((hDe,l$)=>{var _S=fd(),o$=require("chalk"),ts=ee(),a$=require("prompt"),{promisify:nue}=require("util"),cw=(k(),P(q)),sue=require("fs-extra"),iue=require("path"),oue=ie(),{packageJson:aue}=Et(),c$=le();c$.initSync();var cue=require("moment"),lue=nue(a$.get),uue=iue.join(c$.getHdbBasePath(),cw.LICENSE_KEY_DIR_NAME,cw.LICENSE_FILE_NAME,cw.LICENSE_FILE_NAME);l$.exports={getFingerprint:fue,setLicense:due,parseLicense:lw,register:_ue,getRegistrationInfo:mue};async function due(e){if(e&&e.key&&e.company){try{ts.info(`parsing license key: ${e.key} and `);let t=e.company.toString();await lw(e.key.trim(),t.trim())}catch(t){let r="There was an error parsing the license key.";throw ts.error(r),ts.error(t),new Error(r)}return"Wrote license key file. Registration successful."}throw new Error("Invalid key or company specified for license file.")}a(due,"setLicense");async function fue(){let e={};try{e=await _S.generateFingerPrint()}catch(t){let r="Error generating fingerprint.";throw ts.error(r),ts.error(t),new Error(r)}return e}a(fue,"getFingerprint");async function lw(e,t){if(!e||!t)throw new Error("Invalid entries for License Key and Customer Company");ts.info("Validating license input...");let r=_S.validateLicense(e,t);if(ts.info("checking for valid license..."),!r.valid_license)throw new Error("Invalid license found.");if(ts.info("checking valid license date..."),!r.valid_date)throw new Error("This License has expired.");if(ts.info(`checking for valid machine license ${r.valid_machine}`),!r.valid_machine)throw new Error("This license is in use on another machine.");try{ts.info("writing license to disk"),await sue.writeFile(uue,JSON.stringify({license_key:e,company:t}))}catch(n){throw ts.error("Failed to write License"),n}return"Registration successful."}a(lw,"parseLicense");async function _ue(){let e=await hue();return lw(e.HDB_LICENSE,e.CUSTOMER_COMPANY)}a(_ue,"register");async function hue(){let e=await _S.generateFingerPrint(),t={properties:{CUSTOMER_COMPANY:{description:o$.magenta("[COMPANY] Please enter your company name"),required:!0},HDB_LICENSE:{description:o$.magenta(`[HDB_LICENSE] Your fingerprint is ${e} Please enter your license key`),required:!0}}};try{a$.start()}catch(n){ts.error(n)}let r;try{r=await lue(t)}catch(n){throw console.error("There was a problem prompting for registration input. Exiting."),n}return r}a(hue,"promptForRegistration");async function mue(){let e={registered:!1,version:null,ram_allocation:null,license_expiration_date:null},t;try{t=await _S.getLicense()}catch(r){throw ts.error(`There was an error when searching licenses due to: ${r.message}`),r}if(oue.isEmptyOrZeroLength(t))throw new Error("There were no licenses found.");if(e.registered=t.enterprise,e.version=aue.version,e.ram_allocation=t.ram_allocation,isNaN(t.exp_date))e.license_expiration_date=t.enterprise?t.exp_date:null;else{let r=cue.utc(t.exp_date).format("YYYY-MM-DD");e.license_expiration_date=t.enterprise?r:null}return e}a(mue,"getRegistrationInfo")});var d$=C((pDe,u$)=>{"use strict";var pue=Pt(),dw=class{static{a(this,"HubConfigObject")}constructor(t,r,n,s,i,o,c,l,u,f,d,_,h,m){this.port=t,o===null&&(o=void 0),this.server_name=r+pue.SERVER_SUFFIX.HUB,this.pid_file=n,this.max_payload=67108864,this.reconnect_error_reports=100,this.jetstream={enabled:!1},this.tls={cert_file:s,key_file:i,ca_file:o,insecure:c,verify:l},this.leafnodes={port:u,tls:{cert_file:s,key_file:i,ca_file:o,insecure:c}},this.cluster={name:f,port:d,routes:_,tls:{cert_file:s,key_file:i,ca_file:o,insecure:c,verify:l}},this.accounts={SYS:{users:h},HDB:{users:m}},this.system_account="SYS"}};u$.exports=dw});var h$=C((gDe,_$)=>{"use strict";var f$=Pt(),fw=class{static{a(this,"LeafConfigObject")}constructor(t,r,n,s,i,o,c,l,u,f,d){this.port=t,d===null&&(d=void 0),this.server_name=r+f$.SERVER_SUFFIX.LEAF,this.pid_file=n,this.max_payload=67108864,this.jetstream={enabled:!0,store_dir:s,domain:r+f$.SERVER_SUFFIX.LEAF},this.tls={cert_file:u,key_file:f,ca_file:d,insecure:!0},this.leafnodes={remotes:[{tls:{ca_file:d,insecure:!0},urls:i,account:"SYS"},{tls:{ca_file:d,insecure:!0},urls:o,account:"HDB"}]},this.accounts={SYS:{users:c},HDB:{users:l,jetstream:"enabled"}},this.system_account="SYS"}};_$.exports=fw});var p$=C((TDe,m$)=>{"use strict";var _w=class{static{a(this,"HdbUserObject")}constructor(t,r){this.user=t,this.password=r}};m$.exports=_w});var g$=C((RDe,E$)=>{"use strict";var Eue=Pt(),hw=class{static{a(this,"SysUserObject")}constructor(t,r){this.user=t+Eue.SERVER_SUFFIX.ADMIN,this.password=r}};E$.exports=hw});var ES=C((bDe,A$)=>{"use strict";var yl=require("path"),bl=require("fs-extra"),gue=d$(),Sue=h$(),Tue=p$(),Aue=g$(),mw=Wn(),hd=ie(),Nn=Lt(),mS=(k(),P(q)),Ph=Pt(),{CONFIG_PARAMS:Xt}=mS,md=ee(),Dh=le(),S$=mo(),pw=Sr(),Rue=ei(),_d="clustering",yue=1e4,T$=50;A$.exports={generateNatsConfig:Oue,removeNatsConfig:Nue,getHubConfigPath:bue};function bue(){let e=Dh.get(Xt.ROOTPATH);return yl.join(e,_d,Ph.NATS_CONFIG_FILES.HUB_SERVER)}a(bue,"getHubConfigPath");async function Oue(e=!1,t=void 0){let r=Dh.get(Xt.ROOTPATH);bl.ensureDirSync(yl.join(r,"clustering","leaf")),Dh.initSync();let n=Nn.getConfigFromFile(Xt.CLUSTERING_TLS_CERT_AUTH),s=Nn.getConfigFromFile(Xt.CLUSTERING_TLS_PRIVATEKEY),i=Nn.getConfigFromFile(Xt.CLUSTERING_TLS_CERTIFICATE);!await bl.exists(i)&&!await bl.exists(!n)&&await Rue.createNatsCerts();let o=yl.join(r,_d,Ph.PID_FILES.HUB),c=yl.join(r,_d,Ph.PID_FILES.LEAF),l=Nn.getConfigFromFile(Xt.CLUSTERING_LEAFSERVER_STREAMS_PATH),u=yl.join(r,_d,Ph.NATS_CONFIG_FILES.HUB_SERVER),f=yl.join(r,_d,Ph.NATS_CONFIG_FILES.LEAF_SERVER),d=Nn.getConfigFromFile(Xt.CLUSTERING_TLS_INSECURE),_=Nn.getConfigFromFile(Xt.CLUSTERING_TLS_VERIFY),h=Nn.getConfigFromFile(Xt.CLUSTERING_NODENAME),m=Nn.getConfigFromFile(Xt.CLUSTERING_HUBSERVER_LEAFNODES_NETWORK_PORT);await pw.checkNATSServerInstalled()||pS("nats-server dependency is either missing or the wrong version. Run 'npm install' to fix");let S=await mw.listUsers(),g=Nn.getConfigFromFile(Xt.CLUSTERING_USER),R=await mw.getClusterUser();(hd.isEmpty(R)||R.active!==!0)&&pS(`Invalid cluster user '${g}'. A valid user with the role 'cluster_user' must be defined under clustering.user in harperdb-config.yaml`),e||(await hS(Xt.CLUSTERING_HUBSERVER_CLUSTER_NETWORK_PORT),await hS(Xt.CLUSTERING_HUBSERVER_LEAFNODES_NETWORK_PORT),await hS(Xt.CLUSTERING_HUBSERVER_NETWORK_PORT),await hS(Xt.CLUSTERING_LEAFSERVER_NETWORK_PORT));let E=[],T=[];for(let[se,z]of S.entries())z.role?.role===mS.ROLE_TYPES_ENUM.CLUSTER_USER&&z.active&&(E.push(new Aue(z.username,S$.decrypt(z.hash))),T.push(new Tue(z.username,S$.decrypt(z.hash))));let N=[],{hub_routes:v}=Nn.getClusteringRoutes();if(!hd.isEmptyOrZeroLength(v))for(let se of v)N.push(`tls://${R.sys_name_encoded}:${R.uri_encoded_d_hash}@${se.host}:${se.port}`);let H=new gue(Nn.getConfigFromFile(Xt.CLUSTERING_HUBSERVER_NETWORK_PORT),h,o,i,s,n,d,_,m,Nn.getConfigFromFile(Xt.CLUSTERING_HUBSERVER_CLUSTER_NAME),Nn.getConfigFromFile(Xt.CLUSTERING_HUBSERVER_CLUSTER_NETWORK_PORT),N,E,T);n==null&&(delete H.tls.ca_file,delete H.leafnodes.tls.ca_file),t=hd.isEmpty(t)?void 0:t.toLowerCase(),(t===void 0||t===mS.PROCESS_DESCRIPTORS.CLUSTERING_HUB.toLowerCase())&&(await bl.writeJson(u,H),md.trace(`Hub server config written to ${u}`));let X=`tls://${R.sys_name_encoded}:${R.uri_encoded_d_hash}@0.0.0.0:${m}`,W=`tls://${R.uri_encoded_name}:${R.uri_encoded_d_hash}@0.0.0.0:${m}`,$=new Sue(Nn.getConfigFromFile(Xt.CLUSTERING_LEAFSERVER_NETWORK_PORT),h,c,l,[X],[W],E,T,i,s,n,d);n==null&&delete $.tls.ca_file,(t===void 0||t===mS.PROCESS_DESCRIPTORS.CLUSTERING_LEAF.toLowerCase())&&(await bl.writeJson(f,$),md.trace(`Leaf server config written to ${f}`))}a(Oue,"generateNatsConfig");async function hS(e){let t=Dh.get(e);return hd.isEmpty(t)&&pS(`port undefined for '${e}'`),await hd.isPortTaken(t)&&pS(`'${e}' port '${t}' is is in use by another process, check to see if HarperDB is already running or another process is using this port.`),!0}a(hS,"isPortAvailable");function pS(e){let t=`Error generating clustering config: ${e}`;md.error(t),console.error(t),process.exit(1)}a(pS,"generateNatsConfigError");async function Nue(e){let{port:t,config_file:r}=pw.getServerConfig(e),{username:n,decrypt_hash:s}=await mw.getClusterUser(),i=0,o=2e3;for(;i<T$;){try{let f=await pw.createConnection(t,n,s,!1);if(f.protocol.connected===!0){f.close();break}}catch(f){md.trace(`removeNatsConfig waiting for ${e}. Caught and swallowed error ${f}`)}if(i++,i>=T$)throw new Error(`Operations API timed out attempting to connect to ${e}. This is commonly caused by incorrect clustering config. Check hdb.log for further details.`);let u=o*(i*2);u>3e4&&md.notify("Operations API waiting for Nats server connection. This could be caused by large Nats streams or incorrect clustering config."),await hd.async_set_timeout(u)}let c="0".repeat(yue),l=yl.join(Dh.get(Xt.ROOTPATH),_d,r);await bl.writeFile(l,c),await bl.remove(l),md.notify(e,"started.")}a(Nue,"removeNatsConfig")});var w$=C((NDe,N$)=>{"use strict";var rs=le(),wue=fd(),Ve=(k(),P(q)),Lh=Pt(),Co=require("path"),{PACKAGE_ROOT:SS}=Et(),R$=le(),gS=ie(),pd="/dev/null",Iue=Co.join(SS,"launchServiceScripts"),y$=Co.join(SS,"utility/scripts"),Cue=Co.join(y$,Ve.HDB_RESTART_SCRIPT),b$=Co.resolve(SS,"dependencies",`${process.platform}-${process.arch}`,Lh.NATS_BINARY_NAME);function O$(){let t=wue.licenseSearch().ram_allocation||Ve.RAM_ALLOCATION_ENUM.DEFAULT,r=Ve.MEM_SETTING_KEY+t,n={[Ve.PROCESS_NAME_ENV_PROP]:Ve.PROCESS_DESCRIPTORS.HDB,IS_SCRIPTED_SERVICE:!0};return gS.noBootFile()&&(n[Ve.CONFIG_PARAMS.ROOTPATH.toUpperCase()]=gS.getEnvCliRootPath()),{name:Ve.PROCESS_DESCRIPTORS.HDB,script:Ve.LAUNCH_SERVICE_SCRIPTS.MAIN,exec_mode:"fork",env:n,node_args:r,cwd:SS}}a(O$,"generateMainServerConfig");var Pue=9930;function Due(){rs.initSync(!0);let e=rs.get(Ve.CONFIG_PARAMS.ROOTPATH),t=Co.join(e,"clustering",Lh.NATS_CONFIG_FILES.HUB_SERVER),r=Co.join(rs.get(Ve.HDB_SETTINGS_NAMES.LOG_PATH_KEY),Ve.LOG_NAMES.HDB),n=R$.get(Ve.CONFIG_PARAMS.CLUSTERING_HUBSERVER_NETWORK_PORT),s=Lh.LOG_LEVEL_FLAGS[rs.get(Ve.CONFIG_PARAMS.CLUSTERING_LOGLEVEL)]??void 0,i={name:Ve.PROCESS_DESCRIPTORS.CLUSTERING_HUB+(n!==Pue?"-"+n:""),script:b$,args:s?`${s} -c ${t}`:`-c ${t}`,exec_mode:"fork",env:{[Ve.PROCESS_NAME_ENV_PROP]:Ve.PROCESS_DESCRIPTORS.CLUSTERING_HUB},merge_logs:!0,out_file:r,error_file:r,instances:1};return rs.get(Ve.HDB_SETTINGS_NAMES.LOG_TO_FILE)||(i.out_file=pd,i.error_file=pd),i}a(Due,"generateNatsHubServerConfig");var Lue=9940;function Mue(){rs.initSync(!0);let e=rs.get(Ve.CONFIG_PARAMS.ROOTPATH),t=Co.join(e,"clustering",Lh.NATS_CONFIG_FILES.LEAF_SERVER),r=Co.join(rs.get(Ve.HDB_SETTINGS_NAMES.LOG_PATH_KEY),Ve.LOG_NAMES.HDB),n=R$.get(Ve.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_NETWORK_PORT),s=Lh.LOG_LEVEL_FLAGS[rs.get(Ve.CONFIG_PARAMS.CLUSTERING_LOGLEVEL)]??void 0,i={name:Ve.PROCESS_DESCRIPTORS.CLUSTERING_LEAF+(n!==Lue?"-"+n:""),script:b$,args:s?`${s} -c ${t}`:`-c ${t}`,exec_mode:"fork",env:{[Ve.PROCESS_NAME_ENV_PROP]:Ve.PROCESS_DESCRIPTORS.CLUSTERING_LEAF},merge_logs:!0,out_file:r,error_file:r,instances:1};return rs.get(Ve.HDB_SETTINGS_NAMES.LOG_TO_FILE)||(i.out_file=pd,i.error_file=pd),i}a(Mue,"generateNatsLeafServerConfig");function vue(){rs.initSync();let e=Co.join(rs.get(Ve.CONFIG_PARAMS.LOGGING_ROOT),Ve.LOG_NAMES.HDB),t={name:Ve.PROCESS_DESCRIPTORS.CLUSTERING_UPGRADE_4_0_0,script:Ve.LAUNCH_SERVICE_SCRIPTS.NODES_UPGRADE_4_0_0,exec_mode:"fork",env:{[Ve.PROCESS_NAME_ENV_PROP]:Ve.PROCESS_DESCRIPTORS.CLUSTERING_UPGRADE_4_0_0},merge_logs:!0,out_file:e,error_file:e,instances:1,cwd:Iue,autorestart:!1};return rs.get(Ve.HDB_SETTINGS_NAMES.LOG_TO_FILE)||(t.out_file=pd,t.error_file=pd),t}a(vue,"generateClusteringUpgradeV4ServiceConfig");function Uue(){let e={[Ve.PROCESS_NAME_ENV_PROP]:Ve.PROCESS_DESCRIPTORS.RESTART_HDB};return gS.noBootFile()&&(e[Ve.CONFIG_PARAMS.ROOTPATH.toUpperCase()]=gS.getEnvCliRootPath()),{...{name:Ve.PROCESS_DESCRIPTORS.RESTART_HDB,exec_mode:"fork",env:e,instances:1,autorestart:!1,cwd:y$},script:Cue}}a(Uue,"generateRestart");function xue(){return{apps:[O$()]}}a(xue,"generateAllServiceConfigs");N$.exports={generateAllServiceConfigs:xue,generateMainServerConfig:O$,generateRestart:Uue,generateNatsHubServerConfig:Due,generateNatsLeafServerConfig:Mue,generateClusteringUpgradeV4ServiceConfig:vue}});var vh=C((CDe,G$)=>{"use strict";var tt=(k(),P(q)),Bue=ie(),Do=ES(),TS=Sr(),Po=Pt(),Ha=w$(),AS=le(),Ol=ee(),Hue=No(),{startWorker:I$,onMessageFromWorkers:kue}=it(),Fue=od(),IDe=require("util"),Gue=require("child_process"),que=require("fs"),{execFile:$ue}=Gue,je;G$.exports={enterPM2Mode:Vue,start:ka,stop:Ew,reload:P$,restart:D$,list:gw,describe:v$,connect:Lo,kill:Que,startAllServices:jue,startService:Sw,getUniqueServicesList:U$,restartAllServices:Jue,isServiceRegistered:x$,reloadStopStart:B$,restartHdb:M$,deleteProcess:Wue,startClusteringProcesses:k$,startClusteringThreads:F$,isHdbRestartRunning:zue,isClusteringRunning:Zue,stopClustering:Xue,reloadClustering:ede,expectedRestartOfChildren:L$};var Mh=!1;kue(e=>{e.type==="restart"&&AS.initSync(!0)});function Vue(){Mh=!0}a(Vue,"enterPM2Mode");function Lo(){return je||(je=require("pm2")),new Promise((e,t)=>{je.connect((r,n)=>{r&&t(r),e(n)})})}a(Lo,"connect");var en,Kue=10,C$;function ka(e,t=!1){if(Mh)return Yue(e);let r=$ue(e.script,e.args.split(" "),e);r.name=e.name,r.config=e,r.on("exit",async i=>{let o=en.indexOf(r);o>-1&&en.splice(o,1),!C$&&i!==0&&(e.restarts=(e.restarts||0)+1,e.restarts<Kue&&(que.existsSync(Do.getHubConfigPath())?ka(e):(await Do.generateNatsConfig(!0),ka(e),await new Promise(c=>setTimeout(c,3e3)),await Do.removeNatsConfig(tt.PROCESS_DESCRIPTORS.CLUSTERING_HUB),await Do.removeNatsConfig(tt.PROCESS_DESCRIPTORS.CLUSTERING_LEAF))))});let n={serviceName:e.name.replace(/ /g,"-")};function s(i){let o=AS.get(tt.CONFIG_PARAMS.CLUSTERING_LOGLEVEL),c=/\[\d+][^\[]+\[(\w+)]/g,l,u=0,f;for(;l=c.exec(i);){if(l.index&&Po.LOG_LEVEL_HIERARCHY[o]>=Po.LOG_LEVEL_HIERARCHY[f||"info"]){let h=f===Po.LOG_LEVELS.ERR||f===Po.LOG_LEVELS.WRN?Ol.OUTPUTS.STDERR:Ol.OUTPUTS.STDOUT;Ol.logCustomLevel(f||"info",h,n,i.slice(u,l.index).trim())}let[d,_]=l;u=l.index+d.length,f=Po.LOG_LEVELS[_]}if(Po.LOG_LEVEL_HIERARCHY[o]>=Po.LOG_LEVEL_HIERARCHY[f||"info"]){let d=f===Po.LOG_LEVELS.ERR||f===Po.LOG_LEVELS.WRN?Ol.OUTPUTS.STDERR:Ol.OUTPUTS.STDOUT;Ol.logCustomLevel(f||"info",d,n,i.slice(u).trim())}}if(a(s,"extractMessages"),r.stdout.on("data",s),r.stderr.on("data",s),r.unref(),!en&&(en=[],!t)){let i=a(()=>{C$=!0,en&&(en.map(o=>o.kill()),process.exit(0))},"kill_children");process.on("exit",i),process.on("SIGINT",i),process.on("SIGQUIT",i),process.on("SIGTERM",i)}en.push(r)}a(ka,"start");function Yue(e){return new Promise(async(t,r)=>{try{await Lo()}catch(n){r(n)}je.start(e,(n,s)=>{n&&(je.disconnect(),r(n)),je.disconnect(),t(s)})})}a(Yue,"startWithPM2");function Ew(e){if(!Mh){for(let t of en||[])t.name===e&&(en.splice(en.indexOf(t),1),t.kill());return}return new Promise(async(t,r)=>{try{await Lo()}catch(n){r(n)}je.stop(e,async(n,s)=>{n&&(je.disconnect(),r(n)),je.delete(e,(i,o)=>{i&&(je.disconnect(),r(n)),je.disconnect(),t(o)})})})}a(Ew,"stop");function P$(e){return new Promise(async(t,r)=>{try{await Lo()}catch(n){r(n)}je.reload(e,(n,s)=>{n&&(je.disconnect(),r(n)),je.disconnect(),t(s)})})}a(P$,"reload");function D$(e){if(!Mh){L$();for(let t of en||[])t.name===e&&t.kill()}return new Promise(async(t,r)=>{try{await Lo()}catch(n){r(n)}je.restart(e,(n,s)=>{je.disconnect(),t(s)})})}a(D$,"restart");function L$(){for(let e of en||[])e.config&&(e.config.restarts=0)}a(L$,"expectedRestartOfChildren");function Wue(e){return new Promise(async(t,r)=>{try{await Lo()}catch(n){r(n)}je.delete(e,(n,s)=>{n&&(je.disconnect(),r(n)),je.disconnect(),t(s)})})}a(Wue,"deleteProcess");async function M$(){await ka(Ha.generateRestart())}a(M$,"restartHdb");async function zue(){let e=await gw();for(let t in e)if(e[t].name===tt.PROCESS_DESCRIPTORS.RESTART_HDB)return!0;return!1}a(zue,"isHdbRestartRunning");function gw(){return new Promise(async(e,t)=>{try{await Lo()}catch(r){t(r)}je.list((r,n)=>{r&&(je.disconnect(),t(r)),je.disconnect(),e(n)})})}a(gw,"list");function v$(e){return new Promise(async(t,r)=>{try{await Lo()}catch(n){r(n)}je.describe(e,(n,s)=>{n&&(je.disconnect(),r(n)),je.disconnect(),t(s)})})}a(v$,"describe");function Que(){if(!Mh){for(let e of en||[])e.kill();en=[];return}return new Promise(async(e,t)=>{try{await Lo()}catch(r){t(r)}je.killDaemon((r,n)=>{r&&(je.disconnect(),t(r)),je.disconnect(),e(n)})})}a(Que,"kill");async function jue(){try{await k$(),await F$(),await ka(Ha.generateAllServiceConfigs())}catch(e){throw je?.disconnect(),e}}a(jue,"startAllServices");async function Sw(e,t=!1){try{let r;switch(e=e.toLowerCase(),e){case tt.PROCESS_DESCRIPTORS.HDB.toLowerCase():r=Ha.generateMainServerConfig();break;case tt.PROCESS_DESCRIPTORS.CLUSTERING_INGEST_SERVICE.toLowerCase():r=Ha.generateNatsIngestServiceConfig();break;case tt.PROCESS_DESCRIPTORS.CLUSTERING_REPLY_SERVICE.toLowerCase():r=Ha.generateNatsReplyServiceConfig();break;case tt.PROCESS_DESCRIPTORS.CLUSTERING_HUB.toLowerCase():r=Ha.generateNatsHubServerConfig(),await ka(r,t),await Do.removeNatsConfig(e);return;case tt.PROCESS_DESCRIPTORS.CLUSTERING_LEAF.toLowerCase():r=Ha.generateNatsLeafServerConfig(),await ka(r,t),await Do.removeNatsConfig(e);return;case tt.PROCESS_DESCRIPTORS.CLUSTERING_UPGRADE_4_0_0.toLowerCase():r=Ha.generateClusteringUpgradeV4ServiceConfig();break;default:throw new Error(`Start service called with unknown service config: ${e}`)}await ka(r)}catch(r){throw je?.disconnect(),r}}a(Sw,"startService");async function U$(){try{let e=await gw(),t={};for(let r=0,n=e.length;r<n;r++){let s=e[r];t[s.name]===void 0&&(t[s.name]={name:s.name,exec_mode:s.pm2_env.exec_mode})}return t}catch(e){throw je?.disconnect(),e}}a(U$,"getUniqueServicesList");async function Jue(e=[]){try{let t=!1,r=await U$();for(let n=0,s=Object.values(r).length;n<s;n++){let o=Object.values(r)[n].name;e.includes(o)||(o===tt.PROCESS_DESCRIPTORS.HDB?t=!0:await D$(o))}t&&await B$(tt.PROCESS_DESCRIPTORS.HDB)}catch(t){throw je?.disconnect(),t}}a(Jue,"restartAllServices");async function x$(e){if(en?.find(r=>r.name===e))return!0;let t=await Fue.getHDBProcessInfo();return t.core.length&&t.core[0]?.parent==="PM2"}a(x$,"isServiceRegistered");async function B$(e){let t=AS.get(tt.CONFIG_PARAMS.THREADS_COUNT)??AS.get(tt.CONFIG_PARAMS.THREADS),r=await v$(e),n=Bue.isEmptyOrZeroLength(r)?0:r.length;t!==n?(await Ew(e),await Sw(e)):e===tt.PROCESS_DESCRIPTORS.HDB?await M$():await P$(e)}a(B$,"reloadStopStart");var H$;async function k$(e=!1){for(let t in tt.CLUSTERING_PROCESSES){let r=tt.CLUSTERING_PROCESSES[t];await Sw(r,e)}}a(k$,"startClusteringProcesses");async function F$(){H$=I$(tt.LAUNCH_SERVICE_SCRIPTS.NATS_REPLY_SERVICE,{name:tt.PROCESS_DESCRIPTORS.CLUSTERING_REPLY_SERVICE});try{await TS.deleteLocalStream("__HARPERDB_WORK_QUEUE__")}catch{}await TS.updateLocalStreams();let e=await Hue.getAllNodeRecords();for(let t=0,r=e.length;t<r;t++)if(e[t].system_info?.hdb_version===tt.PRE_4_0_0_VERSION){Ol.info("Starting clustering upgrade 4.0.0 process"),I$(tt.LAUNCH_SERVICE_SCRIPTS.NODES_UPGRADE_4_0_0,{name:"Upgrade-4-0-0"});break}}a(F$,"startClusteringThreads");async function Xue(){for(let e in tt.CLUSTERING_PROCESSES)if(e!==tt.CLUSTERING_PROCESSES.CLUSTERING_INGEST_PROC_DESCRIPTOR)if(e===tt.CLUSTERING_PROCESSES.CLUSTERING_REPLY_SERVICE_DESCRIPTOR)await H$.terminate();else{let t=tt.CLUSTERING_PROCESSES[e];await Ew(t)}}a(Xue,"stopClustering");async function Zue(){for(let e in tt.CLUSTERING_PROCESSES){let t=tt.CLUSTERING_PROCESSES[e];if(await x$(t)===!1)return!1}return!0}a(Zue,"isClusteringRunning");async function ede(){await Do.generateNatsConfig(!0),await TS.reloadNATSHub(),await TS.reloadNATSLeaf(),await Do.removeNatsConfig(tt.PROCESS_DESCRIPTORS.CLUSTERING_HUB.toLowerCase()),await Do.removeNatsConfig(tt.PROCESS_DESCRIPTORS.CLUSTERING_LEAF.toLowerCase())}a(ede,"reloadClustering")});var Rw={};Ue(Rw,{compactOnStart:()=>tde,copyDb:()=>W$});async function tde(){Fa.notify("Running compact on start"),console.log("Running compact on start");let e=(0,Tw.get)(x.ROOTPATH),t=new Map,r=Je();(0,Aw.updateConfigValue)(x.STORAGE_COMPACTONSTART,!1);try{for(let n in r){if(n==="system"||n.endsWith("-copy"))continue;let s;for(let l in r[n]){s=r[n][l].primaryStore.path;break}if(!s){console.log("Couldn't find any tables in database",n);continue}let i=(0,RS.join)(e,"backup",n+".mdb"),o=(0,RS.join)(e,fc,n+"-copy.mdb"),c=0;try{c=await q$(n),console.log("Database",n,"before compact has a total record count of",c)}catch(l){Fa.error("Error getting record count for database",n,l),console.error("Error getting record count for database",n,l)}t.set(n,{db_path:s,copy_dest:o,backup_dest:i,record_count:c}),await W$(n,o),console.log("Backing up",n,"to",i),await(0,Nl.move)(s,i,{overwrite:!0})}try{Du()}catch(n){Fa.error("Error resetting databases after backup",n),console.error("Error resetting databases after backup",n)}for(let[n,{db_path:s,copy_dest:i}]of t)console.log("Moving copy compacted",n,"to",s),await(0,Nl.move)(i,s,{overwrite:!0}),await(0,Nl.remove)((0,RS.join)(e,fc,`${n}-copy.mdb-lock`));try{Du()}catch(n){Fa.error("Error resetting databases after backup",n),console.error("Error resetting databases after backup",n),process.exit(0)}}catch(n){Fa.error("Error compacting database, rolling back operation",n),console.error("Error compacting database, rolling back operation",n),(0,Aw.updateConfigValue)(x.STORAGE_COMPACTONSTART,!1);for(let[s,{db_path:i,backup_dest:o}]of t){console.error("Moving backup database",o,"back to",i);try{await(0,Nl.move)(o,i,{overwrite:!0})}catch(c){console.error(c)}}throw Du(),n}for(let[n,{backup_dest:s,record_count:i}]of t){let o=!0,c=await q$(n);if(console.log("Database",n,"after compact has a total record count of",c),i!==c){o=!1;let l=`There is a discrepancy between pre and post compact record count for database ${n}.
25
- Total record count before compaction: ${i}, total after: ${c}.
26
- Database backup has not been removed and can be found here: ${s}`;Fa.error(l),console.error(l)}(0,Tw.get)(x.STORAGE_COMPACTONSTARTKEEPBACKUP)===!0||o===!1||(console.log("Removing backup",s),await(0,Nl.remove)(s))}}async function q$(e){let t=await(0,Y$.describeSchema)({database:e}),r=0;for(let n in t)r+=t[n].record_count;return r}function Ed(){}async function W$(e,t){console.log(`Copying database ${e} to ${t}`);let r=Je()[e];if(!r)throw new Error(`Source database not found: ${e}`);let n;for(let d in r){let _=r[d];_.primaryStore.put=Ed,_.primaryStore.remove=Ed;for(let h in _.indices){let m=_.indices[h];m.put=Ed,m.remove=Ed}_.auditStore&&(_.auditStore.put=Ed,_.auditStore.remove=Ed),n=_.primaryStore.rootStore}if(!n)throw new Error(`Source database does not have any tables: ${e}`);let s=n.dbisDb,i=n.auditStore,o=(0,$$.open)(new V$.default(t)),c=o.openDB(yS.INTERNAL_DBIS_NAME),l,u=0,f=s.useReadTransaction();try{for(let{key:_,value:h}of s.getRange({transaction:f})){let m=h.is_hash_attribute||h.isPrimaryKey,S,g;if(m&&(S=h.compression,g=GE(),g?h.compression=g:delete h.compression,S?.dictionary?.toString()===g?.dictionary?.toString()&&(S=null,g=null)),c.put(_,h),!(m||h.indexed))continue;let R=new K$.default(!m,m);R.encoding="binary",R.compression=S;let E=n.openDB(_,R);E.decoder=null,E.decoderCopies=!1,E.encoding="binary",R.compression=g;let T=o.openDB(_,R);T.encoder=null,console.log("copying",_,"from",e,"to",t),await d(E,T,m,f)}if(i){let _=n.openDB(yS.AUDIT_STORE_NAME,Vf);console.log("copying audit log for",e,"to",t),d(i,_,!1,f)}async function d(_,h,m,S){let g=0,R=0,E=0,T=1e7,N=null;for(;T-- >0;)try{for(let v of _.getKeys({start:N,transaction:S}))try{N=v;let{value:H,version:X}=_.getEntry(v,{transaction:S});if(H?.length<14&&m){E++;continue}l=h.put(v,H,m?X:void 0),g++,S.openTimer&&(S.openTimer=0),R+=(v?.length||10)+H.length,u++>5e3&&(await l,console.log("copied",g,"entries, skipped",E,"delete records,",R,"bytes"),u=0)}catch(H){console.error("Error copying record",typeof v=="symbol"?"symbol":v,"from",e,"to",t,H)}console.log("finish copying, copied",g,"entries, skipped",E,"delete records,",R,"bytes");return}catch{if(typeof N=="string"){if(N==="z")return console.error("Reached end of dbi",N,"for",e,"to",t);N=N.slice(0,-2)+"z"}else if(typeof N=="number")N++;else return console.error("Unknown key type",N,"for",e,"to",t)}}a(d,"copyDbi"),await l,console.log("copied database "+e+" to "+t)}finally{f.done(),o.close()}}var $$,RS,Nl,Tw,V$,K$,yS,Y$,Aw,Fa,yw=Re(()=>{xe();$$=require("lmdb"),RS=require("path"),Nl=require("fs-extra"),Tw=M(le()),V$=M(Yf()),K$=M(Kf()),yS=M(Gt());k();Ai();Y$=M(po()),Aw=M(Lt()),Fa=M(ee());a(tde,"compactOnStart");a(q$,"getTotalDBRecordCount");a(Ed,"noop");a(W$,"copyDb")});var Sd=C((HDe,eV)=>{"use strict";var rde=require("minimist"),{isMainThread:Ow,parentPort:xh,threadId:UDe}=require("worker_threads"),at=(k(),P(q)),ki=ee(),Nw=ie(),OS=ES(),bS=Sr(),xDe=Pt(),J$=Lt(),ri=vh(),z$=od(),{compactOnStart:nde}=(yw(),P(Rw)),sde=_c(),{restartWorkers:NS,onMessageByType:ide}=it(),{handleHDBError:ode,hdb_errors:ade}=he(),{HTTP_STATUS_CODES:cde}=ade,Bh=le(),{sendOperationToNode:Q$,getThisNodeName:lde,monitorNodeCAs:ude}=(gs(),P(Ca)),{getHDBNodeTable:BDe}=(ul(),P(BO));Bh.initSync();var Uh=`Restarting HarperDB. This may take up to ${at.RESTART_TIMEOUT_MS/1e3} seconds.`,dde="Restart is not available from the CLI when running in non-pm2 mode. Either call restart from the API or stop and start HarperDB.",j$="Clustering is not enabled so cannot be restarted",fde="Invalid service",gd,ys;eV.exports={restart:X$,restartService:ww};Ow&&ide(at.ITC_EVENT_TYPES.RESTART,async(e,t)=>{e.workerType?await ww({service:e.workerType}):X$({operation:"restart"}),t.postMessage({type:"restart-complete"})});async function X$(e){ys=Object.keys(e).length===0,gd=await ri.isServiceRegistered(at.PROCESS_DESCRIPTORS.HDB);let t=rde(process.argv);if(t.service){await ww(t);return}if(ys&&!gd){console.error(dde);return}if(ys&&console.log(Uh),gd){ri.enterPM2Mode(),ki.notify(Uh);let r=sde(Object.keys(at.CONFIG_PARAM_MAP),!0);return Nw.isEmptyOrZeroLength(Object.keys(r))||J$.updateConfigValue(void 0,void 0,r,!0,!0),_de(),Uh}return Ow?(ki.notify(Uh),Bh.get(at.CONFIG_PARAMS.STORAGE_COMPACTONSTART)&&await nde(),process.env.HARPER_EXIT_ON_RESTART&&process.exit(0),setTimeout(()=>{NS()},50)):xh.postMessage({type:at.ITC_EVENT_TYPES.RESTART}),Uh}a(X$,"restart");async function ww(e){let{service:t}=e;if(at.HDB_PROCESS_SERVICES[t]===void 0)throw ode(new Error,fde,cde.BAD_REQUEST,void 0,void 0,!0);if(ri.expectedRestartOfChildren(),gd=await ri.isServiceRegistered(at.PROCESS_DESCRIPTORS.HDB),!Ow){e.replicated&&ude(),xh.postMessage({type:at.ITC_EVENT_TYPES.RESTART,workerType:t}),xh.ref(),await new Promise(s=>{xh.on("message",i=>{i.type==="restart-complete"&&(s(),xh.unref())})});let n;if(e.replicated){e.replicated=!1,n=[];for(let s of server.nodes){if(s.name===lde())continue;let i;try{({job_id:i}=await Q$(s,e))}catch(o){n.push({node:s.name,message:o.message});continue}n.push(await new Promise((o,c)=>{let u=2400,f=setInterval(async()=>{if(u--<=0){clearInterval(f);let h=new Error("Timed out waiting for restart job to complete");h.replicated=n,c(h)}let _=(await Q$(s,{operation:"get_job",id:i})).results[0];if(_.status==="COMPLETE"&&(clearInterval(f),o({node:s.name,message:_.message})),_.status==="ERROR"){clearInterval(f);let h=new Error(_.message);h.replicated=n,c(h)}},250)}))}return{replicated:n}}return}let r;switch(t){case at.HDB_PROCESS_SERVICES.clustering:if(!Bh.get(at.CONFIG_PARAMS.CLUSTERING_ENABLED)){r=j$;break}ys&&console.log("Restarting clustering"),ki.notify("Restarting clustering"),await Z$();break;case at.HDB_PROCESS_SERVICES.clustering_config:case at.HDB_PROCESS_SERVICES["clustering config"]:if(!Bh.get(at.CONFIG_PARAMS.CLUSTERING_ENABLED)){r=j$;break}ys&&console.log("Restarting clustering_config"),ki.notify("Restarting clustering_config"),await ri.reloadClustering();break;case"custom_functions":case"custom functions":case at.HDB_PROCESS_SERVICES.harperdb:case at.HDB_PROCESS_SERVICES.http_workers:case at.HDB_PROCESS_SERVICES.http:if(ys&&!gd){r=`Restart ${t} is not available from the CLI when running in non-pm2 mode. Either call restart ${t} from the API or stop and start HarperDB.`;break}ys&&console.log("Restarting http_workers"),ki.notify("Restarting http_workers"),ys?await ri.restart(at.PROCESS_DESCRIPTORS.HDB):await NS("http");break;default:r=`Unrecognized service: ${t}`;break}return r?(ki.error(r),ys&&console.error(r),r):(t==="custom_functions"&&(t="Custom Functions"),`Restarting ${t}`)}a(ww,"restartService");async function _de(){await Z$(),await ri.restart(at.PROCESS_DESCRIPTORS.HDB),await Nw.async_set_timeout(2e3),Bh.get(at.CONFIG_PARAMS.CLUSTERING_ENABLED)&&await bw(),ys&&(await bS.closeConnection(),process.exit(0))}a(_de,"restartPM2Mode");async function Z$(){if(!J$.getConfigFromFile(at.CONFIG_PARAMS.CLUSTERING_ENABLED))return;if((await z$.getHDBProcessInfo()).clustering.length===0)ki.trace("Clustering not running, restart will start clustering services"),await OS.generateNatsConfig(!0),await ri.startClusteringProcesses(),await ri.startClusteringThreads(),await bw(),ys&&await bS.closeConnection();else{await OS.generateNatsConfig(!0),gd?(ki.trace("Restart clustering restarting PM2 managed Hub and Leaf servers"),await ri.restart(at.PROCESS_DESCRIPTORS.CLUSTERING_HUB),await ri.restart(at.PROCESS_DESCRIPTORS.CLUSTERING_LEAF)):(await z$.getHDBProcessInfo()).clustering.forEach(s=>{ki.trace("Restart clustering killing process pid",s.pid),process.kill(s.pid)}),await Nw.async_set_timeout(3e3),await bw(),await bS.updateLocalStreams(),ys&&await bS.closeConnection(),ki.trace("Restart clustering restarting ingest and reply service threads");let t=NS(at.LAUNCH_SERVICE_SCRIPTS.NATS_INGEST_SERVICE),r=NS(at.LAUNCH_SERVICE_SCRIPTS.NATS_REPLY_SERVICE);await t,await r}}a(Z$,"restartClustering");async function bw(){await OS.removeNatsConfig(at.PROCESS_DESCRIPTORS.CLUSTERING_HUB),await OS.removeNatsConfig(at.PROCESS_DESCRIPTORS.CLUSTERING_LEAF)}a(bw,"removeNatsConfig")});var dV=C((GDe,uV)=>{"use strict";var FDe=require("lodash"),wn=(k(),P(q)),{handleHDBError:tV,hdb_errors:hde}=he(),{HDB_ERROR_MSGS:mde,HTTP_STATUS_CODES:pde}=hde,Iw=ee();uV.exports={getRolePermissions:gde};var wl=Object.create(null),Ede=a(e=>({key:e,perms:{}}),"perms_template_obj"),iV=a((e=!1)=>({describe:e,tables:{}}),"schema_perms_template"),oV=a((e=!1,t=!1,r=!1,n=!1)=>({[wn.PERMS_CRUD_ENUM.READ]:e,[wn.PERMS_CRUD_ENUM.INSERT]:t,[wn.PERMS_CRUD_ENUM.UPDATE]:r,[wn.PERMS_CRUD_ENUM.DELETE]:n}),"permissions_template"),Cw=a((e=!1,t=!1,r=!1,n=!1,s=!1)=>({attribute_permissions:[],describe:e,...oV(t,r,n,s)}),"table_perms_template"),rV=a((e,t=oV())=>({attribute_name:e,describe:lV(t),[Hh]:t[Hh],[Pw]:t[Pw],[Dw]:t[Dw]}),"attr_perms_template"),nV=a((e,t=!1)=>({attribute_name:e,describe:t,[Hh]:t}),"timestamp_attr_perms_template"),{READ:Hh,INSERT:Pw,UPDATE:Dw}=wn.PERMS_CRUD_ENUM,aV=Object.values(wn.PERMS_CRUD_ENUM),cV=[Hh,Pw,Dw];function gde(e){let t;try{if(e.permission.super_user||e.permission.cluster_user)return e.permission;let r={...global.hdb_schema};delete r[wn.SYSTEM_SCHEMA_NAME],t=e.role;let n=JSON.stringify([e.__updatedtime__,r]);if(wl[t]&&wl[t].key===n)return wl[t].perms;let s=Sde(e,r);return wl[t]?wl[t].key=n:wl[t]=Ede(n),wl[t].perms=s,s}catch(r){if(!e[wn.TIME_STAMP_NAMES_ENUM.UPDATED_TIME]||e[wn.TIME_STAMP_NAMES_ENUM.UPDATED_TIME]<wn.PERMS_UPDATE_RELEASE_TIMESTAMP){let n=`Role permissions for role '${t}' must be updated to align with new structure from the 2.2.0 release.`;throw Iw.error(n),Iw.debug(r),tV(new Error,mde.OUTDATED_PERMS_TRANSLATION_ERROR,pde.BAD_REQUEST)}else{let n=`There was an error while translating role permissions for role: ${t}.
24
+ `)}catch(r){r.code==="ENOENT"?Zr.debug("no license file found"):Zr.error(`could not search for licenses due to: '${r.message}`)}for(let r=0;r<t.length;++r){let n=t[r];try{if(Vle.isEmptyOrZeroLength(n))continue;let s=JSON.parse(n),i=s$(s.license_key,s.company);i.valid_machine===!0&&i.valid_date===!0&&i.valid_machine===!0&&(e.exp_date=i.exp_date>e.exp_date?i.exp_date:e.exp_date,e.ram_allocation=i.ram_allocation,e.enterprise=!0)}catch(s){Zr.error("There was an error parsing the license string."),Zr.error(s),e.ram_allocation=Rl.RAM_ALLOCATION_ENUM.DEFAULT,e.enterprise=!1}}return nw=e,e}a(aw,"licenseSearch");async function tue(){return nw||await aw(),nw}a(tue,"getLicense");function rue(){let e=aw().ram_allocation,t=process.constrainedMemory?.()||e$();if(t=Math.round(Math.min(t,e$())/2**20),t>e)return`This server has more memory (${t}MB) than HarperDB is licensed for (${e}MB), this should only be used for educational and development purposes.`}a(rue,"checkMemoryLimit")});var uw=C((hDe,l$)=>{var _S=fd(),o$=require("chalk"),ts=ee(),a$=require("prompt"),{promisify:nue}=require("util"),cw=(k(),P(q)),sue=require("fs-extra"),iue=require("path"),oue=ie(),{packageJson:aue}=Et(),c$=le();c$.initSync();var cue=require("moment"),lue=nue(a$.get),uue=iue.join(c$.getHdbBasePath(),cw.LICENSE_KEY_DIR_NAME,cw.LICENSE_FILE_NAME,cw.LICENSE_FILE_NAME);l$.exports={getFingerprint:fue,setLicense:due,parseLicense:lw,register:_ue,getRegistrationInfo:mue};async function due(e){if(e&&e.key&&e.company){try{ts.info(`parsing license key: ${e.key} and `);let t=e.company.toString();await lw(e.key.trim(),t.trim())}catch(t){let r="There was an error parsing the license key.";throw ts.error(r),ts.error(t),new Error(r)}return"Wrote license key file. Registration successful."}throw new Error("Invalid key or company specified for license file.")}a(due,"setLicense");async function fue(){let e={};try{e=await _S.generateFingerPrint()}catch(t){let r="Error generating fingerprint.";throw ts.error(r),ts.error(t),new Error(r)}return e}a(fue,"getFingerprint");async function lw(e,t){if(!e||!t)throw new Error("Invalid entries for License Key and Customer Company");ts.info("Validating license input...");let r=_S.validateLicense(e,t);if(ts.info("checking for valid license..."),!r.valid_license)throw new Error("Invalid license found.");if(ts.info("checking valid license date..."),!r.valid_date)throw new Error("This License has expired.");if(ts.info(`checking for valid machine license ${r.valid_machine}`),!r.valid_machine)throw new Error("This license is in use on another machine.");try{ts.info("writing license to disk"),await sue.writeFile(uue,JSON.stringify({license_key:e,company:t}))}catch(n){throw ts.error("Failed to write License"),n}return"Registration successful."}a(lw,"parseLicense");async function _ue(){let e=await hue();return lw(e.HDB_LICENSE,e.CUSTOMER_COMPANY)}a(_ue,"register");async function hue(){let e=await _S.generateFingerPrint(),t={properties:{CUSTOMER_COMPANY:{description:o$.magenta("[COMPANY] Please enter your company name"),required:!0},HDB_LICENSE:{description:o$.magenta(`[HDB_LICENSE] Your fingerprint is ${e} Please enter your license key`),required:!0}}};try{a$.start()}catch(n){ts.error(n)}let r;try{r=await lue(t)}catch(n){throw console.error("There was a problem prompting for registration input. Exiting."),n}return r}a(hue,"promptForRegistration");async function mue(){let e={registered:!1,version:null,ram_allocation:null,license_expiration_date:null},t;try{t=await _S.getLicense()}catch(r){throw ts.error(`There was an error when searching licenses due to: ${r.message}`),r}if(oue.isEmptyOrZeroLength(t))throw new Error("There were no licenses found.");if(e.registered=t.enterprise,e.version=aue.version,e.ram_allocation=t.ram_allocation,isNaN(t.exp_date))e.license_expiration_date=t.enterprise?t.exp_date:null;else{let r=cue.utc(t.exp_date).format("YYYY-MM-DD");e.license_expiration_date=t.enterprise?r:null}return e}a(mue,"getRegistrationInfo")});var d$=C((pDe,u$)=>{"use strict";var pue=Pt(),dw=class{static{a(this,"HubConfigObject")}constructor(t,r,n,s,i,o,c,l,u,f,d,_,h,m){this.port=t,o===null&&(o=void 0),this.server_name=r+pue.SERVER_SUFFIX.HUB,this.pid_file=n,this.max_payload=67108864,this.reconnect_error_reports=100,this.jetstream={enabled:!1},this.tls={cert_file:s,key_file:i,ca_file:o,insecure:c,verify:l},this.leafnodes={port:u,tls:{cert_file:s,key_file:i,ca_file:o,insecure:c}},this.cluster={name:f,port:d,routes:_,tls:{cert_file:s,key_file:i,ca_file:o,insecure:c,verify:l}},this.accounts={SYS:{users:h},HDB:{users:m}},this.system_account="SYS"}};u$.exports=dw});var h$=C((gDe,_$)=>{"use strict";var f$=Pt(),fw=class{static{a(this,"LeafConfigObject")}constructor(t,r,n,s,i,o,c,l,u,f,d){this.port=t,d===null&&(d=void 0),this.server_name=r+f$.SERVER_SUFFIX.LEAF,this.pid_file=n,this.max_payload=67108864,this.jetstream={enabled:!0,store_dir:s,domain:r+f$.SERVER_SUFFIX.LEAF},this.tls={cert_file:u,key_file:f,ca_file:d,insecure:!0},this.leafnodes={remotes:[{tls:{ca_file:d,insecure:!0},urls:i,account:"SYS"},{tls:{ca_file:d,insecure:!0},urls:o,account:"HDB"}]},this.accounts={SYS:{users:c},HDB:{users:l,jetstream:"enabled"}},this.system_account="SYS"}};_$.exports=fw});var p$=C((TDe,m$)=>{"use strict";var _w=class{static{a(this,"HdbUserObject")}constructor(t,r){this.user=t,this.password=r}};m$.exports=_w});var g$=C((RDe,E$)=>{"use strict";var Eue=Pt(),hw=class{static{a(this,"SysUserObject")}constructor(t,r){this.user=t+Eue.SERVER_SUFFIX.ADMIN,this.password=r}};E$.exports=hw});var ES=C((bDe,A$)=>{"use strict";var yl=require("path"),bl=require("fs-extra"),gue=d$(),Sue=h$(),Tue=p$(),Aue=g$(),mw=Wn(),hd=ie(),Nn=Lt(),mS=(k(),P(q)),Ph=Pt(),{CONFIG_PARAMS:Xt}=mS,md=ee(),Dh=le(),S$=mo(),pw=Sr(),Rue=ei(),_d="clustering",yue=1e4,T$=50;A$.exports={generateNatsConfig:Oue,removeNatsConfig:Nue,getHubConfigPath:bue};function bue(){let e=Dh.get(Xt.ROOTPATH);return yl.join(e,_d,Ph.NATS_CONFIG_FILES.HUB_SERVER)}a(bue,"getHubConfigPath");async function Oue(e=!1,t=void 0){let r=Dh.get(Xt.ROOTPATH);bl.ensureDirSync(yl.join(r,"clustering","leaf")),Dh.initSync();let n=Nn.getConfigFromFile(Xt.CLUSTERING_TLS_CERT_AUTH),s=Nn.getConfigFromFile(Xt.CLUSTERING_TLS_PRIVATEKEY),i=Nn.getConfigFromFile(Xt.CLUSTERING_TLS_CERTIFICATE);!await bl.exists(i)&&!await bl.exists(!n)&&await Rue.createNatsCerts();let o=yl.join(r,_d,Ph.PID_FILES.HUB),c=yl.join(r,_d,Ph.PID_FILES.LEAF),l=Nn.getConfigFromFile(Xt.CLUSTERING_LEAFSERVER_STREAMS_PATH),u=yl.join(r,_d,Ph.NATS_CONFIG_FILES.HUB_SERVER),f=yl.join(r,_d,Ph.NATS_CONFIG_FILES.LEAF_SERVER),d=Nn.getConfigFromFile(Xt.CLUSTERING_TLS_INSECURE),_=Nn.getConfigFromFile(Xt.CLUSTERING_TLS_VERIFY),h=Nn.getConfigFromFile(Xt.CLUSTERING_NODENAME),m=Nn.getConfigFromFile(Xt.CLUSTERING_HUBSERVER_LEAFNODES_NETWORK_PORT);await pw.checkNATSServerInstalled()||pS("nats-server dependency is either missing or the wrong version. Run 'npm install' to fix");let S=await mw.listUsers(),g=Nn.getConfigFromFile(Xt.CLUSTERING_USER),R=await mw.getClusterUser();(hd.isEmpty(R)||R.active!==!0)&&pS(`Invalid cluster user '${g}'. A valid user with the role 'cluster_user' must be defined under clustering.user in harperdb-config.yaml`),e||(await hS(Xt.CLUSTERING_HUBSERVER_CLUSTER_NETWORK_PORT),await hS(Xt.CLUSTERING_HUBSERVER_LEAFNODES_NETWORK_PORT),await hS(Xt.CLUSTERING_HUBSERVER_NETWORK_PORT),await hS(Xt.CLUSTERING_LEAFSERVER_NETWORK_PORT));let E=[],T=[];for(let[se,z]of S.entries())z.role?.role===mS.ROLE_TYPES_ENUM.CLUSTER_USER&&z.active&&(E.push(new Aue(z.username,S$.decrypt(z.hash))),T.push(new Tue(z.username,S$.decrypt(z.hash))));let N=[],{hub_routes:v}=Nn.getClusteringRoutes();if(!hd.isEmptyOrZeroLength(v))for(let se of v)N.push(`tls://${R.sys_name_encoded}:${R.uri_encoded_d_hash}@${se.host}:${se.port}`);let H=new gue(Nn.getConfigFromFile(Xt.CLUSTERING_HUBSERVER_NETWORK_PORT),h,o,i,s,n,d,_,m,Nn.getConfigFromFile(Xt.CLUSTERING_HUBSERVER_CLUSTER_NAME),Nn.getConfigFromFile(Xt.CLUSTERING_HUBSERVER_CLUSTER_NETWORK_PORT),N,E,T);n==null&&(delete H.tls.ca_file,delete H.leafnodes.tls.ca_file),t=hd.isEmpty(t)?void 0:t.toLowerCase(),(t===void 0||t===mS.PROCESS_DESCRIPTORS.CLUSTERING_HUB.toLowerCase())&&(await bl.writeJson(u,H),md.trace(`Hub server config written to ${u}`));let X=`tls://${R.sys_name_encoded}:${R.uri_encoded_d_hash}@0.0.0.0:${m}`,W=`tls://${R.uri_encoded_name}:${R.uri_encoded_d_hash}@0.0.0.0:${m}`,$=new Sue(Nn.getConfigFromFile(Xt.CLUSTERING_LEAFSERVER_NETWORK_PORT),h,c,l,[X],[W],E,T,i,s,n,d);n==null&&delete $.tls.ca_file,(t===void 0||t===mS.PROCESS_DESCRIPTORS.CLUSTERING_LEAF.toLowerCase())&&(await bl.writeJson(f,$),md.trace(`Leaf server config written to ${f}`))}a(Oue,"generateNatsConfig");async function hS(e){let t=Dh.get(e);return hd.isEmpty(t)&&pS(`port undefined for '${e}'`),await hd.isPortTaken(t)&&pS(`'${e}' port '${t}' is is in use by another process, check to see if HarperDB is already running or another process is using this port.`),!0}a(hS,"isPortAvailable");function pS(e){let t=`Error generating clustering config: ${e}`;md.error(t),console.error(t),process.exit(1)}a(pS,"generateNatsConfigError");async function Nue(e){let{port:t,config_file:r}=pw.getServerConfig(e),{username:n,decrypt_hash:s}=await mw.getClusterUser(),i=0,o=2e3;for(;i<T$;){try{let f=await pw.createConnection(t,n,s,!1);if(f.protocol.connected===!0){f.close();break}}catch(f){md.trace(`removeNatsConfig waiting for ${e}. Caught and swallowed error ${f}`)}if(i++,i>=T$)throw new Error(`Operations API timed out attempting to connect to ${e}. This is commonly caused by incorrect clustering config. Check hdb.log for further details.`);let u=o*(i*2);u>3e4&&md.notify("Operations API waiting for Nats server connection. This could be caused by large Nats streams or incorrect clustering config."),await hd.async_set_timeout(u)}let c="0".repeat(yue),l=yl.join(Dh.get(Xt.ROOTPATH),_d,r);await bl.writeFile(l,c),await bl.remove(l),md.notify(e,"started.")}a(Nue,"removeNatsConfig")});var w$=C((NDe,N$)=>{"use strict";var rs=le(),wue=fd(),Ve=(k(),P(q)),Lh=Pt(),Co=require("path"),{PACKAGE_ROOT:SS}=Et(),R$=le(),gS=ie(),pd="/dev/null",Iue=Co.join(SS,"launchServiceScripts"),y$=Co.join(SS,"utility/scripts"),Cue=Co.join(y$,Ve.HDB_RESTART_SCRIPT),b$=Co.resolve(SS,"dependencies",`${process.platform}-${process.arch}`,Lh.NATS_BINARY_NAME);function O$(){let t=wue.licenseSearch().ram_allocation||Ve.RAM_ALLOCATION_ENUM.DEFAULT,r=Ve.MEM_SETTING_KEY+t,n={[Ve.PROCESS_NAME_ENV_PROP]:Ve.PROCESS_DESCRIPTORS.HDB,IS_SCRIPTED_SERVICE:!0};return gS.noBootFile()&&(n[Ve.CONFIG_PARAMS.ROOTPATH.toUpperCase()]=gS.getEnvCliRootPath()),{name:Ve.PROCESS_DESCRIPTORS.HDB,script:Ve.LAUNCH_SERVICE_SCRIPTS.MAIN,exec_mode:"fork",env:n,node_args:r,cwd:SS}}a(O$,"generateMainServerConfig");var Pue=9930;function Due(){rs.initSync(!0);let e=rs.get(Ve.CONFIG_PARAMS.ROOTPATH),t=Co.join(e,"clustering",Lh.NATS_CONFIG_FILES.HUB_SERVER),r=Co.join(rs.get(Ve.HDB_SETTINGS_NAMES.LOG_PATH_KEY),Ve.LOG_NAMES.HDB),n=R$.get(Ve.CONFIG_PARAMS.CLUSTERING_HUBSERVER_NETWORK_PORT),s=Lh.LOG_LEVEL_FLAGS[rs.get(Ve.CONFIG_PARAMS.CLUSTERING_LOGLEVEL)]??void 0,i={name:Ve.PROCESS_DESCRIPTORS.CLUSTERING_HUB+(n!==Pue?"-"+n:""),script:b$,args:s?`${s} -c ${t}`:`-c ${t}`,exec_mode:"fork",env:{[Ve.PROCESS_NAME_ENV_PROP]:Ve.PROCESS_DESCRIPTORS.CLUSTERING_HUB},merge_logs:!0,out_file:r,error_file:r,instances:1};return rs.get(Ve.HDB_SETTINGS_NAMES.LOG_TO_FILE)||(i.out_file=pd,i.error_file=pd),i}a(Due,"generateNatsHubServerConfig");var Lue=9940;function Mue(){rs.initSync(!0);let e=rs.get(Ve.CONFIG_PARAMS.ROOTPATH),t=Co.join(e,"clustering",Lh.NATS_CONFIG_FILES.LEAF_SERVER),r=Co.join(rs.get(Ve.HDB_SETTINGS_NAMES.LOG_PATH_KEY),Ve.LOG_NAMES.HDB),n=R$.get(Ve.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_NETWORK_PORT),s=Lh.LOG_LEVEL_FLAGS[rs.get(Ve.CONFIG_PARAMS.CLUSTERING_LOGLEVEL)]??void 0,i={name:Ve.PROCESS_DESCRIPTORS.CLUSTERING_LEAF+(n!==Lue?"-"+n:""),script:b$,args:s?`${s} -c ${t}`:`-c ${t}`,exec_mode:"fork",env:{[Ve.PROCESS_NAME_ENV_PROP]:Ve.PROCESS_DESCRIPTORS.CLUSTERING_LEAF},merge_logs:!0,out_file:r,error_file:r,instances:1};return rs.get(Ve.HDB_SETTINGS_NAMES.LOG_TO_FILE)||(i.out_file=pd,i.error_file=pd),i}a(Mue,"generateNatsLeafServerConfig");function vue(){rs.initSync();let e=Co.join(rs.get(Ve.CONFIG_PARAMS.LOGGING_ROOT),Ve.LOG_NAMES.HDB),t={name:Ve.PROCESS_DESCRIPTORS.CLUSTERING_UPGRADE_4_0_0,script:Ve.LAUNCH_SERVICE_SCRIPTS.NODES_UPGRADE_4_0_0,exec_mode:"fork",env:{[Ve.PROCESS_NAME_ENV_PROP]:Ve.PROCESS_DESCRIPTORS.CLUSTERING_UPGRADE_4_0_0},merge_logs:!0,out_file:e,error_file:e,instances:1,cwd:Iue,autorestart:!1};return rs.get(Ve.HDB_SETTINGS_NAMES.LOG_TO_FILE)||(t.out_file=pd,t.error_file=pd),t}a(vue,"generateClusteringUpgradeV4ServiceConfig");function Uue(){let e={[Ve.PROCESS_NAME_ENV_PROP]:Ve.PROCESS_DESCRIPTORS.RESTART_HDB};return gS.noBootFile()&&(e[Ve.CONFIG_PARAMS.ROOTPATH.toUpperCase()]=gS.getEnvCliRootPath()),{...{name:Ve.PROCESS_DESCRIPTORS.RESTART_HDB,exec_mode:"fork",env:e,instances:1,autorestart:!1,cwd:y$},script:Cue}}a(Uue,"generateRestart");function xue(){return{apps:[O$()]}}a(xue,"generateAllServiceConfigs");N$.exports={generateAllServiceConfigs:xue,generateMainServerConfig:O$,generateRestart:Uue,generateNatsHubServerConfig:Due,generateNatsLeafServerConfig:Mue,generateClusteringUpgradeV4ServiceConfig:vue}});var vh=C((CDe,G$)=>{"use strict";var tt=(k(),P(q)),Bue=ie(),Do=ES(),TS=Sr(),Po=Pt(),Ha=w$(),AS=le(),Ol=ee(),Hue=No(),{startWorker:I$,onMessageFromWorkers:kue}=it(),Fue=od(),IDe=require("util"),Gue=require("child_process"),que=require("fs"),{execFile:$ue}=Gue,je;G$.exports={enterPM2Mode:Vue,start:ka,stop:Ew,reload:P$,restart:D$,list:gw,describe:v$,connect:Lo,kill:Que,startAllServices:jue,startService:Sw,getUniqueServicesList:U$,restartAllServices:Jue,isServiceRegistered:x$,reloadStopStart:B$,restartHdb:M$,deleteProcess:Wue,startClusteringProcesses:k$,startClusteringThreads:F$,isHdbRestartRunning:zue,isClusteringRunning:Zue,stopClustering:Xue,reloadClustering:ede,expectedRestartOfChildren:L$};var Mh=!1;kue(e=>{e.type==="restart"&&AS.initSync(!0)});function Vue(){Mh=!0}a(Vue,"enterPM2Mode");function Lo(){return je||(je=require("pm2")),new Promise((e,t)=>{je.connect((r,n)=>{r&&t(r),e(n)})})}a(Lo,"connect");var en,Kue=10,C$;function ka(e,t=!1){if(Mh)return Yue(e);let r=$ue(e.script,e.args.split(" "),e);r.name=e.name,r.config=e,r.on("exit",async i=>{let o=en.indexOf(r);o>-1&&en.splice(o,1),!C$&&i!==0&&(e.restarts=(e.restarts||0)+1,e.restarts<Kue&&(que.existsSync(Do.getHubConfigPath())?ka(e):(await Do.generateNatsConfig(!0),ka(e),await new Promise(c=>setTimeout(c,3e3)),await Do.removeNatsConfig(tt.PROCESS_DESCRIPTORS.CLUSTERING_HUB),await Do.removeNatsConfig(tt.PROCESS_DESCRIPTORS.CLUSTERING_LEAF))))});let n={serviceName:e.name.replace(/ /g,"-")};function s(i){let o=AS.get(tt.CONFIG_PARAMS.CLUSTERING_LOGLEVEL),c=/\[\d+][^\[]+\[(\w+)]/g,l,u=0,f;for(;l=c.exec(i);){if(l.index&&Po.LOG_LEVEL_HIERARCHY[o]>=Po.LOG_LEVEL_HIERARCHY[f||"info"]){let h=f===Po.LOG_LEVELS.ERR||f===Po.LOG_LEVELS.WRN?Ol.OUTPUTS.STDERR:Ol.OUTPUTS.STDOUT;Ol.logCustomLevel(f||"info",h,n,i.slice(u,l.index).trim())}let[d,_]=l;u=l.index+d.length,f=Po.LOG_LEVELS[_]}if(Po.LOG_LEVEL_HIERARCHY[o]>=Po.LOG_LEVEL_HIERARCHY[f||"info"]){let d=f===Po.LOG_LEVELS.ERR||f===Po.LOG_LEVELS.WRN?Ol.OUTPUTS.STDERR:Ol.OUTPUTS.STDOUT;Ol.logCustomLevel(f||"info",d,n,i.slice(u).trim())}}if(a(s,"extractMessages"),r.stdout.on("data",s),r.stderr.on("data",s),r.unref(),!en&&(en=[],!t)){let i=a(()=>{C$=!0,en&&(en.map(o=>o.kill()),process.exit(0))},"kill_children");process.on("exit",i),process.on("SIGINT",i),process.on("SIGQUIT",i),process.on("SIGTERM",i)}en.push(r)}a(ka,"start");function Yue(e){return new Promise(async(t,r)=>{try{await Lo()}catch(n){r(n)}je.start(e,(n,s)=>{n&&(je.disconnect(),r(n)),je.disconnect(),t(s)})})}a(Yue,"startWithPM2");function Ew(e){if(!Mh){for(let t of en||[])t.name===e&&(en.splice(en.indexOf(t),1),t.kill());return}return new Promise(async(t,r)=>{try{await Lo()}catch(n){r(n)}je.stop(e,async(n,s)=>{n&&(je.disconnect(),r(n)),je.delete(e,(i,o)=>{i&&(je.disconnect(),r(n)),je.disconnect(),t(o)})})})}a(Ew,"stop");function P$(e){return new Promise(async(t,r)=>{try{await Lo()}catch(n){r(n)}je.reload(e,(n,s)=>{n&&(je.disconnect(),r(n)),je.disconnect(),t(s)})})}a(P$,"reload");function D$(e){if(!Mh){L$();for(let t of en||[])t.name===e&&t.kill()}return new Promise(async(t,r)=>{try{await Lo()}catch(n){r(n)}je.restart(e,(n,s)=>{je.disconnect(),t(s)})})}a(D$,"restart");function L$(){for(let e of en||[])e.config&&(e.config.restarts=0)}a(L$,"expectedRestartOfChildren");function Wue(e){return new Promise(async(t,r)=>{try{await Lo()}catch(n){r(n)}je.delete(e,(n,s)=>{n&&(je.disconnect(),r(n)),je.disconnect(),t(s)})})}a(Wue,"deleteProcess");async function M$(){await ka(Ha.generateRestart())}a(M$,"restartHdb");async function zue(){let e=await gw();for(let t in e)if(e[t].name===tt.PROCESS_DESCRIPTORS.RESTART_HDB)return!0;return!1}a(zue,"isHdbRestartRunning");function gw(){return new Promise(async(e,t)=>{try{await Lo()}catch(r){t(r)}je.list((r,n)=>{r&&(je.disconnect(),t(r)),je.disconnect(),e(n)})})}a(gw,"list");function v$(e){return new Promise(async(t,r)=>{try{await Lo()}catch(n){r(n)}je.describe(e,(n,s)=>{n&&(je.disconnect(),r(n)),je.disconnect(),t(s)})})}a(v$,"describe");function Que(){if(!Mh){for(let e of en||[])e.kill();en=[];return}return new Promise(async(e,t)=>{try{await Lo()}catch(r){t(r)}je.killDaemon((r,n)=>{r&&(je.disconnect(),t(r)),je.disconnect(),e(n)})})}a(Que,"kill");async function jue(){try{await k$(),await F$(),await ka(Ha.generateAllServiceConfigs())}catch(e){throw je?.disconnect(),e}}a(jue,"startAllServices");async function Sw(e,t=!1){try{let r;switch(e=e.toLowerCase(),e){case tt.PROCESS_DESCRIPTORS.HDB.toLowerCase():r=Ha.generateMainServerConfig();break;case tt.PROCESS_DESCRIPTORS.CLUSTERING_INGEST_SERVICE.toLowerCase():r=Ha.generateNatsIngestServiceConfig();break;case tt.PROCESS_DESCRIPTORS.CLUSTERING_REPLY_SERVICE.toLowerCase():r=Ha.generateNatsReplyServiceConfig();break;case tt.PROCESS_DESCRIPTORS.CLUSTERING_HUB.toLowerCase():r=Ha.generateNatsHubServerConfig(),await ka(r,t),await Do.removeNatsConfig(e);return;case tt.PROCESS_DESCRIPTORS.CLUSTERING_LEAF.toLowerCase():r=Ha.generateNatsLeafServerConfig(),await ka(r,t),await Do.removeNatsConfig(e);return;case tt.PROCESS_DESCRIPTORS.CLUSTERING_UPGRADE_4_0_0.toLowerCase():r=Ha.generateClusteringUpgradeV4ServiceConfig();break;default:throw new Error(`Start service called with unknown service config: ${e}`)}await ka(r)}catch(r){throw je?.disconnect(),r}}a(Sw,"startService");async function U$(){try{let e=await gw(),t={};for(let r=0,n=e.length;r<n;r++){let s=e[r];t[s.name]===void 0&&(t[s.name]={name:s.name,exec_mode:s.pm2_env.exec_mode})}return t}catch(e){throw je?.disconnect(),e}}a(U$,"getUniqueServicesList");async function Jue(e=[]){try{let t=!1,r=await U$();for(let n=0,s=Object.values(r).length;n<s;n++){let o=Object.values(r)[n].name;e.includes(o)||(o===tt.PROCESS_DESCRIPTORS.HDB?t=!0:await D$(o))}t&&await B$(tt.PROCESS_DESCRIPTORS.HDB)}catch(t){throw je?.disconnect(),t}}a(Jue,"restartAllServices");async function x$(e){if(en?.find(r=>r.name===e))return!0;let t=await Fue.getHDBProcessInfo();return t.core.length&&t.core[0]?.parent==="PM2"}a(x$,"isServiceRegistered");async function B$(e){let t=AS.get(tt.CONFIG_PARAMS.THREADS_COUNT)??AS.get(tt.CONFIG_PARAMS.THREADS),r=await v$(e),n=Bue.isEmptyOrZeroLength(r)?0:r.length;t!==n?(await Ew(e),await Sw(e)):e===tt.PROCESS_DESCRIPTORS.HDB?await M$():await P$(e)}a(B$,"reloadStopStart");var H$;async function k$(e=!1){for(let t in tt.CLUSTERING_PROCESSES){let r=tt.CLUSTERING_PROCESSES[t];await Sw(r,e)}}a(k$,"startClusteringProcesses");async function F$(){H$=I$(tt.LAUNCH_SERVICE_SCRIPTS.NATS_REPLY_SERVICE,{name:tt.PROCESS_DESCRIPTORS.CLUSTERING_REPLY_SERVICE});try{await TS.deleteLocalStream("__HARPERDB_WORK_QUEUE__")}catch{}await TS.updateLocalStreams();let e=await Hue.getAllNodeRecords();for(let t=0,r=e.length;t<r;t++)if(e[t].system_info?.hdb_version===tt.PRE_4_0_0_VERSION){Ol.info("Starting clustering upgrade 4.0.0 process"),I$(tt.LAUNCH_SERVICE_SCRIPTS.NODES_UPGRADE_4_0_0,{name:"Upgrade-4-0-0"});break}}a(F$,"startClusteringThreads");async function Xue(){for(let e in tt.CLUSTERING_PROCESSES)if(e!==tt.CLUSTERING_PROCESSES.CLUSTERING_INGEST_PROC_DESCRIPTOR)if(e===tt.CLUSTERING_PROCESSES.CLUSTERING_REPLY_SERVICE_DESCRIPTOR)await H$.terminate();else{let t=tt.CLUSTERING_PROCESSES[e];await Ew(t)}}a(Xue,"stopClustering");async function Zue(){for(let e in tt.CLUSTERING_PROCESSES){let t=tt.CLUSTERING_PROCESSES[e];if(await x$(t)===!1)return!1}return!0}a(Zue,"isClusteringRunning");async function ede(){await Do.generateNatsConfig(!0),await TS.reloadNATSHub(),await TS.reloadNATSLeaf(),await Do.removeNatsConfig(tt.PROCESS_DESCRIPTORS.CLUSTERING_HUB.toLowerCase()),await Do.removeNatsConfig(tt.PROCESS_DESCRIPTORS.CLUSTERING_LEAF.toLowerCase())}a(ede,"reloadClustering")});var Rw={};Ue(Rw,{compactOnStart:()=>tde,copyDb:()=>W$});async function tde(){Fa.notify("Running compact on start"),console.log("Running compact on start");let e=(0,Tw.get)(x.ROOTPATH),t=new Map,r=Je();(0,Aw.updateConfigValue)(x.STORAGE_COMPACTONSTART,!1);try{for(let n in r){if(n==="system"||n.endsWith("-copy"))continue;let s;for(let l in r[n]){s=r[n][l].primaryStore.path;break}if(!s){console.log("Couldn't find any tables in database",n);continue}let i=(0,RS.join)(e,"backup",n+".mdb"),o=(0,RS.join)(e,fc,n+"-copy.mdb"),c=0;try{c=await q$(n),console.log("Database",n,"before compact has a total record count of",c)}catch(l){Fa.error("Error getting record count for database",n,l),console.error("Error getting record count for database",n,l)}t.set(n,{db_path:s,copy_dest:o,backup_dest:i,record_count:c}),await W$(n,o),console.log("Backing up",n,"to",i),await(0,Nl.move)(s,i,{overwrite:!0}),console.log("Moving copy compacted",n,"to",s),await(0,Nl.move)(o,s,{overwrite:!0}),await(0,Nl.remove)((0,RS.join)(e,fc,`${n}-copy.mdb-lock`))}try{Du()}catch(n){Fa.error("Error resetting databases after backup",n),console.error("Error resetting databases after backup",n)}try{Du()}catch(n){Fa.error("Error resetting databases after backup",n),console.error("Error resetting databases after backup",n),process.exit(0)}}catch(n){Fa.error("Error compacting database, rolling back operation",n),console.error("Error compacting database, rolling back operation",n),(0,Aw.updateConfigValue)(x.STORAGE_COMPACTONSTART,!1);for(let[s,{db_path:i,backup_dest:o}]of t){console.error("Moving backup database",o,"back to",i);try{await(0,Nl.move)(o,i,{overwrite:!0})}catch(c){console.error(c)}}throw Du(),n}for(let[n,{backup_dest:s,record_count:i}]of t){let o=await q$(n);if(console.log("Database",n,"after compact has a total record count of",o),i!==o){let c=`There is a discrepancy between pre and post compact record count for database ${n}.
25
+ Total record count before compaction: ${i}, total after: ${o}.
26
+ Database backup has not been removed and can be found here: ${s}`;Fa.error(c),console.error(c)}(0,Tw.get)(x.STORAGE_COMPACTONSTARTKEEPBACKUP)!==!0&&(console.log("Removing backup",s),await(0,Nl.remove)(s))}}async function q$(e){let t=await(0,Y$.describeSchema)({database:e}),r=0;for(let n in t)r+=t[n].record_count;return r}function Ed(){}async function W$(e,t){console.log(`Copying database ${e} to ${t}`);let r=Je()[e];if(!r)throw new Error(`Source database not found: ${e}`);let n;for(let d in r){let _=r[d];_.primaryStore.put=Ed,_.primaryStore.remove=Ed;for(let h in _.indices){let m=_.indices[h];m.put=Ed,m.remove=Ed}_.auditStore&&(_.auditStore.put=Ed,_.auditStore.remove=Ed),n=_.primaryStore.rootStore}if(!n)throw new Error(`Source database does not have any tables: ${e}`);let s=n.dbisDb,i=n.auditStore,o=(0,$$.open)(new V$.default(t)),c=o.openDB(yS.INTERNAL_DBIS_NAME),l,u=0,f=s.useReadTransaction();try{for(let{key:_,value:h}of s.getRange({transaction:f})){let m=h.is_hash_attribute||h.isPrimaryKey,S,g;if(m&&(S=h.compression,g=GE(),g?h.compression=g:delete h.compression,S?.dictionary?.toString()===g?.dictionary?.toString()&&(S=null,g=null)),c.put(_,h),!(m||h.indexed))continue;let R=new K$.default(!m,m);R.encoding="binary",R.compression=S;let E=n.openDB(_,R);E.decoder=null,E.decoderCopies=!1,E.encoding="binary",R.compression=g;let T=o.openDB(_,R);T.encoder=null,console.log("copying",_,"from",e,"to",t),await d(E,T,m,f)}if(i){let _=n.openDB(yS.AUDIT_STORE_NAME,Vf);console.log("copying audit log for",e,"to",t),d(i,_,!1,f)}async function d(_,h,m,S){let g=0,R=0,E=0,T=1e7,N=null;for(;T-- >0;)try{for(let v of _.getKeys({start:N,transaction:S}))try{N=v;let{value:H,version:X}=_.getEntry(v,{transaction:S});if(H?.length<14&&m){E++;continue}l=h.put(v,H,m?X:void 0),g++,S.openTimer&&(S.openTimer=0),R+=(v?.length||10)+H.length,u++>5e3&&(await l,console.log("copied",g,"entries, skipped",E,"delete records,",R,"bytes"),u=0)}catch(H){console.error("Error copying record",typeof v=="symbol"?"symbol":v,"from",e,"to",t,H)}console.log("finish copying, copied",g,"entries, skipped",E,"delete records,",R,"bytes");return}catch{if(typeof N=="string"){if(N==="z")return console.error("Reached end of dbi",N,"for",e,"to",t);N=N.slice(0,-2)+"z"}else if(typeof N=="number")N++;else return console.error("Unknown key type",N,"for",e,"to",t)}}a(d,"copyDbi"),await l,console.log("copied database "+e+" to "+t)}finally{f.done(),o.close()}}var $$,RS,Nl,Tw,V$,K$,yS,Y$,Aw,Fa,yw=Re(()=>{xe();$$=require("lmdb"),RS=require("path"),Nl=require("fs-extra"),Tw=M(le()),V$=M(Yf()),K$=M(Kf()),yS=M(Gt());k();Ai();Y$=M(po()),Aw=M(Lt()),Fa=M(ee());a(tde,"compactOnStart");a(q$,"getTotalDBRecordCount");a(Ed,"noop");a(W$,"copyDb")});var Sd=C((HDe,eV)=>{"use strict";var rde=require("minimist"),{isMainThread:Ow,parentPort:xh,threadId:UDe}=require("worker_threads"),at=(k(),P(q)),ki=ee(),Nw=ie(),OS=ES(),bS=Sr(),xDe=Pt(),J$=Lt(),ri=vh(),z$=od(),{compactOnStart:nde}=(yw(),P(Rw)),sde=_c(),{restartWorkers:NS,onMessageByType:ide}=it(),{handleHDBError:ode,hdb_errors:ade}=he(),{HTTP_STATUS_CODES:cde}=ade,Bh=le(),{sendOperationToNode:Q$,getThisNodeName:lde,monitorNodeCAs:ude}=(gs(),P(Ca)),{getHDBNodeTable:BDe}=(ul(),P(BO));Bh.initSync();var Uh=`Restarting HarperDB. This may take up to ${at.RESTART_TIMEOUT_MS/1e3} seconds.`,dde="Restart is not available from the CLI when running in non-pm2 mode. Either call restart from the API or stop and start HarperDB.",j$="Clustering is not enabled so cannot be restarted",fde="Invalid service",gd,ys;eV.exports={restart:X$,restartService:ww};Ow&&ide(at.ITC_EVENT_TYPES.RESTART,async(e,t)=>{e.workerType?await ww({service:e.workerType}):X$({operation:"restart"}),t.postMessage({type:"restart-complete"})});async function X$(e){ys=Object.keys(e).length===0,gd=await ri.isServiceRegistered(at.PROCESS_DESCRIPTORS.HDB);let t=rde(process.argv);if(t.service){await ww(t);return}if(ys&&!gd){console.error(dde);return}if(ys&&console.log(Uh),gd){ri.enterPM2Mode(),ki.notify(Uh);let r=sde(Object.keys(at.CONFIG_PARAM_MAP),!0);return Nw.isEmptyOrZeroLength(Object.keys(r))||J$.updateConfigValue(void 0,void 0,r,!0,!0),_de(),Uh}return Ow?(ki.notify(Uh),Bh.get(at.CONFIG_PARAMS.STORAGE_COMPACTONSTART)&&await nde(),process.env.HARPER_EXIT_ON_RESTART&&process.exit(0),setTimeout(()=>{NS()},50)):xh.postMessage({type:at.ITC_EVENT_TYPES.RESTART}),Uh}a(X$,"restart");async function ww(e){let{service:t}=e;if(at.HDB_PROCESS_SERVICES[t]===void 0)throw ode(new Error,fde,cde.BAD_REQUEST,void 0,void 0,!0);if(ri.expectedRestartOfChildren(),gd=await ri.isServiceRegistered(at.PROCESS_DESCRIPTORS.HDB),!Ow){e.replicated&&ude(),xh.postMessage({type:at.ITC_EVENT_TYPES.RESTART,workerType:t}),xh.ref(),await new Promise(s=>{xh.on("message",i=>{i.type==="restart-complete"&&(s(),xh.unref())})});let n;if(e.replicated){e.replicated=!1,n=[];for(let s of server.nodes){if(s.name===lde())continue;let i;try{({job_id:i}=await Q$(s,e))}catch(o){n.push({node:s.name,message:o.message});continue}n.push(await new Promise((o,c)=>{let u=2400,f=setInterval(async()=>{if(u--<=0){clearInterval(f);let h=new Error("Timed out waiting for restart job to complete");h.replicated=n,c(h)}let _=(await Q$(s,{operation:"get_job",id:i})).results[0];if(_.status==="COMPLETE"&&(clearInterval(f),o({node:s.name,message:_.message})),_.status==="ERROR"){clearInterval(f);let h=new Error(_.message);h.replicated=n,c(h)}},250)}))}return{replicated:n}}return}let r;switch(t){case at.HDB_PROCESS_SERVICES.clustering:if(!Bh.get(at.CONFIG_PARAMS.CLUSTERING_ENABLED)){r=j$;break}ys&&console.log("Restarting clustering"),ki.notify("Restarting clustering"),await Z$();break;case at.HDB_PROCESS_SERVICES.clustering_config:case at.HDB_PROCESS_SERVICES["clustering config"]:if(!Bh.get(at.CONFIG_PARAMS.CLUSTERING_ENABLED)){r=j$;break}ys&&console.log("Restarting clustering_config"),ki.notify("Restarting clustering_config"),await ri.reloadClustering();break;case"custom_functions":case"custom functions":case at.HDB_PROCESS_SERVICES.harperdb:case at.HDB_PROCESS_SERVICES.http_workers:case at.HDB_PROCESS_SERVICES.http:if(ys&&!gd){r=`Restart ${t} is not available from the CLI when running in non-pm2 mode. Either call restart ${t} from the API or stop and start HarperDB.`;break}ys&&console.log("Restarting http_workers"),ki.notify("Restarting http_workers"),ys?await ri.restart(at.PROCESS_DESCRIPTORS.HDB):await NS("http");break;default:r=`Unrecognized service: ${t}`;break}return r?(ki.error(r),ys&&console.error(r),r):(t==="custom_functions"&&(t="Custom Functions"),`Restarting ${t}`)}a(ww,"restartService");async function _de(){await Z$(),await ri.restart(at.PROCESS_DESCRIPTORS.HDB),await Nw.async_set_timeout(2e3),Bh.get(at.CONFIG_PARAMS.CLUSTERING_ENABLED)&&await bw(),ys&&(await bS.closeConnection(),process.exit(0))}a(_de,"restartPM2Mode");async function Z$(){if(!J$.getConfigFromFile(at.CONFIG_PARAMS.CLUSTERING_ENABLED))return;if((await z$.getHDBProcessInfo()).clustering.length===0)ki.trace("Clustering not running, restart will start clustering services"),await OS.generateNatsConfig(!0),await ri.startClusteringProcesses(),await ri.startClusteringThreads(),await bw(),ys&&await bS.closeConnection();else{await OS.generateNatsConfig(!0),gd?(ki.trace("Restart clustering restarting PM2 managed Hub and Leaf servers"),await ri.restart(at.PROCESS_DESCRIPTORS.CLUSTERING_HUB),await ri.restart(at.PROCESS_DESCRIPTORS.CLUSTERING_LEAF)):(await z$.getHDBProcessInfo()).clustering.forEach(s=>{ki.trace("Restart clustering killing process pid",s.pid),process.kill(s.pid)}),await Nw.async_set_timeout(3e3),await bw(),await bS.updateLocalStreams(),ys&&await bS.closeConnection(),ki.trace("Restart clustering restarting ingest and reply service threads");let t=NS(at.LAUNCH_SERVICE_SCRIPTS.NATS_INGEST_SERVICE),r=NS(at.LAUNCH_SERVICE_SCRIPTS.NATS_REPLY_SERVICE);await t,await r}}a(Z$,"restartClustering");async function bw(){await OS.removeNatsConfig(at.PROCESS_DESCRIPTORS.CLUSTERING_HUB),await OS.removeNatsConfig(at.PROCESS_DESCRIPTORS.CLUSTERING_LEAF)}a(bw,"removeNatsConfig")});var dV=C((GDe,uV)=>{"use strict";var FDe=require("lodash"),wn=(k(),P(q)),{handleHDBError:tV,hdb_errors:hde}=he(),{HDB_ERROR_MSGS:mde,HTTP_STATUS_CODES:pde}=hde,Iw=ee();uV.exports={getRolePermissions:gde};var wl=Object.create(null),Ede=a(e=>({key:e,perms:{}}),"perms_template_obj"),iV=a((e=!1)=>({describe:e,tables:{}}),"schema_perms_template"),oV=a((e=!1,t=!1,r=!1,n=!1)=>({[wn.PERMS_CRUD_ENUM.READ]:e,[wn.PERMS_CRUD_ENUM.INSERT]:t,[wn.PERMS_CRUD_ENUM.UPDATE]:r,[wn.PERMS_CRUD_ENUM.DELETE]:n}),"permissions_template"),Cw=a((e=!1,t=!1,r=!1,n=!1,s=!1)=>({attribute_permissions:[],describe:e,...oV(t,r,n,s)}),"table_perms_template"),rV=a((e,t=oV())=>({attribute_name:e,describe:lV(t),[Hh]:t[Hh],[Pw]:t[Pw],[Dw]:t[Dw]}),"attr_perms_template"),nV=a((e,t=!1)=>({attribute_name:e,describe:t,[Hh]:t}),"timestamp_attr_perms_template"),{READ:Hh,INSERT:Pw,UPDATE:Dw}=wn.PERMS_CRUD_ENUM,aV=Object.values(wn.PERMS_CRUD_ENUM),cV=[Hh,Pw,Dw];function gde(e){let t;try{if(e.permission.super_user||e.permission.cluster_user)return e.permission;let r={...global.hdb_schema};delete r[wn.SYSTEM_SCHEMA_NAME],t=e.role;let n=JSON.stringify([e.__updatedtime__,r]);if(wl[t]&&wl[t].key===n)return wl[t].perms;let s=Sde(e,r);return wl[t]?wl[t].key=n:wl[t]=Ede(n),wl[t].perms=s,s}catch(r){if(!e[wn.TIME_STAMP_NAMES_ENUM.UPDATED_TIME]||e[wn.TIME_STAMP_NAMES_ENUM.UPDATED_TIME]<wn.PERMS_UPDATE_RELEASE_TIMESTAMP){let n=`Role permissions for role '${t}' must be updated to align with new structure from the 2.2.0 release.`;throw Iw.error(n),Iw.debug(r),tV(new Error,mde.OUTDATED_PERMS_TRANSLATION_ERROR,pde.BAD_REQUEST)}else{let n=`There was an error while translating role permissions for role: ${t}.
27
27
  ${r.stack}`;throw Iw.error(n),tV(new Error)}}}a(gde,"getRolePermissions");function Sde(e,t){let r=Object.create(null);r.super_user=!1;let n=e.permission;r[wn.SYSTEM_SCHEMA_NAME]=n[wn.SYSTEM_SCHEMA_NAME],r.structure_user=n.structure_user;let s=Array.isArray(e.permission.structure_user)||e.permission.structure_user===!0?e.permission.structure_user:[];return Object.keys(t).forEach(i=>{if(s===!0||s.indexOf(i)>-1){r[i]=Tde(t[i]);return}r[i]=iV(),n[i]?(n[i].describe&&(r[i].describe=!0),Object.keys(t[i]).forEach(o=>{if(n[i].tables[o]){let c=n[i].tables[o],l=t[i][o],u=Ade(c,l);r[i].describe||aV.forEach(f=>{u[f]&&(r[i].describe=!0)}),r[i].tables[o]=u}else r[i].tables[o]=Cw()})):Object.keys(t[i]).forEach(o=>{r[i].tables[o]=Cw()})}),r}a(Sde,"translateRolePermissions");function Tde(e){let t=iV(!0);return Object.keys(e).forEach(r=>{t.tables[r]=Cw(!0,!0,!0,!0,!0)}),t}a(Tde,"createStructureUserPermissions");function Ade(e,t){let{attribute_permissions:r}=e;if(r?.length>0){let s={...e};s.attribute_permissions=[];let i=r.reduce((u,f)=>{let{attribute_name:d}=f,_=f;return wn.TIME_STAMP_NAMES.includes(d)&&(_=nV(d,f[Hh])),u[d]=_,u},{}),o=t.primaryKey||t.hash_attribute,c=!!i[o],l=rV(o);return t.attributes.forEach(({attribute:u})=>{if(i[u]){let f=i[u];f.describe=lV(f),s.attribute_permissions.push(f),c||Rde(f,l)}else if(u!==o){let f;wn.TIME_STAMP_NAMES.includes(u)?f=nV(u):f=rV(u),s.attribute_permissions.push(f)}}),c||s.attribute_permissions.push(l),s.describe=sV(s),s}else return e.describe=sV(e),e}a(Ade,"getTableAttrPerms");function sV(e){return aV.filter(t=>e[t]).length>0}a(sV,"getSchemaTableDescribePerm");function lV(e){return cV.filter(t=>e[t]).length>0}a(lV,"getAttributeDescribePerm");function Rde(e,t){cV.forEach(r=>{e[r]&&!t[r]&&(t[r]=!0,t.describe=!0)})}a(Rde,"checkForHashPerms")});var kh={};Ue(kh,{authentication:()=>gV,bypassAuth:()=>Pde,login:()=>Lde,logout:()=>Mde,start:()=>Dde});function Pde(){EV=!0}async function gV(e,t){let r=e.headers.asObject,n=r.authorization,s=r.cookie,i=r.origin,o=[];try{if(i){let h=e.isOperationsServer?Nde?Ode:[]:bde?yde:[];if(h.includes(i)||h.includes("*")){if(e.method==="OPTIONS"){let m=tn.get(x.HTTP_CORSACCESSCONTROLALLOWHEADERS)??"Accept, Content-Type, Authorization",S=new go([["Access-Control-Allow-Methods","POST, GET, PUT, DELETE, PATCH, OPTIONS"],["Access-Control-Allow-Headers",m],["Access-Control-Allow-Origin",i]]);return wS&&S.set("Access-Control-Allow-Credentials","true"),{status:200,headers:S}}o.push("Access-Control-Allow-Origin",i),wS&&o.push("Access-Control-Allow-Credentials","true")}}let l,u;if(wS){i||(i=r.host);let h=(i?i.replace(/^https?:\/\//,"").replace(/\W/,"_")+"-":"")+"hdb-session=",m=s?.split(/;\s+/)||[];for(let S of m)if(S.startsWith(h)){let g=S.indexOf(";");l=S.slice(h.length,g===-1?S.length:g),u=await fV.get(l);break}e.session=u||(u={})}let f=a((h,m,S)=>{let g=new Td.AuthAuditLog(h,m,Jo.AUTHENTICATION,r["x-forwarded-for"]??e.ip,e.method,e.pathname);g.auth_strategy=S,l&&(g.session_id=l),r.referer&&(g.referer=r.referer),r.origin&&(g.origin=r.origin),m===Bs.SUCCESS?Lw.notify(g):Lw.error(g)},"authAuditLog");if(!e.authorized&&e.mtlsConfig&&e.peerCertificate.subject&&e?._nodeRequest?.socket?.authorizationError&&Lw.error("Authorization error:",e._nodeRequest.socket.authorizationError),e.mtlsConfig&&e.authorized&&e.peerCertificate.subject){let h=e.mtlsConfig.user;h!==null?((h===void 0||h==="Common Name"||h==="CN")&&(h=e.peerCertificate.subject.CN),e.user=await Ye.getUser(h,null,e),f(h,Bs.SUCCESS,"mTLS")):(0,Td.debug)("HTTPS/WSS mTLS authorized connection (mTLS did not authorize a user)","from",e.ip)}let d;if(!e.user)if(n){if(d=Il.get(n),!d){let h=n.indexOf(" "),m=n.slice(0,h),S=n.slice(h+1),g,R;try{switch(m){case"Basic":let E=atob(S),T=E.indexOf(":");g=E.slice(0,T),R=E.slice(T+1),d=g||R?await Ye.getUser(g,R,e):null;break;case"Bearer":try{d=await hO(S)}catch(N){if(N.message==="invalid token")try{return await cg(S),c({status:-1})}catch{throw N}}break}}catch(E){return Ide&&(Il.get(S)||(Il.set(S,S),f(g,Bs.FAILURE,m))),c({status:401,body:ia({error:E.message},e)})}Il.set(n,d),wde&&f(d.username,Bs.SUCCESS,m)}e.user=d}else u?.user?e.user=await Ye.getUser(u.user,null,e):(EV&&(e.ip?.includes("127.0.0.")||e.ip=="::1")||e?._nodeRequest?.socket?.server?._pipeName&&e.ip===void 0)&&(e.user=await(0,hV.getSuperUser)());wS&&(e.session.update=function(h){let m=tn.get(x.AUTHENTICATION_COOKIE_EXPIRES);if(!l){l=(0,mV.v4)();let S=tn.get(x.AUTHENTICATION_COOKIE_DOMAINS),g=m?new Date(Date.now()+(0,Mw.convertToMS)(m)).toUTCString():Cde,R=S?.find(N=>r.host?.endsWith(N)),T=`${(i?i.replace(/^https?:\/\//,"").replace(/\W/,"_")+"-":"")+"hdb-session="}${l}; Path=/; Expires=${g}; ${R?"Domain="+R+"; ":""}HttpOnly${e.protocol==="https"?"; SameSite=None; Secure":""}`;o?o.push("Set-Cookie",T):_?.headers?.set&&_.headers.set("Set-Cookie",T)}return e.protocol==="https"&&(o?(i&&o.push("Access-Control-Expose-Headers","X-Hdb-Session"),o.push("X-Hdb-Session","Secure")):_?.headers?.set&&(i&&_.headers.set("Access-Control-Expose-Headers","X-Hdb-Session"),_.headers.set("X-Hdb-Session","Secure"))),h.id=l,fV.put(h,{expiresAt:m?Date.now()+(0,Mw.convertToMS)(m):void 0})},e.login=async function(h,m){let S=e.user=await Ye.authenticateUser(h,m,e);e.session.update({user:S&&(S.getId?.()??S.username)})});let _=await t(e);return _&&(_.status===401&&(r["user-agent"]?.startsWith("Mozilla")&&r.accept?.startsWith("text/html")&&fs.loginPath?(_.status=302,_.headers.set("Location",fs.loginPath(e))):_.headers.set("WWW-Authenticate","Basic")),c(_))}catch(l){throw c(l)}function c(l){let u=o.length;if(u>0){let f=l.headers;f||(l.headers=f=new go);for(let d=0;d<u;){let _=o[d++];f.set(_,o[d++])}}return o=null,l}a(c,"applyResponseHeaders")}function Dde({server:e,port:t,securePort:r}){e.http(gV,t||r?{port:t,securePort:r}:{port:"all"}),_V||(_V=!0,setInterval(()=>{Il=new Map},tn.get(x.AUTHENTICATION_CACHETTL)).unref(),pV.user.addListener(()=>{Il=new Map}))}async function Lde(e){if(!e.baseRequest?.login)throw new Error("No session for login");return e.baseResponse.headers.set=(t,r)=>{e.fastifyResponse.header(t,r)},await e.baseRequest.login(e.username,e.password??""),"Login successful"}async function Mde(e){if(!e.baseRequest.session)throw new Error("No session for logout");return await e.baseRequest.session.update({user:null}),"Logout successful"}var hV,mV,tn,Td,pV,Mw,Lw,yde,bde,Ode,Nde,fV,wS,EV,wde,Ide,Cde,Il,_V,IS=Re(()=>{hV=M(Wn());Lr();tu();ku();xe();mV=require("uuid"),tn=M(le());k();Td=M(ee()),pV=M(b_());L_();Mw=M(ie());so();Lw=(0,Td.loggerWithTag)("auth-event");tn.initSync();yde=tn.get(x.HTTP_CORSACCESSLIST),bde=tn.get(x.HTTP_CORS),Ode=tn.get(x.OPERATIONSAPI_NETWORK_CORSACCESSLIST),Nde=tn.get(x.OPERATIONSAPI_NETWORK_CORS),fV=_t({table:"hdb_session",database:"system",attributes:[{name:"id",isPrimaryKey:!0},{name:"user"}]}),wS=tn.get(x.AUTHENTICATION_ENABLESESSIONS)??!0,EV=process.env.AUTHENTICATION_AUTHORIZELOCAL??tn.get(x.AUTHENTICATION_AUTHORIZELOCAL)??process.env.DEV_MODE,wde=tn.get(x.LOGGING_AUDITAUTHEVENTS_LOGSUCCESSFUL)??!1,Ide=tn.get(x.LOGGING_AUDITAUTHEVENTS_LOGFAILED)??!1,Cde="Tue, 01 Oct 8307 19:33:20 GMT",Il=new Map;Ye.onInvalidatedUser(()=>{Il=new Map});a(Pde,"bypassAuth");a(gV,"authentication");a(Dde,"start");a(Lde,"login");a(Mde,"logout")});var OV=C((JDe,bV)=>{"use strict";var Ne=require("joi"),SV=require("fs-extra"),TV=require("path"),ns=ot(),AV=le(),RV=(k(),P(q)),yV=ee(),{hdb_errors:vde}=he(),{HDB_ERROR_MSGS:rn}=vde,Mo=/^[a-zA-Z0-9-_]+$/,Ude=/^[a-zA-Z0-9-_]+$/;bV.exports={getDropCustomFunctionValidator:Bde,setCustomFunctionValidator:Hde,addComponentValidator:qde,dropCustomFunctionProjectValidator:$de,packageComponentValidator:Vde,deployComponentValidator:Kde,setComponentFileValidator:kde,getComponentFileValidator:Gde,dropComponentFileValidator:Fde,addSSHKeyValidator:Yde,updateSSHKeyValidator:Wde,deleteSSHKeyValidator:zde,setSSHKnownHostsValidator:Qde};function CS(e,t,r){try{let n=AV.get(RV.CONFIG_PARAMS.COMPONENTSROOT),s=TV.join(n,t);return SV.existsSync(s)?e?t:r.message(rn.PROJECT_EXISTS):e?r.message(rn.NO_PROJECT):t}catch(n){return yV.error(n),r.message(rn.VALIDATION_ERR)}}a(CS,"checkProjectExists");function Fh(e,t){return e.includes("..")?t.message("Invalid file path"):e}a(Fh,"checkFilePath");function xde(e,t,r,n){try{let s=AV.get(RV.CONFIG_PARAMS.COMPONENTSROOT),i=TV.join(s,e,t,r+".js");return SV.existsSync(i)?r:n.message(rn.NO_FILE)}catch(s){return yV.error(s),n.message(rn.VALIDATION_ERR)}}a(xde,"checkFileExists");function Bde(e){let t=Ne.object({project:Ne.string().pattern(Mo).custom(CS.bind(null,!0)).required().messages({"string.pattern.base":rn.BAD_PROJECT_NAME}),type:Ne.string().valid("helpers","routes").required(),file:Ne.string().pattern(Mo).custom(xde.bind(null,e.project,e.type)).custom(Fh).required().messages({"string.pattern.base":rn.BAD_FILE_NAME})});return ns.validateBySchema(e,t)}a(Bde,"getDropCustomFunctionValidator");function Hde(e){let t=Ne.object({project:Ne.string().pattern(Mo).custom(CS.bind(null,!0)).required().messages({"string.pattern.base":rn.BAD_PROJECT_NAME}),type:Ne.string().valid("helpers","routes").required(),file:Ne.string().custom(Fh).required(),function_content:Ne.string().required()});return ns.validateBySchema(e,t)}a(Hde,"setCustomFunctionValidator");function kde(e){let t=Ne.object({project:Ne.string().pattern(Mo).required().messages({"string.pattern.base":rn.BAD_PROJECT_NAME}),file:Ne.string().custom(Fh).required(),payload:Ne.string().allow("").optional(),encoding:Ne.string().valid("utf8","ASCII","binary","hex","base64","utf16le","latin1","ucs2").optional()});return ns.validateBySchema(e,t)}a(kde,"setComponentFileValidator");function Fde(e){let t=Ne.object({project:Ne.string().pattern(Mo).required().messages({"string.pattern.base":rn.BAD_PROJECT_NAME}),file:Ne.string().custom(Fh).optional()});return ns.validateBySchema(e,t)}a(Fde,"dropComponentFileValidator");function Gde(e){let t=Ne.object({project:Ne.string().required(),file:Ne.string().custom(Fh).required(),encoding:Ne.string().valid("utf8","ASCII","binary","hex","base64","utf16le","latin1","ucs2").optional()});return ns.validateBySchema(e,t)}a(Gde,"getComponentFileValidator");function qde(e){let t=Ne.object({project:Ne.string().pattern(Mo).custom(CS.bind(null,!1)).required().messages({"string.pattern.base":rn.BAD_PROJECT_NAME})});return ns.validateBySchema(e,t)}a(qde,"addComponentValidator");function $de(e){let t=Ne.object({project:Ne.string().pattern(Mo).custom(CS.bind(null,!0)).required().messages({"string.pattern.base":rn.BAD_PROJECT_NAME})});return ns.validateBySchema(e,t)}a($de,"dropCustomFunctionProjectValidator");function Vde(e){let t=Ne.object({project:Ne.string().pattern(Mo).required().messages({"string.pattern.base":rn.BAD_PROJECT_NAME}),skip_node_modules:Ne.boolean(),skip_symlinks:Ne.boolean()});return ns.validateBySchema(e,t)}a(Vde,"packageComponentValidator");function Kde(e){let t=Ne.object({project:Ne.string().pattern(Mo).required().messages({"string.pattern.base":rn.BAD_PROJECT_NAME}),package:Ne.string().optional(),restart:Ne.alternatives().try(Ne.boolean(),Ne.string().valid("rolling")).optional()});return ns.validateBySchema(e,t)}a(Kde,"deployComponentValidator");function Yde(e){let t=Ne.object({name:Ne.string().pattern(Ude).required().messages({"string.pattern.base":rn.BAD_SSH_KEY_NAME}),key:Ne.string().required(),host:Ne.string().required(),hostname:Ne.string().required(),known_hosts:Ne.string().optional()});return ns.validateBySchema(e,t)}a(Yde,"addSSHKeyValidator");function Wde(e){let t=Ne.object({name:Ne.string().required(),key:Ne.string().required()});return ns.validateBySchema(e,t)}a(Wde,"updateSSHKeyValidator");function zde(e){let t=Ne.object({name:Ne.string().required()});return ns.validateBySchema(e,t)}a(zde,"deleteSSHKeyValidator");function Qde(e){let t=Ne.object({known_hosts:Ne.string().required()});return ns.validateBySchema(e,t)}a(Qde,"setSSHKnownHostsValidator")});var $h=C((ZDe,PV)=>{"use strict";var PS=require("joi"),Ga=require("path"),Ad=require("fs-extra"),{exec:jde,spawn:Jde}=require("child_process"),Xde=require("util"),Zde=Xde.promisify(jde),Rd=(k(),P(q)),{PACKAGE_ROOT:efe}=Et(),{handleHDBError:Gh,hdb_errors:tfe}=he(),{HTTP_STATUS_CODES:qh}=tfe,Cl=le(),rfe=ot(),qa=ee(),{once:nfe}=require("events");Cl.initSync();var vw=Cl.get(Rd.CONFIG_PARAMS.COMPONENTSROOT),NV="npm install --force --omit=dev --json",sfe=`${NV} --dry-run`,ife=Cl.get(Rd.CONFIG_PARAMS.ROOTPATH),DS=Ga.join(ife,"ssh");PV.exports={installModules:lfe,auditModules:ufe,installAllRootModules:ofe,uninstallRootModule:afe,linkHarperdb:cfe,runCommand:yd};async function ofe(e=!1,t=Cl.get(Rd.CONFIG_PARAMS.ROOTPATH)){await LS();let r=!1,n=process.env;Ad.pathExistsSync(DS)&&Ad.readdirSync(DS).forEach(s=>{s.includes(".key")&&!r&&(n={GIT_SSH_COMMAND:"ssh -F "+Ga.join(DS,"config")+" -o UserKnownHostsFile="+Ga.join(DS,"known_hosts"),...process.env},r=!0)});try{let s=Cl.get(Rd.CONFIG_PARAMS.ROOTPATH),i=Ga.join(s,"node_modules","harperdb");Ad.lstatSync(i).isSymbolicLink()&&Ad.unlinkSync(i)}catch(s){s.code!=="ENOENT"&&qa.error("Error removing symlink:",s)}await yd(e?"npm install --force --ignore-scripts":"npm install --force",t,n)}a(ofe,"installAllRootModules");async function afe(e){await yd(`npm uninstall ${e}`,Cl.get(Rd.CONFIG_PARAMS.ROOTPATH))}a(afe,"uninstallRootModule");async function cfe(){await LS(),await yd(`npm link ${efe}`,Cl.get(Rd.CONFIG_PARAMS.ROOTPATH))}a(cfe,"linkHarperdb");async function yd(e,t=void 0,r=process.env){qa.debug({tagName:"npm_run_command"},`running command: \`${e}\``);let n=Jde(e,{shell:!0,cwd:t,env:r,stdio:["ignore","pipe","pipe"]}),s="",i="";n.stdout.on("data",c=>{let l=c.toString();qa.debug({tagName:"npm_run_command:stdout"},l),s+=l}),n.stderr.on("data",c=>{let l=c.toString();qa.error({tagName:"npm_run_command:stderr"},l),i+=l});let[o]=await nfe(n,"close");if(o!==0)throw new Error(`Command \`${e}\` exited with code ${o}.${i===""?"":` Error: ${i}`}`);return s||void 0}a(yd,"runCommand");async function lfe(e){let t="install_node_modules is deprecated. Dependencies are automatically installed on deploy, and install_node_modules can lead to inconsistent behavior";qa.warn(t,e.projects);let r=CV(e);if(r)throw Gh(r,r.message,qh.BAD_REQUEST);let{projects:n,dry_run:s}=e,i=s===!0?sfe:NV;await LS(),await IV(n);let o={};for(let c=0,l=n.length;c<l;c++){let u=n[c];o[u]={npm_output:null,npm_error:null};let f=Ga.join(vw,u),d,_=null;try{let{stdout:h,stderr:m}=await Zde(i,{cwd:f});d=h?h.replace(`
28
28
  `,""):null,_=m?m.replace(`
29
29
  `,""):null}catch(h){h.stderr?o[u].npm_error=wV(h.stderr):o[u].npm_error=h.message;continue}try{o[u].npm_output=JSON.parse(d)}catch{o[u].npm_output=d}try{o[u].npm_error=JSON.parse(_)}catch{o[u].npm_error=_}}return qa.info(`finished installModules with response ${o}`),o.warning=t,o}a(lfe,"installModules");function wV(e){let t='"error": {',r=e.indexOf('"error": {'),n=e.indexOf(`}