harperdb 4.5.33 → 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/README.md +1 -1
- package/bin/harperdb.js +3 -3
- package/bin/lite.js +3 -3
- package/launchServiceScripts/launchNatsIngestService.js +3 -3
- package/launchServiceScripts/launchNatsReplyService.js +3 -3
- package/launchServiceScripts/launchUpdateNodes4-0-0.js +3 -3
- package/npm-shrinkwrap.json +252 -252
- package/package.json +2 -2
- package/server/jobs/jobProcess.js +3 -3
- package/server/threads/threadServer.js +3 -3
- package/studio/build-local/asset-manifest.json +2 -2
- package/studio/build-local/index.html +1 -1
- package/studio/build-local/static/js/{main.44a7d373.js → main.eae3e997.js} +2 -2
- package/utility/scripts/restartHdb.js +3 -3
- /package/studio/build-local/static/js/{main.44a7d373.js.LICENSE.txt → main.eae3e997.js.LICENSE.txt} +0 -0
package/README.md
CHANGED
package/bin/harperdb.js
CHANGED
|
@@ -22,9 +22,9 @@ Caused by:`));else if(typeof u=="object")try{n+=JSON.stringify(u)}catch{n+="Obje
|
|
|
22
22
|
`,""));return r.replace(`
|
|
23
23
|
`,"")}a(qk,"runCommand");async function oie(){try{await xse.access(eN)}catch{return!1}let e=await qk(`${eN} --version`,void 0),t=e.substring(e.lastIndexOf("v")+1,e.length);return Bse.eq(t,sie)}a(oie,"checkNATSServerInstalled");async function iN(e,t,r,n=!0,s="127.0.0.1"){if(!t&&!r){let o=await Fk.getClusterUser();if(bl(o))throw new Error("Unable to get nats connection. Cluster user is undefined.");t=o.username,r=o.decrypt_hash}ui.trace("create nats connection called");let i=await jse({name:s,port:e,user:t,pass:r,maxReconnectAttempts:-1,waitOnFirstConnect:n,timeout:2e5,tls:{keyFile:Cr.get(ze.CONFIG_PARAMS.CLUSTERING_TLS_PRIVATEKEY),certFile:Cr.get(ze.CONFIG_PARAMS.CLUSTERING_TLS_CERTIFICATE),caFile:Cr.get(ze.CONFIG_PARAMS.CLUSTERING_TLS_CERT_AUTH),rejectUnauthorized:!1}});return i.protocol.transport.socket.unref(),ui.trace("create connection established a nats client connection with id",i?.info?.client_id),i.closed().then(o=>{o&&ui.error("Error with Nats client connection, connection closed",o),i===en&&$k()}),i}a(iN,"createConnection");function $k(){en=void 0,Al=void 0,Rl=void 0,yl=void 0}a($k,"clearClientCache");async function aie(){en&&(await en.drain(),en=void 0,Al=void 0,Rl=void 0,yl=void 0)}a(aie,"closeConnection");var en,yl;async function gp(){return yl||(yl=iN(Cr.get(ze.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_NETWORK_PORT),void 0,void 0),en=await yl),en||yl}a(gp,"getConnection");async function Sp(){if(Al)return Al;bl(en)&&await gp();let{domain:e}=ud(ze.PROCESS_DESCRIPTORS.CLUSTERING_LEAF);if(bl(e))throw new Error("Error getting JetStream domain. Unable to get JetStream manager.");return Al=await en.jetstreamManager({domain:e,timeout:6e4}),Al}a(Sp,"getJetStreamManager");async function Vk(){if(Rl)return Rl;bl(en)&&await gp();let{domain:e}=ud(ze.PROCESS_DESCRIPTORS.CLUSTERING_LEAF);if(bl(e))throw new Error("Error getting JetStream domain. Unable to get JetStream manager.");return Rl=en.jetstream({domain:e,timeout:6e4}),Rl}a(Vk,"getJetStream");async function zi(){let e=en||await gp(),t=Al||await Sp(),r=Rl||await Vk();return{connection:e,jsm:t,js:r}}a(zi,"getNATSReferences");async function cie(e){let t=Cr.get(ze.CONFIG_PARAMS.CLUSTERING_HUBSERVER_NETWORK_PORT),{sys_name:r,decrypt_hash:n}=await Fk.getClusterUser(),s=await iN(t,r,n),i=sN(),o=s.subscribe(i),c=[],l,u=(async()=>{for await(let f of o){let d=Gk.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 Ig.async_set_timeout(e),await o.drain(),await s.close(),await u,c}a(cie,"getServerList");async function oN(e,t){let{jsm:r}=await zi(),n=Cr.get(ze.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_STREAMS_MAXAGE);n=n===null?0:n*1e9;let s=Cr.get(ze.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_STREAMS_MAXMSGS);s=s===null?-1:s;let i=Cr.get(ze.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_STREAMS_MAXBYTES);i=i===null?-1:i,await r.streams.add({name:e,storage:Jse.File,retention:Qse.Limits,subjects:t,discard:Xse.Old,max_msgs:s,max_bytes:i,max_age:n})}a(oN,"createLocalStream");async function Kk(){let{jsm:e}=await zi(),t=await e.streams.list().next(),r=[];return t.forEach(n=>{r.push(n)}),r}a(Kk,"listStreams");async function lie(e){let{jsm:t}=await zi();await t.streams.delete(e)}a(lie,"deleteLocalStream");async function uie(e){let{connection:t}=await zi(),r=[],n=sN(),s=t.subscribe(n),i=(async()=>{for await(let o of s)r.push(Gk.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(uie,"listRemoteStreams");async function die(e,t=void 0,r=void 0){let{jsm:n,js:s}=await zi(),i=xk(),o={durable_name:i,ack_policy:rN.Explicit};t&&(o.deliver_policy=nN.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=tN(f.data),_={nats_timestamp:f.info.timestampNanos,nats_sequence:f.info.streamSequence,entry:d};if(f.headers&&(_.origin=f.headers.get(Fr.MSG_HEADERS.ORIGIN)),u.push(_),f.ack(),f.info.pending===0)break}return await c.delete(),u}a(die,"viewStream");async function*fie(e,t=void 0,r=void 0){let{jsm:n,js:s}=await zi(),i=xk(),o={durable_name:i,ack_policy:rN.Explicit};t&&(o.deliver_policy=nN.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=tN(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(Fr.MSG_HEADERS.ORIGIN)),yield _}if(u.ack(),u.info.pending===0)break}await c.delete()}a(fie,"viewStreamIterator");async function _ie(e,t,r,n){ui.trace(`publishToStream called with subject: ${e}, stream: ${t}, entries:`,n.operation),r=Yk(n,r);let{js:s}=await zi(),i=await Pg(),o=`${e}.${i}`,c=await rie(()=>n instanceof Uint8Array?n:kk.encode(n));try{ui.trace(`publishToStream publishing to subject: ${o}`),tie(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 zk(async()=>{try{await s.publish(o,c,{headers:r})}catch{if(l.code&&l.code.toString()==="503"){ui.trace(`publishToStream creating stream: ${t}`);let f=o.split(".");f[2]="*",await oN(t,[o]),await s.publish(o,c,{headers:r})}else throw l}});throw l}}a(_ie,"publishToStream");function Yk(e,t){t===void 0&&(t=eie());let r=Cr.get(ze.CONFIG_PARAMS.CLUSTERING_NODENAME);return!t.has(Fr.MSG_HEADERS.ORIGIN)&&r&&t.append(Fr.MSG_HEADERS.ORIGIN,r),t}a(Yk,"addNatsMsgHeader");function ud(e){e=e.toLowerCase();let t=Ep.join(Cr.get(ze.CONFIG_PARAMS.ROOTPATH),nie);if(e===ze.PROCESS_DESCRIPTORS.CLUSTERING_HUB.toLowerCase())return bl(ZO)&&(ZO={port:hp.getConfigFromFile(ze.CONFIG_PARAMS.CLUSTERING_HUBSERVER_NETWORK_PORT),server_name:hp.getConfigFromFile(ze.CONFIG_PARAMS.CLUSTERING_NODENAME)+Fr.SERVER_SUFFIX.HUB,config_file:Fr.NATS_CONFIG_FILES.HUB_SERVER,pid_file_path:Ep.join(t,Fr.PID_FILES.HUB),hdb_nats_path:t}),ZO;if(e===ze.PROCESS_DESCRIPTORS.CLUSTERING_LEAF.toLowerCase())return bl(XO)&&(XO={port:hp.getConfigFromFile(ze.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_NETWORK_PORT),server_name:hp.getConfigFromFile(ze.CONFIG_PARAMS.CLUSTERING_NODENAME)+Fr.SERVER_SUFFIX.LEAF,config_file:Fr.NATS_CONFIG_FILES.LEAF_SERVER,domain:hp.getConfigFromFile(ze.CONFIG_PARAMS.CLUSTERING_NODENAME)+Fr.SERVER_SUFFIX.LEAF,pid_file_path:Ep.join(t,Fr.PID_FILES.LEAF),hdb_nats_path:t}),XO;ui.error(`Unable to get Nats server config. Unrecognized process: ${e}`)}a(ud,"getServerConfig");async function Wk(e,t,r,n){try{await e.consumers.add(t,{ack_policy:rN.Explicit,durable_name:r,deliver_policy:nN.StartTime,opt_start_time:n})}catch(s){if(s.message!=="consumer already exists")throw s}}a(Wk,"createConsumer");async function pie(e,t,r){await e.consumers.delete(t,r)}a(pie,"removeConsumer");function hie(e){return e.split(".")[1]}a(hie,"extractServerName");async function mie(e,t,r=6e4,n=sN()){if(!Ig.isObject(t))throw new Error("data param must be an object");let s=kk.encode(t),{connection:i}=await zi(),o={timeout:r};n&&(o.reply=n,o.noMux=!0);let c=await i.request(e,s,o);return tN(c.data)}a(mie,"request");function aN(e){return new Promise(async(t,r)=>{let n=Gse(eN,["--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(aN,"reloadNATS");async function Eie(){let{pid_file_path:e}=ud(ze.PROCESS_DESCRIPTORS.CLUSTERING_HUB);await aN(e)}a(Eie,"reloadNATSHub");async function gie(){let{pid_file_path:e}=ud(ze.PROCESS_DESCRIPTORS.CLUSTERING_LEAF);await aN(e)}a(gie,"reloadNATSLeaf");function Sie(e,t,r){let n;switch(e.code){case Uk.NoResponders:n=`Unable to ${t}, node '${r}' is not listening.`;break;case Uk.Timeout:n=`Unable to ${t}, node '${r}' is listening but did not respond.`;break;default:n=e.message;break}return n}a(Sie,"requestErrorHandler");async function Tie(e,t){let r=t+Fr.SERVER_SUFFIX.LEAF,{connection:n}=await zi(),{jsm:s}=await Iie(r),{schema:i,table:o}=e,c=Cg.createNatsTableStreamName(i,o),l=e.start_time?e.start_time:new Date(Date.now()).toISOString();await zk(async()=>{if(e.subscribe===!0)await Wk(s,c,n.info.server_name,l);else try{await pie(s,c,n.info.server_name)}catch(u){ui.trace(u)}})}a(Tie,"updateRemoteConsumer");async function Aie(e,t,r,n){let s=Cg.createNatsTableStreamName(e,t),i=r+Fr.SERVER_SUFFIX.LEAF,o={type:ze.ITC_EVENT_TYPES.NATS_CONSUMER_UPDATE,status:n,stream_name:s,node_domain_name:i};if(!Hk&&Wse()<Cr.get(ze.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_STREAMS_MAXINGESTTHREADS)){let{updateConsumer:c}=QO();await c(o)}await Kse(o),n==="stop"&&await Ig.async_set_timeout(1e3)}a(Aie,"updateConsumerIterator");function zk(e){return Vse.writeTransaction(ze.SYSTEM_SCHEMA_NAME,ze.SYSTEM_TABLE_NAMES.NODE_TABLE_NAME,e)}a(zk,"exclusiveLock");async function jk(e,t){let r=Cg.createNatsTableStreamName(e,t),n=await Pg(),s=Oie(e,t,n);await oN(r,[s])}a(jk,"createLocalTableStream");async function Rie(e){for(let t=0,r=e.length;t<r;t++){let n=e[t].schema,s=e[t].table;await jk(n,s)}}a(Rie,"createTableStreams");async function Jk(e,t,r=void 0){if(Cr.get(ze.CONFIG_PARAMS.CLUSTERING_ENABLED))try{let n=Cg.createNatsTableStreamName(e,t),{domain:s}=ud(ze.PROCESS_DESCRIPTORS.CLUSTERING_LEAF);await(await(await gp()).jetstreamManager({domain:s,timeout:24e4})).streams.purge(n,r)}catch(n){if(n.message==="stream not found")ui.warn(n);else throw n}}a(Jk,"purgeTableStream");async function yie(e,t){if(Cr.get(ze.CONFIG_PARAMS.CLUSTERING_ENABLED))for(let r=0,n=t.length;r<n;r++)await Jk(e,t[r])}a(yie,"purgeSchemaTableStreams");async function bie(e){return(await Sp()).streams.info(e)}a(bie,"getStreamInfo");function Oie(e,t,r){return`${Fr.SUBJECT_PREFIXES.TXN}.${e}${t?"."+t:""}.${r}`}a(Oie,"createSubjectName");async function Pg(){if(mp)return mp;if(mp=(await Sp())?.nc?.info?.server_name,mp===void 0)throw new Error("Unable to get jetstream manager server name");return mp}a(Pg,"getJsmServerName");async function Nie(){let e=await Sp(),t=await Pg(),r=await Kk();for(let n of r){let s=n.config,i=s.subjects[0];if(!i)continue;let o=wie(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(".");ui.trace(`Updating stream subject name from: ${i} to: ${f}`),s.subjects[0]=f,await e.streams.update(s.name,s)}}a(Nie,"updateLocalStreams");function wie(e){let{config:t}=e,r=!1,n=Cr.get(ze.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_STREAMS_MAXAGE);n=n===null?0:n*1e9;let s=Cr.get(ze.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_STREAMS_MAXBYTES);s=s===null?-1:s;let i=Cr.get(ze.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(wie,"updateStreamLimits");async function Iie(e){let t,r;try{t=await en.jetstream({domain:e}),r=await en.jetstreamManager({domain:e,checkAPI:!1})}catch(n){throw ui.error("Unable to connect to:",e),n}return{js:t,jsm:r}}a(Iie,"connectToRemoteJS")});function cN(e){let t=e.get(Dg),r=t?(0,dd.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:Ap(e)??1,nodes:[]})})}i[n]=0,e.putSync(Dg,(0,dd.pack)(r))}return r}function Tp(e){return cN(e).remoteNameToId}function Zk(e,t){let r=cN(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(Dg,(0,dd.pack)(r)),s}function Lg(e,t){let r=cN(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(Dg,(0,dd.pack)(r))}return Xk.trace?.("The remote node name map",e,n,s),s}var Xk,dd,Dg,lN=Re(()=>{Xk=M(ei());ss();dd=require("msgpackr"),Dg=Symbol.for("remote-ids");a(cN,"getIdMappingRecord");a(Tp,"exportIdMapping");a(Zk,"remoteToLocalNodeId");a(Lg,"getIdOfRemoteNode")});var uN={};xe(uN,{commits_awaiting_replication:()=>fd,getHDBNodeTable:()=>cr,getReplicationSharedStatus:()=>Mg,iterateRoutes:()=>yp,shouldReplicateToNode:()=>Rp,subscribeToNodeUpdates:()=>_d});function cr(){return eF||(eF=_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 Mg(e,t,r,n){return new Float64Array(e.getUserSharedBuffer(["replicated",t,r],new ArrayBuffer(48),n&&{callback:n}))}function _d(e){cr().subscribe({}).then(async t=>{for await(let r of t){let n=r?.value?.name;sF.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 cr().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 Rp(e,t){let r=Ha.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===Ha.default.get(x.REPLICATION_SHARD))))&&cr().primaryStore.get(et())?.replicates||e.subscriptions?.some(n=>(n.database||n.schema)===t&&n.subscribe)}function Cie(){_d(e=>{ka({},(t,r)=>{let n=e.name,s=tF.get(n);if(s||tF.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=Mg(i,r,n,()=>{let c=o[0],l=o.lastTime;for(let{txnTime:u,onConfirm:f}of fd.get(r)||[])u>l&&u<=c&&f();o.lastTime=c});o.lastTime=0,s.set(r,o)}})})}function*yp(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=Ha.default.get(x.REPLICATION_SECUREPORT)??(!Ha.default.get(x.REPLICATION_PORT)&&Ha.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||Ha.default.get(x.REPLICATION_PORT)||Ha.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){rF.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 rF,nF,Ha,sF,eF,tF,fd,Ol=Re(()=>{Le();ss();Mm();rF=require("worker_threads"),nF=M(pe()),Ha=M(ce());k();sF=M(ei());server.nodes=[];a(cr,"getHDBNodeTable");a(Mg,"getReplicationSharedStatus");a(_d,"subscribeToNodeUpdates");a(Rp,"shouldReplicateToNode");tF=new Map;UL((e,t,r)=>{if(r>server.nodes.length)throw new nF.ClientError(`Cannot confirm replication to more nodes (${r}) than are in the network (${server.nodes.length})`);fd||(fd=new Map,Cie());let n=fd.get(e);return n||(n=[],fd.set(e,n)),new Promise(s=>{let i=0;n.push({txnTime:t,onConfirm:a(()=>{++i===r&&s()},"onConfirm")})})});a(Cie,"startSubscriptionToReplications");a(yp,"iterateRoutes")});var aF={};xe(aF,{connectedToNode:()=>Nl,disconnectedFromNode:()=>hd,ensureNode:()=>Mo,requestClusterStatus:()=>oF,startOnMainThread:()=>_N});async function _N(e){let t=0,r=Xe();for(let i of Object.getOwnPropertyNames(r)){let o=r[i];for(let c in o){let l=o[c];if(l.auditStore){vg.set(i,Ap(l.auditStore));break}}}Ji.whenThreadsStarted.then(async()=>{let i=[];for await(let o of r.system.hdb_nodes?.search([])||[])i.push(o);for(let o of yp(e))try{let c=!o.subscriptions;if(c){let u=et(),f=cr().primaryStore.get(u);if(f!==null){let d=e.url??Fa();(f===void 0||f.url!==d||f.shard!==e.shard)&&await Mo(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)}_d(s)});let n;function s(i,o=i?.name){let c=et()&&o===et()||Fa()&&i?.url===Fa();if(c){let d=!!i?.replicates;if(n!==void 0&&n!==d)for(let _ of cr().search([]))_.replicates&&_.name!==o&&s(_,_.name);n=d}if(it.trace("Setting up node replication for",i),!i){for(let[d,_]of ji){let p;for(let[h,{worker:S,nodes:g}]of _){let R=g[0];if(R&&R.name==o){p=!0;for(let[E,{worker:T}]of _)_.delete(E),it.warn("Node was deleted, unsubscribing from node",o,E,d),T?.postMessage({type:"unsubscribe-from-node",node:o,database:E,url:d});break}}if(p){ji.get(d).iterator.remove(),ji.delete(d);return}}return}if(c)return;if(!i.url){it.info(`Node ${i.name} is missing url`);return}let l=ji.get(i.url);if(l&&l.iterator.remove(),!(i.replicates===!0||i.replicates?.sends)&&!i.subscriptions?.length&&!l)return;if(it.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 pd)if(i.url===_.url){pd.delete(d);break}pd.set(i.name,i)}let u=Xe();if(l||(l=new Map,ji.set(i.url,l)),l.iterator=ka(e,(d,_,p)=>{p?f(_,!0):f(_,!1)}),i.subscriptions)for(let d of i.subscriptions){let _=d.database||d.schema;u[_]||(it.warn(`Database ${_} not found for node ${i.name}, making a subscription anyway`),f(_,!1))}function f(d,_){it.trace("Setting up replication for database",d,"on node",i.name);let p=l.get(d),h,S=[{replicateByDefault:_,...i}];vg.has(d)&&(S.push({replicateByDefault:_,name:et(),start_time:vg.get(d),end_time:Date.now(),replicates:!0}),vg.delete(d));let g=Rp(i,d),R=Ji.workers.filter(E=>E.name==="http");if(p?(h=p.worker,p.nodes=S):g&&(t=t%R.length,h=R[t++],l.set(d,{worker:h,nodes:S,url:i.url}),h?.on("exit",()=>{l.get(d)?.worker===h&&(l.delete(d),f(d,_))})),g)setTimeout(()=>{let E={type:"subscribe-to-node",database:d,nodes:S};h?h.postMessage(E):bp(E)},Pie);else{it.info("Node no longer should be used, unsubscribing from node",i.replicates,!!u[d],cr().primaryStore.get(et())?.replicates),cr().primaryStore.get(et())?.replicates||(n=!1);let E={type:"unsubscribe-from-node",database:d,url:i.url,name:i.name};h?h.postMessage(E):xg(E)}}a(f,"onDatabase")}a(s,"onNodeUpdate"),hd=a(function(i){try{it.info("Disconnected from node",i.name,i.url,"finished",!!i.finished);let o=Array.from(pd.keys()),c=o.sort(),l=c.indexOf(i.name||di(i.url));if(l===-1){it.warn("Disconnected node not found in node map",i.name,o);return}let u=ji.get(i.url),f=u?.get(i.database);if(!f){it.warn("Disconnected node not found in replication map",i.database,u);return}if(f.connected=!1,i.finished||!fN.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,p=(l+1)%c.length;for(;l!==p;){let h=c[p],S=pd.get(h);u=ji.get(S.url);let g=u?.get(i.database);if(!g||g.connected===!1||g.nodes[0].shard!==_){p=(p+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)){it.info(`Disconnected node is already failing over to ${h} for ${i.database}`);continue}N.end_time<Date.now()||(E.push(N),T=!0)}if(f.nodes=[f.nodes[0]],!T){it.info(`Disconnected node ${i.name} has no nodes to fail over to ${h}`);return}it.info(`Failing over ${i.database} from ${i.name} to ${h}`),R?R.postMessage({type:"subscribe-to-node",database:i.database,nodes:E}):bp({database:i.database,nodes:E});return}it.warn("Unable to find any other node to fail over to",i.name,i.url)}catch(o){it.error("Error failing over node",o)}},"disconnectedFromNode"),Nl=a(function(i){let o=ji.get(i.url),c=o?.get(i.database);if(!c){it.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){it.info("Connected node has no nodes",i.database,c);return}if(!l.name){it.debug("Connected node is not named yet",i.database,c);return}c.nodes=[l];let u=!1;for(let f of ji.values()){let d=f.get(i.database);if(!d||d==c)continue;let{worker:_,nodes:p,connected:h}=d;if(p)if(h===!1&&p[0].shard===l.shard)u=!0,c.nodes.push(p[0]);else{let S=p.filter(g=>g.name!==l.name);S.length<p.length&&(d.nodes=S,_.postMessage({type:"subscribe-to-node",database:i.database,nodes:p}))}}u&&c.worker&&c.worker.postMessage({type:"subscribe-to-node",database:i.database,nodes:c.nodes})},"connectedToNode"),(0,Ji.onMessageByType)("disconnected-from-node",hd),(0,Ji.onMessageByType)("connected-to-node",Nl),(0,Ji.onMessageByType)("request-cluster-status",oF)}function oF(e,t){let r=[];for(let[n,s]of pd)try{let i=ji.get(s.url);it.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(p=>!(p.end_time<Date.now())).map(p=>p.name)});let c=(0,dN.cloneDeep)(s);c.database_sockets=o,delete c.ca,delete c.node_name,delete c.__updatedtime__,delete c.__createdtime__,r.push(c)}}catch(i){it.warn("Error getting cluster status for",s?.url,i)}return t?.postMessage({type:"cluster-status",connections:r}),{connections:r}}async function Mo(e,t){let r=cr();e=e??di(t.url),t.name=e;try{if(t.ca){let s=new iF.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){it.error("Error parsing replication CA info for hdb_nodes table",s.message)}let n=r.primaryStore.get(e);if(it.debug(`Ensuring node ${e} at ${t.url}, existing record:`,n,"new record:",t),!n)await r.patch(t);else{t.replicates&&!fN.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,dN.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])]}it.info(`Updating node ${e} at ${t.url}`),await r.patch(t)}}var Ji,Ug,it,dN,fN,iF,Pie,ji,hd,Nl,pd,vg,Op=Re(()=>{Le();Ji=M(nt());ss();Ug=require("worker_threads");Ol();it=M(J()),dN=require("lodash"),fN=M(ce());k();iF=require("crypto"),Pie=200,ji=new Map,pd=new Map,vg=new Map;a(_N,"startOnMainThread");a(oF,"requestClusterStatus");Ug.parentPort&&(hd=a(e=>{Ug.parentPort.postMessage({type:"disconnected-from-node",...e})},"disconnectedFromNode"),Nl=a(e=>{Ug.parentPort.postMessage({type:"connected-to-node",...e})},"connectedToNode"),(0,Ji.onMessageByType)("subscribe-to-node",e=>{bp(e)}),(0,Ji.onMessageByType)("unsubscribe-from-node",e=>{xg(e)}));a(Mo,"ensureNode")});var os=P(PF=>{"use strict";var lr=require("path"),{watch:Die}=require("chokidar"),Dn=require("fs-extra"),md=require("node-forge"),_F=require("net"),{generateKeyPair:hN,X509Certificate:vo,createPrivateKey:pF}=require("crypto"),Lie=require("util");hN=Lie.promisify(hN);var Nt=md.pki,fi=require("joi"),{v4:hF}=require("uuid"),{validateBySchema:SN}=ct(),Tt=J(),is=ce(),Cs=(k(),C(G)),{CONFIG_PARAMS:Il}=Cs,_i=nb(),{ClientError:qa}=pe(),Bg=require("node:tls"),{relative:mF,join:Mie}=require("node:path"),{CERT_PREFERENCE_APP:_De,CERTIFICATE_VALUES:cF}=_i,vie=Ea(),mN=Ot(),{table:Uie,getDatabases:xie,databases:pN}=(Le(),C(st)),{getJWTRSAKeys:lF}=(od(),C(_p));Object.assign(PF,{generateKeys:RN,updateConfigCert:bF,createCsr:$ie,signCertificate:Vie,setCertTable:Ed,loadCertificates:AF,reviewSelfSignedCert:bN,createTLSSelector:NF,listCertificates:IF,addCertificate:Jie,removeCertificate:Xie,createNatsCerts:Wie,generateCertsKeys:Yie,getReplicationCert:wp,getReplicationCertAuth:qie,renewSelfSigned:zie,hostnamesFromCert:ON,getKey:Zie});var{urlToNodeName:EF,getThisNodeUrl:Bie,getThisNodeName:kg,clearThisNodeName:Hie}=(ss(),C(Uo)),{readFileSync:kie,statSync:gF}=require("node:fs"),pDe=ce(),{getTicketKeys:Fie,onMessageFromWorkers:Gie}=nt(),Ga=J(),{isMainThread:SF}=require("worker_threads"),{TLSSocket:TF,createSecureContext:hDe}=require("node:tls"),TN=3650,Np=["127.0.0.1","localhost","::1"],AN=[{name:"countryName",value:"USA"},{name:"stateOrProvinceName",value:"Colorado"},{name:"localityName",value:"Denver"},{name:"organizationName",value:"HarperDB, Inc."}];Gie(async e=>{e.type===Cs.ITC_EVENT_TYPES.RESTART&&(is.initSync(!0),await bN())});var Gr;function Va(){return Gr||(Gr=xie().system.hdb_certificate,Gr||(Gr=Uie({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__"}]}))),Gr}a(Va,"getCertTable");async function wp(){let e=NF("operations-api"),t={secureContexts:null,setSecureContext:a(s=>{},"setSecureContext")};await e.initialize(t);let r=t.secureContexts.get(kg());if(!r)return;let n=new vo(r.options.cert);return r.cert_parsed=n,r.issuer=n.issuer,r}a(wp,"getReplicationCert");async function qie(){Va();let e=(await wp()).options.cert,r=new vo(e).issuer.match(/CN=(.*)/)?.[1];return Gr.get(r)}a(qie,"getReplicationCertAuth");var uF,$a=new Map;function AF(){if(uF)return;uF=!0;let e=[{configKey:Il.TLS},{configKey:Il.OPERATIONSAPI_TLS}];Va();let t=lr.dirname(mN.getConfigFilePath()),r;for(let{configKey:n}of e){let s=mN.getConfigFromFile(n);if(s){Array.isArray(s)||(s=[s]);for(let i of s){let o=i.privateKey,c=o&&mF(Mie(t,"keys"),o);c&&dF(o,l=>{$a.set(c,l)},"private key");for(let l of[!1,!0]){let u=i[l?"certificateAuthority":"certificate"];if(u&&SF){let f;dF(u,d=>{if(cF.cert===d)return;let _=i.hostname??i.hostnames??i.host??i.hosts;_&&!Array.isArray(_)&&(_=[_]);let p=OF(u),h=new vo(p),S;try{S=CF(h)}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(h.checkIssued(new vo(cF.cert)))return;let g=Gr.primaryStore.get(S),R=gF(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=Gr.put({name:S,uses:["https",...n.includes("operations")?["operations"]:[]],ciphers:i.ciphers,certificate:p,private_key_name:c,is_authority:l,hostnames:_,file_timestamp:R,details:{issuer:h.issuer.replace(/\n/g," "),subject:h.subject?.replace(/\n/g," "),subject_alt_name:h.subjectAltName,serial_number:h.serialNumber,valid_from:h.validFrom,valid_to:h.validTo}})},l?"certificate authority":"certificate")}}}}}return r}a(AF,"loadCertificates");function dF(e,t,r){let n,s=a((i,o)=>{try{let c=o.mtimeMs;c&&c!==n&&(n&&SF&&Tt.warn(`Reloading ${r}:`,i),n=c,t(OF(i)))}catch(c){Tt.error(`Error loading ${r}:`,i,c)}},"loadFile");Dn.existsSync(e)?s(e,gF(e)):Tt.error(`${r} file not found:`,e),Die(e,{persistent:!1}).on("change",s)}a(dF,"loadAndWatch");function EN(){let e=Bie();if(e==null){let t=Np[0];return Tt.info("replication url is missing from harperdb-config.yaml, using default host"+t),t}return EF(e)}a(EN,"getHost");function Hg(){let e=kg();if(e==null){let t=Np[0];return Tt.info("replication url is missing from harperdb-config.yaml, using default host"+t),t}return e}a(Hg,"getCommonName");async function $ie(){let e=await wp(),t=Nt.certificateFromPem(e.options.cert),r=Nt.privateKeyFromPem(e.options.key);Tt.info("Creating CSR with cert named:",e.name);let n=Nt.createCertificationRequest();n.publicKey=t.publicKey;let s=[{name:"commonName",value:Hg()},...AN];Tt.info("Creating CSR with subject",s),n.setSubject(s);let i=[{name:"unstructuredName",value:"HarperDB, Inc."},{name:"extensionRequest",extensions:RF()}];return Tt.info("Creating CSR with attributes",i),n.setAttributes(i),n.sign(r),md.pki.certificationRequestToPem(n)}a($ie,"createCsr");function RF(){let e=Np.includes(Hg())?Np:[...Np,Hg()];return e.includes(EN())||e.push(EN()),[{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=>_F.isIP(t)?{type:7,ip:t}:{type:2,value:t})}]}a(RF,"certExtensions");async function Vie(e){let t={},r=lr.join(is.getHdbBasePath(),Cs.LICENSE_KEY_DIR_NAME);if(e.csr){let n,s;Va();for await(let f of Gr.search([]))if(f.is_authority&&!f.details.issuer.includes("HarperDB-Certificate-Authority")){if($a.has(f.private_key_name)){n=$a.get(f.private_key_name),s=f;break}else if(f.private_key_name&&await Dn.exists(lr.join(r,f.private_key_name))){n=Dn.readFile(lr.join(r,f.private_key_name)),s=f;break}}if(!n){let f=await gN();s=f.ca,n=f.private_key}n=Nt.privateKeyFromPem(n),t.signingCA=s.certificate;let i=Nt.certificateFromPem(s.certificate);Tt.info("Signing CSR with cert named",s.name);let o=Nt.certificationRequestFromPem(e.csr);try{o.verify()}catch(f){return Tt.error(f),new Error("Error verifying CSR: "+f.message)}let c=md.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()+TN),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,md.md.sha256.create()),t.certificate=Nt.certificateToPem(c)}else Tt.info("Sign cert did not receive a CSR from:",e.url,"only the CA will be returned");return t}a(Vie,"signCertificate");async function Kie(e,t){await Ed({name:kg(),uses:["https","wss"],certificate:e,private_key_name:"privateKey.pem",is_authority:!1,is_self_signed:!0}),await Ed({name:t.subject.getField("CN").value,uses:["https","wss"],certificate:Nt.certificateToPem(t),private_key_name:"privateKey.pem",is_authority:!0,is_self_signed:!0})}a(Kie,"createCertificateTable");async function Ed(e){let t=new vo(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},Va(),await Gr.patch(e)}a(Ed,"setCertTable");async function RN(){let e=await hN("rsa",{modulusLength:4096,publicKeyEncoding:{type:"spki",format:"pem"},privateKeyEncoding:{type:"pkcs8",format:"pem"}});return{public_key:Nt.publicKeyFromPem(e.publicKey),private_key:Nt.privateKeyFromPem(e.privateKey)}}a(RN,"generateKeys");async function yN(e,t,r){let n=Nt.createCertificate();if(!t){let o=await wp();t=Nt.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()+TN);let i=[{name:"commonName",value:Hg()},...AN];return n.setSubject(i),n.setIssuer(r.subject.attributes),n.setExtensions(RF()),n.sign(e,md.md.sha256.create()),Nt.certificateToPem(n)}a(yN,"generateCertificates");async function gN(){let e=await IF(),t;for(let r of e){if(!r.is_authority)continue;let n=await wF(r.private_key_name);if(r.private_key_name&&n&&new vo(r.certificate).checkPrivateKey(pF(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(gN,"getCertAuthority");async function yF(e,t,r=!0){let n=Nt.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()+TN);let i=[{name:"commonName",value:`HarperDB-Certificate-Authority-${is.get(Il.REPLICATION_HOSTNAME)??EF(is.get(Il.REPLICATION_URL))??hF().split("-")[0]}`},...AN];n.setSubject(i),n.setIssuer(i),n.setExtensions([{name:"basicConstraints",cA:!0,critical:!0},{name:"keyUsage",keyCertSign:!0,critical:!0}]),n.sign(e,md.md.sha256.create());let o=lr.join(is.getHdbBasePath(),Cs.LICENSE_KEY_DIR_NAME),c=lr.join(o,_i.PRIVATEKEY_PEM_NAME);return r&&await Dn.writeFile(c,Nt.privateKeyToPem(e)),n}a(yF,"generateCertAuthority");async function Yie(){let{private_key:e,public_key:t}=await RN(),r=await yF(e,t),n=await yN(e,t,r);await Kie(n,r),bF()}a(Yie,"generateCertsKeys");async function Wie(){let e=await yN(Nt.privateKeyFromPem(_i.CERTIFICATE_VALUES.key),void 0,Nt.certificateFromPem(_i.CERTIFICATE_VALUES.cert)),t=lr.join(is.getHdbBasePath(),Cs.LICENSE_KEY_DIR_NAME),r=lr.join(t,_i.NATS_CERTIFICATE_PEM_NAME);await Dn.exists(r)||await Dn.writeFile(r,e);let n=lr.join(t,_i.NATS_CA_PEM_NAME);await Dn.exists(n)||await Dn.writeFile(n,_i.CERTIFICATE_VALUES.cert)}a(Wie,"createNatsCerts");async function zie(){Va();for await(let e of Gr.search([{attribute:"is_self_signed",value:!0}]))await Gr.delete(e.name);await bN()}a(zie,"renewSelfSigned");async function bN(){Hie(),await AF(),Va();let e=await gN();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:Nt.privateKeyFromPem(Dn.readFileSync(u)),keyPath:u}}catch(f){return Tt.warn(`Failed to parse private key from ${u}:`,f.message),{key:null,keyPath:u}}},"tryToParseKey"),n=is.get(Il.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=is.get(Il.TLS_PRIVATEKEY),f=r(u);s=f.key,i=f.keyPath}let o=lr.join(is.getHdbBasePath(),Cs.LICENSE_KEY_DIR_NAME),c=mF(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 RN(),Dn.existsSync(lr.join(o,_i.PRIVATEKEY_PEM_NAME))&&(c=`privateKey${hF().split("-")[0]}.pem`),await Dn.writeFile(lr.join(o,c),Nt.privateKeyToPem(s)));let l=await yF(s,Nt.setRsaPublicKey(s.n,s.e),!1);await Ed({name:l.subject.getField("CN").value,uses:["https"],certificate:Nt.certificateToPem(l),private_key_name:c,is_authority:!0,is_self_signed:!0})}if(!await wp()){let r=kg();Tt.notify(`A suitable replication certificate was not found, creating new self singed cert named: ${r}`),e=e??await gN();let n=Nt.certificateFromPem(e.ca.certificate),s=n.publicKey,i=await yN(Nt.privateKeyFromPem(e.private_key),s,n);await Ed({name:r,uses:["https","operations","wss"],certificate:i,is_authority:!1,private_key_name:e.ca.private_key_name,is_self_signed:!0})}}a(bN,"reviewSelfSignedCert");function bF(){let e=vie(Object.keys(Cs.CONFIG_PARAM_MAP),!0),t=lr.join(is.getHdbBasePath(),Cs.LICENSE_KEY_DIR_NAME),r=lr.join(t,_i.PRIVATEKEY_PEM_NAME),n=lr.join(t,_i.NATS_CERTIFICATE_PEM_NAME),s=lr.join(t,_i.NATS_CA_PEM_NAME),i=Cs.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),mN.updateConfigValue(void 0,void 0,o,!1,!0)}a(bF,"updateConfigCert");function OF(e){return e.startsWith("-----BEGIN")?e:kie(e,"utf8")}a(OF,"readPEM");var fF=Bg.createSecureContext;Bg.createSecureContext=function(e){if(!e.cert||!e.key)return fF(e);let t={...e};delete t.key,delete t.cert;let r=fF(t);return r.context.setCert(e.cert),r.context.setKey(e.key,void 0),r};var jie=TF.prototype._init;TF.prototype._init=function(e,t){jie.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 wl=new Map;function NF(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(),wl.clear();let f=0;for await(let d of pN.system.hdb_certificate.search([])){let _=d.certificate,p=new vo(_);d.is_authority&&(p.asString=_,wl.set(p.subject,_))}for await(let d of pN.system.hdb_certificate.search([]))try{if(d.is_authority)continue;let _=e==="operations-api",p=d.is_self_signed?1:2;_&&d.uses?.includes?.("operations")&&(p+=1);let h=await wF(d.private_key_name),S=d.certificate,g=new vo(S);if(wl.has(g.issuer)&&(S+=`
|
|
24
24
|
`+wl.get(g.issuer)),!h||!S)throw new Error("Missing private key or certificate for secure server");let R={ciphers:d.ciphers,ticketKeys:Fie(),availableCAs:wl,ca:t&&Array.from(wl.values()),cert:S,key:h,key_file:d.private_key_name,is_self_signed:d.is_self_signed};o&&(R.sessionIdContext=o.sessionIdContext);let E=Bg.createSecureContext(R);E.name=d.name,E.options=R,E.quality=p,E.certificateAuthorities=Array.from(wl),E.certStart=S.toString().slice(0,100);let T=d.hostnames??ON(g);Array.isArray(T)||(T=[T]);let N;for(let v of T)if(v){v[0]==="*"&&(s=!0,v=v.slice(1)),v===EN()&&(p+=2),_F.isIP(v)&&(N=!0);let H=r.get(v)?.quality??0;p>H&&r.set(v,E)}else Ga.error("No hostname found for certificate at",Bg.certificate);Ga.trace("Adding TLS",E.name,"for",o.ports||"client","cert named",d.name,"hostnames",T,"quality",p,"best quality",f),p>f&&(i.defaultContext=n=E,f=p,o&&(o.defaultContext=E))}catch(_){Ga.error("Error applying TLS for",d.name,_)}o?.secureContextsListeners.forEach(d=>d()),c(n)}catch(f){l(f)}}a(u,"updateTLS"),pN.system.hdb_certificate.subscribe({listener:a(()=>setTimeout(()=>u(),1500).unref(),"listener"),omitCurrent:!0}),u()})),i;function i(o,c){Ga.info("TLS requested for",o||"(no SNI)");let l=o;for(;;){let f=r.get(l);if(f)return Ga.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?Ga.debug("No certificate found to match",o,"using the default certificate"):Ga.debug("No SNI, using the default certificate",n?.name);let u=n;u?u.updatedContext&&(u=u.updatedContext):Ga.info("No default certificate found"),c(null,u)}a(i,"SNICallback")}a(NF,"createTLSSelector");async function wF(e){let t=$a.get(e);return!t&&e?await Dn.readFile(lr.join(is.get(Il.ROOTPATH),Cs.LICENSE_KEY_DIR_NAME,e),"utf8"):t}a(wF,"getPrivateKeyByName");async function IF(){Va();let e=[];for await(let t of Gr.search([]))e.push(t);return e}a(IF,"listCertificates");async function Jie(e){let t=SN(e,fi.object({name:fi.string().required(),certificate:fi.string().required(),is_authority:fi.boolean().required(),private_key:fi.string(),hosts:fi.array(),uses:fi.array()}));if(t)throw new qa(t.message);let{name:r,certificate:n,private_key:s,is_authority:i}=e,o=new vo(n),c=!1,l=!1,u;for(let[p,h]of $a)!s&&!c&&o.checkPrivateKey(pF(h))&&(c=!0,u=p),s&&s===h&&(l=!0,u=p);if(!i&&!s&&!c)throw new qa("A suitable private key was not found for this certificate");let f;if(!r){try{f=CF(o)}catch(p){Tt.error(p)}if(f==null)throw new qa("Error extracting certificate common name, please provide a name parameter")}let d=Qie(r??f);s&&!c&&!l&&(await Dn.writeFile(lr.join(is.getHdbBasePath(),Cs.LICENSE_KEY_DIR_NAME,d+".pem"),s),$a.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 Ed(_),"Successfully added certificate: "+d}a(Jie,"addCertificate");function Qie(e){return e.replace(/[^a-z0-9\.]/gi,"-")}a(Qie,"sanitizeName");async function Xie(e){let t=SN(e,fi.object({name:fi.string().required()}));if(t)throw new qa(t.message);let{name:r}=e;Va();let n=await Gr.get(r);if(!n)throw new qa(r+" not found");let{private_key_name:s}=n;if(s){let i=Array.from(await Gr.search([{attribute:"private_key_name",value:s}]));i.length===1&&i[0].name===r&&(Tt.info("Removing private key named",s),await Dn.remove(lr.join(is.getHdbBasePath(),Cs.LICENSE_KEY_DIR_NAME,s)))}return await Gr.delete(r),"Successfully removed "+r}a(Xie,"removeCertificate");function CF(e){let t=e.subject?.match(/CN=(.*)/)?.[1];return t||ON(e)[0]}a(CF,"getPrimaryHostName");function ON(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(ON,"hostnamesFromCert");async function Zie(e){if(e.bypass_auth!==!0)throw new qa("Unauthorized","401");let t=SN(e,fi.object({name:fi.string().required()}));if(t)throw new qa(t.message);let{name:r}=e;if(r===".jwtPrivate")return(await lF()).privateKey;if(r===".jwtPublic")return(await lF()).publicKey;if($a.get(r))return $a.get(e.name);throw new qa("Key not found")}a(Zie,"getKey")});var XF={};xe(XF,{CONFIRMATION_STATUS_POSITION:()=>jF,NodeReplicationConnection:()=>Sd,OPERATION_REQUEST:()=>CN,RECEIVED_TIME_POSITION:()=>DN,RECEIVED_VERSION_POSITION:()=>PN,RECEIVING_STATUS_POSITION:()=>LN,RECEIVING_STATUS_RECEIVING:()=>QF,RECEIVING_STATUS_WAITING:()=>JF,SENDING_TIME_POSITION:()=>Ip,createWebSocket:()=>Wg,database_subscriptions:()=>Ya,replicateOverWS:()=>Cp,table_update_listeners:()=>vN});async function Wg(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(!wN){let l=(0,KF.createTLSSelector)("operations-api"),u={secureContexts:null};await l.initialize(u),wN=u.secureContexts}if(i=wN.get(s),i&&le.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,WF.isIP)(t?.serverName)?void 0:t?.serverName,noDelay:!0,highWaterMark:128*1024,rejectUnauthorized:n!==!1,secureContext:void 0};return i&&(Kg?.caCount!==xo.size&&(Kg=YF.createSecureContext({...i.options,ca:[...xo,...i.options.availableCAs.values()]}),Kg.caCount=xo.size),c.secureContext=Kg),new $F.WebSocket(e,"harperdb-replication-v1",c)}function Cp(e,t,r){let n=t.port||t.securePort,s=Cl.pid%1e3+"-"+VF.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||Ya,d,_,p=!1,h=t.subscription;h?.then&&h.then(A=>h=A);let S=t.tables||u&&Xe()[u];if(!r){le.error?.("No authorization provided"),pn(1008,"Unauthorized");return}let g=new Map,R=[],E=r.name;E&&t.connection&&(t.connection.nodeName=E);let T,N,v,H,Z,W,$,se=6e4,z,fe=0,ue=0,ee=0,Ae=qF.default.get(x.REPLICATION_BLOBTIMEOUT)??12e4,he=new Map,ye=[],kt=0,ft;if(t.url){let A=a(()=>{Z&&ue===e._socket?.bytesRead&&ee===e._socket?.bytesWritten?e.terminate():(Z=performance.now(),e.ping(),ue=e._socket?.bytesRead,ee=e._socket?.bytesWritten)},"send_ping");v=setInterval(A,FF).unref(),A()}else Fn();e._socket?.setMaxListeners(200);function Fn(){clearTimeout(H),ue=e._socket?.bytesRead,ee=e._socket?.bytesWritten,H=setTimeout(()=>{ue===e._socket?.bytesRead&&ee===e._socket?.bytesWritten&&(le.warn?.(`Timeout waiting for ping from ${E}, terminating connection and reconnecting`),e.terminate())},FF*2).unref()}a(Fn,"resetPingTimer");function _n(){return _||(_=Mg(d,u,E)),_}a(_n,"getSharedStatus"),u&&ha(u);let Dr,wf,Pc=[],jA=[],JA,Ft=[],If=[],Cf=[],QA=150,um=25,Pf=0,Ce=0,Df=!1,fo,Lr,Gn,Dc;e.on("message",A=>{fe=performance.now();try{let y=A.dataView=new Pl(A.buffer,A.byteOffset,A.byteLength);if(A[0]>127){let B=(0,Ze.decode)(A),[w,D,q]=B;switch(w){case LF:{if(D){if(E){if(E!==D){le.error?.(s,`Node name mismatch, expecting to connect to ${E}, but peer reported name as ${D}, disconnecting`),e.send((0,Ze.encode)([gd])),pn(1008,"Node name mismatch");return}}else if(E=D,t.connection?.tentativeNode){let oe=t.connection.tentativeNode;oe.name=E,t.connection.tentativeNode=null,Mo(E,oe)}if(t.connection&&(t.connection.nodeName=E),le.debug?.(s,"received node name:",E,"db:",u),!u)try{ha(u=B[2]),u==="system"&&(Dr=ka(t,(oe,V)=>{pa(V)&&vf(V)}),e.on("close",()=>{Dr?.remove()}))}catch(oe){le.warn?.(s,"Error setting database",oe),e.send((0,Ze.encode)([gd])),pn(1008,oe.message);return}_a()}break}case HF:{le.debug?.(s,"Received table definitions for",D.map(oe=>oe.table));for(let oe of D){let V=B[2];oe.database=V;let X;pa(V)&&(V==="system"?We[V]?.[oe.table]||(X=L(oe,We[V]?.[oe.table])):X=L(oe,We[V]?.[oe.table]),d||(d=X?.auditStore),S||(S=Xe()?.[V]))}break}case gd:pn();break;case CN: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)([Gg,V]))},V=>{e.send((0,Ze.encode)([Gg,{requestId:D.requestId,error:V instanceof Error?V.toString():V}]))})}catch(oe){e.send((0,Ze.encode)([Gg,{requestId:D.requestId,error:oe instanceof Error?oe.toString():oe}]))}break;case Gg:let{resolve:Q,reject:j}=g.get(D.requestId);D.error?j(new Error(D.error)):Q(D),g.delete(D.requestId);break;case NN:let F=B[3];S||(u?le.error?.(s,"No tables found for",u):le.error?.(s,"Database name never received"));let Ue=S[F];Ue=L({table:F,database:u,attributes:D.attributes,schemaDefined:D.schemaDefined},Ue),Pc[q]={name:F,decoder:new Ze.Packr({useBigIntExtension:!0,randomAccessStructure:!0,freezeData:!0,typedStructs:D.typedStructs,structures:D.structures}),getEntry(oe){return Ue.primaryStore.getEntry(oe)},rootStore:Ue.primaryStore.rootStore};break;case MF:Dc=d?Zk(D,d):new Map,JA=B[2],le.debug?.(s,`Acknowledged subscription request, receiving messages for nodes: ${JA}`);break;case vF:let Ee=q;Cf[Ee]=D;break;case BF:_n()[jF]=D,le.trace?.(s,"received and broadcasting committed update",D),_n().buffer.notify();break;case xF:T=D,h.send({type:"end_txn",localTime:T,remoteNodeIds:R});break;case qg:{let oe=B[1],{fileId:V,size:X,finished:de,error:me}=oe,ae=he.get(V);le.debug?.("Received blob",V,"has stream",!!ae,"connectedToBlob",!!ae?.connectedToBlob,"length",B[2].length,"finished",de),ae||(ae=new IN.PassThrough,ae.expectedSize=X,he.set(V,ae)),ae.lastChunk=Date.now();let Ie=B[2];Mt(Ie.byteLength,"bytes-received",`${E}.${u}`,"replication","blob");try{de?(me?(ae.on("error",()=>{}),ae.destroy(new Error("Blob error: "+me+" for record "+(ae.recordId??"unknown")+" from "+E))):ae.end(Ie),ae.connectedToBlob&&he.delete(V)):ae.write(Ie)}catch(He){le.error?.(`Error receiving blob for ${ae.recordId} from ${E} and streaming to storage`,He),he.delete(V)}break}case UF:{let oe=D,V;try{let X=B[3],de=jA[q]||(jA[q]=S[B[4]]);if(!de)return le.warn?.("Unknown table id trying to handle record request",q);let me=de.primaryStore.getBinaryFast(Symbol.for("structures")),ae=me?.length;if(ae>0&&ae!==Ce){Ce=ae;let He=(0,Ze.decode)(me);e.send((0,Ze.encode)([NN,{typedStructs:He.typed,structures:He.named},q,de.tableName]))}let Ie=de.primaryStore.getBinaryFast(X);if(Ie){let He=de.primaryStore.decoder.decode(Ie,{valueAsBuffer:!0}),De=He.value;He[jc]&Br&&(De=Buffer.from(De),a_(()=>de.primaryStore.decoder.decode(Ie),rt=>Lc(rt,X),de.primaryStore.rootStore)),V=(0,Ze.encode)([Fg,oe,{value:De,expiresAt:He.expiresAt,version:He.version,residencyId:He.residencyId,nodeId:He.nodeId,user:He.user}])}else V=(0,Ze.encode)([Fg,oe])}catch(X){V=(0,Ze.encode)([Fg,oe,{error:X.message}])}e.send(V);break}case Fg:{let{resolve:oe,reject:V,tableId:X,key:de}=g.get(B[1]),me=B[2];if(me?.error)V(new Error(me.error));else if(me){let ae;jm(()=>{let Ie=Pc[X].decoder.decode(me.value);me.value=Ie,me.key=de,oe(me)||ae&&setTimeout(()=>ae.forEach(Ym),6e4).unref()},d?.rootStore,Ie=>{let He=Lf(Ie,de);return ae||(ae=[]),ae.push(He),He})}else oe();g.delete(B[1]);break}case DF:{Gn=D;let oe,V,X=!1;if(h){if(u!==h.databaseName&&!h.then){le.error?.("Subscription request for wrong database",u,h.databaseName);return}}else h=f.get(u);if(le.debug?.(s,"received subscription request for",u,"at",Gn),!h){let Oe;h=new Promise(Gt=>{le.debug?.("Waiting for subscription to database "+u),Oe=Gt}),h.ready=Oe,Ya.set(u,h)}if(r.name)V=cr().subscribe(r.name),V.then(async Oe=>{oe=Oe;for await(let Gt of oe){let It=Gt.value;if(!(It?.replicates===!0||It?.replicates?.receives||It?.subscriptions?.some(Or=>(Or.database||Or.schema)===u&&Or.publish!==!1))){X=!0,e.send((0,Ze.encode)([gd])),pn(1008,`Unauthorized database subscription to ${u}`);return}}},Oe=>{le.error?.(s,"Error subscribing to HDB nodes",Oe)});else if(!(r?.role?.permission?.super_user||r.replicates)){e.send((0,Ze.encode)([gd])),pn(1008,`Unauthorized database subscription to ${u}`);return}if(Lr&&(le.debug?.(s,"stopping previous subscription",u),Lr.emit("close")),Gn.length===0)return;let de=Gn[0],me=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,qn=a((Oe,Gt)=>{if(Oe.type==="end_txn"){ae.txnTime&&(o[i]!==66&&le.error?.("Invalid encoding of message"),_o(9),_o(Yg),m(rt=Gt),bi()),i=c,ae.txnTime=0;return}let It=Oe.nodeId,Or=Oe.tableId,Rt=He[Or];if(!Rt&&(Rt=He[Or]=me(h.tableById[Or]),!Rt))return le.debug?.("Not subscribed to table",Or);let As=Rt.table,Ct=As.primaryStore,js=Ct.encoder;(Oe.extendedType&sE||!js.typedStructs)&&(js._mergeStructures(js.getStructures()),js.typedStructs&&(js.lastTypedStructuresLength=js.typedStructs.length));let gu=Ie[It];if(!(gu&&gu.startTime<Gt&&(!gu.endTime||gu.endTime>Gt)))return Vg&&le.trace?.(s,"skipping replication update",Oe.recordId,"to:",E,"from:",It,"subscribed:",Ie),gD();Vg&&le.trace?.(s,"sending replication update",Oe.recordId,"to:",E,"from:",It,"subscribed:",Ie);let XA=Oe.version;ae.txnTime!==XA&&(ae.txnTime&&(Vg&&le.trace?.(s,"new txn time, sending queued txn",ae.txnTime),o[i]!==66&&le.error?.("Invalid encoding of message"),bi()),ae.txnTime=XA,i=c,m(XA));let Uc=Oe.residencyId,ZA=Mf(Uc,As),fm;if(ZA&&!ZA.includes(E)){let Js=Mf(Oe.previousResidencyId,As);if(Js&&!Js.includes(E)&&(Oe.type==="put"||Oe.type==="patch")||As.getResidencyById)return gD();let Uf=Oe.recordId;le.trace?.(s,"sending invalidation",Uf,E,"from",It);let xf=0;Uc&&(xf|=Xc),Oe.previousResidencyId&&(xf|=Zc);let rR,_m=null;for(let SD in As.indices){if(!_m){if(rR=Oe.getValue(Ct,!0),!rR)break;_m={}}_m[SD]=rR[SD]}fm=Jc(Oe.version,Or,Uf,null,It,Oe.user,Oe.type==="put"||Oe.type==="patch"?"invalidate":Oe.type,js.encode(_m),xf,Uc,Oe.previousResidencyId,Oe.expiresAt)}function gD(){return le.trace?.(s,"skipping audit record",Oe.recordId),W||(W=setTimeout(()=>{W=null,(rt||0)+kF/2<De&&(Vg&&le.trace?.(s,"sending skipped sequence update",De),e.send((0,Ze.encode)([xF,De])))},kF).unref()),new Promise(setImmediate)}a(gD,"skipAuditRecord");let eR=js.typedStructs,tR=js.structures;if((eR?.length!=Rt.typed_length||tR?.length!=Rt.structure_length)&&(Rt.typed_length=eR?.length,Rt.structure_length=tR.length,le.debug?.(s,"send table struct",Rt.typed_length,Rt.structure_length),Rt.sentName||(Rt.sentName=!0),e.send((0,Ze.encode)([NN,{typedStructs:eR,structures:tR,attributes:As.attributes,schemaDefined:As.schemaDefined},Or,Rt.table.tableName]))),Uc&&!If[Uc]&&(e.send((0,Ze.encode)([vF,ZA,Uc])),If[Uc]=!0),fm)_o(fm.length),K(fm);else{let Js=Oe.encoded;Oe.extendedType&Br&&a_(()=>Oe.getValue(Ct),xf=>Lc(xf,Oe.recordId),Ct.rootStore);let Uf=Js[0]===66?8:0;_o(Js.length-Uf),K(Js,Uf),le.trace?.("wrote record",Oe.recordId,"length:",Js.length)}return e._socket.writableNeedDrain?new Promise(Js=>{le.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",Js)}):kt>um?new Promise(Js=>{ft=Js}):new Promise(setImmediate)},"sendAuditRecord"),bi=a(()=>{c-i>8?(e.send(o.subarray(i,c)),le.debug?.(s,"Sent message, size:",c-i),Mt(c-i,"bytes-sent",`${E}.${u}`,"replication","egress")):le.debug?.(s,"skipping empty transaction")},"sendQueuedData");Lr=new MN.EventEmitter,Lr.once("close",()=>{X=!0,oe?.end()});for(let{startTime:Oe}of Gn)Oe<De&&(De=Oe);(V||Promise.resolve()).then(async()=>{h=await h,d=h.auditStore,He=h.tableById.map(me),Ie=[];for(let{name:Gt,startTime:It,endTime:Or}of Gn){let Rt=Lg(Gt,d);le.debug?.("subscription to",Gt,"using local id",Rt,"starting",It),Ie[Rt]={startTime:It,endTime:Or}}vf(u),Dr||(Dr=Dl(Gt=>{Gt.databaseName===u&&vf(u)}),wf=Pp(Gt=>{Gt===u&&(e.send((0,Ze.encode)([gd])),pn())}),e.on("close",()=>{Dr?.remove(),wf?.remove()})),e.send((0,Ze.encode)([MF,Tp(h.auditStore),Gn.map(({name:Gt})=>Gt)]));let Oe=!0;do{isFinite(De)||(le.warn?.("Invalid sequence id "+De),pn(1008,"Invalid sequence id"+De));let Gt;if(Oe&&!X&&(Oe=!1,De===0)){let It=De,Or=zg(d);for(let Rt in S){if(!me(Rt))continue;let As=S[Rt];le.warn?.(`Fully copying ${Rt} table to ${E}`);for(let Ct of As.primaryStore.getRange({snapshot:!1,versions:!0})){if(X)return;if(Ct.localTime>=De){le.trace?.(s,"Copying record from",u,Rt,Ct.key,Ct.localTime),It=Math.max(Ct.localTime,It),Gt=!0,_n()[Ip]=1;let js=Jc(Ct.version,As.tableId,Ct.key,null,Or,null,"put",a_(()=>As.primaryStore.encoder.encode(Ct.value),gu=>Lc(gu,Ct.key)),Ct.metadataFlags&-256,Ct.residencyId,null,Ct.expiresAt);await qn({recordId:Ct.key,tableId:As.tableId,type:"put",getValue(){return Ct.value},encoded:js,version:Ct.version,residencyId:Ct.residencyId,nodeId:Or,extendedType:Ct.metadataFlags},Ct.localTime)}}}Gt&&qn({type:"end_txn"},De),_n()[Ip]=0,De=It}for(let{key:It,value:Or}of d.getRange({start:De||1,exclusiveStart:!0,snapshot:!1})){if(X)return;let Rt=St(Or);le.debug?.("sending audit record",new Date(It)),_n()[Ip]=It,De=It,await qn(Rt,It),Lr.startTime=It,Gt=!0}Gt&&qn({type:"end_txn"},De),_n()[Ip]=0,await ZF(d)}while(!X)}).catch(Oe=>{le.error?.(s,"Error handling subscription to node",Oe),pn(1008,"Error handling subscription to node")});break}}return}y.position=8;let I=!0,b,U;do{_n();let B=y.readInt();if(B===9&&y.getUint8(y.position)==Yg){y.position++,T=U=y.readFloat64(),_[PN]=T,_[DN]=Date.now(),_[LN]=JF,le.trace?.("received remote sequence update",T,u);break}let w=y.position,D=St(A,w,w+B),q=Pc[D.tableId];q||le.error?.(`No table found with an id of ${D.tableId}`);let Q;D.residencyId&&(Q=Cf[D.residencyId],le.trace?.(s,"received residency list",Q,D.type,D.recordId));try{let j=D.recordId;jm(()=>{b={table:q.name,id:j,type:D.type,nodeId:Dc.get(D.nodeId),residencyList:Q,timestamp:D.version,value:D.getValue(q),user:D.user,beginTxn:I,expiresAt:D.expiresAt}},d?.rootStore,F=>Lf(F,j))}catch(j){throw j.message+="typed structures for current decoder"+JSON.stringify(q.decoder.typedStructs),j}I=!1,le.trace?.(s,"received replication message",D.type,"id",b.id,"version",new Date(D.version),"nodeId",b.nodeId),_[PN]=D.version,_[DN]=Date.now(),_[LN]=QF,h.send(b),y.position=w+B}while(y.position<A.byteLength);Pf++,Mt(A.byteLength,"bytes-received",`${E}.${u}.${b?.table||"unknown_table"}`,"replication","ingest"),Pf>QA&&!Df&&(Df=!0,e.pause(),le.debug?.(`Commit backlog causing replication back-pressure, requesting that ${E} pause replication`)),h.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")}Pf--,Df&&(Df=!1,e.resume(),le.debug?.(`Replication resuming ${E}`)),ye.length>0&&await Promise.all(ye),le.trace?.("All blobs finished"),!N&&U&&(le.trace?.(s,"queuing confirmation of a commit at",U),setTimeout(()=>{e.send((0,Ze.encode)([BF,N])),le.trace?.(s,"sent confirmation of a commit at",N),N=null},toe)),N=U,le.debug?.("last sequence committed",new Date(U),u)}})}catch(y){le.error?.(s,"Error handling incoming replication message",y)}}),e.on("ping",Fn),e.on("pong",()=>{t.connection&&(t.connection.latency=performance.now()-Z,t.isSubscriptionConnection&&Nl({name:E,database:u,url:t.url,latency:t.connection.latency})),Z=null}),e.on("close",(A,y)=>{clearInterval(v),clearTimeout(H),clearInterval($),Lr&&Lr.emit("close"),fo&&fo.end();for(let[I,{reject:b}]of g)b(new Error(`Connection closed ${y?.toString()} ${A}`));le.debug?.(s,"closed",A,y?.toString())});function pn(A,y){e.isFinished=!0,e.close(A,y),t.connection?.emit("finished")}a(pn,"close");let Mr=new Set;async function Lc(A,y){let I=Wm(A);if(Mr.has(I)){le.debug?.("Blob already being sent",I);return}Mr.add(I);try{let b;kt++;for await(let U of A.stream())b&&(le.debug?.("Sending blob chunk",I,"length",b.length),e.send((0,Ze.encode)([qg,{fileId:I,size:A.size},b]))),b=U,e._socket.writableNeedDrain&&(le.debug?.("draining",I),await new Promise(B=>e._socket.once("drain",B)),le.debug?.("drained",I)),Mt(U.length,"bytes-sent",`${E}.${u}`,"replication","blob");le.debug?.("Sending final blob chunk",I,"length",b.length),e.send((0,Ze.encode)([qg,{fileId:I,size:A.size,finished:!0},b]))}catch(b){le.warn?.("Error sending blob",b,"blob id",I,"for record",y),e.send((0,Ze.encode)([qg,{fileId:I,finished:!0,error:b.toString()},Buffer.alloc(0)]))}finally{Mr.delete(I),kt--,kt<um&&ft?.()}}a(Lc,"sendBlobs");function Lf(A,y){let I=Wm(A),b=he.get(I);le.debug?.("Received transaction for record",y,"with blob",I,"has stream",!!b,"ended",!!b?.writableEnded),b?b.writableEnded&&he.delete(I):(b=new IN.PassThrough,he.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=Eo(()=>o_(U).saving,h.auditStore?.rootStore);return B&&(B.blobId=I,ye.push(B),B.finally(()=>{le.debug?.(`Finished receiving blob stream ${I}`),ye.splice(ye.indexOf(B),1)})),U}a(Lf,"receiveBlobs");function _a(){if(p||(p=!0,t.connection?.on("subscriptions-updated",_a)),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=h?.auditStore);try{for(let b of h?.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 j of b.subscriptions)if(j.subscribe&&(j.schema||j.database)===u){let F=j.table;S?.[F]?.replicate!==!1&&B.push(F)}w=!1}else for(let j in S)(w?S[j].replicate===!1:S[j].replicate)&&B.push(j);let D=d&&Lg(b.name,d),q=h?.dbisDB?.get([Symbol.for("seq"),D])??1,Q=Math.max(q?.seqId??1,(typeof b.start_time=="string"?new Date(b.start_time).getTime():b.start_time)??1);if(le.debug?.("Starting time recorded in db",b.name,D,u,q?.seqId,"start time:",Q,new Date(Q)),y!==b){let j=d&&Lg(y.name,d),F=h?.dbisDB?.get([Symbol.for("seq"),j])??1;for(let Ue of F?.nodes||[])Ue.name===b.name&&(Q=Ue.seqId,le.debug?.("Using sequence id from proxy node",y.name,Q))}if(D===void 0?le.warn("Starting subscription request from node",b,"but no node id found"):R.push(D),A.get(D)>Q&&(Q=A.get(D),le.debug?.("Updating start time from more recent txn recorded",y.name,Q)),Q===1&&$g)try{new URL($g).hostname===b.name&&E===b.name?(le.warn?.(`Requesting full copy of database ${u} from ${$g}`),Q=0):Q=Date.now()-6e4}catch(j){le.error?.("Error parsing leader URL",$g,j)}return le.trace?.(s,"defining subscription request",b.name,u,new Date(Q)),{name:b.name,replicateByDefault:w,tables:B,startTime:Q,endTime:b.end_time}});if(I)if(le.debug?.(s,"sending subscription request",I,h?.dbisDB?.path),clearTimeout(z),I.length>0)e.send((0,Ze.encode)([DF,I]));else{let b=a(()=>{let U=performance.now();z=setTimeout(()=>{fe<=U?pn(1008,"Connection has no subscriptions and is no longer used"):b()},se).unref()},"schedule_close");b()}}a(_a,"sendSubscriptionRequestUpdate");function Mf(A,y){if(!A)return;let I=Ft[A];return I||(I=y.getResidencyRecord(A),Ft[A]=I),I}a(Mf,"getResidence");function pa(A){return!(Ka&&Ka!="*"&&!Ka[A]&&!Ka.includes?.(A)&&!Ka.some?.(y=>y.name===A))}a(pa,"checkDatabaseAccess");function ha(A){if(h=h||f.get(A),!pa(A))throw new Error(`Access to database "${A}" is not permitted`);h||le.warn?.(`No database named "${A}" was declared and registered`),d=h?.auditStore,S||(S=Xe()?.[A]);let y=et();if(y===E)throw y?new Error("Should not connect to self",y):new Error("Node name not defined");return dm(y,A),!0}a(ha,"setDatabase");function dm(A,y){let I=Xe()?.[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}))})}le.trace?.("Sending database info for node",A,"database name",y),e.send((0,Ze.encode)([LF,A,y,b]))}a(dm,"sendNodeDBName");function vf(A){let y=Xe()?.[A],I=[];for(let b in y){if(Gn&&!Gn.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)([HF,I,A]))}a(vf,"sendDBSchema"),$=setInterval(()=>{for(let[A,y]of he)y.lastChunk+Ae<Date.now()&&(le.warn?.(`Timeout waiting for blob stream to finish ${A} for record ${y.recordId??"unknown"} from ${E}`),he.delete(A),y.end())},Ae).unref();let Mc=1,vc=[];return{end(){fo&&fo.end(),Lr&&Lr.emit("close")},getRecord(A){let y=Mc++;return new Promise((I,b)=>{let U=[UF,y,A.table.tableId,A.id];vc[A.table.tableId]||(U.push(A.table.tableName),vc[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=Mc++;return A.requestId=y,e.send((0,Ze.encode)([CN,A])),new Promise((I,b)=>{g.set(y,{resolve:I,reject:b})})}};function _o(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 m(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]){le.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 q=A.attributes[D],Q=w.find(j=>j.name===q.name);(!Q||Q.type!==q.type)&&(b?le.error?.(`Schema for '${u}.${A.table}' is defined locally, but attribute '${q.name}: ${q.type}' from '${E}' does not match local attribute ${Q?"'"+Q.name+": "+Q.type+"'":"which does not exist"}`):(U=!0,B||(q.indexed=!0),Q?w[w.indexOf(Q)]=q:w.push(q)))}return U?(le.debug?.("(Re)creating",A),_t({table:A.table,database:A.database,schemaDefined:A.schemaDefined,attributes:w,...y})):y}}var qF,Ze,$F,VF,le,MN,KF,YF,Cl,WF,IN,zF,DF,LF,MF,gd,vF,NN,UF,Fg,CN,Gg,xF,BF,HF,qg,jF,PN,DN,Ip,LN,JF,QF,eoe,$g,vN,Ya,Vg,kF,toe,FF,wN,Kg,GF,Sd,UN=Re(()=>{Le();Mi();lN();xN();ss();qF=M(ce());k();xu();Ze=require("msgpackr"),$F=require("ws"),VF=require("worker_threads"),le=M(ei());Op();MN=require("events"),KF=M(os()),YF=M(require("node:tls"));Ol();Cl=M(require("node:process")),WF=require("node:net");Ki();Rn();IN=require("node:stream"),zF=M(require("minimist")),DF=129,LF=140,MF=141,gd=142,vF=130,NN=132,UF=133,Fg=134,CN=136,Gg=137,xF=143,BF=144,HF=145,qg=146,jF=0,PN=1,DN=2,Ip=3,LN=4,JF=0,QF=1,eoe=(0,zF.default)(Cl.argv),$g=eoe.HDB_LEADER_URL??Cl.env.HDB_LEADER_URL,vN=new Map,Ya=new Map,Vg=!0,kF=300,toe=2,FF=3e4;a(Wg,"createWebSocket");GF=500,Sd=class extends MN.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??di(r)}static{a(this,"NodeReplicationConnection")}socket;startTime;retryTime=GF;retries=0;isConnected=!0;isFinished=!1;nodeSubscriptions;latency=0;replicateTablesByDefault;session;sessionResolve;sessionReject;async connect(){this.session||this.resetSession();let r=[];this.socket=await Wg(this.url,{serverName:this.nodeName,authorization:this.authorization});let n;le.debug?.(`Connecting to ${this.url}, db: ${this.databaseName}, process ${Cl.pid}`),this.socket.on("open",()=>{this.socket._socket.unref(),le[this.isConnected?"info":"warn"]?.(`Connected to ${this.url}, db: ${this.databaseName}`),this.retries=0,this.retryTime=GF,this.nodeSubscriptions&&Nl({name:this.nodeName,database:this.databaseName,url:this.url}),this.isConnected=!0,n=Cp(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"?(le.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"?le.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`):le.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&&hd({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();le.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(Cp,"replicateOverWS")});var Uo={};xe(Uo,{clearThisNodeName:()=>uoe,disableReplication:()=>ioe,enabled_databases:()=>Ka,forEachReplicatedDatabase:()=>ka,getThisNodeId:()=>zg,getThisNodeName:()=>et,getThisNodeUrl:()=>Fa,hostnameToUrl:()=>Zg,lastTimeInAuditStore:()=>Ap,monitorNodeCAs:()=>aG,replicateOperation:()=>foe,replication_certificate_authorities:()=>xo,sendOperationToNode:()=>Dp,servers:()=>noe,setReplicator:()=>lG,start:()=>soe,startOnMainThread:()=>_N,subscribeToNode:()=>bp,unsubscribeFromNode:()=>xg,urlToNodeName:()=>di});function soe(e){if(e.port||(e.port=Ps.default.get(x.OPERATIONSAPI_NETWORK_PORT)),e.securePort||(e.securePort=Ps.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 yp(e))t.set(di(s.url),s);ooe(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(),Cp(s,e,i?.user),s.on("error",l=>{l.code!=="ECONNREFUSED"&&ur.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&&ur.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=cr().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)){ur.warn("Revoked certificate used in attempt to connect to node",l.name,"certificate serial number",s.peerCertificate.serialNumber);return}else s.user=l;else ur.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:ur.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(xo);c.options.availableCAs&&l.push(...c.options.availableCAs.values());let u={...c.options,ca:l};c.updatedContext=Xg.createSecureContext(u)}catch(l){ur.error("Error creating replication TLS config",l)}},"updateContexts");s.secureContextsListeners.push(i),n.push(i),Ps.default.get(x.REPLICATION_ENABLEROOTCAS)!==!1&&i()}aG(()=>{for(let s of n)s()})}function aG(e){let t=0;_d(r=>{r?.ca&&(xo.add(r.ca),xo.size!==t&&(t=xo.size,e?.()))})}function ioe(e=!0){oG=e}function ooe(e){oG||(Xe(),Ka=e.databases,ka(e,(t,r)=>{if(!t){let n=e.databaseSubscriptions||Ya;for(let[s,i]of Jg){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];lG(r,s,e),vN.get(s)?.forEach(i=>i(s))}}))}function lG(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 cG extends Wr{static{a(this,"Replicator")}static connection;static subscription;static async subscribe(){let i=r.databaseSubscriptions||Ya,o=i.get(e),c=o?.tableById||[];c[t.tableId]=t;let l=o?.ready;if(ur.trace("Setting up replicator subscription to database",e),!o?.auditStore)return this.subscription=o=new Vn,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 p=coe(_,cG.subscription,e);p?.isConnected&&!u.has(p)&&(!f||p.latency<f.latency)&&(f=p)}if(!f)throw l||new sG.ServerError("No connection to any other nodes are available",502);let d={requestId:roe++,table:t,entry:i,id:i.key};u.add(f);try{return await f.getRecord(d)}catch(_){if(f.isConnected)throw _;ur.warn("Error in load from node",Qg,_),l||(l=_)}}while(!0)}}}static isReplicator=!0},{intermediateSource:!0})}function aoe(e,t,r,n,s){let i=Jg.get(e);i||(i=new Map,Jg.set(e,i));let o=i.get(r);if(o)return o;if(t)return i.set(r,o=new Sd(e,t,r,n,s)),o.connect(),o.once("finished",()=>i.delete(r)),o}function coe(e,t,r){let n=eG.get(e);n||(n=new Map,eG.set(e,n));let s=n.get(r);if(s)return s;let i=cr().primaryStore.get(e);return i?.url&&(s=new Sd(i.url,t,r,e,i.authorization),n.set(r,s),s.connect(),s.once("finished",()=>n.delete(r))),s}async function Dp(e,t,r){r||(r={}),r.serverName=e.name;let n=await Wg(e.url,r),s=Cp(n,{},{});return new Promise((i,o)=>{n.on("open",()=>{i(s.sendOperation(t))}),n.on("error",c=>{o(c)}),n.on("close",c=>{ur.info("Sending operation connection to "+e.url+" closed",c)})}).finally(()=>{n.close()})}function bp(e){try{iG.isMainThread&&ur.trace("Subscribing on main thread (should not happen in multi-threaded instance)",e.nodes[0].url,e.database);let t=Ya.get(e.database);if(!t){let n;t=new Promise(s=>{ur.info("Waiting for subscription to database "+e.database),n=s}),t.ready=n,Ya.set(e.database,t)}let r=aoe(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=>Rp(n,e.database)),e.replicateByDefault)}catch(t){ur.error("Error in subscription to node",e.nodes[0]?.url,t)}}async function xg({name:e,url:t,database:r}){ur.trace("Unsubscribing from node",e,t,r,"nodes",Array.from(cr().primaryStore.getRange({})));let n=Jg.get(t);if(n){let s=n.get(r);s&&(s.unsubscribe(),n.delete(r))}}function loe(){if(BN!==void 0)return BN;let e=Ps.default.get(x.OPERATIONSAPI_TLS_CERTIFICATE)||Ps.default.get(x.TLS_CERTIFICATE);if(e)return BN=new rG.X509Certificate((0,nG.readFileSync)(e)).subject?.match(/CN=(.*)/)?.[1]??null}function et(){return Qg||(Qg=Ps.default.get("replication_hostname")??di(Ps.default.get("replication_url"))??loe()??tG("operationsapi_network_secureport")??tG("operationsapi_network_port")??"127.0.0.1")}function uoe(){Qg=void 0}function tG(e){let t=Ps.default.get(e),r=t?.lastIndexOf?.(":");if(r>0)return t.slice(0,r)}function jg(e){let t=Ps.default.get(e),r=t?.lastIndexOf?.(":");return r>0?+t.slice(r+1).replace(/[\[\]]/g,""):+t}function zg(e){return Tp(e)?.[et()]}function Fa(){let e=Ps.default.get("replication_url");return e||Zg(et())}function Zg(e){let t=jg("replication_port");if(t)return`ws://${e}:${t}`;if(t=jg("replication_secureport"),t)return`wss://${e}:${t}`;if(t=jg("operationsapi_network_port"),t)return`ws://${e}:${t}`;if(t=jg("operationsapi_network_secureport"),t)return`wss://${e}:${t}`}function di(e){if(e)return new URL(e).hostname}function ka(e,t){for(let n of Object.getOwnPropertyNames(We))r(n);return Pp(n=>{r(n)}),Dl((n,s)=>{r(n.databaseName)});function r(n){let s=We[n];ur.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):doe(n)&&t(s,n,!1)}a(r,"forDatabase")}function doe(e){let t=We[e];for(let r in t)if(t[r].replicate)return!0}function Ap(e){for(let t of e.getKeys({limit:1,reverse:!0}))return t}async function foe(e){let t={message:""};if(e.replicated){e.replicated=!1,ur.trace?.("Replicating operation",e.operation,"to nodes",Ye.nodes.map(n=>n.name));let r=await Promise.allSettled(Ye.nodes.map(n=>Dp(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 Ps,ur,rG,nG,Xg,sG,iG,oG,roe,noe,xo,Ka,Jg,eG,BN,Qg,ss=Re(()=>{Le();ya();Au();UN();Ur();Ps=M(ce()),ur=M(J()),rG=require("crypto"),nG=require("fs");Op();Ol();k();lN();Xg=M(require("node:tls")),sG=M(pe()),iG=require("worker_threads"),roe=1,noe=[],xo=Ps.default.get(x.REPLICATION_ENABLEROOTCAS)!==!1?new Set(Xg.rootCertificates):new Set;a(soe,"start");a(aG,"monitorNodeCAs");a(ioe,"disableReplication");a(ooe,"assignReplicationSource");a(lG,"setReplicator");Jg=new Map;a(aoe,"getSubscriptionConnection");eG=new Map;a(coe,"getRetrievalConnectionByName");a(Dp,"sendOperationToNode");a(bp,"subscribeToNode");a(xg,"unsubscribeFromNode");a(loe,"getCommonNameFromCert");a(et,"getThisNodeName");a(uoe,"clearThisNodeName");Object.defineProperty(Ye,"hostname",{get(){return et()}});a(tG,"getHostFromListeningPort");a(jg,"getPortFromListeningPort");a(zg,"getThisNodeId");Ye.replication={getThisNodeId:zg,exportIdMapping:Tp};a(Fa,"getThisNodeUrl");a(Zg,"hostnameToUrl");a(di,"urlToNodeName");a(ka,"forEachReplicatedDatabase");a(doe,"hasExplicitlyReplicatedTable");a(Ap,"lastTimeInAuditStore");a(foe,"replicateOperation")});var Mp=P((qDe,pG)=>{"use strict";var Td=Rk(),{validateBySchema:Lp}=ct(),{common_validators:Ad,schema_regex:HN}=Bi(),dr=require("joi"),_oe=J(),poe=require("uuid").v4,rS=Co(),Rd=(k(),C(G)),hoe=require("util"),Wa=Jn(),{handleHDBError:Bo,hdb_errors:moe,ClientError:Ll}=pe(),{HDB_ERROR_MSGS:eS,HTTP_STATUS_CODES:Ho}=moe,{SchemaEventMsg:nS}=oi(),uG=ar(),{getDatabases:Eoe}=(Le(),C(st)),{transformReq:yd}=ie(),{replicateOperation:dG}=(ss(),C(Uo)),{cleanupOrphans:GDe}=(Rn(),C(vu)),tS=dr.string().min(1).max(Ad.schema_length.maximum).pattern(HN).messages({"string.pattern.base":"{:#label} "+Ad.schema_format.message}),goe=dr.string().min(1).max(Ad.schema_length.maximum).pattern(HN).messages({"string.pattern.base":"{:#label} "+Ad.schema_format.message}).required(),Soe=dr.string().min(1).max(Ad.schema_length.maximum).pattern(HN).messages({"string.pattern.base":"{:#label} "+Ad.schema_format.message,"any.required":"'primary_key' is required","string.base":"'primary_key' must be a string"}).required();pG.exports={createSchema:Toe,createSchemaStructure:fG,createTable:Aoe,createTableStructure:_G,createAttribute:Noe,dropSchema:Roe,dropTable:yoe,dropAttribute:boe,getBackup:woe,cleanupOrphanBlobs:Ioe};async function Toe(e){let t=await fG(e);return rS.signalSchemaChange(new nS(process.pid,e.operation,e.schema)),t}a(Toe,"createSchema");async function fG(e){let t=Lp(e,dr.object({database:tS,schema:tS}));if(t)throw new Ll(t.message);if(yd(e),!await Td.checkSchemaExists(e.schema))throw Bo(new Error,eS.SCHEMA_EXISTS_ERR(e.schema),Ho.BAD_REQUEST,Rd.LOG_LEVELS.ERROR,eS.SCHEMA_EXISTS_ERR(e.schema),!0);return await Wa.createSchema(e),`database '${e.schema}' successfully created`}a(fG,"createSchemaStructure");async function Aoe(e){return yd(e),e.hash_attribute=e.primary_key??e.hash_attribute,await _G(e)}a(Aoe,"createTable");async function _G(e){let t=Lp(e,dr.object({database:tS,schema:tS,table:goe,residence:dr.array().items(dr.string().min(1)).optional(),hash_attribute:Soe}));if(t)throw new Ll(t.message);if(!await Td.checkSchemaTableExists(e.schema,e.table))throw Bo(new Error,eS.TABLE_EXISTS_ERR(e.schema,e.table),Ho.BAD_REQUEST,Rd.LOG_LEVELS.ERROR,eS.TABLE_EXISTS_ERR(e.schema,e.table),!0);let n={name:e.table,schema:e.schema,id:poe(),hash_attribute:e.hash_attribute};try{if(e.residence)if(global.clustering_on)n.residence=e.residence,await Wa.createTable(n,e);else throw Bo(new Error,"Clustering does not appear to be enabled. Cannot insert table with property 'residence'.",Ho.BAD_REQUEST);else await Wa.createTable(n,e);return`table '${e.schema}.${e.table}' successfully created.`}catch(s){throw s}}a(_G,"createTableStructure");async function Roe(e){let t=Lp(e,dr.object({database:dr.string(),schema:dr.string()}).or("database","schema").messages({"object.missing":"'database' is required"}));if(t)throw new Ll(t.message);yd(e);let r=await Td.checkSchemaExists(e.schema);if(r)throw Bo(new Error,r,Ho.NOT_FOUND,Rd.LOG_LEVELS.ERROR,r,!0);let n=await Td.schema_describe.describeSchema({schema:e.schema}),s=Object.keys(global.hdb_schema[e.schema]);await Wa.dropSchema(e),rS.signalSchemaChange(new nS(process.pid,e.operation,e.schema)),await uG.purgeSchemaTableStreams(e.schema,s);let i=await dG(e);return i.message=`successfully deleted '${e.schema}'`,i}a(Roe,"dropSchema");async function yoe(e){let t=Lp(e,dr.object({database:dr.string(),schema:dr.string(),table:dr.string().required()}));if(t)throw new Ll(t.message);yd(e);let r=await Td.checkSchemaTableExists(e.schema,e.table);if(r)throw Bo(new Error,r,Ho.NOT_FOUND,Rd.LOG_LEVELS.ERROR,r,!0);await Wa.dropTable(e),await uG.purgeTableStream(e.schema,e.table);let n=await dG(e);return n.message=`successfully deleted table '${e.schema}.${e.table}'`,n}a(yoe,"dropTable");async function boe(e){let t=Lp(e,dr.object({database:dr.string(),schema:dr.string(),table:dr.string().required(),attribute:dr.string().required()}));if(t)throw new Ll(t.message);yd(e);let r=await Td.checkSchemaTableExists(e.schema,e.table);if(r)throw Bo(new Error,r,Ho.NOT_FOUND,Rd.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",Ho.BAD_REQUEST,void 0,void 0,!0);if(Rd.TIME_STAMP_NAMES.indexOf(e.attribute)>=0)throw Bo(new Error,`cannot drop internal timestamp attribute: ${e.attribute}`,Ho.BAD_REQUEST,void 0,void 0,!0);try{return await Wa.dropAttribute(e),Ooe(e),rS.signalSchemaChange(new nS(process.pid,e.operation,e.schema,e.table,e.attribute)),`successfully deleted attribute '${e.attribute}'`}catch(n){throw _oe.error(`Got an error deleting attribute ${hoe.inspect(e)}.`),n}}a(boe,"dropAttribute");function Ooe(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(Ooe,"dropAttributeFromGlobal");async function Noe(e){yd(e);let t=Eoe()[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}`,Ho.BAD_REQUEST,void 0,void 0,!0);return await Wa.createAttribute(e),rS.signalSchemaChange(new nS(process.pid,e.operation,e.schema,e.table,e.attribute)),`attribute '${e.schema}.${e.table}.${e.attribute}' successfully created.`}a(Noe,"createAttribute");function woe(e){return Wa.getBackup(e)}a(woe,"getBackup");function Ioe(e){if(!e.database)throw new Ll('Must provide "database" name for search for orphaned blobs');if(!databases[e.database])throw new Ll(`Unknown database '${e.database}'`);let{cleanupOrphans:r}=(Rn(),C(vu));return r(databases[e.database],e.database),{message:"Orphaned blobs cleanup started, check logs for progress"}}a(Ioe,"cleanupOrphanBlobs")});var mG=P((VDe,hG)=>{"use strict";var{OPERATIONS_ENUM:Coe}=(k(),C(G)),kN=class{static{a(this,"ReadAuditLogObject")}constructor(t,r,n=void 0,s=void 0){this.operation=Coe.READ_AUDIT_LOG,this.schema=t,this.table=r,this.search_type=n,this.search_values=s}};hG.exports=kN});var FN=P((WDe,AG)=>{"use strict";var Poe=Jn(),YDe=mG(),sS=ie(),iS=(k(),C(G)),Doe=ce(),{handleHDBError:EG,hdb_errors:Loe}=pe(),{HDB_ERROR_MSGS:gG,HTTP_STATUS_CODES:SG}=Loe,Moe=Object.values(iS.READ_AUDIT_LOG_SEARCH_TYPES_ENUM),TG="To use this operation audit log must be enabled in harperdb-config.yaml";AG.exports=voe;async function voe(e){if(sS.isEmpty(e.schema))throw new Error(gG.SCHEMA_REQUIRED_ERR);if(sS.isEmpty(e.table))throw new Error(gG.TABLE_REQUIRED_ERR);if(!Doe.get(iS.CONFIG_PARAMS.LOGGING_AUDITLOG))throw EG(new Error,TG,SG.BAD_REQUEST,iS.LOG_LEVELS.ERROR,TG,!0);let t=sS.checkSchemaTableExist(e.schema,e.table);if(t)throw EG(new Error,t,SG.NOT_FOUND,iS.LOG_LEVELS.ERROR,t,!0);if(!sS.isEmpty(e.search_type)&&Moe.indexOf(e.search_type)<0)throw new Error(`Invalid search_type '${e.search_type}'`);return await Poe.readAuditLog(e)}a(voe,"readAuditLog")});var yG=P((jDe,RG)=>{"use strict";var{OPERATIONS_ENUM:Uoe}=(k(),C(G)),GN=class{static{a(this,"GetBackupObject")}constructor(t,r,n=void 0,s=void 0){this.operation=Uoe.GET_BACKUP,this.schema=t,this.table=r}};RG.exports=GN});var NG=P((ZDe,OG)=>{"use strict";var xoe=Jn(),QDe=yG(),qN=ie(),Boe=(k(),C(G)),XDe=ce(),{handleHDBError:Hoe,hdb_errors:koe}=pe(),{HDB_ERROR_MSGS:bG,HTTP_STATUS_CODES:Foe}=koe;OG.exports=Goe;async function Goe(e){if(qN.isEmpty(e.schema))throw new Error(bG.SCHEMA_REQUIRED_ERR);if(qN.isEmpty(e.table))throw new Error(bG.TABLE_REQUIRED_ERR);let t=qN.checkSchemaTableExist(e.schema,e.table);if(t)throw Hoe(new Error,t,Foe.NOT_FOUND,Boe.LOG_LEVELS.ERROR,t,!0);return await xoe.getBackup(read_audit_log_object)}a(Goe,"getBackup")});var PG=P((tLe,CG)=>{"use strict";var qoe=ce(),za=require("joi"),$oe=ct(),wG=require("moment"),Voe=require("fs-extra"),$N=require("path"),Koe=require("lodash"),vp=(k(),C(G)),{LOG_LEVELS:Ml}=(k(),C(G)),Yoe="YYYY-MM-DD hh:mm:ss",Woe=$N.resolve(__dirname,"../logs");CG.exports=function(e){return $oe.validateBySchema(e,zoe)};var zoe=za.object({from:za.custom(IG),until:za.custom(IG),level:za.valid(Ml.NOTIFY,Ml.FATAL,Ml.ERROR,Ml.WARN,Ml.INFO,Ml.DEBUG,Ml.TRACE),order:za.valid("asc","desc"),limit:za.number().min(1),start:za.number().min(0),log_name:za.custom(joe)});function IG(e,t){if(wG(e,wG.ISO_8601).format(Yoe)==="Invalid date")return t.message(`'${t.state.path[0]}' date '${e}' is invalid.`)}a(IG,"validateDatetime");function joe(e,t){if(Koe.invert(vp.LOG_NAMES)[e]===void 0)return t.message(`'log_name' '${e}' is invalid.`);let n=qoe.get(vp.HDB_SETTINGS_NAMES.LOG_PATH_KEY),s=e===void 0?vp.LOG_NAMES.HDB:e,i=s===vp.LOG_NAMES.INSTALL?$N.join(Woe,vp.LOG_NAMES.INSTALL):$N.join(n,s);return Voe.existsSync(i)?null:t.message(`'log_name' '${e}' does not exist.`)}a(joe,"validateReadLogPath")});var KN=P((nLe,LG)=>{"use strict";var oS=(k(),C(G)),Joe=J(),Qoe=ce(),Xoe=PG(),VN=require("path"),DG=require("fs-extra"),{once:Zoe}=require("events"),{handleHDBError:eae,hdb_errors:tae}=pe(),{PACKAGE_ROOT:rae}=at(),nae=VN.join(rae,"logs"),sae=1e3,iae=200;LG.exports=oae;async function oae(e){let t=Xoe(e);if(t)throw eae(t,t.message,tae.HTTP_STATUS_CODES.BAD_REQUEST,void 0,void 0,!0);let r=Qoe.get(oS.HDB_SETTINGS_NAMES.LOG_PATH_KEY),n=e.log_name===void 0?oS.LOG_NAMES.HDB:e.log_name,s=n===oS.LOG_NAMES.INSTALL?VN.join(nae,oS.LOG_NAMES.INSTALL):VN.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?sae:e.limit,_=e.order===void 0?void 0:e.order,p=e.start===void 0?0:e.start,h=p+d,S=0;_==="desc"&&!l&&!f&&(S=Math.max(DG.statSync(s).size-(h+5)*iae,0));let g=DG.createReadStream(s,{start:S});g.on("error",H=>{Joe.error(H)});let R=0,E=[],T="",N;g.on("data",H=>{let Z=/(?:^|\n)(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:[\d\.]+Z) \[(.+?)]: /g;H=T+H;let W=0,$;for(;($=Z.exec(H))&&!g.destroyed;){N&&(N.message=H.slice(W,$.index),v(N));let[se,z,fe]=$,ue=fe.split("] ["),ee=ue[0],Ae=ue[1];ue.splice(0,2),N={timestamp:z,thread:ee,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 Z,W,$;switch(!0){case(i&&c&&u):Z=new Date(H.timestamp),W=new Date(l),$=new Date(f),H.level===o&&Z>=W&&Z<=$&&R<p?R++:H.level===o&&Z>=W&&Z<=$&&(ja(H,_,E),R++,R===h&&g.destroy());break;case(i&&c):Z=new Date(H.timestamp),W=new Date(l),H.level===o&&Z>=W&&R<p?R++:H.level===o&&Z>=W&&(ja(H,_,E),R++,R===h&&g.destroy());break;case(i&&u):Z=new Date(H.timestamp),$=new Date(f),H.level===o&&Z<=$&&R<p?R++:H.level===o&&Z<=$&&(ja(H,_,E),R++,R===h&&g.destroy());break;case(c&&u):Z=new Date(H.timestamp),W=new Date(l),$=new Date(f),Z>=W&&Z<=$&&R<p?R++:Z>=W&&Z<=$&&(ja(H,_,E),R++,R===h&&g.destroy());break;case i:H.level===o&&R<p?R++:H.level===o&&(ja(H,_,E),R++,R===h&&g.destroy());break;case c:Z=new Date(H.timestamp),W=new Date(l),Z>=W&&R<p?R++:Z>=W&&R>=p&&(ja(H,_,E),R++,R===h&&g.destroy());break;case u:Z=new Date(H.timestamp),$=new Date(f),Z<=$&&R<p?R++:Z<=$&&R>=p&&(ja(H,_,E),R++,R===h&&g.destroy());break;default:R<p?R++:(ja(H,_,E),R++,R===h&&g.destroy())}}return a(v,"onLogMessage"),await Zoe(g,"close"),E}a(oae,"readLog");function ja(e,t,r){t==="desc"?aae(e,r):t==="asc"?cae(e,r):r.push(e)}a(ja,"pushLineToResult");function aae(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(aae,"insertDescending");function cae(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(cae,"insertAscending")});var aS=P((lLe,xG)=>{"use strict";var YN=require("joi"),{string:bd,boolean:MG,date:lae}=YN.types(),uae=ct(),{validateSchemaExists:iLe,validateTableExists:oLe,validateSchemaName:aLe}=Bi(),dae=(k(),C(G)),fae=yt(),vG=ce();vG.initSync();var cLe=bd.invalid(vG.get(dae.CONFIG_PARAMS.CLUSTERING_NODENAME)??"node_name").pattern(fae.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),UG={operation:bd.valid("add_node","update_node","set_node_replication"),node_name:bd.optional(),subscriptions:YN.array().items({table:bd.optional(),schema:bd.optional(),database:bd.optional(),subscribe:MG.required(),publish:MG.required().custom(pae),start_time:lae.iso()})};function _ae(e){return uae.validateBySchema(e,YN.object(UG))}a(_ae,"addUpdateNodeValidator");function pae(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(pae,"checkForFalsy");xG.exports={addUpdateNodeValidator:_ae,validation_schema:UG}});var Od=P((dLe,BG)=>{"use strict";var WN=class{static{a(this,"Node")}constructor(t,r,n){this.name=t,this.subscriptions=r,this.system_info=n}},zN=class{static{a(this,"NodeSubscription")}constructor(t,r,n,s){this.schema=t,this.table=r,this.publish=n,this.subscribe=s}};BG.exports={Node:WN,NodeSubscription:zN}});var kG=P((_Le,HG)=>{"use strict";var hae=(k(),C(G)).OPERATIONS_ENUM,jN=class{static{a(this,"UpsertObject")}constructor(t,r,n,s=void 0){this.operation=hae.UPSERT,this.schema=t,this.table=r,this.records=n,this.__origin=s}};HG.exports=jN});var Up=P((hLe,FG)=>{"use strict";var JN=class{static{a(this,"RemotePayloadObject")}constructor(t,r,n,s){this.operation=t,this.node_name=r,this.subscriptions=n,this.system_info=s}},QN=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)}};FG.exports={RemotePayloadObject:JN,RemotePayloadSubscription:QN}});var qG=P((ELe,GG)=>{"use strict";var XN=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}};GG.exports=XN});var VG=P((yLe,$G)=>{"use strict";var mae=qG(),SLe=qt(),TLe=pt(),Eae=J(),{getSchemaPath:ALe,getTransactionAuditStorePath:RLe}=gt(),{getDatabases:gae}=(Le(),C(st));$G.exports=Sae;async function Sae(e){let t=new mae;try{let r=gae()[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){Eae.warn(`unable to stat table dbi due to ${r}`)}return t}a(Sae,"lmdbGetTableSize")});var YG=P((OLe,KG)=>{"use strict";var ZN=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}};KG.exports=ZN});var ko=P((DLe,JG)=>{"use strict";var Tae=require("fs-extra"),Aae=require("path"),tn=require("systeminformation"),Ja=J(),WG=ar(),wLe=yt(),Nd=(k(),C(G)),Rae=VG(),yae=wo(),{getThreadInfo:zG}=nt(),xp=ce();xp.initSync();var bae=YG(),{openEnvironment:ILe}=pt(),{getSchemaPath:CLe}=gt(),{database:PLe,databases:ew}=(Le(),C(st)),cS;JG.exports={getHDBProcessInfo:sw,getNetworkInfo:ow,getDiskInfo:iw,getMemoryInfo:nw,getCPUInfo:rw,getTimeInfo:tw,getSystemInformation:aw,systemInformation:Oae,getTableSize:cw,getMetrics:lw};function tw(){return tn.time()}a(tw,"getTimeInfo");async function rw(){try{let{family:e,model:t,stepping:r,revision:n,voltage:s,speedmin:i,speedmax:o,governor:c,socket:l,cache:u,...f}=await tn.cpu();f.cpu_speed=await tn.cpuCurrentSpeed();let{raw_currentload:d,raw_currentload_idle:_,raw_currentload_irq:p,raw_currentload_nice:h,raw_currentload_system:S,raw_currentload_user:g,cpus:R,...E}=await tn.currentLoad();return E.cpus=[],R.forEach(T=>{let{raw_load:N,raw_load_idle:v,raw_load_irq:H,raw_load_nice:Z,raw_load_system:W,raw_load_user:$,...se}=T;E.cpus.push(se)}),f.current_load=E,f}catch(e){return Ja.error(`error in getCPUInfo: ${e}`),{}}}a(rw,"getCPUInfo");async function nw(){try{let{buffers:e,cached:t,slab:r,buffcache:n,...s}=await tn.mem();return Object.assign(s,process.memoryUsage())}catch(e){return Ja.error(`error in getMemoryInfo: ${e}`),{}}}a(nw,"getMemoryInfo");async function sw(){let e={core:[],clustering:[]};try{let t=await tn.processes(),r;try{r=Number.parseInt(await Tae.readFile(Aae.join(xp.get(Nd.CONFIG_PARAMS.ROOTPATH),Nd.HDB_PID_FILE),"utf8"))}catch(n){if(n.code===Nd.NODE_ERROR_CODES.ENOENT)Ja.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 Ja.error(`error in getHDBProcessInfo: ${t}`),e}}a(sw,"getHDBProcessInfo");async function iw(){let e={};try{if(!xp.get(Nd.CONFIG_PARAMS.OPERATIONSAPI_SYSINFO_DISK))return e;let{rIO_sec:t,wIO_sec:r,tIO_sec:n,ms:s,...i}=await tn.disksIO();e.io=i;let{rx_sec:o,tx_sec:c,wx_sec:l,...u}=await tn.fsStats();return e.read_write=u,e.size=await tn.fsSize(),e}catch(t){return Ja.error(`error in getDiskInfo: ${t}`),e}}a(iw,"getDiskInfo");async function ow(){let e={default_interface:null,latency:{},interfaces:[],stats:[],connections:[]};try{return xp.get(Nd.CONFIG_PARAMS.OPERATIONSAPI_SYSINFO_NETWORK)&&(e.default_interface=await tn.networkInterfaceDefault(),e.latency=await tn.inetChecksite("google.com"),(await tn.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 tn.networkStats()).forEach(n=>{let{rx_sec:s,tx_sec:i,ms:o,...c}=n;e.stats.push(c)})),e}catch(t){return Ja.error(`error in getNetworkInfo: ${t}`),e}}a(ow,"getNetworkInfo");async function aw(){if(cS!==void 0)return cS;let e={};try{let{codepage:t,logofile:r,serial:n,build:s,servicepack:i,uefi:o,...c}=await tn.osInfo();e=c;let l=await tn.versions("node, npm");return e.node_version=l.node,e.npm_version=l.npm,cS=e,cS}catch(t){return Ja.error(`error in getSystemInformation: ${t}`),e}}a(aw,"getSystemInformation");async function cw(){let e=[],t=await yae.describeAll();for(let r of Object.values(t))for(let n of Object.values(r))e.push(await Rae(n));return e}a(cw,"getTableSize");async function lw(){let e={};for(let t in ew){let r=e[t]={},n=r.tables={};for(let s in ew[t])try{let i=ew[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){Ja.notify(`Error getting stats for table ${s}: ${i}`)}}return e}a(lw,"getMetrics");async function jG(){if(xp.get(Nd.CONFIG_PARAMS.CLUSTERING_ENABLED)){let{jsm:e}=await WG.getNATSReferences(),t=await WG.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(jG,"getNatsStreamInfo");async function Oae(e){let t=new bae;if(!Array.isArray(e.attributes)||e.attributes.length===0)return t.system=await aw(),t.time=tw(),t.cpu=await rw(),t.memory=await nw(),t.disk=await iw(),t.network=await ow(),t.harperdb_processes=await sw(),t.table_size=await cw(),t.metrics=await lw(),t.threads=await zG(),t.replication=await jG(),t;for(let r=0;r<e.attributes.length;r++)switch(e.attributes[r]){case"system":t.system=await aw();break;case"time":t.time=tw();break;case"cpu":t.cpu=await rw();break;case"memory":t.memory=await nw();break;case"disk":t.disk=await iw();break;case"network":t.network=await ow();break;case"harperdb_processes":t.harperdb_processes=await sw();break;case"table_size":t.table_size=await cw();break;case"database_metrics":case"metrics":t.metrics=await lw();break;case"threads":t.threads=await zG();break;case"replication":t.replication=await jG();break;default:break}return t}a(Oae,"systemInformation")});var Fo=P((xLe,eq)=>{"use strict";var Nae=In(),uw=ie(),wae=require("util"),vl=(k(),C(G)),QG=ce();QG.initSync();var Iae=qO(),XG=jr(),{Node:MLe,NodeSubscription:vLe}=Od(),Cae=ju(),Pae=kG(),{RemotePayloadObject:Dae,RemotePayloadSubscription:Lae}=Up(),{handleHDBError:Mae,hdb_errors:vae}=pe(),{HTTP_STATUS_CODES:Uae,HDB_ERROR_MSGS:xae}=vae,Bae=ai(),Hae=ko(),{packageJson:kae}=at(),{getDatabases:Fae}=(Le(),C(st)),ULe=wae.promisify(Iae.authorize),Gae=XG.searchByHash,qae=XG.searchByValue;eq.exports={isEmpty:$ae,getNodeRecord:Vae,upsertNodeRecord:Kae,buildNodePayloads:Yae,checkClusteringEnabled:Wae,getAllNodeRecords:zae,getSystemInfo:jae,reverseSubscription:ZG};function $ae(e){return e==null}a($ae,"isEmpty");async function Vae(e){let t=new Cae(vl.SYSTEM_SCHEMA_NAME,vl.SYSTEM_TABLE_NAMES.NODE_TABLE_NAME,[e],["*"]);return Gae(t)}a(Vae,"getNodeRecord");async function Kae(e){let t=new Pae(vl.SYSTEM_SCHEMA_NAME,vl.SYSTEM_TABLE_NAMES.NODE_TABLE_NAME,[e]);return Nae.upsert(t)}a(Kae,"upsertNodeRecord");function ZG(e){if(uw.isEmpty(e.subscribe)||uw.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(ZG,"reverseSubscription");function Yae(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=uw.getTableHashAttribute(l,u),{subscribe:d,publish:_}=ZG(c),p=Fae()[l]?.[u],h=new Lae(l,u,f,_,d,c.start_time,p.schemaDefined?p.attributes:void 0);s.push(h)}return new Dae(r,t,s,n)}a(Yae,"buildNodePayloads");function Wae(){if(!QG.get(vl.CONFIG_PARAMS.CLUSTERING_ENABLED))throw Mae(new Error,xae.CLUSTERING_NOT_ENABLED,Uae.BAD_REQUEST,void 0,void 0,!0)}a(Wae,"checkClusteringEnabled");async function zae(){let e=new Bae(vl.SYSTEM_SCHEMA_NAME,vl.SYSTEM_TABLE_NAMES.NODE_TABLE_NAME,"name","*",void 0,["*"]);return Array.from(await qae(e))}a(zae,"getAllNodeRecords");async function jae(){let e=await Hae.getSystemInformation();return{hdb_version:kae.version,node_version:e.node_version,platform:e.platform}}a(jae,"getSystemInfo")});var dw=P((HLe,cq)=>{"use strict";var lS=ar(),tq=ie(),rq=yt(),nq=(k(),C(G)),uS=J(),sq=Mp(),Jae=z_(),{RemotePayloadObject:Qae}=Up(),{handleHDBError:iq,hdb_errors:Xae}=pe(),{HTTP_STATUS_CODES:oq}=Xae,{NodeSubscription:aq}=Od();cq.exports=Zae;async function Zae(e,t){let r;try{r=await lS.request(`${t}.${rq.REQUEST_SUFFIX}`,new Qae(nq.OPERATIONS_ENUM.DESCRIBE_ALL,t,void 0,void 0)),uS.trace("Response from remote describe all request:",r)}catch(o){uS.error(`addNode received error from describe all request to remote node: ${o}`);let c=lS.requestErrorHandler(o,"add_node",t);throw iq(new Error,c,oq.INTERNAL_SERVER_ERROR,"error",c)}if(r.status===rq.UPDATE_REMOTE_RESPONSE_STATUSES.ERROR){let o=`Error returned from remote node ${t}: ${r.message}`;throw iq(new Error,o,oq.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===nq.SYSTEM_SCHEMA_NAME){await lS.createLocalTableStream(l,c);let h=new aq(l,c,o.publish,o.subscribe);h.start_time=o.start_time,i.push(h);continue}let u=tq.doesSchemaExist(l),f=n[l]!==void 0,d=c?tq.doesTableExist(l,c):!0,_=c?n?.[l]?.[c]!==void 0:!0;if(!u&&!f||!d&&!_){s.push(o);continue}if(!u&&f&&(uS.trace(`addNode creating schema: ${l}`),await sq.createSchema({operation:"create_schema",schema:l})),!d&&_){uS.trace(`addNode creating table: ${c} in schema: ${l} with attributes ${JSON.stringify(n[l][c].attributes)}`);let h=new Jae(l,c,n[l][c].hash_attribute);n[l][c].attributes&&(h.attributes=n[l][c].attributes),await sq.createTable(h)}await lS.createLocalTableStream(l,c);let p=new aq(l,c,o.publish,o.subscribe);p.start_time=o.start_time,i.push(p)}return{added:i,skipped:s}}a(Zae,"reviewSubscriptions")});var Ul={};xe(Ul,{addNodeBack:()=>sce,removeNodeBack:()=>ice,setNode:()=>nce});async function nce(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=di(t)):t=Zg(r);let n=(0,uq.validateBySchema)(e,rce);if(n)throw(0,Go.handleHDBError)(n,n.message,tce.BAD_REQUEST,void 0,void 0,!0);if(e.operation==="remove_node"){if(!t&&!r)throw new Go.ClientError("url or hostname is required for remove_node operation");let p=r,h=cr(),S=await h.get(p);if(!S)throw new Go.ClientError(p+" does not exist");try{await Dp({url:S.url},{operation:jt.REMOVE_NODE_BACK,name:S?.subscriptions?.length>0?et():p},void 0)}catch(g){as.warn(`Error removing node from target node ${p}, 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 h.delete(p),`Successfully removed '${p}' from cluster`}if(!t)throw new Go.ClientError("url required for this operation");let s=Fa();if(s==null)throw new Go.ClientError("replication url is missing from harperdb-config.yaml");let i,o,c;if(t?.startsWith("wss:")){i=await(0,Ds.getReplicationCert)();let p=await(0,Ds.getReplicationCertAuth)();if(!i)throw new Error("Unable to find a certificate to use for replication");i.options.is_self_signed?(o=await(0,Ds.createCsr)(),as.info("Sending CSR to target node:",t)):p&&(c=p.certificate,as.info("Sending CA named",p.name,"to target node",t))}let l={operation:jt.ADD_NODE_BACK,hostname:(0,Xa.get)(x.REPLICATION_HOSTNAME),target_hostname:r,url:s,csr:o,cert_auth:c,authorization:e.retain_authorization?e.authorization:null};if((0,Xa.get)(x.REPLICATION_SHARD)!==void 0&&(l.shard=(0,Xa.get)(x.REPLICATION_SHARD)),e.subscriptions?l.subscriptions=e.subscriptions.map(lq):l.subscriptions=null,e.hasOwnProperty("subscribe")||e.hasOwnProperty("publish")){let p=lq(e);l.subscribe=p.subscribe,l.publish=p.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 Dp({url:t},l,e)}catch(p){p.message=`Error returned from ${t}: `+p.message,as.warn("Error adding node:",t,"to cluster:",p),f=p}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&&(as.info("CSR response received from node:",t,"saving certificate and CA in hdb_certificate"),await(0,Ds.setCertTable)({name:ece.certificateFromPem(u.signingCA).issuer.getField("CN").value,certificate:u.signingCA,is_authority:!0}),u.certificate&&await(0,Ds.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 p={url:s,ca:c,replicates:!0,subscriptions:null};(0,Xa.get)(x.REPLICATION_SHARD)!==void 0&&(p.shard=(0,Xa.get)(x.REPLICATION_SHARD)),e.retain_authorization&&(p.authorization=e.authorization),e.start_time&&(p.start_time=e.start_time),await Mo(et(),p)}await Mo(u?u.nodeName:d.name??di(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 sce(e){as.trace("addNodeBack received request:",e);let t=await(0,Ds.signCertificate)(e),r;e.csr?(r=t.signingCA,as.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,as.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,Ds.getReplicationCertAuth)();if(n.replicates){let i={url:Fa(),ca:s?.certificate,replicates:!0,subscriptions:null};(0,Xa.get)(x.REPLICATION_SHARD)!==void 0&&(i.shard=(0,Xa.get)(x.REPLICATION_SHARD),t.shard=i.shard),e.start_time&&(i.start_time=e.start_time),e.authorization&&(i.authorization=e.authorization),await Mo(et(),i)}return await Mo(e.hostname,n),t.nodeName=et(),t.usingCA=s?.certificate,as.info("addNodeBack responding to:",e.url,"with CA named:",s?.name),t}async function ice(e){as.trace("removeNodeBack received request:",e),await cr().delete(e.name)}function lq(e){let{subscribe:t,publish:r}=e;return{...e,subscribe:r,publish:t}}var Ds,uq,Qa,Xa,as,Go,ece,tce,rce,xl=Re(()=>{Ds=M(os()),uq=M(ct()),Qa=M(require("joi")),Xa=M(ce());k();Op();Ol();ss();as=M(J()),Go=M(pe()),{pki:ece}=require("node-forge"),{HTTP_STATUS_CODES:tce}=Go.hdb_errors,rce=Qa.default.object({hostname:Qa.default.string(),verify_tls:Qa.default.boolean(),replicates:Qa.default.boolean(),subscriptions:Qa.default.array(),revoked_certificates:Qa.default.array(),shard:Qa.default.number()});a(nce,"setNode");a(sce,"addNodeBack");a(ice,"removeNodeBack");a(lq,"reverseSubscription")});var wd=P((WLe,fq)=>{"use strict";var{handleHDBError:dS,hdb_errors:oce}=pe(),{HTTP_STATUS_CODES:fS}=oce,{addUpdateNodeValidator:ace}=aS(),_S=J(),pS=(k(),C(G)),dq=yt(),cce=ie(),Bp=ar(),Hp=Fo(),fw=ce(),lce=dw(),{Node:uce,NodeSubscription:dce}=Od(),{broadcast:fce}=nt(),{setNode:_ce}=(xl(),C(Ul)),KLe=ce(),YLe=(k(),C(G)),pce="Unable to create subscriptions due to schema and/or tables not existing on the local or remote node",hce="Some subscriptions were unsuccessful due to schema and/or tables not existing on the local or remote node",mce=fw.get(pS.CONFIG_PARAMS.CLUSTERING_NODENAME);fq.exports=Ece;async function Ece(e,t=!1){if(_S.trace("addNode called with:",e),fw.get(pS.CONFIG_PARAMS.REPLICATION_URL)||fw.get(pS.CONFIG_PARAMS.REPLICATION_HOSTNAME))return _ce(e);Hp.checkClusteringEnabled();let r=ace(e);if(r)throw dS(r,r.message,fS.BAD_REQUEST,void 0,void 0,!0);let n=e.node_name;if(!t){let d=await Hp.getNodeRecord(n);if(!cce.isEmptyOrZeroLength(d))throw dS(new Error,`Node '${n}' has already been added, perform update_node to proceed.`,fS.BAD_REQUEST,void 0,void 0,!0)}let{added:s,skipped:i}=await lce(e.subscriptions,n),o={message:void 0,added:s,skipped:i};if(s.length===0)return o.message=pce,o;let c=Hp.buildNodePayloads(s,mce,pS.OPERATIONS_ENUM.ADD_NODE,await Hp.getSystemInfo()),l=[];for(let d=0,_=s.length;d<_;d++){let p=s[d];s[d].start_time===void 0&&delete s[d].start_time,l.push(new dce(p.schema,p.table,p.publish,p.subscribe))}_S.trace("addNode sending remote payload:",c);let u;try{u=await Bp.request(`${n}.${dq.REQUEST_SUFFIX}`,c)}catch(d){_S.error(`addNode received error from request: ${d}`);for(let p=0,h=s.length;p<h;p++){let S=s[p];S.publish=!1,S.subscribe=!1,await Bp.updateRemoteConsumer(S,n)}let _=Bp.requestErrorHandler(d,"add_node",n);throw dS(new Error,_,fS.INTERNAL_SERVER_ERROR,"error",_)}if(u.status===dq.UPDATE_REMOTE_RESPONSE_STATUSES.ERROR){let d=`Error returned from remote node ${n}: ${u.message}`;throw dS(new Error,d,fS.INTERNAL_SERVER_ERROR,"error",d)}_S.trace(u);for(let d=0,_=s.length;d<_;d++){let p=s[d];await Bp.updateRemoteConsumer(p,n),p.subscribe===!0&&await Bp.updateConsumerIterator(p.schema,p.table,n,"start")}let f=new uce(n,l,u.system_info);return await Hp.upsertNodeRecord(f),fce({type:"nats_update"}),i.length>0?o.message=hce:o.message=`Successfully added '${n}' to manifest`,o}a(Ece,"addNode")});var mw=P((JLe,pq)=>{"use strict";var{handleHDBError:_w,hdb_errors:gce}=pe(),{HTTP_STATUS_CODES:pw}=gce,{addUpdateNodeValidator:Sce}=aS(),kp=J(),hS=(k(),C(G)),_q=yt(),jLe=ie(),Fp=ar(),Gp=Fo(),hw=ce(),{cloneDeep:Tce}=require("lodash"),Ace=dw(),{Node:Rce,NodeSubscription:yce}=Od(),{broadcast:bce}=nt(),{setNode:Oce}=(xl(),C(Ul)),Nce="Unable to update subscriptions due to schema and/or tables not existing on the local or remote node",wce="Some subscriptions were unsuccessful due to schema and/or tables not existing on the local or remote node",Ice=hw.get(hS.CONFIG_PARAMS.CLUSTERING_NODENAME);pq.exports=Cce;async function Cce(e){if(kp.trace("updateNode called with:",e),hw.get(hS.CONFIG_PARAMS.REPLICATION_URL)??hw.get(hS.CONFIG_PARAMS.REPLICATION_HOSTNAME))return Oce(e);Gp.checkClusteringEnabled();let t=Sce(e);if(t)throw _w(t,t.message,pw.BAD_REQUEST,void 0,void 0,!0);let r=e.node_name,n,s=await Gp.getNodeRecord(r);s.length>0&&(n=Tce(s));let{added:i,skipped:o}=await Ace(e.subscriptions,r),c={message:void 0,updated:i,skipped:o};if(i.length===0)return c.message=Nce,c;let l=Gp.buildNodePayloads(i,Ice,hS.OPERATIONS_ENUM.UPDATE_NODE,await Gp.getSystemInfo());for(let f=0,d=i.length;f<d;f++){let _=i[f];kp.trace(`updateNode updating work stream for node: ${r} subscription:`,_),i[f].start_time===void 0&&delete i[f].start_time}kp.trace("updateNode sending remote payload:",l);let u;try{u=await Fp.request(`${r}.${_q.REQUEST_SUFFIX}`,l)}catch(f){kp.error(`updateNode received error from request: ${f}`);let d=Fp.requestErrorHandler(f,"update_node",r);throw _w(new Error,d,pw.INTERNAL_SERVER_ERROR,"error",d)}if(u.status===_q.UPDATE_REMOTE_RESPONSE_STATUSES.ERROR){let f=`Error returned from remote node ${r}: ${u.message}`;throw _w(new Error,f,pw.INTERNAL_SERVER_ERROR,"error",f)}kp.trace(u);for(let f=0,d=i.length;f<d;f++){let _=i[f];await Fp.updateRemoteConsumer(_,r),_.subscribe===!0?await Fp.updateConsumerIterator(_.schema,_.table,r,"start"):await Fp.updateConsumerIterator(_.schema,_.table,r,"stop")}return n||(n=[new Rce(r,[],u.system_info)]),await Pce(n[0],i,u.system_info),o.length>0?c.message=wce:c.message=`Successfully updated '${r}'`,c}a(Cce,"updateNode");async function Pce(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 yce(o.schema,o.table,o.publish,o.subscribe))}n.system_info=r,await Gp.upsertNodeRecord(n),bce({type:"nats_update"})}a(Pce,"updateNodeTable")});var Sq=P((XLe,gq)=>{"use strict";var Eq=require("joi"),{string:hq}=Eq.types(),Dce=ct(),mq=(k(),C(G)),Lce=ce(),Mce=yt();gq.exports=vce;function vce(e){let t=hq.invalid(Lce.get(mq.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=Eq.object({operation:hq.valid(mq.OPERATIONS_ENUM.REMOVE_NODE).required(),node_name:t});return Dce.validateBySchema(e,r)}a(vce,"removeNodeValidator")});var mS=P((eMe,bq)=>{"use strict";var{handleHDBError:Tq,hdb_errors:Uce}=pe(),{HTTP_STATUS_CODES:Aq}=Uce,xce=Sq(),qp=J(),Rq=Fo(),Bce=ie(),Id=(k(),C(G)),yq=yt(),Ew=ar(),gw=ce(),{RemotePayloadObject:Hce}=Up(),{NodeSubscription:kce}=Od(),Fce=W_(),Gce=al(),{broadcast:qce}=nt(),{setNode:$ce}=(xl(),C(Ul)),Vce=gw.get(Id.CONFIG_PARAMS.CLUSTERING_NODENAME);bq.exports=Kce;async function Kce(e){if(qp.trace("removeNode called with:",e),gw.get(Id.CONFIG_PARAMS.REPLICATION_URL)??gw.get(Id.CONFIG_PARAMS.REPLICATION_HOSTNAME))return $ce(e);Rq.checkClusteringEnabled();let t=xce(e);if(t)throw Tq(t,t.message,Aq.BAD_REQUEST,void 0,void 0,!0);let r=e.node_name,n=await Rq.getNodeRecord(r);if(Bce.isEmptyOrZeroLength(n))throw Tq(new Error,`Node '${r}' was not found.`,Aq.BAD_REQUEST,void 0,void 0,!0);n=n[0];let s=new Hce(Id.OPERATIONS_ENUM.REMOVE_NODE,Vce,[]),i,o=!1;for(let l=0,u=n.subscriptions.length;l<u;l++){let f=n.subscriptions[l];f.subscribe===!0&&await Ew.updateConsumerIterator(f.schema,f.table,r,"stop");try{await Ew.updateRemoteConsumer(new kce(f.schema,f.table,!1,!1),r)}catch(d){qp.error(d)}}try{i=await Ew.request(`${r}.${yq.REQUEST_SUFFIX}`,s),qp.trace("Remove node reply from remote node:",r,i)}catch(l){qp.error("removeNode received error from request:",l),o=!0}let c=new Fce(Id.SYSTEM_SCHEMA_NAME,Id.SYSTEM_TABLE_NAMES.NODE_TABLE_NAME,[r]);return await Gce.deleteRecord(c),qce({type:"nats_update"}),i?.status===yq.UPDATE_REMOTE_RESPONSE_STATUSES.ERROR||o?(qp.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(Kce,"removeNode")});var wq=P((rMe,Nq)=>{"use strict";var Oq=require("joi"),{string:Yce,array:Wce}=Oq.types(),zce=ct(),jce=aS();Nq.exports=Jce;function Jce(e){let t=Oq.object({operation:Yce.valid("configure_cluster").required(),connections:Wce.items(jce.validation_schema).required()});return zce.validateBySchema(e,t)}a(Jce,"configureClusterValidator")});var Sw=P((sMe,Lq)=>{"use strict";var Iq=(k(),C(G)),ES=J(),Qce=ie(),Xce=ce(),Zce=mS(),ele=wd(),tle=Fo(),rle=wq(),{handleHDBError:Cq,hdb_errors:nle}=pe(),{HTTP_STATUS_CODES:Pq}=nle,sle="Configure cluster complete.",ile="Failed to configure the cluster. Check the logs for more details.",ole="Configure cluster was partially successful. Errors occurred when attempting to configure the following nodes. Check the logs for more details.";Lq.exports=ale;async function ale(e){ES.trace("configure cluster called with:",e);let t=rle(e);if(t)throw Cq(t,t.message,Pq.BAD_REQUEST,void 0,void 0,!0);let r=await tle.getAllNodeRecords(),n=[];if(Xce.get(Iq.CONFIG_PARAMS.CLUSTERING_ENABLED)){for(let f=0,d=r.length;f<d;f++){let _=await Dq(Zce,{operation:Iq.OPERATIONS_ENUM.REMOVE_NODE,node_name:r[f].name},r[f].name);n.push(_)}ES.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 Dq(ele,d,d.node_name);s.push(_)}ES.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"&&(ES.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(Qce.isEmptyOrZeroLength(o))return{message:sle,connections:c};if(l)return{message:ole,failed_nodes:o,connections:c};throw Cq(new Error,ile,Pq.INTERNAL_SERVER_ERROR,void 0,void 0,!0)}a(ale,"configureCluster");async function Dq(e,t,r){try{return{node_name:r,result:await e(t)}}catch(n){return{node_name:r,error:n,status:"rejected"}}}a(Dq,"functionWrapper")});var xq=P((oMe,Uq)=>{"use strict";var $p=require("joi"),cle=ct(),{validateSchemaExists:Mq,validateTableExists:lle,validateSchemaName:vq}=Bi(),ule=$p.object({operation:$p.string().valid("purge_stream"),schema:$p.string().custom(Mq).custom(vq).optional(),database:$p.string().custom(Mq).custom(vq).optional(),table:$p.string().custom(lle).required()});function dle(e){return cle.validateBySchema(e,ule)}a(dle,"purgeStreamValidator");Uq.exports=dle});var Tw=P((cMe,Bq)=>{"use strict";var{handleHDBError:fle,hdb_errors:_le}=pe(),{HTTP_STATUS_CODES:ple}=_le,hle=xq(),mle=ar(),Ele=Fo();Bq.exports=gle;async function gle(e){e.schema=e.schema??e.database;let t=hle(e);if(t)throw fle(t,t.message,ple.BAD_REQUEST,void 0,void 0,!0);Ele.checkClusteringEnabled();let{schema:r,table:n,options:s}=e;return await mle.purgeTableStream(r,n,s),`Successfully purged table '${r}.${n}'`}a(gle,"purgeStream")});var TS=P((uMe,Vq)=>{"use strict";var Rw=Fo(),Sle=ar(),SS=ce(),Cd=(k(),C(G)),Bl=yt(),Tle=ie(),Aw=J(),{RemotePayloadObject:Ale}=Up(),{ErrorCode:Hq}=require("nats"),{parentPort:kq}=require("worker_threads"),{onMessageByType:Rle}=nt(),{getThisNodeName:yle}=(ss(),C(Uo)),{requestClusterStatus:ble}=(Op(),C(aF)),{getReplicationSharedStatus:Ole,getHDBNodeTable:Nle}=(Ol(),C(uN)),{CONFIRMATION_STATUS_POSITION:wle,RECEIVED_VERSION_POSITION:Ile,RECEIVED_TIME_POSITION:Cle,SENDING_TIME_POSITION:Ple,RECEIVING_STATUS_POSITION:Dle,RECEIVING_STATUS_RECEIVING:Lle}=(UN(),C(XF)),Fq=SS.get(Cd.CONFIG_PARAMS.CLUSTERING_ENABLED),Gq=SS.get(Cd.CONFIG_PARAMS.CLUSTERING_NODENAME);Vq.exports={clusterStatus:Mle,buildNodeStatus:$q};var qq;Rle("cluster-status",async e=>{qq(e)});async function Mle(){if(SS.get(Cd.CONFIG_PARAMS.REPLICATION_URL)||SS.get(Cd.CONFIG_PARAMS.REPLICATION_HOSTNAME)){let n;if(kq){kq.postMessage({type:"request-cluster-status"}),n=await new Promise(i=>{qq=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=Ole(u,l,o);c.lastCommitConfirmed=gS(f[wle]),c.lastReceivedRemoteTime=gS(f[Ile]),c.lastReceivedLocalTime=gS(f[Cle]),c.sendingMessage=gS(f[Ple]),c.lastReceivedStatus=f[Dle]===Lle?"Receiving":"Waiting"}}}else n=ble();n.node_name=yle();let s=Nle().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:Gq,is_enabled:Fq,connections:[]};if(!Fq)return e;let t=await Rw.getAllNodeRecords();if(Tle.isEmptyOrZeroLength(t))return e;let r=[];for(let n=0,s=t.length;n<s;n++)r.push($q(t[n],e.connections));return await Promise.allSettled(r),e}a(Mle,"clusterStatus");function gS(e){return e?e===1?"Copying":new Date(e).toUTCString():void 0}a(gS,"asDate");async function $q(e,t){let r=e.name,n=new Ale(Cd.OPERATIONS_ENUM.CLUSTER_STATUS,Gq,void 0,await Rw.getSystemInfo()),s,i,o=Bl.CLUSTER_STATUS_STATUSES.OPEN;try{let l=Date.now();s=await Sle.request(Bl.REQUEST_SUBJECT(r),n),i=Date.now()-l,s.status===Bl.UPDATE_REMOTE_RESPONSE_STATUSES.ERROR&&(o=Bl.CLUSTER_STATUS_STATUSES.CLOSED,Aw.error(`Error getting node status from ${r} `,s))}catch(l){Aw.warn(`Error getting node status from ${r}`,l),l.code===Hq.NoResponders?o=Bl.CLUSTER_STATUS_STATUSES.NO_RESPONDERS:l.code===Hq.Timeout?o=Bl.CLUSTER_STATUS_STATUSES.TIMEOUT:o=Bl.CLUSTER_STATUS_STATUSES.CLOSED}let c=new vle(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 Rw.upsertNodeRecord(l)}catch(l){Aw.error("Cluster status encountered an error updating system info for node:",r,l)}t.push(c)}a($q,"buildNodeStatus");function vle(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(vle,"NodeStatusObject")});var RS=P((fMe,Kq)=>{"use strict";var{handleHDBError:Ule,hdb_errors:xle}=pe(),{HTTP_STATUS_CODES:Ble}=xle,Hle=ar(),kle=Fo(),yw=ie(),AS=require("joi"),Fle=ct(),Gle=2e3,qle=AS.object({timeout:AS.number().min(1),connected_nodes:AS.boolean(),routes:AS.boolean()});Kq.exports=$le;async function $le(e){kle.checkClusteringEnabled();let t=Fle.validateBySchema(e,qle);if(t)throw Ule(t,t.message,Ble.BAD_REQUEST,void 0,void 0,!0);let{timeout:r,connected_nodes:n,routes:s}=e,i=n===void 0||yw.autoCastBoolean(n),o=s===void 0||yw.autoCastBoolean(s),c={nodes:[]},l=await Hle.getServerList(r??Gle),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,p=l[f].data;if(_.name.endsWith("-hub")){let h={name:_.name.slice(0,-4),response_time:l[f].response_time};i&&(h.connected_nodes=[],u[_.name]&&u[_.name].forEach(S=>{h.connected_nodes.includes(S.name.slice(0,-4))||h.connected_nodes.push(S.name.slice(0,-4))})),o&&(h.routes=p.cluster?.urls?p.cluster?.urls.map(S=>({host:S.split(":")[0],port:yw.autoCast(S.split(":")[1])})):[]),c.nodes.push(h)}}return c}a($le,"clusterNetwork")});var jq=P((pMe,zq)=>{"use strict";var bw=require("joi"),Yq=ct(),{route_constraints:Wq}=ib();zq.exports={setRoutesValidator:Vle,deleteRoutesValidator:Kle};function Vle(e){let t=bw.object({server:bw.valid("hub","leaf"),routes:Wq.required()});return Yq.validateBySchema(e,t)}a(Vle,"setRoutesValidator");function Kle(e){let t=bw.object({routes:Wq.required()});return Yq.validateBySchema(e,t)}a(Kle,"deleteRoutesValidator")});var yS=P((mMe,r$)=>{"use strict";var qo=Ot(),Ow=ie(),Ls=(k(),C(G)),Pd=ce(),Jq=jq(),{handleHDBError:Qq,hdb_errors:Yle}=pe(),{HTTP_STATUS_CODES:Xq}=Yle,Zq="cluster routes successfully set",e$="cluster routes successfully deleted";r$.exports={setRoutes:zle,getRoutes:jle,deleteRoutes:Jle};function Wle(e){let t=qo.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=Ow.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"?qo.updateConfigValue(Ls.CONFIG_PARAMS.CLUSTERING_HUBSERVER_CLUSTER_NETWORK_ROUTES,r):qo.updateConfigValue(Ls.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_NETWORK_ROUTES,r),{message:Zq,set:i,skipped:s}}a(Wle,"setRoutesNats");function zle(e){let t=Jq.setRoutesValidator(e);if(t)throw Qq(t,t.message,Xq.BAD_REQUEST,void 0,void 0,!0);if(Pd.get(Ls.CONFIG_PARAMS.CLUSTERING_ENABLED))return Wle(e);let r=[],n=[],s=Pd.get(Ls.CONFIG_PARAMS.REPLICATION_ROUTES)??[];return e.routes.forEach(i=>{t$(s,i)?n.push(i):(s.push(i),r.push(i))}),qo.updateConfigValue(Ls.CONFIG_PARAMS.REPLICATION_ROUTES,s),{message:Zq,set:r,skipped:n}}a(zle,"setRoutes");function t$(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(t$,"existsInArray");function jle(){if(Pd.get(Ls.CONFIG_PARAMS.CLUSTERING_ENABLED)){let e=qo.getClusteringRoutes();return{hub:e.hub_routes,leaf:e.leaf_routes}}else return Pd.get(Ls.CONFIG_PARAMS.REPLICATION_ROUTES)??[]}a(jle,"getRoutes");function Jle(e){let t=Jq.deleteRoutesValidator(e);if(t)throw Qq(t,t.message,Xq.BAD_REQUEST,void 0,void 0,!0);if(Pd.get(Ls.CONFIG_PARAMS.CLUSTERING_ENABLED))return Qle(e);let r=[],n=[],s=Pd.get(Ls.CONFIG_PARAMS.REPLICATION_ROUTES)??[],i=[];return s.forEach(o=>{t$(e.routes,o)?r.push(o):(i.push(o),n.push(o))}),qo.updateConfigValue(Ls.CONFIG_PARAMS.REPLICATION_ROUTES,i),{message:e$,deleted:r,skipped:n}}a(Jle,"deleteRoutes");function Qle(e){let t=qo.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,p=r.length;_<p;_++){let h=r[_];if(f.host===h.host&&f.port===h.port){r.splice(_,1),d=!0,o=!0,s.push(f);break}}if(!d){let _=!0;for(let p=0,h=n.length;p<h;p++){let S=n[p];if(f.host===S.host&&f.port===S.port){n.splice(p,1),c=!0,_=!1,s.push(f);break}}_&&i.push(f)}}return o&&(r=Ow.isEmptyOrZeroLength(r)?null:r,qo.updateConfigValue(Ls.CONFIG_PARAMS.CLUSTERING_HUBSERVER_CLUSTER_NETWORK_ROUTES,r)),c&&(n=Ow.isEmptyOrZeroLength(n)?null:n,qo.updateConfigValue(Ls.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_NETWORK_ROUTES,n)),{message:e$,deleted:s,skipped:i}}a(Qle,"deleteRoutesNats")});var s$=P((gMe,n$)=>{"use strict";var Vp=require("alasql"),Hl=require("recursive-iterator"),pi=J(),Xle=ie(),Kp=(k(),C(G)),Nw=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,eue(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=>Kp.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=>!Kp.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][Kp.PERMS_CRUD_ENUM.READ]){let c;t[i].tables[o].attribute_permissions.length>0?c=Zle(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=>!Kp.SEARCH_WILDCARDS.includes(u));c.forEach(({attribute_name:u})=>{let f=new Vp.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 Zle(e){return e.filter(t=>t[Kp.PERMS_CRUD_ENUM.READ])}a(Zle,"filterReadRestrictedAttrs");function eue(e,t,r,n,s){tue(e,t,r,n,s)}a(eue,"interpretAST");function Yp(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(Yp,"addSchemaTableToMap");function tue(e,t,r,n,s){if(!e){pi.info("getRecordAttributesAST: invalid SQL syntax tree");return}e instanceof Vp.yy.Insert?iue(e,t,r):e instanceof Vp.yy.Select?rue(e,t,r,n,s):e instanceof Vp.yy.Update?nue(e,t,r):e instanceof Vp.yy.Delete?sue(e,t,r):pi.error("AST in getRecordAttributesAST() is not a valid SQL type.")}a(tue,"getRecordAttributesAST");function rue(e,t,r,n,s){if(!e){pi.info("getSelectAttributes: invalid SQL syntax tree");return}if(!e.from||e.from[0]===void 0)return;let i=e.from[0].databaseid;if(Xle.isEmptyOrZeroLength(i)){pi.error("No schema specified");return}e.from.forEach(c=>{Yp(c,t,r,n,s)}),e.joins&&e.joins.forEach(c=>{c.as&&(c.table.as=c.as),Yp(c.table,t,r,n,s)});let o=new Hl(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{pi.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 Hl(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{pi.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 Hl(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{pi.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 Hl(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{pi.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(rue,"getSelectAttributes");function nue(e,t,r){if(!e){pi.info("getUpdateAttributes: invalid SQL syntax tree");return}let n=new Hl(e.columns),s=e.table.databaseid;Yp(e.table,t,r);for(let{node:i}of n)i&&i.columnid&&ww(e.table.tableid,s,i.columnid,t,r)}a(nue,"getUpdateAttributes");function sue(e,t,r){if(!e){pi.info("getDeleteAttributes: invalid SQL syntax tree");return}let n=new Hl(e.where),s=e.table.databaseid;Yp(e.table,t,r);for(let{node:i}of n)i&&i.columnid&&ww(e.table.tableid,s,i.columnid,t,r)}a(sue,"getDeleteAttributes");function iue(e,t,r){if(!e){pi.info("getInsertAttributes: invalid SQL syntax tree");return}let n=new Hl(e.columns),s=e.into.databaseid;Yp(e.into,t,r);for(let{node:i}of n)i&&i.columnid&&ww(e.into.tableid,s,i.columnid,t,r)}a(iue,"getInsertAttributes");function ww(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(ww,"pushAttribute");n$.exports=Nw});var o$=P((TMe,i$)=>{"use strict";var bS=(k(),C(G)),OS=class{static{a(this,"BaseLicense")}constructor(t=0,r=bS.RAM_ALLOCATION_ENUM.DEFAULT,n=bS.LICENSE_VALUES.VERSION_DEFAULT,s){this.exp_date=t,this.ram_allocation=r,this.version=n,this.fingerprint=s}},Iw=class extends OS{static{a(this,"ExtendedLicense")}constructor(t=0,r=bS.RAM_ALLOCATION_ENUM.DEFAULT,n=bS.LICENSE_VALUES.VERSION_DEFAULT,s,i=!1){super(t,r,n,s),this.enterprise=i}};i$.exports={BaseLicense:OS,ExtendedLicense:Iw}});var Md=P((RMe,f$)=>{"use strict";var Ld=require("fs-extra"),NS=(bE(),C(yE)),c$=require("crypto"),oue=require("moment"),aue=require("uuid").v4,rn=J(),Pw=require("path"),cue=ie(),kl=(k(),C(G)),{totalmem:a$}=require("os"),lue=o$().ExtendedLicense,Dd="invalid license key format",uue="061183",due="mofi25",fue="aes-256-cbc",_ue=16,pue=32,l$=ce(),{resolvePath:u$}=Ot();l$.initSync();var Cw;f$.exports={validateLicense:d$,generateFingerPrint:mue,licenseSearch:Mw,getLicense:Sue,checkMemoryLimit:Tue};function Dw(){return Pw.join(l$.getHdbBasePath(),kl.LICENSE_KEY_DIR_NAME,kl.LICENSE_FILE_NAME)}a(Dw,"getLicenseDirPath");function hue(){let e=Dw();return u$(Pw.join(e,kl.LICENSE_FILE_NAME))}a(hue,"getLicenseFilePath");function Lw(){let e=Dw();return u$(Pw.join(e,kl.REG_KEY_FILE_NAME))}a(Lw,"getFingerPrintFilePath");async function mue(){let e=Lw();try{return await Ld.readFile(e,"utf8")}catch(t){if(t.code==="ENOENT")return await Eue();throw rn.error(`Error writing fingerprint file to ${e}`),rn.error(t),new Error("There was an error generating the fingerprint")}}a(mue,"generateFingerPrint");async function Eue(){let e=aue(),t=NS.hash(e,NS.HASH_FUNCTION.MD5),r=Lw();try{await Ld.mkdirp(Dw()),await Ld.writeFile(r,t)}catch(n){if(n.code==="EEXIST")return t;throw rn.error(`Error writing fingerprint file to ${r}`),rn.error(n),new Error("There was an error generating the fingerprint")}return t}a(Eue,"writeFingerprint");function d$(e,t){let r={valid_license:!1,valid_date:!1,valid_machine:!1,exp_date:null,ram_allocation:kl.RAM_ALLOCATION_ENUM.DEFAULT,version:kl.LICENSE_VALUES.VERSION_DEFAULT};if(!e)return rn.error("empty license key passed to validate."),r;let n=Lw(),s=!1;try{s=Ld.statSync(n)}catch(i){rn.error(i)}if(s){let i;try{i=Ld.readFileSync(n,"utf8")}catch{rn.error("error validating this machine in the license"),r.valid_machine=!1;return}let o=e.split(due),c=o[1];c=Buffer.concat([Buffer.from(c)],_ue);let l=Buffer.concat([Buffer.from(i)],pue),u=c$.createDecipheriv(fue,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 p=gue(o[0],i);if(p)f=p;else throw r.valid_license=!1,r.valid_machine=!1,console.error(Dd),rn.error(Dd),new Error(Dd)}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(Dd),rn.error(Dd),new Error(Dd)}else r.exp_date=f;r.exp_date<oue().valueOf()&&(r.valid_date=!1),NS.validate(o[1],`${uue}${i}${t}`,NS.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||rn.error("Invalid licence"),r}a(d$,"validateLicense");function gue(e,t){try{let r=c$.createDecipher("aes192",t),n=r.update(e,"hex","utf8");return n.trim(),n+=r.final("utf8"),n}catch{rn.warn("Check old license failed")}}a(gue,"checkOldLicense");function Mw(){let e=new lue,t=[];try{t=Ld.readFileSync(hue(),"utf-8").split(`\r
|
|
25
|
-
`)}catch(r){r.code==="ENOENT"?rn.debug("no license file found"):rn.error(`could not search for licenses due to: '${r.message}`)}for(let r=0;r<t.length;++r){let n=t[r];try{if(cue.isEmptyOrZeroLength(n))continue;let s=JSON.parse(n),i=d$(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){rn.error("There was an error parsing the license string."),rn.error(s),e.ram_allocation=kl.RAM_ALLOCATION_ENUM.DEFAULT,e.enterprise=!1}}return Cw=e,e}a(Mw,"licenseSearch");async function Sue(){return Cw||await Mw(),Cw}a(Sue,"getLicense");function Tue(){let e=Mw().ram_allocation,t=process.constrainedMemory?.()||a$();if(t=Math.round(Math.min(t,a$())/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(Tue,"checkMemoryLimit")});var IS=P((bMe,m$)=>{var wS=Md(),_$=require("chalk"),cs=J(),p$=require("prompt"),{promisify:Aue}=require("util"),vw=(k(),C(G)),Rue=require("fs-extra"),yue=require("path"),bue=ie(),{packageJson:Oue}=at(),h$=ce();h$.initSync();var Nue=require("moment"),wue=Aue(p$.get),Iue=yue.join(h$.getHdbBasePath(),vw.LICENSE_KEY_DIR_NAME,vw.LICENSE_FILE_NAME,vw.LICENSE_FILE_NAME);m$.exports={getFingerprint:Pue,setLicense:Cue,parseLicense:Uw,register:Due,getRegistrationInfo:Mue};async function Cue(e){if(e&&e.key&&e.company){try{cs.info(`parsing license key: ${e.key} and `);let t=e.company.toString();await Uw(e.key.trim(),t.trim())}catch(t){let r="There was an error parsing the license key.";throw cs.error(r),cs.error(t),new Error(r)}return"Wrote license key file. Registration successful."}throw new Error("Invalid key or company specified for license file.")}a(Cue,"setLicense");async function Pue(){let e={};try{e=await wS.generateFingerPrint()}catch(t){let r="Error generating fingerprint.";throw cs.error(r),cs.error(t),new Error(r)}return e}a(Pue,"getFingerprint");async function Uw(e,t){if(!e||!t)throw new Error("Invalid entries for License Key and Customer Company");cs.info("Validating license input...");let r=wS.validateLicense(e,t);if(cs.info("checking for valid license..."),!r.valid_license)throw new Error("Invalid license found.");if(cs.info("checking valid license date..."),!r.valid_date)throw new Error("This License has expired.");if(cs.info(`checking for valid machine license ${r.valid_machine}`),!r.valid_machine)throw new Error("This license is in use on another machine.");try{cs.info("writing license to disk"),await Rue.writeFile(Iue,JSON.stringify({license_key:e,company:t}))}catch(n){throw cs.error("Failed to write License"),n}return"Registration successful."}a(Uw,"parseLicense");async function Due(){let e=await Lue();return Uw(e.HDB_LICENSE,e.CUSTOMER_COMPANY)}a(Due,"register");async function Lue(){let e=await wS.generateFingerPrint(),t={properties:{CUSTOMER_COMPANY:{description:_$.magenta("[COMPANY] Please enter your company name"),required:!0},HDB_LICENSE:{description:_$.magenta(`[HDB_LICENSE] Your fingerprint is ${e} Please enter your license key`),required:!0}}};try{p$.start()}catch(n){cs.error(n)}let r;try{r=await wue(t)}catch(n){throw console.error("There was a problem prompting for registration input. Exiting."),n}return r}a(Lue,"promptForRegistration");async function Mue(){let e={registered:!1,version:null,ram_allocation:null,license_expiration_date:null},t;try{t=await wS.getLicense()}catch(r){throw cs.error(`There was an error when searching licenses due to: ${r.message}`),r}if(bue.isEmptyOrZeroLength(t))throw new Error("There were no licenses found.");if(e.registered=t.enterprise,e.version=Oue.version,e.ram_allocation=t.ram_allocation,isNaN(t.exp_date))e.license_expiration_date=t.enterprise?t.exp_date:null;else{let r=Nue.utc(t.exp_date).format("YYYY-MM-DD");e.license_expiration_date=t.enterprise?r:null}return e}a(Mue,"getRegistrationInfo")});var g$=P((NMe,E$)=>{"use strict";var vue=yt(),xw=class{static{a(this,"HubConfigObject")}constructor(t,r,n,s,i,o,c,l,u,f,d,_,p,h){this.port=t,o===null&&(o=void 0),this.server_name=r+vue.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:p},HDB:{users:h}},this.system_account="SYS"}};E$.exports=xw});var A$=P((IMe,T$)=>{"use strict";var S$=yt(),Bw=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+S$.SERVER_SUFFIX.LEAF,this.pid_file=n,this.max_payload=67108864,this.jetstream={enabled:!0,store_dir:s,domain:r+S$.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"}};T$.exports=Bw});var y$=P((PMe,R$)=>{"use strict";var Hw=class{static{a(this,"HdbUserObject")}constructor(t,r){this.user=t,this.password=r}};R$.exports=Hw});var O$=P((LMe,b$)=>{"use strict";var Uue=yt(),kw=class{static{a(this,"SysUserObject")}constructor(t,r){this.user=t+Uue.SERVER_SUFFIX.ADMIN,this.password=r}};b$.exports=kw});var LS=P((vMe,I$)=>{"use strict";var Fl=require("path"),Gl=require("fs-extra"),xue=g$(),Bue=A$(),Hue=y$(),kue=O$(),Fw=wn(),Ud=ie(),Ln=Ot(),PS=(k(),C(G)),Wp=yt(),{CONFIG_PARAMS:Zt}=PS,xd=J(),zp=ce(),N$=No(),Gw=ar(),Fue=os(),vd="clustering",Gue=1e4,w$=50;I$.exports={generateNatsConfig:$ue,removeNatsConfig:Vue,getHubConfigPath:que};function que(){let e=zp.get(Zt.ROOTPATH);return Fl.join(e,vd,Wp.NATS_CONFIG_FILES.HUB_SERVER)}a(que,"getHubConfigPath");async function $ue(e=!1,t=void 0){let r=zp.get(Zt.ROOTPATH);Gl.ensureDirSync(Fl.join(r,"clustering","leaf")),zp.initSync();let n=Ln.getConfigFromFile(Zt.CLUSTERING_TLS_CERT_AUTH),s=Ln.getConfigFromFile(Zt.CLUSTERING_TLS_PRIVATEKEY),i=Ln.getConfigFromFile(Zt.CLUSTERING_TLS_CERTIFICATE);!await Gl.exists(i)&&!await Gl.exists(!n)&&await Fue.createNatsCerts();let o=Fl.join(r,vd,Wp.PID_FILES.HUB),c=Fl.join(r,vd,Wp.PID_FILES.LEAF),l=Ln.getConfigFromFile(Zt.CLUSTERING_LEAFSERVER_STREAMS_PATH),u=Fl.join(r,vd,Wp.NATS_CONFIG_FILES.HUB_SERVER),f=Fl.join(r,vd,Wp.NATS_CONFIG_FILES.LEAF_SERVER),d=Ln.getConfigFromFile(Zt.CLUSTERING_TLS_INSECURE),_=Ln.getConfigFromFile(Zt.CLUSTERING_TLS_VERIFY),p=Ln.getConfigFromFile(Zt.CLUSTERING_NODENAME),h=Ln.getConfigFromFile(Zt.CLUSTERING_HUBSERVER_LEAFNODES_NETWORK_PORT);await Gw.checkNATSServerInstalled()||DS("nats-server dependency is either missing or the wrong version. Run 'npm install' to fix");let S=await Fw.listUsers(),g=Ln.getConfigFromFile(Zt.CLUSTERING_USER),R=await Fw.getClusterUser();(Ud.isEmpty(R)||R.active!==!0)&&DS(`Invalid cluster user '${g}'. A valid user with the role 'cluster_user' must be defined under clustering.user in harperdb-config.yaml`),e||(await CS(Zt.CLUSTERING_HUBSERVER_CLUSTER_NETWORK_PORT),await CS(Zt.CLUSTERING_HUBSERVER_LEAFNODES_NETWORK_PORT),await CS(Zt.CLUSTERING_HUBSERVER_NETWORK_PORT),await CS(Zt.CLUSTERING_LEAFSERVER_NETWORK_PORT));let E=[],T=[];for(let[se,z]of S.entries())z.role?.role===PS.ROLE_TYPES_ENUM.CLUSTER_USER&&z.active&&(E.push(new kue(z.username,N$.decrypt(z.hash))),T.push(new Hue(z.username,N$.decrypt(z.hash))));let N=[],{hub_routes:v}=Ln.getClusteringRoutes();if(!Ud.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 xue(Ln.getConfigFromFile(Zt.CLUSTERING_HUBSERVER_NETWORK_PORT),p,o,i,s,n,d,_,h,Ln.getConfigFromFile(Zt.CLUSTERING_HUBSERVER_CLUSTER_NAME),Ln.getConfigFromFile(Zt.CLUSTERING_HUBSERVER_CLUSTER_NETWORK_PORT),N,E,T);n==null&&(delete H.tls.ca_file,delete H.leafnodes.tls.ca_file),t=Ud.isEmpty(t)?void 0:t.toLowerCase(),(t===void 0||t===PS.PROCESS_DESCRIPTORS.CLUSTERING_HUB.toLowerCase())&&(await Gl.writeJson(u,H),xd.trace(`Hub server config written to ${u}`));let Z=`tls://${R.sys_name_encoded}:${R.uri_encoded_d_hash}@0.0.0.0:${h}`,W=`tls://${R.uri_encoded_name}:${R.uri_encoded_d_hash}@0.0.0.0:${h}`,$=new Bue(Ln.getConfigFromFile(Zt.CLUSTERING_LEAFSERVER_NETWORK_PORT),p,c,l,[Z],[W],E,T,i,s,n,d);n==null&&delete $.tls.ca_file,(t===void 0||t===PS.PROCESS_DESCRIPTORS.CLUSTERING_LEAF.toLowerCase())&&(await Gl.writeJson(f,$),xd.trace(`Leaf server config written to ${f}`))}a($ue,"generateNatsConfig");async function CS(e){let t=zp.get(e);return Ud.isEmpty(t)&&DS(`port undefined for '${e}'`),await Ud.isPortTaken(t)&&DS(`'${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(CS,"isPortAvailable");function DS(e){let t=`Error generating clustering config: ${e}`;xd.error(t),console.error(t),process.exit(1)}a(DS,"generateNatsConfigError");async function Vue(e){let{port:t,config_file:r}=Gw.getServerConfig(e),{username:n,decrypt_hash:s}=await Fw.getClusterUser(),i=0,o=2e3;for(;i<w$;){try{let f=await Gw.createConnection(t,n,s,!1);if(f.protocol.connected===!0){f.close();break}}catch(f){xd.trace(`removeNatsConfig waiting for ${e}. Caught and swallowed error ${f}`)}if(i++,i>=w$)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&&xd.notify("Operations API waiting for Nats server connection. This could be caused by large Nats streams or incorrect clustering config."),await Ud.async_set_timeout(u)}let c="0".repeat(Gue),l=Fl.join(zp.get(Zt.ROOTPATH),vd,r);await Gl.writeFile(l,c),await Gl.remove(l),xd.notify(e,"started.")}a(Vue,"removeNatsConfig")});var v$=P((xMe,M$)=>{"use strict";var ls=ce(),Kue=Md(),Ve=(k(),C(G)),jp=yt(),$o=require("path"),{PACKAGE_ROOT:vS}=at(),C$=ce(),MS=ie(),Bd="/dev/null",Yue=$o.join(vS,"launchServiceScripts"),P$=$o.join(vS,"utility/scripts"),Wue=$o.join(P$,Ve.HDB_RESTART_SCRIPT),D$=$o.resolve(vS,"dependencies",`${process.platform}-${process.arch}`,jp.NATS_BINARY_NAME);function L$(){let t=Kue.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 MS.noBootFile()&&(n[Ve.CONFIG_PARAMS.ROOTPATH.toUpperCase()]=MS.getEnvCliRootPath()),{name:Ve.PROCESS_DESCRIPTORS.HDB,script:Ve.LAUNCH_SERVICE_SCRIPTS.MAIN,exec_mode:"fork",env:n,node_args:r,cwd:vS}}a(L$,"generateMainServerConfig");var zue=9930;function jue(){ls.initSync(!0);let e=ls.get(Ve.CONFIG_PARAMS.ROOTPATH),t=$o.join(e,"clustering",jp.NATS_CONFIG_FILES.HUB_SERVER),r=$o.join(ls.get(Ve.HDB_SETTINGS_NAMES.LOG_PATH_KEY),Ve.LOG_NAMES.HDB),n=C$.get(Ve.CONFIG_PARAMS.CLUSTERING_HUBSERVER_NETWORK_PORT),s=jp.LOG_LEVEL_FLAGS[ls.get(Ve.CONFIG_PARAMS.CLUSTERING_LOGLEVEL)]??void 0,i={name:Ve.PROCESS_DESCRIPTORS.CLUSTERING_HUB+(n!==zue?"-"+n:""),script:D$,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 ls.get(Ve.HDB_SETTINGS_NAMES.LOG_TO_FILE)||(i.out_file=Bd,i.error_file=Bd),i}a(jue,"generateNatsHubServerConfig");var Jue=9940;function Que(){ls.initSync(!0);let e=ls.get(Ve.CONFIG_PARAMS.ROOTPATH),t=$o.join(e,"clustering",jp.NATS_CONFIG_FILES.LEAF_SERVER),r=$o.join(ls.get(Ve.HDB_SETTINGS_NAMES.LOG_PATH_KEY),Ve.LOG_NAMES.HDB),n=C$.get(Ve.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_NETWORK_PORT),s=jp.LOG_LEVEL_FLAGS[ls.get(Ve.CONFIG_PARAMS.CLUSTERING_LOGLEVEL)]??void 0,i={name:Ve.PROCESS_DESCRIPTORS.CLUSTERING_LEAF+(n!==Jue?"-"+n:""),script:D$,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 ls.get(Ve.HDB_SETTINGS_NAMES.LOG_TO_FILE)||(i.out_file=Bd,i.error_file=Bd),i}a(Que,"generateNatsLeafServerConfig");function Xue(){ls.initSync();let e=$o.join(ls.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:Yue,autorestart:!1};return ls.get(Ve.HDB_SETTINGS_NAMES.LOG_TO_FILE)||(t.out_file=Bd,t.error_file=Bd),t}a(Xue,"generateClusteringUpgradeV4ServiceConfig");function Zue(){let e={[Ve.PROCESS_NAME_ENV_PROP]:Ve.PROCESS_DESCRIPTORS.RESTART_HDB};return MS.noBootFile()&&(e[Ve.CONFIG_PARAMS.ROOTPATH.toUpperCase()]=MS.getEnvCliRootPath()),{...{name:Ve.PROCESS_DESCRIPTORS.RESTART_HDB,exec_mode:"fork",env:e,instances:1,autorestart:!1,cwd:P$},script:Wue}}a(Zue,"generateRestart");function ede(){return{apps:[L$()]}}a(ede,"generateAllServiceConfigs");M$.exports={generateAllServiceConfigs:ede,generateMainServerConfig:L$,generateRestart:Zue,generateNatsHubServerConfig:jue,generateNatsLeafServerConfig:Que,generateClusteringUpgradeV4ServiceConfig:Xue}});var Hd=P((kMe,z$)=>{"use strict";var tt=(k(),C(G)),tde=ie(),Ko=LS(),US=ar(),Vo=yt(),Za=v$(),xS=ce(),ql=J(),rde=Fo(),{startWorker:U$,onMessageFromWorkers:nde}=nt(),sde=ko(),HMe=require("util"),ide=require("child_process"),ode=require("fs"),{execFile:ade}=ide,je;z$.exports={enterPM2Mode:cde,start:ec,stop:qw,reload:B$,restart:H$,list:$w,describe:G$,connect:Yo,kill:_de,startAllServices:pde,startService:Vw,getUniqueServicesList:q$,restartAllServices:hde,isServiceRegistered:$$,reloadStopStart:V$,restartHdb:F$,deleteProcess:dde,startClusteringProcesses:Y$,startClusteringThreads:W$,isHdbRestartRunning:fde,isClusteringRunning:Ede,stopClustering:mde,reloadClustering:gde,expectedRestartOfChildren:k$};var Jp=!1;nde(e=>{e.type==="restart"&&xS.initSync(!0)});function cde(){Jp=!0}a(cde,"enterPM2Mode");function Yo(){return je||(je=require("pm2")),new Promise((e,t)=>{je.connect((r,n)=>{r&&t(r),e(n)})})}a(Yo,"connect");var nn,lde=10,x$;function ec(e,t=!1){if(Jp)return ude(e);let r=ade(e.script,e.args.split(" "),e);r.name=e.name,r.config=e,r.on("exit",async i=>{let o=nn.indexOf(r);o>-1&&nn.splice(o,1),!x$&&i!==0&&(e.restarts=(e.restarts||0)+1,e.restarts<lde&&(ode.existsSync(Ko.getHubConfigPath())?ec(e):(await Ko.generateNatsConfig(!0),ec(e),await new Promise(c=>setTimeout(c,3e3)),await Ko.removeNatsConfig(tt.PROCESS_DESCRIPTORS.CLUSTERING_HUB),await Ko.removeNatsConfig(tt.PROCESS_DESCRIPTORS.CLUSTERING_LEAF))))});let n={serviceName:e.name.replace(/ /g,"-")};function s(i){let o=xS.get(tt.CONFIG_PARAMS.CLUSTERING_LOGLEVEL),c=/\[\d+][^\[]+\[(\w+)]/g,l,u=0,f;for(;l=c.exec(i);){if(l.index&&Vo.LOG_LEVEL_HIERARCHY[o]>=Vo.LOG_LEVEL_HIERARCHY[f||"info"]){let p=f===Vo.LOG_LEVELS.ERR||f===Vo.LOG_LEVELS.WRN?ql.OUTPUTS.STDERR:ql.OUTPUTS.STDOUT;ql.logCustomLevel(f||"info",p,n,i.slice(u,l.index).trim())}let[d,_]=l;u=l.index+d.length,f=Vo.LOG_LEVELS[_]}if(Vo.LOG_LEVEL_HIERARCHY[o]>=Vo.LOG_LEVEL_HIERARCHY[f||"info"]){let d=f===Vo.LOG_LEVELS.ERR||f===Vo.LOG_LEVELS.WRN?ql.OUTPUTS.STDERR:ql.OUTPUTS.STDOUT;ql.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(),!nn&&(nn=[],!t)){let i=a(()=>{x$=!0,nn&&(nn.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)}nn.push(r)}a(ec,"start");function ude(e){return new Promise(async(t,r)=>{try{await Yo()}catch(n){r(n)}je.start(e,(n,s)=>{n&&(je.disconnect(),r(n)),je.disconnect(),t(s)})})}a(ude,"startWithPM2");function qw(e){if(!Jp){for(let t of nn||[])t.name===e&&(nn.splice(nn.indexOf(t),1),t.kill());return}return new Promise(async(t,r)=>{try{await Yo()}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(qw,"stop");function B$(e){return new Promise(async(t,r)=>{try{await Yo()}catch(n){r(n)}je.reload(e,(n,s)=>{n&&(je.disconnect(),r(n)),je.disconnect(),t(s)})})}a(B$,"reload");function H$(e){if(!Jp){k$();for(let t of nn||[])t.name===e&&t.kill()}return new Promise(async(t,r)=>{try{await Yo()}catch(n){r(n)}je.restart(e,(n,s)=>{je.disconnect(),t(s)})})}a(H$,"restart");function k$(){for(let e of nn||[])e.config&&(e.config.restarts=0)}a(k$,"expectedRestartOfChildren");function dde(e){return new Promise(async(t,r)=>{try{await Yo()}catch(n){r(n)}je.delete(e,(n,s)=>{n&&(je.disconnect(),r(n)),je.disconnect(),t(s)})})}a(dde,"deleteProcess");async function F$(){await ec(Za.generateRestart())}a(F$,"restartHdb");async function fde(){let e=await $w();for(let t in e)if(e[t].name===tt.PROCESS_DESCRIPTORS.RESTART_HDB)return!0;return!1}a(fde,"isHdbRestartRunning");function $w(){return new Promise(async(e,t)=>{try{await Yo()}catch(r){t(r)}je.list((r,n)=>{r&&(je.disconnect(),t(r)),je.disconnect(),e(n)})})}a($w,"list");function G$(e){return new Promise(async(t,r)=>{try{await Yo()}catch(n){r(n)}je.describe(e,(n,s)=>{n&&(je.disconnect(),r(n)),je.disconnect(),t(s)})})}a(G$,"describe");function _de(){if(!Jp){for(let e of nn||[])e.kill();nn=[];return}return new Promise(async(e,t)=>{try{await Yo()}catch(r){t(r)}je.killDaemon((r,n)=>{r&&(je.disconnect(),t(r)),je.disconnect(),e(n)})})}a(_de,"kill");async function pde(){try{await Y$(),await W$(),await ec(Za.generateAllServiceConfigs())}catch(e){throw je?.disconnect(),e}}a(pde,"startAllServices");async function Vw(e,t=!1){try{let r;switch(e=e.toLowerCase(),e){case tt.PROCESS_DESCRIPTORS.HDB.toLowerCase():r=Za.generateMainServerConfig();break;case tt.PROCESS_DESCRIPTORS.CLUSTERING_INGEST_SERVICE.toLowerCase():r=Za.generateNatsIngestServiceConfig();break;case tt.PROCESS_DESCRIPTORS.CLUSTERING_REPLY_SERVICE.toLowerCase():r=Za.generateNatsReplyServiceConfig();break;case tt.PROCESS_DESCRIPTORS.CLUSTERING_HUB.toLowerCase():r=Za.generateNatsHubServerConfig(),await ec(r,t),await Ko.removeNatsConfig(e);return;case tt.PROCESS_DESCRIPTORS.CLUSTERING_LEAF.toLowerCase():r=Za.generateNatsLeafServerConfig(),await ec(r,t),await Ko.removeNatsConfig(e);return;case tt.PROCESS_DESCRIPTORS.CLUSTERING_UPGRADE_4_0_0.toLowerCase():r=Za.generateClusteringUpgradeV4ServiceConfig();break;default:throw new Error(`Start service called with unknown service config: ${e}`)}await ec(r)}catch(r){throw je?.disconnect(),r}}a(Vw,"startService");async function q$(){try{let e=await $w(),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(q$,"getUniqueServicesList");async function hde(e=[]){try{let t=!1,r=await q$();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 H$(o))}t&&await V$(tt.PROCESS_DESCRIPTORS.HDB)}catch(t){throw je?.disconnect(),t}}a(hde,"restartAllServices");async function $$(e){if(nn?.find(r=>r.name===e))return!0;let t=await sde.getHDBProcessInfo();return t.core.length&&t.core[0]?.parent==="PM2"}a($$,"isServiceRegistered");async function V$(e){let t=xS.get(tt.CONFIG_PARAMS.THREADS_COUNT)??xS.get(tt.CONFIG_PARAMS.THREADS),r=await G$(e),n=tde.isEmptyOrZeroLength(r)?0:r.length;t!==n?(await qw(e),await Vw(e)):e===tt.PROCESS_DESCRIPTORS.HDB?await F$():await B$(e)}a(V$,"reloadStopStart");var K$;async function Y$(e=!1){for(let t in tt.CLUSTERING_PROCESSES){let r=tt.CLUSTERING_PROCESSES[t];await Vw(r,e)}}a(Y$,"startClusteringProcesses");async function W$(){K$=U$(tt.LAUNCH_SERVICE_SCRIPTS.NATS_REPLY_SERVICE,{name:tt.PROCESS_DESCRIPTORS.CLUSTERING_REPLY_SERVICE});try{await US.deleteLocalStream("__HARPERDB_WORK_QUEUE__")}catch{}await US.updateLocalStreams();let e=await rde.getAllNodeRecords();for(let t=0,r=e.length;t<r;t++)if(e[t].system_info?.hdb_version===tt.PRE_4_0_0_VERSION){ql.info("Starting clustering upgrade 4.0.0 process"),U$(tt.LAUNCH_SERVICE_SCRIPTS.NODES_UPGRADE_4_0_0,{name:"Upgrade-4-0-0"});break}}a(W$,"startClusteringThreads");async function mde(){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 K$.terminate();else{let t=tt.CLUSTERING_PROCESSES[e];await qw(t)}}a(mde,"stopClustering");async function Ede(){for(let e in tt.CLUSTERING_PROCESSES){let t=tt.CLUSTERING_PROCESSES[e];if(await $$(t)===!1)return!1}return!0}a(Ede,"isClusteringRunning");async function gde(){await Ko.generateNatsConfig(!0),await US.reloadNATSHub(),await US.reloadNATSLeaf(),await Ko.removeNatsConfig(tt.PROCESS_DESCRIPTORS.CLUSTERING_HUB.toLowerCase()),await Ko.removeNatsConfig(tt.PROCESS_DESCRIPTORS.CLUSTERING_LEAF.toLowerCase())}a(gde,"reloadClustering")});var kS={};xe(kS,{compactOnStart:()=>Sde,copyDb:()=>eV});async function Sde(){tc.notify("Running compact on start"),console.log("Running compact on start");let e=(0,Kw.get)(x.ROOTPATH),t=new Map,r=Xe();(0,Yw.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,BS.join)(e,"backup",n+".mdb"),o=(0,BS.join)(e,xc,n+"-copy.mdb"),c=0;try{c=await j$(n),console.log("Database",n,"before compact has a total record count of",c)}catch(l){tc.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 eV(n,o),console.log("Backing up",n,"to",i),await(0,$l.move)(s,i,{overwrite:!0})}try{Fd()}catch(n){tc.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,$l.move)(i,s,{overwrite:!0}),await(0,$l.remove)((0,BS.join)(e,xc,`${n}-copy.mdb-lock`));try{Fd()}catch(n){tc.error("Error resetting databases after backup",n),console.error("Error resetting databases after backup",n),process.exit(0)}}catch(n){tc.error("Error compacting database, rolling back operation",n),console.error("Error compacting database, rolling back operation",n),(0,Yw.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,$l.move)(o,i,{overwrite:!0})}catch(c){console.error(c)}}throw Fd(),n}for(let[n,{backup_dest:s,record_count:i}]of t){let o=!0,c=await j$(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}.
|
|
26
|
-
Total record count before compaction: ${i}, total after: ${
|
|
27
|
-
Database backup has not been removed and can be found here: ${s}`;tc.error(
|
|
25
|
+
`)}catch(r){r.code==="ENOENT"?rn.debug("no license file found"):rn.error(`could not search for licenses due to: '${r.message}`)}for(let r=0;r<t.length;++r){let n=t[r];try{if(cue.isEmptyOrZeroLength(n))continue;let s=JSON.parse(n),i=d$(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){rn.error("There was an error parsing the license string."),rn.error(s),e.ram_allocation=kl.RAM_ALLOCATION_ENUM.DEFAULT,e.enterprise=!1}}return Cw=e,e}a(Mw,"licenseSearch");async function Sue(){return Cw||await Mw(),Cw}a(Sue,"getLicense");function Tue(){let e=Mw().ram_allocation,t=process.constrainedMemory?.()||a$();if(t=Math.round(Math.min(t,a$())/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(Tue,"checkMemoryLimit")});var IS=P((bMe,m$)=>{var wS=Md(),_$=require("chalk"),cs=J(),p$=require("prompt"),{promisify:Aue}=require("util"),vw=(k(),C(G)),Rue=require("fs-extra"),yue=require("path"),bue=ie(),{packageJson:Oue}=at(),h$=ce();h$.initSync();var Nue=require("moment"),wue=Aue(p$.get),Iue=yue.join(h$.getHdbBasePath(),vw.LICENSE_KEY_DIR_NAME,vw.LICENSE_FILE_NAME,vw.LICENSE_FILE_NAME);m$.exports={getFingerprint:Pue,setLicense:Cue,parseLicense:Uw,register:Due,getRegistrationInfo:Mue};async function Cue(e){if(e&&e.key&&e.company){try{cs.info(`parsing license key: ${e.key} and `);let t=e.company.toString();await Uw(e.key.trim(),t.trim())}catch(t){let r="There was an error parsing the license key.";throw cs.error(r),cs.error(t),new Error(r)}return"Wrote license key file. Registration successful."}throw new Error("Invalid key or company specified for license file.")}a(Cue,"setLicense");async function Pue(){let e={};try{e=await wS.generateFingerPrint()}catch(t){let r="Error generating fingerprint.";throw cs.error(r),cs.error(t),new Error(r)}return e}a(Pue,"getFingerprint");async function Uw(e,t){if(!e||!t)throw new Error("Invalid entries for License Key and Customer Company");cs.info("Validating license input...");let r=wS.validateLicense(e,t);if(cs.info("checking for valid license..."),!r.valid_license)throw new Error("Invalid license found.");if(cs.info("checking valid license date..."),!r.valid_date)throw new Error("This License has expired.");if(cs.info(`checking for valid machine license ${r.valid_machine}`),!r.valid_machine)throw new Error("This license is in use on another machine.");try{cs.info("writing license to disk"),await Rue.writeFile(Iue,JSON.stringify({license_key:e,company:t}))}catch(n){throw cs.error("Failed to write License"),n}return"Registration successful."}a(Uw,"parseLicense");async function Due(){let e=await Lue();return Uw(e.HDB_LICENSE,e.CUSTOMER_COMPANY)}a(Due,"register");async function Lue(){let e=await wS.generateFingerPrint(),t={properties:{CUSTOMER_COMPANY:{description:_$.magenta("[COMPANY] Please enter your company name"),required:!0},HDB_LICENSE:{description:_$.magenta(`[HDB_LICENSE] Your fingerprint is ${e} Please enter your license key`),required:!0}}};try{p$.start()}catch(n){cs.error(n)}let r;try{r=await wue(t)}catch(n){throw console.error("There was a problem prompting for registration input. Exiting."),n}return r}a(Lue,"promptForRegistration");async function Mue(){let e={registered:!1,version:null,ram_allocation:null,license_expiration_date:null},t;try{t=await wS.getLicense()}catch(r){throw cs.error(`There was an error when searching licenses due to: ${r.message}`),r}if(bue.isEmptyOrZeroLength(t))throw new Error("There were no licenses found.");if(e.registered=t.enterprise,e.version=Oue.version,e.ram_allocation=t.ram_allocation,isNaN(t.exp_date))e.license_expiration_date=t.enterprise?t.exp_date:null;else{let r=Nue.utc(t.exp_date).format("YYYY-MM-DD");e.license_expiration_date=t.enterprise?r:null}return e}a(Mue,"getRegistrationInfo")});var g$=P((NMe,E$)=>{"use strict";var vue=yt(),xw=class{static{a(this,"HubConfigObject")}constructor(t,r,n,s,i,o,c,l,u,f,d,_,p,h){this.port=t,o===null&&(o=void 0),this.server_name=r+vue.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:p},HDB:{users:h}},this.system_account="SYS"}};E$.exports=xw});var A$=P((IMe,T$)=>{"use strict";var S$=yt(),Bw=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+S$.SERVER_SUFFIX.LEAF,this.pid_file=n,this.max_payload=67108864,this.jetstream={enabled:!0,store_dir:s,domain:r+S$.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"}};T$.exports=Bw});var y$=P((PMe,R$)=>{"use strict";var Hw=class{static{a(this,"HdbUserObject")}constructor(t,r){this.user=t,this.password=r}};R$.exports=Hw});var O$=P((LMe,b$)=>{"use strict";var Uue=yt(),kw=class{static{a(this,"SysUserObject")}constructor(t,r){this.user=t+Uue.SERVER_SUFFIX.ADMIN,this.password=r}};b$.exports=kw});var LS=P((vMe,I$)=>{"use strict";var Fl=require("path"),Gl=require("fs-extra"),xue=g$(),Bue=A$(),Hue=y$(),kue=O$(),Fw=wn(),Ud=ie(),Ln=Ot(),PS=(k(),C(G)),Wp=yt(),{CONFIG_PARAMS:Zt}=PS,xd=J(),zp=ce(),N$=No(),Gw=ar(),Fue=os(),vd="clustering",Gue=1e4,w$=50;I$.exports={generateNatsConfig:$ue,removeNatsConfig:Vue,getHubConfigPath:que};function que(){let e=zp.get(Zt.ROOTPATH);return Fl.join(e,vd,Wp.NATS_CONFIG_FILES.HUB_SERVER)}a(que,"getHubConfigPath");async function $ue(e=!1,t=void 0){let r=zp.get(Zt.ROOTPATH);Gl.ensureDirSync(Fl.join(r,"clustering","leaf")),zp.initSync();let n=Ln.getConfigFromFile(Zt.CLUSTERING_TLS_CERT_AUTH),s=Ln.getConfigFromFile(Zt.CLUSTERING_TLS_PRIVATEKEY),i=Ln.getConfigFromFile(Zt.CLUSTERING_TLS_CERTIFICATE);!await Gl.exists(i)&&!await Gl.exists(!n)&&await Fue.createNatsCerts();let o=Fl.join(r,vd,Wp.PID_FILES.HUB),c=Fl.join(r,vd,Wp.PID_FILES.LEAF),l=Ln.getConfigFromFile(Zt.CLUSTERING_LEAFSERVER_STREAMS_PATH),u=Fl.join(r,vd,Wp.NATS_CONFIG_FILES.HUB_SERVER),f=Fl.join(r,vd,Wp.NATS_CONFIG_FILES.LEAF_SERVER),d=Ln.getConfigFromFile(Zt.CLUSTERING_TLS_INSECURE),_=Ln.getConfigFromFile(Zt.CLUSTERING_TLS_VERIFY),p=Ln.getConfigFromFile(Zt.CLUSTERING_NODENAME),h=Ln.getConfigFromFile(Zt.CLUSTERING_HUBSERVER_LEAFNODES_NETWORK_PORT);await Gw.checkNATSServerInstalled()||DS("nats-server dependency is either missing or the wrong version. Run 'npm install' to fix");let S=await Fw.listUsers(),g=Ln.getConfigFromFile(Zt.CLUSTERING_USER),R=await Fw.getClusterUser();(Ud.isEmpty(R)||R.active!==!0)&&DS(`Invalid cluster user '${g}'. A valid user with the role 'cluster_user' must be defined under clustering.user in harperdb-config.yaml`),e||(await CS(Zt.CLUSTERING_HUBSERVER_CLUSTER_NETWORK_PORT),await CS(Zt.CLUSTERING_HUBSERVER_LEAFNODES_NETWORK_PORT),await CS(Zt.CLUSTERING_HUBSERVER_NETWORK_PORT),await CS(Zt.CLUSTERING_LEAFSERVER_NETWORK_PORT));let E=[],T=[];for(let[se,z]of S.entries())z.role?.role===PS.ROLE_TYPES_ENUM.CLUSTER_USER&&z.active&&(E.push(new kue(z.username,N$.decrypt(z.hash))),T.push(new Hue(z.username,N$.decrypt(z.hash))));let N=[],{hub_routes:v}=Ln.getClusteringRoutes();if(!Ud.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 xue(Ln.getConfigFromFile(Zt.CLUSTERING_HUBSERVER_NETWORK_PORT),p,o,i,s,n,d,_,h,Ln.getConfigFromFile(Zt.CLUSTERING_HUBSERVER_CLUSTER_NAME),Ln.getConfigFromFile(Zt.CLUSTERING_HUBSERVER_CLUSTER_NETWORK_PORT),N,E,T);n==null&&(delete H.tls.ca_file,delete H.leafnodes.tls.ca_file),t=Ud.isEmpty(t)?void 0:t.toLowerCase(),(t===void 0||t===PS.PROCESS_DESCRIPTORS.CLUSTERING_HUB.toLowerCase())&&(await Gl.writeJson(u,H),xd.trace(`Hub server config written to ${u}`));let Z=`tls://${R.sys_name_encoded}:${R.uri_encoded_d_hash}@0.0.0.0:${h}`,W=`tls://${R.uri_encoded_name}:${R.uri_encoded_d_hash}@0.0.0.0:${h}`,$=new Bue(Ln.getConfigFromFile(Zt.CLUSTERING_LEAFSERVER_NETWORK_PORT),p,c,l,[Z],[W],E,T,i,s,n,d);n==null&&delete $.tls.ca_file,(t===void 0||t===PS.PROCESS_DESCRIPTORS.CLUSTERING_LEAF.toLowerCase())&&(await Gl.writeJson(f,$),xd.trace(`Leaf server config written to ${f}`))}a($ue,"generateNatsConfig");async function CS(e){let t=zp.get(e);return Ud.isEmpty(t)&&DS(`port undefined for '${e}'`),await Ud.isPortTaken(t)&&DS(`'${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(CS,"isPortAvailable");function DS(e){let t=`Error generating clustering config: ${e}`;xd.error(t),console.error(t),process.exit(1)}a(DS,"generateNatsConfigError");async function Vue(e){let{port:t,config_file:r}=Gw.getServerConfig(e),{username:n,decrypt_hash:s}=await Fw.getClusterUser(),i=0,o=2e3;for(;i<w$;){try{let f=await Gw.createConnection(t,n,s,!1);if(f.protocol.connected===!0){f.close();break}}catch(f){xd.trace(`removeNatsConfig waiting for ${e}. Caught and swallowed error ${f}`)}if(i++,i>=w$)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&&xd.notify("Operations API waiting for Nats server connection. This could be caused by large Nats streams or incorrect clustering config."),await Ud.async_set_timeout(u)}let c="0".repeat(Gue),l=Fl.join(zp.get(Zt.ROOTPATH),vd,r);await Gl.writeFile(l,c),await Gl.remove(l),xd.notify(e,"started.")}a(Vue,"removeNatsConfig")});var v$=P((xMe,M$)=>{"use strict";var ls=ce(),Kue=Md(),Ve=(k(),C(G)),jp=yt(),$o=require("path"),{PACKAGE_ROOT:vS}=at(),C$=ce(),MS=ie(),Bd="/dev/null",Yue=$o.join(vS,"launchServiceScripts"),P$=$o.join(vS,"utility/scripts"),Wue=$o.join(P$,Ve.HDB_RESTART_SCRIPT),D$=$o.resolve(vS,"dependencies",`${process.platform}-${process.arch}`,jp.NATS_BINARY_NAME);function L$(){let t=Kue.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 MS.noBootFile()&&(n[Ve.CONFIG_PARAMS.ROOTPATH.toUpperCase()]=MS.getEnvCliRootPath()),{name:Ve.PROCESS_DESCRIPTORS.HDB,script:Ve.LAUNCH_SERVICE_SCRIPTS.MAIN,exec_mode:"fork",env:n,node_args:r,cwd:vS}}a(L$,"generateMainServerConfig");var zue=9930;function jue(){ls.initSync(!0);let e=ls.get(Ve.CONFIG_PARAMS.ROOTPATH),t=$o.join(e,"clustering",jp.NATS_CONFIG_FILES.HUB_SERVER),r=$o.join(ls.get(Ve.HDB_SETTINGS_NAMES.LOG_PATH_KEY),Ve.LOG_NAMES.HDB),n=C$.get(Ve.CONFIG_PARAMS.CLUSTERING_HUBSERVER_NETWORK_PORT),s=jp.LOG_LEVEL_FLAGS[ls.get(Ve.CONFIG_PARAMS.CLUSTERING_LOGLEVEL)]??void 0,i={name:Ve.PROCESS_DESCRIPTORS.CLUSTERING_HUB+(n!==zue?"-"+n:""),script:D$,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 ls.get(Ve.HDB_SETTINGS_NAMES.LOG_TO_FILE)||(i.out_file=Bd,i.error_file=Bd),i}a(jue,"generateNatsHubServerConfig");var Jue=9940;function Que(){ls.initSync(!0);let e=ls.get(Ve.CONFIG_PARAMS.ROOTPATH),t=$o.join(e,"clustering",jp.NATS_CONFIG_FILES.LEAF_SERVER),r=$o.join(ls.get(Ve.HDB_SETTINGS_NAMES.LOG_PATH_KEY),Ve.LOG_NAMES.HDB),n=C$.get(Ve.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_NETWORK_PORT),s=jp.LOG_LEVEL_FLAGS[ls.get(Ve.CONFIG_PARAMS.CLUSTERING_LOGLEVEL)]??void 0,i={name:Ve.PROCESS_DESCRIPTORS.CLUSTERING_LEAF+(n!==Jue?"-"+n:""),script:D$,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 ls.get(Ve.HDB_SETTINGS_NAMES.LOG_TO_FILE)||(i.out_file=Bd,i.error_file=Bd),i}a(Que,"generateNatsLeafServerConfig");function Xue(){ls.initSync();let e=$o.join(ls.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:Yue,autorestart:!1};return ls.get(Ve.HDB_SETTINGS_NAMES.LOG_TO_FILE)||(t.out_file=Bd,t.error_file=Bd),t}a(Xue,"generateClusteringUpgradeV4ServiceConfig");function Zue(){let e={[Ve.PROCESS_NAME_ENV_PROP]:Ve.PROCESS_DESCRIPTORS.RESTART_HDB};return MS.noBootFile()&&(e[Ve.CONFIG_PARAMS.ROOTPATH.toUpperCase()]=MS.getEnvCliRootPath()),{...{name:Ve.PROCESS_DESCRIPTORS.RESTART_HDB,exec_mode:"fork",env:e,instances:1,autorestart:!1,cwd:P$},script:Wue}}a(Zue,"generateRestart");function ede(){return{apps:[L$()]}}a(ede,"generateAllServiceConfigs");M$.exports={generateAllServiceConfigs:ede,generateMainServerConfig:L$,generateRestart:Zue,generateNatsHubServerConfig:jue,generateNatsLeafServerConfig:Que,generateClusteringUpgradeV4ServiceConfig:Xue}});var Hd=P((kMe,z$)=>{"use strict";var tt=(k(),C(G)),tde=ie(),Ko=LS(),US=ar(),Vo=yt(),Za=v$(),xS=ce(),ql=J(),rde=Fo(),{startWorker:U$,onMessageFromWorkers:nde}=nt(),sde=ko(),HMe=require("util"),ide=require("child_process"),ode=require("fs"),{execFile:ade}=ide,je;z$.exports={enterPM2Mode:cde,start:ec,stop:qw,reload:B$,restart:H$,list:$w,describe:G$,connect:Yo,kill:_de,startAllServices:pde,startService:Vw,getUniqueServicesList:q$,restartAllServices:hde,isServiceRegistered:$$,reloadStopStart:V$,restartHdb:F$,deleteProcess:dde,startClusteringProcesses:Y$,startClusteringThreads:W$,isHdbRestartRunning:fde,isClusteringRunning:Ede,stopClustering:mde,reloadClustering:gde,expectedRestartOfChildren:k$};var Jp=!1;nde(e=>{e.type==="restart"&&xS.initSync(!0)});function cde(){Jp=!0}a(cde,"enterPM2Mode");function Yo(){return je||(je=require("pm2")),new Promise((e,t)=>{je.connect((r,n)=>{r&&t(r),e(n)})})}a(Yo,"connect");var nn,lde=10,x$;function ec(e,t=!1){if(Jp)return ude(e);let r=ade(e.script,e.args.split(" "),e);r.name=e.name,r.config=e,r.on("exit",async i=>{let o=nn.indexOf(r);o>-1&&nn.splice(o,1),!x$&&i!==0&&(e.restarts=(e.restarts||0)+1,e.restarts<lde&&(ode.existsSync(Ko.getHubConfigPath())?ec(e):(await Ko.generateNatsConfig(!0),ec(e),await new Promise(c=>setTimeout(c,3e3)),await Ko.removeNatsConfig(tt.PROCESS_DESCRIPTORS.CLUSTERING_HUB),await Ko.removeNatsConfig(tt.PROCESS_DESCRIPTORS.CLUSTERING_LEAF))))});let n={serviceName:e.name.replace(/ /g,"-")};function s(i){let o=xS.get(tt.CONFIG_PARAMS.CLUSTERING_LOGLEVEL),c=/\[\d+][^\[]+\[(\w+)]/g,l,u=0,f;for(;l=c.exec(i);){if(l.index&&Vo.LOG_LEVEL_HIERARCHY[o]>=Vo.LOG_LEVEL_HIERARCHY[f||"info"]){let p=f===Vo.LOG_LEVELS.ERR||f===Vo.LOG_LEVELS.WRN?ql.OUTPUTS.STDERR:ql.OUTPUTS.STDOUT;ql.logCustomLevel(f||"info",p,n,i.slice(u,l.index).trim())}let[d,_]=l;u=l.index+d.length,f=Vo.LOG_LEVELS[_]}if(Vo.LOG_LEVEL_HIERARCHY[o]>=Vo.LOG_LEVEL_HIERARCHY[f||"info"]){let d=f===Vo.LOG_LEVELS.ERR||f===Vo.LOG_LEVELS.WRN?ql.OUTPUTS.STDERR:ql.OUTPUTS.STDOUT;ql.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(),!nn&&(nn=[],!t)){let i=a(()=>{x$=!0,nn&&(nn.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)}nn.push(r)}a(ec,"start");function ude(e){return new Promise(async(t,r)=>{try{await Yo()}catch(n){r(n)}je.start(e,(n,s)=>{n&&(je.disconnect(),r(n)),je.disconnect(),t(s)})})}a(ude,"startWithPM2");function qw(e){if(!Jp){for(let t of nn||[])t.name===e&&(nn.splice(nn.indexOf(t),1),t.kill());return}return new Promise(async(t,r)=>{try{await Yo()}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(qw,"stop");function B$(e){return new Promise(async(t,r)=>{try{await Yo()}catch(n){r(n)}je.reload(e,(n,s)=>{n&&(je.disconnect(),r(n)),je.disconnect(),t(s)})})}a(B$,"reload");function H$(e){if(!Jp){k$();for(let t of nn||[])t.name===e&&t.kill()}return new Promise(async(t,r)=>{try{await Yo()}catch(n){r(n)}je.restart(e,(n,s)=>{je.disconnect(),t(s)})})}a(H$,"restart");function k$(){for(let e of nn||[])e.config&&(e.config.restarts=0)}a(k$,"expectedRestartOfChildren");function dde(e){return new Promise(async(t,r)=>{try{await Yo()}catch(n){r(n)}je.delete(e,(n,s)=>{n&&(je.disconnect(),r(n)),je.disconnect(),t(s)})})}a(dde,"deleteProcess");async function F$(){await ec(Za.generateRestart())}a(F$,"restartHdb");async function fde(){let e=await $w();for(let t in e)if(e[t].name===tt.PROCESS_DESCRIPTORS.RESTART_HDB)return!0;return!1}a(fde,"isHdbRestartRunning");function $w(){return new Promise(async(e,t)=>{try{await Yo()}catch(r){t(r)}je.list((r,n)=>{r&&(je.disconnect(),t(r)),je.disconnect(),e(n)})})}a($w,"list");function G$(e){return new Promise(async(t,r)=>{try{await Yo()}catch(n){r(n)}je.describe(e,(n,s)=>{n&&(je.disconnect(),r(n)),je.disconnect(),t(s)})})}a(G$,"describe");function _de(){if(!Jp){for(let e of nn||[])e.kill();nn=[];return}return new Promise(async(e,t)=>{try{await Yo()}catch(r){t(r)}je.killDaemon((r,n)=>{r&&(je.disconnect(),t(r)),je.disconnect(),e(n)})})}a(_de,"kill");async function pde(){try{await Y$(),await W$(),await ec(Za.generateAllServiceConfigs())}catch(e){throw je?.disconnect(),e}}a(pde,"startAllServices");async function Vw(e,t=!1){try{let r;switch(e=e.toLowerCase(),e){case tt.PROCESS_DESCRIPTORS.HDB.toLowerCase():r=Za.generateMainServerConfig();break;case tt.PROCESS_DESCRIPTORS.CLUSTERING_INGEST_SERVICE.toLowerCase():r=Za.generateNatsIngestServiceConfig();break;case tt.PROCESS_DESCRIPTORS.CLUSTERING_REPLY_SERVICE.toLowerCase():r=Za.generateNatsReplyServiceConfig();break;case tt.PROCESS_DESCRIPTORS.CLUSTERING_HUB.toLowerCase():r=Za.generateNatsHubServerConfig(),await ec(r,t),await Ko.removeNatsConfig(e);return;case tt.PROCESS_DESCRIPTORS.CLUSTERING_LEAF.toLowerCase():r=Za.generateNatsLeafServerConfig(),await ec(r,t),await Ko.removeNatsConfig(e);return;case tt.PROCESS_DESCRIPTORS.CLUSTERING_UPGRADE_4_0_0.toLowerCase():r=Za.generateClusteringUpgradeV4ServiceConfig();break;default:throw new Error(`Start service called with unknown service config: ${e}`)}await ec(r)}catch(r){throw je?.disconnect(),r}}a(Vw,"startService");async function q$(){try{let e=await $w(),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(q$,"getUniqueServicesList");async function hde(e=[]){try{let t=!1,r=await q$();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 H$(o))}t&&await V$(tt.PROCESS_DESCRIPTORS.HDB)}catch(t){throw je?.disconnect(),t}}a(hde,"restartAllServices");async function $$(e){if(nn?.find(r=>r.name===e))return!0;let t=await sde.getHDBProcessInfo();return t.core.length&&t.core[0]?.parent==="PM2"}a($$,"isServiceRegistered");async function V$(e){let t=xS.get(tt.CONFIG_PARAMS.THREADS_COUNT)??xS.get(tt.CONFIG_PARAMS.THREADS),r=await G$(e),n=tde.isEmptyOrZeroLength(r)?0:r.length;t!==n?(await qw(e),await Vw(e)):e===tt.PROCESS_DESCRIPTORS.HDB?await F$():await B$(e)}a(V$,"reloadStopStart");var K$;async function Y$(e=!1){for(let t in tt.CLUSTERING_PROCESSES){let r=tt.CLUSTERING_PROCESSES[t];await Vw(r,e)}}a(Y$,"startClusteringProcesses");async function W$(){K$=U$(tt.LAUNCH_SERVICE_SCRIPTS.NATS_REPLY_SERVICE,{name:tt.PROCESS_DESCRIPTORS.CLUSTERING_REPLY_SERVICE});try{await US.deleteLocalStream("__HARPERDB_WORK_QUEUE__")}catch{}await US.updateLocalStreams();let e=await rde.getAllNodeRecords();for(let t=0,r=e.length;t<r;t++)if(e[t].system_info?.hdb_version===tt.PRE_4_0_0_VERSION){ql.info("Starting clustering upgrade 4.0.0 process"),U$(tt.LAUNCH_SERVICE_SCRIPTS.NODES_UPGRADE_4_0_0,{name:"Upgrade-4-0-0"});break}}a(W$,"startClusteringThreads");async function mde(){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 K$.terminate();else{let t=tt.CLUSTERING_PROCESSES[e];await qw(t)}}a(mde,"stopClustering");async function Ede(){for(let e in tt.CLUSTERING_PROCESSES){let t=tt.CLUSTERING_PROCESSES[e];if(await $$(t)===!1)return!1}return!0}a(Ede,"isClusteringRunning");async function gde(){await Ko.generateNatsConfig(!0),await US.reloadNATSHub(),await US.reloadNATSLeaf(),await Ko.removeNatsConfig(tt.PROCESS_DESCRIPTORS.CLUSTERING_HUB.toLowerCase()),await Ko.removeNatsConfig(tt.PROCESS_DESCRIPTORS.CLUSTERING_LEAF.toLowerCase())}a(gde,"reloadClustering")});var kS={};xe(kS,{compactOnStart:()=>Sde,copyDb:()=>eV});async function Sde(){tc.notify("Running compact on start"),console.log("Running compact on start");let e=(0,Kw.get)(x.ROOTPATH),t=new Map,r=Xe();(0,Yw.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,BS.join)(e,"backup",n+".mdb"),o=(0,BS.join)(e,xc,n+"-copy.mdb"),c=0;try{c=await j$(n),console.log("Database",n,"before compact has a total record count of",c)}catch(l){tc.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 eV(n,o),console.log("Backing up",n,"to",i),await(0,$l.move)(s,i,{overwrite:!0}),console.log("Moving copy compacted",n,"to",s),await(0,$l.move)(o,s,{overwrite:!0}),await(0,$l.remove)((0,BS.join)(e,xc,`${n}-copy.mdb-lock`))}try{Fd()}catch(n){tc.error("Error resetting databases after backup",n),console.error("Error resetting databases after backup",n)}try{Fd()}catch(n){tc.error("Error resetting databases after backup",n),console.error("Error resetting databases after backup",n),process.exit(0)}}catch(n){tc.error("Error compacting database, rolling back operation",n),console.error("Error compacting database, rolling back operation",n),(0,Yw.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,$l.move)(o,i,{overwrite:!0})}catch(c){console.error(c)}}throw Fd(),n}for(let[n,{backup_dest:s,record_count:i}]of t){let o=await j$(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}.
|
|
26
|
+
Total record count before compaction: ${i}, total after: ${o}.
|
|
27
|
+
Database backup has not been removed and can be found here: ${s}`;tc.error(c),console.error(c)}(0,Kw.get)(x.STORAGE_COMPACTONSTARTKEEPBACKUP)!==!0&&(console.log("Removing backup",s),await(0,$l.remove)(s))}}async function j$(e){let t=await(0,Z$.describeSchema)({database:e}),r=0;for(let n in t)r+=t[n].record_count;return r}function kd(){}async function eV(e,t){console.log(`Copying database ${e} to ${t}`);let r=Xe()[e];if(!r)throw new Error(`Source database not found: ${e}`);let n;for(let d in r){let _=r[d];_.primaryStore.put=kd,_.primaryStore.remove=kd;for(let p in _.indices){let h=_.indices[p];h.put=kd,h.remove=kd}_.auditStore&&(_.auditStore.put=kd,_.auditStore.remove=kd),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,J$.open)(new Q$.default(t)),c=o.openDB(HS.INTERNAL_DBIS_NAME),l,u=0,f=s.useReadTransaction();try{for(let{key:_,value:p}of s.getRange({transaction:f})){let h=p.is_hash_attribute||p.isPrimaryKey,S,g;if(h&&(S=p.compression,g=GS(),g?p.compression=g:delete p.compression,S?.dictionary?.toString()===g?.dictionary?.toString()&&(S=null,g=null)),c.put(_,p),!(h||p.indexed))continue;let R=new X$.default(!h,h);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,h,f)}if(i){let _=n.openDB(HS.AUDIT_STORE_NAME,Qp);console.log("copying audit log for",e,"to",t),d(i,_,!1,f)}async function d(_,p,h,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:Z}=_.getEntry(v,{transaction:S});if(H?.length<14&&h){E++;continue}l=p.put(v,H,h?Z: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 J$,BS,$l,Kw,Q$,X$,HS,Z$,Yw,tc,FS=Re(()=>{Le();J$=require("lmdb"),BS=require("path"),$l=require("fs-extra"),Kw=M(ce()),Q$=M(S_()),X$=M(g_()),HS=M(qt());k();Mi();Z$=M(wo()),Yw=M(Ot()),tc=M(J());a(Sde,"compactOnStart");a(j$,"getTotalDBRecordCount");a(kd,"noop");a(eV,"copyDb")});var rc=P((zMe,aV)=>{"use strict";var Tde=require("minimist"),{isMainThread:zw,parentPort:Zp,threadId:KMe}=require("worker_threads"),lt=(k(),C(G)),Qi=J(),jw=ie(),$S=LS(),qS=ar(),YMe=yt(),sV=Ot(),hi=Hd(),tV=ko(),{compactOnStart:Ade}=(FS(),C(kS)),Rde=Ea(),{restartWorkers:VS,onMessageByType:yde}=nt(),{handleHDBError:bde,hdb_errors:Ode}=pe(),{HTTP_STATUS_CODES:Nde}=Ode,eh=ce(),{sendOperationToNode:rV,getThisNodeName:wde,monitorNodeCAs:Ide}=(ss(),C(Uo)),{getHDBNodeTable:WMe}=(Ol(),C(uN));eh.initSync();var Xp=`Restarting HarperDB. This may take up to ${lt.RESTART_TIMEOUT_MS/1e3} seconds.`,Cde="Restart is not available from the CLI when running in non-pm2 mode. Either call restart from the API or stop and start HarperDB.",nV="Clustering is not enabled so cannot be restarted",Pde="Invalid service",Gd,Ms;aV.exports={restart:iV,restartService:Jw};zw&&yde(lt.ITC_EVENT_TYPES.RESTART,async(e,t)=>{e.workerType?await Jw({service:e.workerType}):iV({operation:"restart"}),t.postMessage({type:"restart-complete"})});async function iV(e){Ms=Object.keys(e).length===0,Gd=await hi.isServiceRegistered(lt.PROCESS_DESCRIPTORS.HDB);let t=Tde(process.argv);if(t.service){await Jw(t);return}if(Ms&&!Gd){console.error(Cde);return}if(Ms&&console.log(Xp),Gd){hi.enterPM2Mode(),Qi.notify(Xp);let r=Rde(Object.keys(lt.CONFIG_PARAM_MAP),!0);return jw.isEmptyOrZeroLength(Object.keys(r))||sV.updateConfigValue(void 0,void 0,r,!0,!0),Dde(),Xp}return zw?(Qi.notify(Xp),eh.get(lt.CONFIG_PARAMS.STORAGE_COMPACTONSTART)&&await Ade(),process.env.HARPER_EXIT_ON_RESTART&&process.exit(0),setTimeout(()=>{VS()},50)):Zp.postMessage({type:lt.ITC_EVENT_TYPES.RESTART}),Xp}a(iV,"restart");async function Jw(e){let{service:t}=e;if(lt.HDB_PROCESS_SERVICES[t]===void 0)throw bde(new Error,Pde,Nde.BAD_REQUEST,void 0,void 0,!0);if(hi.expectedRestartOfChildren(),Gd=await hi.isServiceRegistered(lt.PROCESS_DESCRIPTORS.HDB),!zw){e.replicated&&Ide(),Zp.postMessage({type:lt.ITC_EVENT_TYPES.RESTART,workerType:t}),Zp.ref(),await new Promise(s=>{Zp.on("message",i=>{i.type==="restart-complete"&&(s(),Zp.unref())})});let n;if(e.replicated){e.replicated=!1,n=[];for(let s of server.nodes){if(s.name===wde())continue;let i;try{({job_id:i}=await rV(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 p=new Error("Timed out waiting for restart job to complete");p.replicated=n,c(p)}let _=(await rV(s,{operation:"get_job",id:i})).results[0];if(_.status==="COMPLETE"&&(clearInterval(f),o({node:s.name,message:_.message})),_.status==="ERROR"){clearInterval(f);let p=new Error(_.message);p.replicated=n,c(p)}},250)}))}return{replicated:n}}return}let r;switch(t){case lt.HDB_PROCESS_SERVICES.clustering:if(!eh.get(lt.CONFIG_PARAMS.CLUSTERING_ENABLED)){r=nV;break}Ms&&console.log("Restarting clustering"),Qi.notify("Restarting clustering"),await oV();break;case lt.HDB_PROCESS_SERVICES.clustering_config:case lt.HDB_PROCESS_SERVICES["clustering config"]:if(!eh.get(lt.CONFIG_PARAMS.CLUSTERING_ENABLED)){r=nV;break}Ms&&console.log("Restarting clustering_config"),Qi.notify("Restarting clustering_config"),await hi.reloadClustering();break;case"custom_functions":case"custom functions":case lt.HDB_PROCESS_SERVICES.harperdb:case lt.HDB_PROCESS_SERVICES.http_workers:case lt.HDB_PROCESS_SERVICES.http:if(Ms&&!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}Ms&&console.log("Restarting http_workers"),Qi.notify("Restarting http_workers"),Ms?await hi.restart(lt.PROCESS_DESCRIPTORS.HDB):await VS("http");break;default:r=`Unrecognized service: ${t}`;break}return r?(Qi.error(r),Ms&&console.error(r),r):(t==="custom_functions"&&(t="Custom Functions"),`Restarting ${t}`)}a(Jw,"restartService");async function Dde(){await oV(),await hi.restart(lt.PROCESS_DESCRIPTORS.HDB),await jw.async_set_timeout(2e3),eh.get(lt.CONFIG_PARAMS.CLUSTERING_ENABLED)&&await Ww(),Ms&&(await qS.closeConnection(),process.exit(0))}a(Dde,"restartPM2Mode");async function oV(){if(!sV.getConfigFromFile(lt.CONFIG_PARAMS.CLUSTERING_ENABLED))return;if((await tV.getHDBProcessInfo()).clustering.length===0)Qi.trace("Clustering not running, restart will start clustering services"),await $S.generateNatsConfig(!0),await hi.startClusteringProcesses(),await hi.startClusteringThreads(),await Ww(),Ms&&await qS.closeConnection();else{await $S.generateNatsConfig(!0),Gd?(Qi.trace("Restart clustering restarting PM2 managed Hub and Leaf servers"),await hi.restart(lt.PROCESS_DESCRIPTORS.CLUSTERING_HUB),await hi.restart(lt.PROCESS_DESCRIPTORS.CLUSTERING_LEAF)):(await tV.getHDBProcessInfo()).clustering.forEach(s=>{Qi.trace("Restart clustering killing process pid",s.pid),process.kill(s.pid)}),await jw.async_set_timeout(3e3),await Ww(),await qS.updateLocalStreams(),Ms&&await qS.closeConnection(),Qi.trace("Restart clustering restarting ingest and reply service threads");let t=VS(lt.LAUNCH_SERVICE_SCRIPTS.NATS_INGEST_SERVICE),r=VS(lt.LAUNCH_SERVICE_SCRIPTS.NATS_REPLY_SERVICE);await t,await r}}a(oV,"restartClustering");async function Ww(){await $S.removeNatsConfig(lt.PROCESS_DESCRIPTORS.CLUSTERING_HUB),await $S.removeNatsConfig(lt.PROCESS_DESCRIPTORS.CLUSTERING_LEAF)}a(Ww,"removeNatsConfig")});var gV=P((QMe,EV)=>{"use strict";var JMe=require("lodash"),Mn=(k(),C(G)),{handleHDBError:cV,hdb_errors:Lde}=pe(),{HDB_ERROR_MSGS:Mde,HTTP_STATUS_CODES:vde}=Lde,Qw=J();EV.exports={getRolePermissions:xde};var Vl=Object.create(null),Ude=a(e=>({key:e,perms:{}}),"perms_template_obj"),fV=a((e=!1)=>({describe:e,tables:{}}),"schema_perms_template"),_V=a((e=!1,t=!1,r=!1,n=!1)=>({[Mn.PERMS_CRUD_ENUM.READ]:e,[Mn.PERMS_CRUD_ENUM.INSERT]:t,[Mn.PERMS_CRUD_ENUM.UPDATE]:r,[Mn.PERMS_CRUD_ENUM.DELETE]:n}),"permissions_template"),Xw=a((e=!1,t=!1,r=!1,n=!1,s=!1)=>({attribute_permissions:[],describe:e,..._V(t,r,n,s)}),"table_perms_template"),lV=a((e,t=_V())=>({attribute_name:e,describe:mV(t),[th]:t[th],[Zw]:t[Zw],[eI]:t[eI]}),"attr_perms_template"),uV=a((e,t=!1)=>({attribute_name:e,describe:t,[th]:t}),"timestamp_attr_perms_template"),{READ:th,INSERT:Zw,UPDATE:eI}=Mn.PERMS_CRUD_ENUM,pV=Object.values(Mn.PERMS_CRUD_ENUM),hV=[th,Zw,eI];function xde(e){let t;try{if(e.permission.super_user||e.permission.cluster_user)return e.permission;let r={...global.hdb_schema};delete r[Mn.SYSTEM_SCHEMA_NAME],t=e.role;let n=JSON.stringify([e.__updatedtime__,r]);if(Vl[t]&&Vl[t].key===n)return Vl[t].perms;let s=Bde(e,r);return Vl[t]?Vl[t].key=n:Vl[t]=Ude(n),Vl[t].perms=s,s}catch(r){if(!e[Mn.TIME_STAMP_NAMES_ENUM.UPDATED_TIME]||e[Mn.TIME_STAMP_NAMES_ENUM.UPDATED_TIME]<Mn.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 Qw.error(n),Qw.debug(r),cV(new Error,Mde.OUTDATED_PERMS_TRANSLATION_ERROR,vde.BAD_REQUEST)}else{let n=`There was an error while translating role permissions for role: ${t}.
|
|
28
28
|
${r.stack}`;throw Qw.error(n),cV(new Error)}}}a(xde,"getRolePermissions");function Bde(e,t){let r=Object.create(null);r.super_user=!1;let n=e.permission;r[Mn.SYSTEM_SCHEMA_NAME]=n[Mn.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]=Hde(t[i]);return}r[i]=fV(),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=kde(c,l);r[i].describe||pV.forEach(f=>{u[f]&&(r[i].describe=!0)}),r[i].tables[o]=u}else r[i].tables[o]=Xw()})):Object.keys(t[i]).forEach(o=>{r[i].tables[o]=Xw()})}),r}a(Bde,"translateRolePermissions");function Hde(e){let t=fV(!0);return Object.keys(e).forEach(r=>{t.tables[r]=Xw(!0,!0,!0,!0,!0)}),t}a(Hde,"createStructureUserPermissions");function kde(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 Mn.TIME_STAMP_NAMES.includes(d)&&(_=uV(d,f[th])),u[d]=_,u},{}),o=t.primaryKey||t.hash_attribute,c=!!i[o],l=lV(o);return t.attributes.forEach(({attribute:u})=>{if(i[u]){let f=i[u];f.describe=mV(f),s.attribute_permissions.push(f),c||Fde(f,l)}else if(u!==o){let f;Mn.TIME_STAMP_NAMES.includes(u)?f=uV(u):f=lV(u),s.attribute_permissions.push(f)}}),c||s.attribute_permissions.push(l),s.describe=dV(s),s}else return e.describe=dV(e),e}a(kde,"getTableAttrPerms");function dV(e){return pV.filter(t=>e[t]).length>0}a(dV,"getSchemaTableDescribePerm");function mV(e){return hV.filter(t=>e[t]).length>0}a(mV,"getAttributeDescribePerm");function Fde(e,t){hV.forEach(r=>{e[r]&&!t[r]&&(t[r]=!0,t.describe=!0)})}a(Fde,"checkForHashPerms")});var rh={};xe(rh,{authentication:()=>OV,bypassAuth:()=>zde,login:()=>Jde,logout:()=>Qde,start:()=>jde});function zde(){bV=!0}async function OV(e,t){let r=e.headers.asObject,n=r.authorization,s=r.cookie,i=r.origin,o=[];try{if(i){let p=e.isOperationsServer?Vde?$de:[]:qde?Gde:[];if(p.includes(i)||p.includes("*")){if(e.method==="OPTIONS"){let h=sn.get(x.HTTP_CORSACCESSCONTROLALLOWHEADERS)??"Accept, Content-Type, Authorization",S=new Lo([["Access-Control-Allow-Methods","POST, GET, PUT, DELETE, PATCH, OPTIONS"],["Access-Control-Allow-Headers",h],["Access-Control-Allow-Origin",i]]);return KS&&S.set("Access-Control-Allow-Credentials","true"),{status:200,headers:S}}o.push("Access-Control-Allow-Origin",i),KS&&o.push("Access-Control-Allow-Credentials","true")}}let l,u;if(KS){i||(i=r.host);let p=(i?i.replace(/^https?:\/\//,"").replace(/\W/,"_")+"-":"")+"hdb-session=",h=s?.split(/;\s+/)||[];for(let S of h)if(S.startsWith(p)){let g=S.indexOf(";");l=S.slice(p.length,g===-1?S.length:g),u=await SV.get(l);break}e.session=u||(u={})}let f=a((p,h,S)=>{let g=new qd.AuthAuditLog(p,h,ma.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),h===Qs.SUCCESS?tI.notify(g):tI.error(g)},"authAuditLog");if(!e.authorized&&e.mtlsConfig&&e.peerCertificate.subject&&e?._nodeRequest?.socket?.authorizationError&&tI.error("Authorization error:",e._nodeRequest.socket.authorizationError),e.mtlsConfig&&e.authorized&&e.peerCertificate.subject){let p=e.mtlsConfig.user;p!==null?((p===void 0||p==="Common Name"||p==="CN")&&(p=e.peerCertificate.subject.CN),e.user=await Ye.getUser(p,null,e),f(p,Qs.SUCCESS,"mTLS")):(0,qd.debug)("HTTPS/WSS mTLS authorized connection (mTLS did not authorize a user)","from",e.ip)}let d;if(!e.user)if(n){if(d=Kl.get(n),!d){let p=n.indexOf(" "),h=n.slice(0,p),S=n.slice(p+1),g,R;try{switch(h){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 GO(S)}catch(N){if(N.message==="invalid token")try{return await Tg(S),c({status:-1})}catch{throw N}}break}}catch(E){return Yde&&(Kl.get(S)||(Kl.set(S,S),f(g,Qs.FAILURE,h))),c({status:401,body:wa({error:E.message},e)})}Kl.set(n,d),Kde&&f(d.username,Qs.SUCCESS,h)}e.user=d}else u?.user?e.user=await Ye.getUser(u.user,null,e):(bV&&(e.ip?.includes("127.0.0.")||e.ip=="::1")||e?._nodeRequest?.socket?.server?._pipeName&&e.ip===void 0)&&(e.user=await(0,AV.getSuperUser)());KS&&(e.session.update=function(p){let h=sn.get(x.AUTHENTICATION_COOKIE_EXPIRES);if(!l){l=(0,RV.v4)();let S=sn.get(x.AUTHENTICATION_COOKIE_DOMAINS),g=h?new Date(Date.now()+(0,rI.convertToMS)(h)).toUTCString():Wde,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"))),p.id=l,SV.put(p,{expiresAt:h?Date.now()+(0,rI.convertToMS)(h):void 0})},e.login=async function(p,h){let S=e.user=await Ye.authenticateUser(p,h,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")&&bs.loginPath?(_.status=302,_.headers.set("Location",bs.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 Lo);for(let d=0;d<u;){let _=o[d++];f.set(_,o[d++])}}return o=null,l}a(c,"applyResponseHeaders")}function jde({server:e,port:t,securePort:r}){e.http(OV,t||r?{port:t,securePort:r}:{port:"all"}),TV||(TV=!0,setInterval(()=>{Kl=new Map},sn.get(x.AUTHENTICATION_CACHETTL)).unref(),yV.user.addListener(()=>{Kl=new Map}))}async function Jde(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 Qde(e){if(!e.baseRequest.session)throw new Error("No session for logout");return await e.baseRequest.session.update({user:null}),"Logout successful"}var AV,RV,sn,qd,yV,rI,tI,Gde,qde,$de,Vde,SV,KS,bV,Kde,Yde,Wde,Kl,TV,YS=Re(()=>{AV=M(wn());Ur();Iu();od();Le();RV=require("uuid"),sn=M(ce());k();qd=M(J()),yV=M(H_());cp();rI=M(ie());go();tI=(0,qd.loggerWithTag)("auth-event");sn.initSync();Gde=sn.get(x.HTTP_CORSACCESSLIST),qde=sn.get(x.HTTP_CORS),$de=sn.get(x.OPERATIONSAPI_NETWORK_CORSACCESSLIST),Vde=sn.get(x.OPERATIONSAPI_NETWORK_CORS),SV=_t({table:"hdb_session",database:"system",attributes:[{name:"id",isPrimaryKey:!0},{name:"user"}]}),KS=sn.get(x.AUTHENTICATION_ENABLESESSIONS)??!0,bV=process.env.AUTHENTICATION_AUTHORIZELOCAL??sn.get(x.AUTHENTICATION_AUTHORIZELOCAL)??process.env.DEV_MODE,Kde=sn.get(x.LOGGING_AUDITAUTHEVENTS_LOGSUCCESSFUL)??!1,Yde=sn.get(x.LOGGING_AUDITAUTHEVENTS_LOGFAILED)??!1,Wde="Tue, 01 Oct 8307 19:33:20 GMT",Kl=new Map;Ye.onInvalidatedUser(()=>{Kl=new Map});a(zde,"bypassAuth");a(OV,"authentication");a(jde,"start");a(Jde,"login");a(Qde,"logout")});var LV=P((ave,DV)=>{"use strict";var Ne=require("joi"),NV=require("fs-extra"),wV=require("path"),us=ct(),IV=ce(),CV=(k(),C(G)),PV=J(),{hdb_errors:Xde}=pe(),{HDB_ERROR_MSGS:on}=Xde,Wo=/^[a-zA-Z0-9-_]+$/,Zde=/^[a-zA-Z0-9-_]+$/;DV.exports={getDropCustomFunctionValidator:tfe,setCustomFunctionValidator:rfe,addComponentValidator:ofe,dropCustomFunctionProjectValidator:afe,packageComponentValidator:cfe,deployComponentValidator:lfe,setComponentFileValidator:nfe,getComponentFileValidator:ife,dropComponentFileValidator:sfe,addSSHKeyValidator:ufe,updateSSHKeyValidator:dfe,deleteSSHKeyValidator:ffe,setSSHKnownHostsValidator:_fe};function WS(e,t,r){try{let n=IV.get(CV.CONFIG_PARAMS.COMPONENTSROOT),s=wV.join(n,t);return NV.existsSync(s)?e?t:r.message(on.PROJECT_EXISTS):e?r.message(on.NO_PROJECT):t}catch(n){return PV.error(n),r.message(on.VALIDATION_ERR)}}a(WS,"checkProjectExists");function nh(e,t){return e.includes("..")?t.message("Invalid file path"):e}a(nh,"checkFilePath");function efe(e,t,r,n){try{let s=IV.get(CV.CONFIG_PARAMS.COMPONENTSROOT),i=wV.join(s,e,t,r+".js");return NV.existsSync(i)?r:n.message(on.NO_FILE)}catch(s){return PV.error(s),n.message(on.VALIDATION_ERR)}}a(efe,"checkFileExists");function tfe(e){let t=Ne.object({project:Ne.string().pattern(Wo).custom(WS.bind(null,!0)).required().messages({"string.pattern.base":on.BAD_PROJECT_NAME}),type:Ne.string().valid("helpers","routes").required(),file:Ne.string().pattern(Wo).custom(efe.bind(null,e.project,e.type)).custom(nh).required().messages({"string.pattern.base":on.BAD_FILE_NAME})});return us.validateBySchema(e,t)}a(tfe,"getDropCustomFunctionValidator");function rfe(e){let t=Ne.object({project:Ne.string().pattern(Wo).custom(WS.bind(null,!0)).required().messages({"string.pattern.base":on.BAD_PROJECT_NAME}),type:Ne.string().valid("helpers","routes").required(),file:Ne.string().custom(nh).required(),function_content:Ne.string().required()});return us.validateBySchema(e,t)}a(rfe,"setCustomFunctionValidator");function nfe(e){let t=Ne.object({project:Ne.string().pattern(Wo).required().messages({"string.pattern.base":on.BAD_PROJECT_NAME}),file:Ne.string().custom(nh).required(),payload:Ne.string().allow("").optional(),encoding:Ne.string().valid("utf8","ASCII","binary","hex","base64","utf16le","latin1","ucs2").optional()});return us.validateBySchema(e,t)}a(nfe,"setComponentFileValidator");function sfe(e){let t=Ne.object({project:Ne.string().pattern(Wo).required().messages({"string.pattern.base":on.BAD_PROJECT_NAME}),file:Ne.string().custom(nh).optional()});return us.validateBySchema(e,t)}a(sfe,"dropComponentFileValidator");function ife(e){let t=Ne.object({project:Ne.string().required(),file:Ne.string().custom(nh).required(),encoding:Ne.string().valid("utf8","ASCII","binary","hex","base64","utf16le","latin1","ucs2").optional()});return us.validateBySchema(e,t)}a(ife,"getComponentFileValidator");function ofe(e){let t=Ne.object({project:Ne.string().pattern(Wo).custom(WS.bind(null,!1)).required().messages({"string.pattern.base":on.BAD_PROJECT_NAME})});return us.validateBySchema(e,t)}a(ofe,"addComponentValidator");function afe(e){let t=Ne.object({project:Ne.string().pattern(Wo).custom(WS.bind(null,!0)).required().messages({"string.pattern.base":on.BAD_PROJECT_NAME})});return us.validateBySchema(e,t)}a(afe,"dropCustomFunctionProjectValidator");function cfe(e){let t=Ne.object({project:Ne.string().pattern(Wo).required().messages({"string.pattern.base":on.BAD_PROJECT_NAME}),skip_node_modules:Ne.boolean(),skip_symlinks:Ne.boolean()});return us.validateBySchema(e,t)}a(cfe,"packageComponentValidator");function lfe(e){let t=Ne.object({project:Ne.string().pattern(Wo).required().messages({"string.pattern.base":on.BAD_PROJECT_NAME}),package:Ne.string().optional(),restart:Ne.alternatives().try(Ne.boolean(),Ne.string().valid("rolling")).optional()});return us.validateBySchema(e,t)}a(lfe,"deployComponentValidator");function ufe(e){let t=Ne.object({name:Ne.string().pattern(Zde).required().messages({"string.pattern.base":on.BAD_SSH_KEY_NAME}),key:Ne.string().required(),host:Ne.string().required(),hostname:Ne.string().required(),known_hosts:Ne.string().optional()});return us.validateBySchema(e,t)}a(ufe,"addSSHKeyValidator");function dfe(e){let t=Ne.object({name:Ne.string().required(),key:Ne.string().required()});return us.validateBySchema(e,t)}a(dfe,"updateSSHKeyValidator");function ffe(e){let t=Ne.object({name:Ne.string().required()});return us.validateBySchema(e,t)}a(ffe,"deleteSSHKeyValidator");function _fe(e){let t=Ne.object({known_hosts:Ne.string().required()});return us.validateBySchema(e,t)}a(_fe,"setSSHKnownHostsValidator")});var oh=P((lve,BV)=>{"use strict";var zS=require("joi"),nc=require("path"),$d=require("fs-extra"),{exec:pfe,spawn:hfe}=require("child_process"),mfe=require("util"),Efe=mfe.promisify(pfe),Vd=(k(),C(G)),{PACKAGE_ROOT:gfe}=at(),{handleHDBError:sh,hdb_errors:Sfe}=pe(),{HTTP_STATUS_CODES:ih}=Sfe,Yl=ce(),Tfe=ct(),sc=J(),{once:Afe}=require("events");Yl.initSync();var nI=Yl.get(Vd.CONFIG_PARAMS.COMPONENTSROOT),MV="npm install --force --omit=dev --json",Rfe=`${MV} --dry-run`,yfe=Yl.get(Vd.CONFIG_PARAMS.ROOTPATH),jS=nc.join(yfe,"ssh");BV.exports={installModules:wfe,auditModules:Ife,installAllRootModules:bfe,uninstallRootModule:Ofe,linkHarperdb:Nfe,runCommand:Kd};async function bfe(e=!1,t=Yl.get(Vd.CONFIG_PARAMS.ROOTPATH)){await JS();let r=!1,n=process.env;$d.pathExistsSync(jS)&&$d.readdirSync(jS).forEach(s=>{s.includes(".key")&&!r&&(n={GIT_SSH_COMMAND:"ssh -F "+nc.join(jS,"config")+" -o UserKnownHostsFile="+nc.join(jS,"known_hosts"),...process.env},r=!0)});try{let s=Yl.get(Vd.CONFIG_PARAMS.ROOTPATH),i=nc.join(s,"node_modules","harperdb");$d.lstatSync(i).isSymbolicLink()&&$d.unlinkSync(i)}catch(s){s.code!=="ENOENT"&&sc.error("Error removing symlink:",s)}await Kd(e?"npm install --force --ignore-scripts":"npm install --force",t,n)}a(bfe,"installAllRootModules");async function Ofe(e){await Kd(`npm uninstall ${e}`,Yl.get(Vd.CONFIG_PARAMS.ROOTPATH))}a(Ofe,"uninstallRootModule");async function Nfe(){await JS(),await Kd(`npm link ${gfe}`,Yl.get(Vd.CONFIG_PARAMS.ROOTPATH))}a(Nfe,"linkHarperdb");async function Kd(e,t=void 0,r=process.env){sc.debug({tagName:"npm_run_command"},`running command: \`${e}\``);let n=hfe(e,{shell:!0,cwd:t,env:r,stdio:["ignore","pipe","pipe"]}),s="",i="";n.stdout.on("data",c=>{let l=c.toString();sc.debug({tagName:"npm_run_command:stdout"},l),s+=l}),n.stderr.on("data",c=>{let l=c.toString();sc.error({tagName:"npm_run_command:stderr"},l),i+=l});let[o]=await Afe(n,"close");if(o!==0)throw new Error(`Command \`${e}\` exited with code ${o}.${i===""?"":` Error: ${i}`}`);return s||void 0}a(Kd,"runCommand");async function wfe(e){let t="install_node_modules is deprecated. Dependencies are automatically installed on deploy, and install_node_modules can lead to inconsistent behavior";sc.warn(t,e.projects);let r=xV(e);if(r)throw sh(r,r.message,ih.BAD_REQUEST);let{projects:n,dry_run:s}=e,i=s===!0?Rfe:MV;await JS(),await UV(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=nc.join(nI,u),d,_=null;try{let{stdout:p,stderr:h}=await Efe(i,{cwd:f});d=p?p.replace(`
|
|
29
29
|
`,""):null,_=h?h.replace(`
|
|
30
30
|
`,""):null}catch(p){p.stderr?o[u].npm_error=vV(p.stderr):o[u].npm_error=p.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 sc.info(`finished installModules with response ${o}`),o.warning=t,o}a(wfe,"installModules");function vV(e){let t='"error": {',r=e.indexOf('"error": {'),n=e.indexOf(`}
|