harperdb 4.5.34 → 4.5.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 +211 -211
- package/package.json +1 -1
- 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.ce641166.js → main.eae3e997.js} +2 -2
- package/utility/scripts/restartHdb.js +3 -3
- /package/studio/build-local/static/js/{main.ce641166.js.LICENSE.txt → main.eae3e997.js.LICENSE.txt} +0 -0
|
@@ -21,9 +21,9 @@ Caused by:`));else if(typeof u=="object")try{n+=JSON.stringify(u)}catch{n+="Obje
|
|
|
21
21
|
`,""));return r.replace(`
|
|
22
22
|
`,"")}a(kH,"runCommand");async function Rne(){try{await Xre.access(sO)}catch{return!1}let e=await kH(`${sO} --version`,void 0),t=e.substring(e.lastIndexOf("v")+1,e.length);return Zre.eq(t,Tne)}a(Rne,"checkNATSServerInstalled");async function lO(e,t,r,n=!0,s="127.0.0.1"){if(!t&&!r){let o=await BH.getClusterUser();if(rl(o))throw new Error("Unable to get nats connection. Cluster user is undefined.");t=o.username,r=o.decrypt_hash}js.trace("create nats connection called");let i=await dne({name:s,port:e,user:t,pass:r,maxReconnectAttempts:-1,waitOnFirstConnect:n,timeout:2e5,tls:{keyFile:wr.get(Qe.CONFIG_PARAMS.CLUSTERING_TLS_PRIVATEKEY),certFile:wr.get(Qe.CONFIG_PARAMS.CLUSTERING_TLS_CERTIFICATE),caFile:wr.get(Qe.CONFIG_PARAMS.CLUSTERING_TLS_CERT_AUTH),rejectUnauthorized:!1}});return i.protocol.transport.socket.unref(),js.trace("create connection established a nats client connection with id",i?.info?.client_id),i.closed().then(o=>{o&&js.error("Error with Nats client connection, connection closed",o),i===Jr&&FH()}),i}a(lO,"createConnection");function FH(){Jr=void 0,Zc=void 0,el=void 0,tl=void 0}a(FH,"clearClientCache");async function yne(){Jr&&(await Jr.drain(),Jr=void 0,Zc=void 0,el=void 0,tl=void 0)}a(yne,"closeConnection");var Jr,tl;async function V_(){return tl||(tl=lO(wr.get(Qe.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_NETWORK_PORT),void 0,void 0),Jr=await tl),Jr||tl}a(V_,"getConnection");async function K_(){if(Zc)return Zc;rl(Jr)&&await V_();let{domain:e}=Bu(Qe.PROCESS_DESCRIPTORS.CLUSTERING_LEAF);if(rl(e))throw new Error("Error getting JetStream domain. Unable to get JetStream manager.");return Zc=await Jr.jetstreamManager({domain:e,timeout:6e4}),Zc}a(K_,"getJetStreamManager");async function GH(){if(el)return el;rl(Jr)&&await V_();let{domain:e}=Bu(Qe.PROCESS_DESCRIPTORS.CLUSTERING_LEAF);if(rl(e))throw new Error("Error getting JetStream domain. Unable to get JetStream manager.");return el=Jr.jetstream({domain:e,timeout:6e4}),el}a(GH,"getJetStream");async function Ui(){let e=Jr||await V_(),t=Zc||await K_(),r=el||await GH();return{connection:e,jsm:t,js:r}}a(Ui,"getNATSReferences");async function bne(e){let t=wr.get(Qe.CONFIG_PARAMS.CLUSTERING_HUBSERVER_NETWORK_PORT),{sys_name:r,decrypt_hash:n}=await BH.getClusterUser(),s=await lO(t,r,n),i=cO(),o=s.subscribe(i),c=[],l,u=(async()=>{for await(let f of o){let d=HH.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 YE.async_set_timeout(e),await o.drain(),await s.close(),await u,c}a(bne,"getServerList");async function uO(e,t){let{jsm:r}=await Ui(),n=wr.get(Qe.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_STREAMS_MAXAGE);n=n===null?0:n*1e9;let s=wr.get(Qe.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_STREAMS_MAXMSGS);s=s===null?-1:s;let i=wr.get(Qe.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_STREAMS_MAXBYTES);i=i===null?-1:i,await r.streams.add({name:e,storage:fne.File,retention:_ne.Limits,subjects:t,discard:hne.Old,max_msgs:s,max_bytes:i,max_age:n})}a(uO,"createLocalStream");async function qH(){let{jsm:e}=await Ui(),t=await e.streams.list().next(),r=[];return t.forEach(n=>{r.push(n)}),r}a(qH,"listStreams");async function One(e){let{jsm:t}=await Ui();await t.streams.delete(e)}a(One,"deleteLocalStream");async function Nne(e){let{connection:t}=await Ui(),r=[],n=cO(),s=t.subscribe(n),i=(async()=>{for await(let o of s)r.push(HH.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(Nne,"listRemoteStreams");async function wne(e,t=void 0,r=void 0){let{jsm:n,js:s}=await Ui(),i=MH(),o={durable_name:i,ack_policy:oO.Explicit};t&&(o.deliver_policy=aO.StartTime,o.opt_start_time=new Date(t).toISOString()),await n.consumers.add(e,o);let c=await s.consumers.get(e,i),l=r?await c.fetch({max_messages:r,expires:2e3}):await c.consume();if(c._info.num_pending===0)return[];let u=[];for await(let f of l){let d=iO(f.data),_={nats_timestamp:f.info.timestampNanos,nats_sequence:f.info.streamSequence,entry:d};if(f.headers&&(_.origin=f.headers.get(Hr.MSG_HEADERS.ORIGIN)),u.push(_),f.ack(),f.info.pending===0)break}return await c.delete(),u}a(wne,"viewStream");async function*Ine(e,t=void 0,r=void 0){let{jsm:n,js:s}=await Ui(),i=MH(),o={durable_name:i,ack_policy:oO.Explicit};t&&(o.deliver_policy=aO.StartTime,o.opt_start_time=new Date(t).toISOString()),await n.consumers.add(e,o);let c=await s.consumers.get(e,i),l=r?await c.fetch({max_messages:r,expires:2e3}):await c.consume();if(c._info.num_pending===0)return[];for await(let u of l){let f=iO(u.data);f[0]||(f=[f]);for(let d of f){let _={nats_timestamp:u.info.timestampNanos,nats_sequence:u.info.streamSequence,entry:d};u.headers&&(_.origin=u.headers.get(Hr.MSG_HEADERS.ORIGIN)),yield _}if(u.ack(),u.info.pending===0)break}await c.delete()}a(Ine,"viewStreamIterator");async function Cne(e,t,r,n){js.trace(`publishToStream called with subject: ${e}, stream: ${t}, entries:`,n.operation),r=$H(n,r);let{js:s}=await Ui(),i=await zE(),o=`${e}.${i}`,c=await gne(()=>n instanceof Uint8Array?n:xH.encode(n));try{js.trace(`publishToStream publishing to subject: ${o}`),Ene(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 KH(async()=>{try{await s.publish(o,c,{headers:r})}catch{if(l.code&&l.code.toString()==="503"){js.trace(`publishToStream creating stream: ${t}`);let f=o.split(".");f[2]="*",await uO(t,[o]),await s.publish(o,c,{headers:r})}else throw l}});throw l}}a(Cne,"publishToStream");function $H(e,t){t===void 0&&(t=pne());let r=wr.get(Qe.CONFIG_PARAMS.CLUSTERING_NODENAME);return!t.has(Hr.MSG_HEADERS.ORIGIN)&&r&&t.append(Hr.MSG_HEADERS.ORIGIN,r),t}a($H,"addNatsMsgHeader");function Bu(e){e=e.toLowerCase();let t=$_.join(wr.get(Qe.CONFIG_PARAMS.ROOTPATH),Sne);if(e===Qe.PROCESS_DESCRIPTORS.CLUSTERING_HUB.toLowerCase())return rl(nO)&&(nO={port:G_.getConfigFromFile(Qe.CONFIG_PARAMS.CLUSTERING_HUBSERVER_NETWORK_PORT),server_name:G_.getConfigFromFile(Qe.CONFIG_PARAMS.CLUSTERING_NODENAME)+Hr.SERVER_SUFFIX.HUB,config_file:Hr.NATS_CONFIG_FILES.HUB_SERVER,pid_file_path:$_.join(t,Hr.PID_FILES.HUB),hdb_nats_path:t}),nO;if(e===Qe.PROCESS_DESCRIPTORS.CLUSTERING_LEAF.toLowerCase())return rl(rO)&&(rO={port:G_.getConfigFromFile(Qe.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_NETWORK_PORT),server_name:G_.getConfigFromFile(Qe.CONFIG_PARAMS.CLUSTERING_NODENAME)+Hr.SERVER_SUFFIX.LEAF,config_file:Hr.NATS_CONFIG_FILES.LEAF_SERVER,domain:G_.getConfigFromFile(Qe.CONFIG_PARAMS.CLUSTERING_NODENAME)+Hr.SERVER_SUFFIX.LEAF,pid_file_path:$_.join(t,Hr.PID_FILES.LEAF),hdb_nats_path:t}),rO;js.error(`Unable to get Nats server config. Unrecognized process: ${e}`)}a(Bu,"getServerConfig");async function VH(e,t,r,n){try{await e.consumers.add(t,{ack_policy:oO.Explicit,durable_name:r,deliver_policy:aO.StartTime,opt_start_time:n})}catch(s){if(s.message!=="consumer already exists")throw s}}a(VH,"createConsumer");async function Pne(e,t,r){await e.consumers.delete(t,r)}a(Pne,"removeConsumer");function Dne(e){return e.split(".")[1]}a(Dne,"extractServerName");async function Lne(e,t,r=6e4,n=cO()){if(!YE.isObject(t))throw new Error("data param must be an object");let s=xH.encode(t),{connection:i}=await Ui(),o={timeout:r};n&&(o.reply=n,o.noMux=!0);let c=await i.request(e,s,o);return iO(c.data)}a(Lne,"request");function dO(e){return new Promise(async(t,r)=>{let n=nne(sO,["--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(dO,"reloadNATS");async function Mne(){let{pid_file_path:e}=Bu(Qe.PROCESS_DESCRIPTORS.CLUSTERING_HUB);await dO(e)}a(Mne,"reloadNATSHub");async function vne(){let{pid_file_path:e}=Bu(Qe.PROCESS_DESCRIPTORS.CLUSTERING_LEAF);await dO(e)}a(vne,"reloadNATSLeaf");function Une(e,t,r){let n;switch(e.code){case LH.NoResponders:n=`Unable to ${t}, node '${r}' is not listening.`;break;case LH.Timeout:n=`Unable to ${t}, node '${r}' is listening but did not respond.`;break;default:n=e.message;break}return n}a(Une,"requestErrorHandler");async function xne(e,t){let r=t+Hr.SERVER_SUFFIX.LEAF,{connection:n}=await Ui(),{jsm:s}=await Vne(r),{schema:i,table:o}=e,c=WE.createNatsTableStreamName(i,o),l=e.start_time?e.start_time:new Date(Date.now()).toISOString();await KH(async()=>{if(e.subscribe===!0)await VH(s,c,n.info.server_name,l);else try{await Pne(s,c,n.info.server_name)}catch(u){js.trace(u)}})}a(xne,"updateRemoteConsumer");async function Bne(e,t,r,n){let s=WE.createNatsTableStreamName(e,t),i=r+Hr.SERVER_SUFFIX.LEAF,o={type:Qe.ITC_EVENT_TYPES.NATS_CONSUMER_UPDATE,status:n,stream_name:s,node_domain_name:i};if(!UH&&lne()<wr.get(Qe.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_STREAMS_MAXINGESTTHREADS)){let{updateConsumer:c}=tO();await c(o)}await ane(o),n==="stop"&&await YE.async_set_timeout(1e3)}a(Bne,"updateConsumerIterator");function KH(e){return one.writeTransaction(Qe.SYSTEM_SCHEMA_NAME,Qe.SYSTEM_TABLE_NAMES.NODE_TABLE_NAME,e)}a(KH,"exclusiveLock");async function YH(e,t){let r=WE.createNatsTableStreamName(e,t),n=await zE(),s=Gne(e,t,n);await uO(r,[s])}a(YH,"createLocalTableStream");async function Hne(e){for(let t=0,r=e.length;t<r;t++){let n=e[t].schema,s=e[t].table;await YH(n,s)}}a(Hne,"createTableStreams");async function WH(e,t,r=void 0){if(wr.get(Qe.CONFIG_PARAMS.CLUSTERING_ENABLED))try{let n=WE.createNatsTableStreamName(e,t),{domain:s}=Bu(Qe.PROCESS_DESCRIPTORS.CLUSTERING_LEAF);await(await(await V_()).jetstreamManager({domain:s,timeout:24e4})).streams.purge(n,r)}catch(n){if(n.message==="stream not found")js.warn(n);else throw n}}a(WH,"purgeTableStream");async function kne(e,t){if(wr.get(Qe.CONFIG_PARAMS.CLUSTERING_ENABLED))for(let r=0,n=t.length;r<n;r++)await WH(e,t[r])}a(kne,"purgeSchemaTableStreams");async function Fne(e){return(await K_()).streams.info(e)}a(Fne,"getStreamInfo");function Gne(e,t,r){return`${Hr.SUBJECT_PREFIXES.TXN}.${e}${t?"."+t:""}.${r}`}a(Gne,"createSubjectName");async function zE(){if(q_)return q_;if(q_=(await K_())?.nc?.info?.server_name,q_===void 0)throw new Error("Unable to get jetstream manager server name");return q_}a(zE,"getJsmServerName");async function qne(){let e=await K_(),t=await zE(),r=await qH();for(let n of r){let s=n.config,i=s.subjects[0];if(!i)continue;let o=$ne(n),c=i.split(".");if(c[c.length-1]===t&&!o||s.name==="__HARPERDB_WORK_QUEUE__")continue;let u=i.split(".");u[u.length-1]=t;let f=u.join(".");js.trace(`Updating stream subject name from: ${i} to: ${f}`),s.subjects[0]=f,await e.streams.update(s.name,s)}}a(qne,"updateLocalStreams");function $ne(e){let{config:t}=e,r=!1,n=wr.get(Qe.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_STREAMS_MAXAGE);n=n===null?0:n*1e9;let s=wr.get(Qe.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_STREAMS_MAXBYTES);s=s===null?-1:s;let i=wr.get(Qe.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_STREAMS_MAXMSGS);return i=i===null?-1:i,n!==t.max_age&&(t.max_age=n,r=!0),s!==t.max_bytes&&(t.max_bytes=s,r=!0),i!==t.max_msgs&&(t.max_msgs=i,r=!0),r}a($ne,"updateStreamLimits");async function Vne(e){let t,r;try{t=await Jr.jetstream({domain:e}),r=await Jr.jetstreamManager({domain:e,checkAPI:!1})}catch(n){throw js.error("Unable to connect to:",e),n}return{js:t,jsm:r}}a(Vne,"connectToRemoteJS")});function fO(e){let t=e.get(QE),r=t?(0,Hu.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:W_(e)??1,nodes:[]})})}i[n]=0,e.putSync(QE,(0,Hu.pack)(r))}return r}function Y_(e){return fO(e).remoteNameToId}function jH(e,t){let r=fO(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(QE,(0,Hu.pack)(r)),s}function jE(e,t){let r=fO(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(QE,(0,Hu.pack)(r))}return QH.trace?.("The remote node name map",e,n,s),s}var QH,Hu,QE,_O=Re(()=>{QH=M(Fs());ps();Hu=require("msgpackr"),QE=Symbol.for("remote-ids");a(fO,"getIdMappingRecord");a(Y_,"exportIdMapping");a(jH,"remoteToLocalNodeId");a(jE,"getIdOfRemoteNode")});var hO={};Ue(hO,{commits_awaiting_replication:()=>ku,getHDBNodeTable:()=>ir,getReplicationSharedStatus:()=>JE,iterateRoutes:()=>Q_,shouldReplicateToNode:()=>z_,subscribeToNodeUpdates:()=>Fu});function ir(){return JH||(JH=_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 JE(e,t,r,n){return new Float64Array(e.getUserSharedBuffer(["replicated",t,r],new ArrayBuffer(48),n&&{callback:n}))}function Fu(e){ir().subscribe({}).then(async t=>{for await(let r of t){let n=r?.value?.name;tk.debug?.("adding node",n,"on node",et()," on process",process.pid),server.nodes=server.nodes.filter(i=>i.name!==n),r.type==="put"&&n!==et()&&(r.value?server.nodes.push(r.value):console.error("Invalid node update event",r));let s=new Map;for await(let i of ir().search({}))if(i.shard!=null){let o=s.get(i.shard);o||s.set(i.shard,o=[]),o.push(i)}server.shards=s,(r.type==="put"||r.type==="delete")&&e(r.value,r.id)}})}function z_(e,t){let r=ga.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===ga.default.get(x.REPLICATION_SHARD))))&&ir().primaryStore.get(et())?.replicates||e.subscriptions?.some(n=>(n.database||n.schema)===t&&n.subscribe)}function Kne(){Fu(e=>{Sa({},(t,r)=>{let n=e.name,s=XH.get(n);if(s||XH.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=JE(i,r,n,()=>{let c=o[0],l=o.lastTime;for(let{txnTime:u,onConfirm:f}of ku.get(r)||[])u>l&&u<=c&&f();o.lastTime=c});o.lastTime=0,s.set(r,o)}})})}function*Q_(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=ga.default.get(x.REPLICATION_SECUREPORT)??(!ga.default.get(x.REPLICATION_PORT)&&ga.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||ga.default.get(x.REPLICATION_PORT)||ga.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){ZH.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 ZH,ek,ga,tk,JH,XH,ku,nl=Re(()=>{xe();ps();tp();ZH=require("worker_threads"),ek=M(he()),ga=M(le());k();tk=M(Fs());server.nodes=[];a(ir,"getHDBNodeTable");a(JE,"getReplicationSharedStatus");a(Fu,"subscribeToNodeUpdates");a(z_,"shouldReplicateToNode");XH=new Map;JD((e,t,r)=>{if(r>server.nodes.length)throw new ek.ClientError(`Cannot confirm replication to more nodes (${r}) than are in the network (${server.nodes.length})`);ku||(ku=new Map,Kne());let n=ku.get(e);return n||(n=[],ku.set(e,n)),new Promise(s=>{let i=0;n.push({txnTime:t,onConfirm:a(()=>{++i===r&&s()},"onConfirm")})})});a(Kne,"startSubscriptionToReplications");a(Q_,"iterateRoutes")});var sk={};Ue(sk,{connectedToNode:()=>sl,disconnectedFromNode:()=>qu,ensureNode:()=>To,requestClusterStatus:()=>nk,startOnMainThread:()=>EO});async function EO(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){XE.set(i,W_(l.auditStore));break}}}Bi.whenThreadsStarted.then(async()=>{let i=[];for await(let o of r.system.hdb_nodes?.search([])||[])i.push(o);for(let o of Q_(e))try{let c=!o.subscriptions;if(c){let u=et(),f=ir().primaryStore.get(u);if(f!==null){let d=e.url??Ta();(f===void 0||f.url!==d||f.shard!==e.shard)&&await To(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)}Fu(s)});let n;function s(i,o=i?.name){let c=et()&&o===et()||Ta()&&i?.url===Ta();if(c){let d=!!i?.replicates;if(n!==void 0&&n!==d)for(let _ of ir().search([]))_.replicates&&_.name!==o&&s(_,_.name);n=d}if(nt.trace("Setting up node replication for",i),!i){for(let[d,_]of xi){let h;for(let[m,{worker:S,nodes:g}]of _){let R=g[0];if(R&&R.name==o){h=!0;for(let[E,{worker:T}]of _)_.delete(E),nt.warn("Node was deleted, unsubscribing from node",o,E,d),T?.postMessage({type:"unsubscribe-from-node",node:o,database:E,url:d});break}}if(h){xi.get(d).iterator.remove(),xi.delete(d);return}}return}if(c)return;if(!i.url){nt.info(`Node ${i.name} is missing url`);return}let l=xi.get(i.url);if(l&&l.iterator.remove(),!(i.replicates===!0||i.replicates?.sends)&&!i.subscriptions?.length&&!l)return;if(nt.info(`Added node ${i.name} at ${i.url} for process ${et()}`),i.replicates&&i.subscriptions&&(i={...i,subscriptions:null}),i.name){for(let[d,_]of Gu)if(i.url===_.url){Gu.delete(d);break}Gu.set(i.name,i)}let u=Xe();if(l||(l=new Map,xi.set(i.url,l)),l.iterator=Sa(e,(d,_,h)=>{h?f(_,!0):f(_,!1)}),i.subscriptions)for(let d of i.subscriptions){let _=d.database||d.schema;u[_]||(nt.warn(`Database ${_} not found for node ${i.name}, making a subscription anyway`),f(_,!1))}function f(d,_){nt.trace("Setting up replication for database",d,"on node",i.name);let h=l.get(d),m,S=[{replicateByDefault:_,...i}];XE.has(d)&&(S.push({replicateByDefault:_,name:et(),start_time:XE.get(d),end_time:Date.now(),replicates:!0}),XE.delete(d));let g=z_(i,d),R=Bi.workers.filter(E=>E.name==="http");if(h?(m=h.worker,h.nodes=S):g&&(t=t%R.length,m=R[t++],l.set(d,{worker:m,nodes:S,url:i.url}),m?.on("exit",()=>{l.get(d)?.worker===m&&(l.delete(d),f(d,_))})),g)setTimeout(()=>{let E={type:"subscribe-to-node",database:d,nodes:S};m?m.postMessage(E):j_(E)},Yne);else{nt.info("Node no longer should be used, unsubscribing from node",i.replicates,!!u[d],ir().primaryStore.get(et())?.replicates),ir().primaryStore.get(et())?.replicates||(n=!1);let E={type:"unsubscribe-from-node",database:d,url:i.url,name:i.name};m?m.postMessage(E):eg(E)}}a(f,"onDatabase")}a(s,"onNodeUpdate"),qu=a(function(i){try{nt.info("Disconnected from node",i.name,i.url,"finished",!!i.finished);let o=Array.from(Gu.keys()),c=o.sort(),l=c.indexOf(i.name||Js(i.url));if(l===-1){nt.warn("Disconnected node not found in node map",i.name,o);return}let u=xi.get(i.url),f=u?.get(i.database);if(!f){nt.warn("Disconnected node not found in replication map",i.database,u);return}if(f.connected=!1,i.finished||!pO.default.get(x.REPLICATION_FAILOVER))return;let d=f.nodes[0];if(!(d.replicates===!0||d.replicates?.sends||d.subscriptions?.length))return;let _=d.shard,h=(l+1)%c.length;for(;l!==h;){let m=c[h],S=Gu.get(m);u=xi.get(S.url);let g=u?.get(i.database);if(!g||g.connected===!1||g.nodes[0].shard!==_){h=(h+1)%c.length;continue}let{worker:R,nodes:E}=g,T=!1;for(let N of f.nodes){if(E.some(v=>v.name===N.name)){nt.info(`Disconnected node is already failing over to ${m} for ${i.database}`);continue}N.end_time<Date.now()||(E.push(N),T=!0)}if(f.nodes=[f.nodes[0]],!T){nt.info(`Disconnected node ${i.name} has no nodes to fail over to ${m}`);return}nt.info(`Failing over ${i.database} from ${i.name} to ${m}`),R?R.postMessage({type:"subscribe-to-node",database:i.database,nodes:E}):j_({database:i.database,nodes:E});return}nt.warn("Unable to find any other node to fail over to",i.name,i.url)}catch(o){nt.error("Error failing over node",o)}},"disconnectedFromNode"),sl=a(function(i){let o=xi.get(i.url),c=o?.get(i.database);if(!c){nt.warn("Connected node not found in replication map, this may be because the node is being removed",i.database,o);return}c.connected=!0,c.latency=i.latency;let l=c.nodes[0];if(!l){nt.info("Connected node has no nodes",i.database,c);return}if(!l.name){nt.debug("Connected node is not named yet",i.database,c);return}c.nodes=[l];let u=!1;for(let f of xi.values()){let d=f.get(i.database);if(!d||d==c)continue;let{worker:_,nodes:h,connected:m}=d;if(h)if(m===!1&&h[0].shard===l.shard)u=!0,c.nodes.push(h[0]);else{let S=h.filter(g=>g.name!==l.name);S.length<h.length&&(d.nodes=S,_.postMessage({type:"subscribe-to-node",database:i.database,nodes:h}))}}u&&c.worker&&c.worker.postMessage({type:"subscribe-to-node",database:i.database,nodes:c.nodes})},"connectedToNode"),(0,Bi.onMessageByType)("disconnected-from-node",qu),(0,Bi.onMessageByType)("connected-to-node",sl),(0,Bi.onMessageByType)("request-cluster-status",nk)}function nk(e,t){let r=[];for(let[n,s]of Gu)try{let i=xi.get(s.url);nt.info("Getting cluster status for",n,s.url,"has dbs",i?.size);let o=[];if(i){for(let[l,{worker:u,connected:f,nodes:d,latency:_}]of i)o.push({database:l,connected:f,latency:_,thread_id:u?.threadId,nodes:d.filter(h=>!(h.end_time<Date.now())).map(h=>h.name)});let c=(0,mO.cloneDeep)(s);c.database_sockets=o,delete c.ca,delete c.node_name,delete c.__updatedtime__,delete c.__createdtime__,r.push(c)}}catch(i){nt.warn("Error getting cluster status for",s?.url,i)}return t?.postMessage({type:"cluster-status",connections:r}),{connections:r}}async function To(e,t){let r=ir();e=e??Js(t.url),t.name=e;try{if(t.ca){let s=new rk.X509Certificate(t.ca);t.ca_info={issuer:s.issuer.replace(/\n/g," "),subject:s.subject.replace(/\n/g," "),subject_alt_name:s.subjectAltName,serial_number:s.serialNumber,valid_from:s.validFrom,valid_to:s.validTo}}}catch(s){nt.error("Error parsing replication CA info for hdb_nodes table",s.message)}let n=r.primaryStore.get(e);if(nt.debug(`Ensuring node ${e} at ${t.url}, existing record:`,n,"new record:",t),!n)await r.patch(t);else{t.replicates&&!pO.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,mO.cloneDeep)(n[s]);for(let c of t[s]){let l=!1;for(let u of o)if((c.database??c.schema)===(u.database??u.schema)&&c.table===u.table){u.publish=c.publish,u.subscribe=c.subscribe,l=!0;break}l||i.push(c)}t.subscriptions=[...o,...i];break}if(Array.isArray(t.revoked_certificates)){let s=n.revoked_certificates||[];t.revoked_certificates=[...new Set([...s,...t.revoked_certificates])]}nt.info(`Updating node ${e} at ${t.url}`),await r.patch(t)}}var Bi,ZE,nt,mO,pO,rk,Yne,xi,qu,sl,Gu,XE,J_=Re(()=>{xe();Bi=M(ot());ps();ZE=require("worker_threads");nl();nt=M(ee()),mO=require("lodash"),pO=M(le());k();rk=require("crypto"),Yne=200,xi=new Map,Gu=new Map,XE=new Map;a(EO,"startOnMainThread");a(nk,"requestClusterStatus");ZE.parentPort&&(qu=a(e=>{ZE.parentPort.postMessage({type:"disconnected-from-node",...e})},"disconnectedFromNode"),sl=a(e=>{ZE.parentPort.postMessage({type:"connected-to-node",...e})},"connectedToNode"),(0,Bi.onMessageByType)("subscribe-to-node",e=>{j_(e)}),(0,Bi.onMessageByType)("unsubscribe-from-node",e=>{eg(e)}));a(To,"ensureNode")});var ei=C(wk=>{"use strict";var or=require("path"),{watch:Wne}=require("chokidar"),bn=require("fs-extra"),$u=require("node-forge"),uk=require("net"),{generateKeyPair:SO,X509Certificate:Ao,createPrivateKey:dk}=require("crypto"),zne=require("util");SO=zne.promisify(SO);var bt=$u.pki,Xs=require("joi"),{v4:fk}=require("uuid"),{validateBySchema:yO}=it(),Tt=ee(),Jn=le(),Es=(k(),P(q)),{CONFIG_PARAMS:ol}=Es,Zs=yA(),{ClientError:Ra}=he(),tg=require("node:tls"),{relative:_k,join:Qne}=require("node:path"),{CERT_PREFERENCE_APP:_Ie,CERTIFICATE_VALUES:ik}=Zs,jne=_c(),TO=Ct(),{table:Jne,getDatabases:Xne,databases:gO}=(xe(),P(ct)),{getJWTRSAKeys:ok}=(Mu(),P(k_));Object.assign(wk,{generateKeys:NO,updateConfigCert:Ak,createCsr:ise,signCertificate:ose,setCertTable:Vu,loadCertificates:gk,reviewSelfSignedCert:IO,createTLSSelector:yk,listCertificates:Ok,addCertificate:fse,removeCertificate:hse,createNatsCerts:lse,generateCertsKeys:cse,getReplicationCert:Z_,getReplicationCertAuth:sse,renewSelfSigned:use,hostnamesFromCert:CO,getKey:mse});var{urlToNodeName:hk,getThisNodeUrl:Zne,getThisNodeName:ng,clearThisNodeName:ese}=(ps(),P(Oa)),{readFileSync:tse,statSync:mk}=require("node:fs"),hIe=le(),{getTicketKeys:rse,onMessageFromWorkers:nse}=ot(),Aa=ee(),{isMainThread:pk}=require("worker_threads"),{TLSSocket:Ek,createSecureContext:mIe}=require("node:tls"),bO=3650,X_=["127.0.0.1","localhost","::1"],OO=[{name:"countryName",value:"USA"},{name:"stateOrProvinceName",value:"Colorado"},{name:"localityName",value:"Denver"},{name:"organizationName",value:"HarperDB, Inc."}];nse(async e=>{e.type===Es.ITC_EVENT_TYPES.RESTART&&(Jn.initSync(!0),await IO())});var kr;function ba(){return kr||(kr=Xne().system.hdb_certificate,kr||(kr=Jne({table:"hdb_certificate",database:"system",attributes:[{name:"name",isPrimaryKey:!0},{attribute:"uses"},{attribute:"certificate"},{attribute:"is_authority"},{attribute:"private_key_name"},{attribute:"details"},{attribute:"is_self_signed"},{attribute:"__updatedtime__"}]}))),kr}a(ba,"getCertTable");async function Z_(){let e=yk("operations-api"),t={secureContexts:null,setSecureContext:a(s=>{},"setSecureContext")};await e.initialize(t);let r=t.secureContexts.get(ng());if(!r)return;let n=new Ao(r.options.cert);return r.cert_parsed=n,r.issuer=n.issuer,r}a(Z_,"getReplicationCert");async function sse(){ba();let e=(await Z_()).options.cert,r=new Ao(e).issuer.match(/CN=(.*)/)?.[1];return kr.get(r)}a(sse,"getReplicationCertAuth");var ak,ya=new Map;function gk(){if(ak)return;ak=!0;let e=[{configKey:ol.TLS},{configKey:ol.OPERATIONSAPI_TLS}];ba();let t=or.dirname(TO.getConfigFilePath()),r;for(let{configKey:n}of e){let s=TO.getConfigFromFile(n);if(s){Array.isArray(s)||(s=[s]);for(let i of s){let o=i.privateKey,c=o&&_k(Qne(t,"keys"),o);c&&ck(o,l=>{ya.set(c,l)},"private key");for(let l of[!1,!0]){let u=i[l?"certificateAuthority":"certificate"];if(u&&pk){let f;ck(u,d=>{if(ik.cert===d)return;let _=i.hostname??i.hostnames??i.host??i.hosts;_&&!Array.isArray(_)&&(_=[_]);let h=Rk(u),m=new Ao(h),S;try{S=Nk(m)}catch(T){logger.error("error extracting host name from certificate",T);return}if(S==null){logger.error("No host name found on certificate");return}if(m.checkIssued(new Ao(ik.cert)))return;let g=kr.primaryStore.get(S),R=mk(u).mtimeMs,E=!g||g.is_self_signed?1:g.file_timestamp??g.__updatedtime__;if(g&&R<=E){R<E&&Tt.info(`Certificate ${S} at ${u} is older (${new Date(R)}) than the certificate in the database (${E>1?new Date(E):"only self signed certificate available"})`);return}r=kr.put({name:S,uses:["https",...n.includes("operations")?["operations"]:[]],ciphers:i.ciphers,certificate:h,private_key_name:c,is_authority:l,hostnames:_,file_timestamp:R,details:{issuer:m.issuer.replace(/\n/g," "),subject:m.subject?.replace(/\n/g," "),subject_alt_name:m.subjectAltName,serial_number:m.serialNumber,valid_from:m.validFrom,valid_to:m.validTo}})},l?"certificate authority":"certificate")}}}}}return r}a(gk,"loadCertificates");function ck(e,t,r){let n,s=a((i,o)=>{try{let c=o.mtimeMs;c&&c!==n&&(n&&pk&&Tt.warn(`Reloading ${r}:`,i),n=c,t(Rk(i)))}catch(c){Tt.error(`Error loading ${r}:`,i,c)}},"loadFile");bn.existsSync(e)?s(e,mk(e)):Tt.error(`${r} file not found:`,e),Wne(e,{persistent:!1}).on("change",s)}a(ck,"loadAndWatch");function AO(){let e=Zne();if(e==null){let t=X_[0];return Tt.info("replication url is missing from harperdb-config.yaml, using default host"+t),t}return hk(e)}a(AO,"getHost");function rg(){let e=ng();if(e==null){let t=X_[0];return Tt.info("replication url is missing from harperdb-config.yaml, using default host"+t),t}return e}a(rg,"getCommonName");async function ise(){let e=await Z_(),t=bt.certificateFromPem(e.options.cert),r=bt.privateKeyFromPem(e.options.key);Tt.info("Creating CSR with cert named:",e.name);let n=bt.createCertificationRequest();n.publicKey=t.publicKey;let s=[{name:"commonName",value:rg()},...OO];Tt.info("Creating CSR with subject",s),n.setSubject(s);let i=[{name:"unstructuredName",value:"HarperDB, Inc."},{name:"extensionRequest",extensions:Sk()}];return Tt.info("Creating CSR with attributes",i),n.setAttributes(i),n.sign(r),$u.pki.certificationRequestToPem(n)}a(ise,"createCsr");function Sk(){let e=X_.includes(rg())?X_:[...X_,rg()];return e.includes(AO())||e.push(AO()),[{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=>uk.isIP(t)?{type:7,ip:t}:{type:2,value:t})}]}a(Sk,"certExtensions");async function ose(e){let t={},r=or.join(Jn.getHdbBasePath(),Es.LICENSE_KEY_DIR_NAME);if(e.csr){let n,s;ba();for await(let f of kr.search([]))if(f.is_authority&&!f.details.issuer.includes("HarperDB-Certificate-Authority")){if(ya.has(f.private_key_name)){n=ya.get(f.private_key_name),s=f;break}else if(f.private_key_name&&await bn.exists(or.join(r,f.private_key_name))){n=bn.readFile(or.join(r,f.private_key_name)),s=f;break}}if(!n){let f=await RO();s=f.ca,n=f.private_key}n=bt.privateKeyFromPem(n),t.signingCA=s.certificate;let i=bt.certificateFromPem(s.certificate);Tt.info("Signing CSR with cert named",s.name);let o=bt.certificationRequestFromPem(e.csr);try{o.verify()}catch(f){return Tt.error(f),new Error("Error verifying CSR: "+f.message)}let c=$u.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()+bO),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,$u.md.sha256.create()),t.certificate=bt.certificateToPem(c)}else Tt.info("Sign cert did not receive a CSR from:",e.url,"only the CA will be returned");return t}a(ose,"signCertificate");async function ase(e,t){await Vu({name:ng(),uses:["https","wss"],certificate:e,private_key_name:"privateKey.pem",is_authority:!1,is_self_signed:!0}),await Vu({name:t.subject.getField("CN").value,uses:["https","wss"],certificate:bt.certificateToPem(t),private_key_name:"privateKey.pem",is_authority:!0,is_self_signed:!0})}a(ase,"createCertificateTable");async function Vu(e){let t=new Ao(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},ba(),await kr.patch(e)}a(Vu,"setCertTable");async function NO(){let e=await SO("rsa",{modulusLength:4096,publicKeyEncoding:{type:"spki",format:"pem"},privateKeyEncoding:{type:"pkcs8",format:"pem"}});return{public_key:bt.publicKeyFromPem(e.publicKey),private_key:bt.privateKeyFromPem(e.privateKey)}}a(NO,"generateKeys");async function wO(e,t,r){let n=bt.createCertificate();if(!t){let o=await Z_();t=bt.certificateFromPem(o.options.cert).publicKey}n.publicKey=t,n.serialNumber=Math.random().toString().slice(2,10),n.validity.notBefore=new Date;let s=new Date;n.validity.notAfter=s,n.validity.notAfter.setDate(s.getDate()+bO);let i=[{name:"commonName",value:rg()},...OO];return n.setSubject(i),n.setIssuer(r.subject.attributes),n.setExtensions(Sk()),n.sign(e,$u.md.sha256.create()),bt.certificateToPem(n)}a(wO,"generateCertificates");async function RO(){let e=await Ok(),t;for(let r of e){if(!r.is_authority)continue;let n=await bk(r.private_key_name);if(r.private_key_name&&n&&new Ao(r.certificate).checkPrivateKey(dk(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(RO,"getCertAuthority");async function Tk(e,t,r=!0){let n=bt.createCertificate();n.publicKey=t,n.serialNumber=Math.random().toString().slice(2,10),n.validity.notBefore=new Date;let s=new Date;n.validity.notAfter=s,n.validity.notAfter.setDate(s.getDate()+bO);let i=[{name:"commonName",value:`HarperDB-Certificate-Authority-${Jn.get(ol.REPLICATION_HOSTNAME)??hk(Jn.get(ol.REPLICATION_URL))??fk().split("-")[0]}`},...OO];n.setSubject(i),n.setIssuer(i),n.setExtensions([{name:"basicConstraints",cA:!0,critical:!0},{name:"keyUsage",keyCertSign:!0,critical:!0}]),n.sign(e,$u.md.sha256.create());let o=or.join(Jn.getHdbBasePath(),Es.LICENSE_KEY_DIR_NAME),c=or.join(o,Zs.PRIVATEKEY_PEM_NAME);return r&&await bn.writeFile(c,bt.privateKeyToPem(e)),n}a(Tk,"generateCertAuthority");async function cse(){let{private_key:e,public_key:t}=await NO(),r=await Tk(e,t),n=await wO(e,t,r);await ase(n,r),Ak()}a(cse,"generateCertsKeys");async function lse(){let e=await wO(bt.privateKeyFromPem(Zs.CERTIFICATE_VALUES.key),void 0,bt.certificateFromPem(Zs.CERTIFICATE_VALUES.cert)),t=or.join(Jn.getHdbBasePath(),Es.LICENSE_KEY_DIR_NAME),r=or.join(t,Zs.NATS_CERTIFICATE_PEM_NAME);await bn.exists(r)||await bn.writeFile(r,e);let n=or.join(t,Zs.NATS_CA_PEM_NAME);await bn.exists(n)||await bn.writeFile(n,Zs.CERTIFICATE_VALUES.cert)}a(lse,"createNatsCerts");async function use(){ba();for await(let e of kr.search([{attribute:"is_self_signed",value:!0}]))await kr.delete(e.name);await IO()}a(use,"renewSelfSigned");async function IO(){ese(),await gk(),ba();let e=await RO();if(!e){Tt.notify("A matching Certificate Authority and key was not found. A new CA will be created in advance, so it's available if needed.");let r=a(u=>{try{return{key:bt.privateKeyFromPem(bn.readFileSync(u)),keyPath:u}}catch(f){return Tt.warn(`Failed to parse private key from ${u}:`,f.message),{key:null,keyPath:u}}},"tryToParseKey"),n=Jn.get(ol.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=Jn.get(ol.TLS_PRIVATEKEY),f=r(u);s=f.key,i=f.keyPath}let o=or.join(Jn.getHdbBasePath(),Es.LICENSE_KEY_DIR_NAME),c=_k(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 NO(),bn.existsSync(or.join(o,Zs.PRIVATEKEY_PEM_NAME))&&(c=`privateKey${fk().split("-")[0]}.pem`),await bn.writeFile(or.join(o,c),bt.privateKeyToPem(s)));let l=await Tk(s,bt.setRsaPublicKey(s.n,s.e),!1);await Vu({name:l.subject.getField("CN").value,uses:["https"],certificate:bt.certificateToPem(l),private_key_name:c,is_authority:!0,is_self_signed:!0})}if(!await Z_()){let r=ng();Tt.notify(`A suitable replication certificate was not found, creating new self singed cert named: ${r}`),e=e??await RO();let n=bt.certificateFromPem(e.ca.certificate),s=n.publicKey,i=await wO(bt.privateKeyFromPem(e.private_key),s,n);await Vu({name:r,uses:["https","operations","wss"],certificate:i,is_authority:!1,private_key_name:e.ca.private_key_name,is_self_signed:!0})}}a(IO,"reviewSelfSignedCert");function Ak(){let e=jne(Object.keys(Es.CONFIG_PARAM_MAP),!0),t=or.join(Jn.getHdbBasePath(),Es.LICENSE_KEY_DIR_NAME),r=or.join(t,Zs.PRIVATEKEY_PEM_NAME),n=or.join(t,Zs.NATS_CERTIFICATE_PEM_NAME),s=or.join(t,Zs.NATS_CA_PEM_NAME),i=Es.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),TO.updateConfigValue(void 0,void 0,o,!1,!0)}a(Ak,"updateConfigCert");function Rk(e){return e.startsWith("-----BEGIN")?e:tse(e,"utf8")}a(Rk,"readPEM");var lk=tg.createSecureContext;tg.createSecureContext=function(e){if(!e.cert||!e.key)return lk(e);let t={...e};delete t.key,delete t.cert;let r=lk(t);return r.context.setCert(e.cert),r.context.setKey(e.key,void 0),r};var dse=Ek.prototype._init;Ek.prototype._init=function(e,t){dse.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 il=new Map;function yk(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(),il.clear();let f=0;for await(let d of gO.system.hdb_certificate.search([])){let _=d.certificate,h=new Ao(_);d.is_authority&&(h.asString=_,il.set(h.subject,_))}for await(let d of gO.system.hdb_certificate.search([]))try{if(d.is_authority)continue;let _=e==="operations-api",h=d.is_self_signed?1:2;_&&d.uses?.includes?.("operations")&&(h+=1);let m=await bk(d.private_key_name),S=d.certificate,g=new Ao(S);if(il.has(g.issuer)&&(S+=`
|
|
23
23
|
`+il.get(g.issuer)),!m||!S)throw new Error("Missing private key or certificate for secure server");let R={ciphers:d.ciphers,ticketKeys:rse(),availableCAs:il,ca:t&&Array.from(il.values()),cert:S,key:m,key_file:d.private_key_name,is_self_signed:d.is_self_signed};o&&(R.sessionIdContext=o.sessionIdContext);let E=tg.createSecureContext(R);E.name=d.name,E.options=R,E.quality=h,E.certificateAuthorities=Array.from(il),E.certStart=S.toString().slice(0,100);let T=d.hostnames??CO(g);Array.isArray(T)||(T=[T]);let N;for(let v of T)if(v){v[0]==="*"&&(s=!0,v=v.slice(1)),v===AO()&&(h+=2),uk.isIP(v)&&(N=!0);let H=r.get(v)?.quality??0;h>H&&r.set(v,E)}else Aa.error("No hostname found for certificate at",tg.certificate);Aa.trace("Adding TLS",E.name,"for",o.ports||"client","cert named",d.name,"hostnames",T,"quality",h,"best quality",f),h>f&&(i.defaultContext=n=E,f=h,o&&(o.defaultContext=E))}catch(_){Aa.error("Error applying TLS for",d.name,_)}o?.secureContextsListeners.forEach(d=>d()),c(n)}catch(f){l(f)}}a(u,"updateTLS"),gO.system.hdb_certificate.subscribe({listener:a(()=>setTimeout(()=>u(),1500).unref(),"listener"),omitCurrent:!0}),u()})),i;function i(o,c){Aa.info("TLS requested for",o||"(no SNI)");let l=o;for(;;){let f=r.get(l);if(f)return Aa.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?Aa.debug("No certificate found to match",o,"using the default certificate"):Aa.debug("No SNI, using the default certificate",n?.name);let u=n;u?u.updatedContext&&(u=u.updatedContext):Aa.info("No default certificate found"),c(null,u)}a(i,"SNICallback")}a(yk,"createTLSSelector");async function bk(e){let t=ya.get(e);return!t&&e?await bn.readFile(or.join(Jn.get(ol.ROOTPATH),Es.LICENSE_KEY_DIR_NAME,e),"utf8"):t}a(bk,"getPrivateKeyByName");async function Ok(){ba();let e=[];for await(let t of kr.search([]))e.push(t);return e}a(Ok,"listCertificates");async function fse(e){let t=yO(e,Xs.object({name:Xs.string().required(),certificate:Xs.string().required(),is_authority:Xs.boolean().required(),private_key:Xs.string(),hosts:Xs.array(),uses:Xs.array()}));if(t)throw new Ra(t.message);let{name:r,certificate:n,private_key:s,is_authority:i}=e,o=new Ao(n),c=!1,l=!1,u;for(let[h,m]of ya)!s&&!c&&o.checkPrivateKey(dk(m))&&(c=!0,u=h),s&&s===m&&(l=!0,u=h);if(!i&&!s&&!c)throw new Ra("A suitable private key was not found for this certificate");let f;if(!r){try{f=Nk(o)}catch(h){Tt.error(h)}if(f==null)throw new Ra("Error extracting certificate common name, please provide a name parameter")}let d=_se(r??f);s&&!c&&!l&&(await bn.writeFile(or.join(Jn.getHdbBasePath(),Es.LICENSE_KEY_DIR_NAME,d+".pem"),s),ya.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 Vu(_),"Successfully added certificate: "+d}a(fse,"addCertificate");function _se(e){return e.replace(/[^a-z0-9\.]/gi,"-")}a(_se,"sanitizeName");async function hse(e){let t=yO(e,Xs.object({name:Xs.string().required()}));if(t)throw new Ra(t.message);let{name:r}=e;ba();let n=await kr.get(r);if(!n)throw new Ra(r+" not found");let{private_key_name:s}=n;if(s){let i=Array.from(await kr.search([{attribute:"private_key_name",value:s}]));i.length===1&&i[0].name===r&&(Tt.info("Removing private key named",s),await bn.remove(or.join(Jn.getHdbBasePath(),Es.LICENSE_KEY_DIR_NAME,s)))}return await kr.delete(r),"Successfully removed "+r}a(hse,"removeCertificate");function Nk(e){let t=e.subject?.match(/CN=(.*)/)?.[1];return t||CO(e)[0]}a(Nk,"getPrimaryHostName");function CO(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(CO,"hostnamesFromCert");async function mse(e){if(e.bypass_auth!==!0)throw new Ra("Unauthorized","401");let t=yO(e,Xs.object({name:Xs.string().required()}));if(t)throw new Ra(t.message);let{name:r}=e;if(r===".jwtPrivate")return(await ok()).privateKey;if(r===".jwtPublic")return(await ok()).publicKey;if(ya.get(r))return ya.get(e.name);throw new Ra("Key not found")}a(mse,"getKey")});var Qk={};Ue(Qk,{CONFIRMATION_STATUS_POSITION:()=>Yk,NodeReplicationConnection:()=>Yu,OPERATION_REQUEST:()=>MO,RECEIVED_TIME_POSITION:()=>UO,RECEIVED_VERSION_POSITION:()=>vO,RECEIVING_STATUS_POSITION:()=>xO,RECEIVING_STATUS_RECEIVING:()=>zk,RECEIVING_STATUS_WAITING:()=>Wk,SENDING_TIME_POSITION:()=>eh,createWebSocket:()=>dg,database_subscriptions:()=>wa,replicateOverWS:()=>th,table_update_listeners:()=>HO});async function dg(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(!DO){let l=(0,qk.createTLSSelector)("operations-api"),u={secureContexts:null};await l.initialize(u),DO=u.secureContexts}if(i=DO.get(s),i&&ce.debug?.("Creating web socket for URL",e,"with certificate named:",i.name),!i&&n!==!1)throw new Error("Unable to find a valid certificate to use for replication to connect to "+e)}let o={};r&&(o.Authorization=r);let c={headers:o,localAddress:s?.startsWith("127.0")?s:void 0,servername:(0,Vk.isIP)(t?.serverName)?void 0:t?.serverName,noDelay:!0,highWaterMark:128*1024,rejectUnauthorized:n!==!1,secureContext:void 0};return i&&(lg?.caCount!==Ro.size&&(lg=$k.createSecureContext({...i.options,ca:[...Ro,...i.options.availableCAs.values()]}),lg.caCount=Ro.size),c.secureContext=lg),new Fk.WebSocket(e,"harperdb-replication-v1",c)}function th(e,t,r){let n=t.port||t.securePort,s=al.pid%1e3+"-"+Gk.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||wa,d,_,h=!1,m=t.subscription;m?.then&&m.then(A=>m=A);let S=t.tables||u&&Xe()[u];if(!r){ce.error?.("No authorization provided"),cn(1008,"Unauthorized");return}let g=new Map,R=[],E=r.name;E&&t.connection&&(t.connection.nodeName=E);let T,N,v,H,X,W,$,se=6e4,z,fe=0,ue=0,Z=0,Ae=kk.default.get(x.REPLICATION_BLOBTIMEOUT)??12e4,me=new Map,ye=[],Ht=0,dt;if(t.url){let A=a(()=>{X&&ue===e._socket?.bytesRead&&Z===e._socket?.bytesWritten?e.terminate():(X=performance.now(),e.ping(),ue=e._socket?.bytesRead,Z=e._socket?.bytesWritten)},"send_ping");v=setInterval(A,Bk).unref(),A()}else Ln();e._socket?.setMaxListeners(200);function Ln(){clearTimeout(H),ue=e._socket?.bytesRead,Z=e._socket?.bytesWritten,H=setTimeout(()=>{ue===e._socket?.bytesRead&&Z===e._socket?.bytesWritten&&(ce.warn?.(`Timeout waiting for ping from ${E}, terminating connection and reconnecting`),e.terminate())},Bk*2).unref()}a(Ln,"resetPingTimer");function an(){return _||(_=JE(d,u,E)),_}a(an,"getSharedStatus"),u&&jo(u);let Cr,jd,oc=[],JT=[],XT,kt=[],Jd=[],Xd=[],ZT=150,wm=25,Zd=0,Ce=0,ef=!1,Ji,Pr,Mn,ac;e.on("message",A=>{fe=performance.now();try{let y=A.dataView=new cl(A.buffer,A.byteOffset,A.byteLength);if(A[0]>127){let B=(0,Ze.decode)(A),[w,D,G]=B;switch(w){case Ck:{if(D){if(E){if(E!==D){ce.error?.(s,`Node name mismatch, expecting to connect to ${E}, but peer reported name as ${D}, disconnecting`),e.send((0,Ze.encode)([Ku])),cn(1008,"Node name mismatch");return}}else if(E=D,t.connection?.tentativeNode){let oe=t.connection.tentativeNode;oe.name=E,t.connection.tentativeNode=null,To(E,oe)}if(t.connection&&(t.connection.nodeName=E),ce.debug?.(s,"received node name:",E,"db:",u),!u)try{jo(u=B[2]),u==="system"&&(Cr=Sa(t,(oe,V)=>{Qo(V)&&nf(V)}),e.on("close",()=>{Cr?.remove()}))}catch(oe){ce.warn?.(s,"Error setting database",oe),e.send((0,Ze.encode)([Ku])),cn(1008,oe.message);return}zo()}break}case Uk:{ce.debug?.(s,"Received table definitions for",D.map(oe=>oe.table));for(let oe of D){let V=B[2];oe.database=V;let J;Qo(V)&&(V==="system"?We[V]?.[oe.table]||(J=L(oe,We[V]?.[oe.table])):J=L(oe,We[V]?.[oe.table]),d||(d=J?.auditStore),S||(S=Xe()?.[V]))}break}case Ku:cn();break;case MO: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)([ig,V]))},V=>{e.send((0,Ze.encode)([ig,{requestId:D.requestId,error:V instanceof Error?V.toString():V}]))})}catch(oe){e.send((0,Ze.encode)([ig,{requestId:D.requestId,error:oe instanceof Error?oe.toString():oe}]))}break;case ig:let{resolve:j,reject:Q}=g.get(D.requestId);D.error?Q(new Error(D.error)):j(D),g.delete(D.requestId);break;case PO:let F=B[3];S||(u?ce.error?.(s,"No tables found for",u):ce.error?.(s,"Database name never received"));let ve=S[F];ve=L({table:F,database:u,attributes:D.attributes,schemaDefined:D.schemaDefined},ve),oc[G]={name:F,decoder:new Ze.Packr({useBigIntExtension:!0,randomAccessStructure:!0,freezeData:!0,typedStructs:D.typedStructs,structures:D.structures}),getEntry(oe){return ve.primaryStore.getEntry(oe)},rootStore:ve.primaryStore.rootStore};break;case Pk:ac=d?jH(D,d):new Map,XT=B[2],ce.debug?.(s,`Acknowledged subscription request, receiving messages for nodes: ${XT}`);break;case Dk:let Ee=G;Xd[Ee]=D;break;case vk:an()[Yk]=D,ce.trace?.(s,"received and broadcasting committed update",D),an().buffer.notify();break;case Mk:T=D,m.send({type:"end_txn",localTime:T,remoteNodeIds:R});break;case og:{let oe=B[1],{fileId:V,size:J,finished:de,error:pe}=oe,ae=me.get(V);ce.debug?.("Received blob",V,"has stream",!!ae,"connectedToBlob",!!ae?.connectedToBlob,"length",B[2].length,"finished",de),ae||(ae=new LO.PassThrough,ae.expectedSize=J,me.set(V,ae)),ae.lastChunk=Date.now();let Ie=B[2];Mt(Ie.byteLength,"bytes-received",`${E}.${u}`,"replication","blob");try{de?(pe?(ae.on("error",()=>{}),ae.destroy(new Error("Blob error: "+pe+" for record "+(ae.recordId??"unknown")+" from "+E))):ae.end(Ie),ae.connectedToBlob&&me.delete(V)):ae.write(Ie)}catch(He){ce.error?.(`Error receiving blob for ${ae.recordId} from ${E} and streaming to storage`,He),me.delete(V)}break}case Lk:{let oe=D,V;try{let J=B[3],de=JT[G]||(JT[G]=S[B[4]]);if(!de)return ce.warn?.("Unknown table id trying to handle record request",G);let pe=de.primaryStore.getBinaryFast(Symbol.for("structures")),ae=pe?.length;if(ae>0&&ae!==Ce){Ce=ae;let He=(0,Ze.decode)(pe);e.send((0,Ze.encode)([PO,{typedStructs:He.typed,structures:He.named},G,de.tableName]))}let Ie=de.primaryStore.getBinaryFast(J);if(Ie){let He=de.primaryStore.decoder.decode(Ie,{valueAsBuffer:!0}),De=He.value;He[Cc]&Ur&&(De=Buffer.from(De),Uf(()=>de.primaryStore.decoder.decode(Ie),rt=>cc(rt,J),de.primaryStore.rootStore)),V=(0,Ze.encode)([sg,oe,{value:De,expiresAt:He.expiresAt,version:He.version,residencyId:He.residencyId,nodeId:He.nodeId,user:He.user}])}else V=(0,Ze.encode)([sg,oe])}catch(J){V=(0,Ze.encode)([sg,oe,{error:J.message}])}e.send(V);break}case sg:{let{resolve:oe,reject:V,tableId:J,key:de}=g.get(B[1]),pe=B[2];if(pe?.error)V(new Error(pe.error));else if(pe){let ae;Ep(()=>{let Ie=oc[J].decoder.decode(pe.value);pe.value=Ie,pe.key=de,oe(pe)||ae&&setTimeout(()=>ae.forEach(hp),6e4).unref()},d?.rootStore,Ie=>{let He=tf(Ie,de);return ae||(ae=[]),ae.push(He),He})}else oe();g.delete(B[1]);break}case Ik:{Mn=D;let oe,V,J=!1;if(m){if(u!==m.databaseName&&!m.then){ce.error?.("Subscription request for wrong database",u,m.databaseName);return}}else m=f.get(u);if(ce.debug?.(s,"received subscription request for",u,"at",Mn),!m){let Oe;m=new Promise(Ft=>{ce.debug?.("Waiting for subscription to database "+u),Oe=Ft}),m.ready=Oe,wa.set(u,m)}if(r.name)V=ir().subscribe(r.name),V.then(async Oe=>{oe=Oe;for await(let Ft of oe){let Nt=Ft.value;if(!(Nt?.replicates===!0||Nt?.replicates?.receives||Nt?.subscriptions?.some(yr=>(yr.database||yr.schema)===u&&yr.publish!==!1))){J=!0,e.send((0,Ze.encode)([Ku])),cn(1008,`Unauthorized database subscription to ${u}`);return}}},Oe=>{ce.error?.(s,"Error subscribing to HDB nodes",Oe)});else if(!(r?.role?.permission?.super_user||r.replicates)){e.send((0,Ze.encode)([Ku])),cn(1008,`Unauthorized database subscription to ${u}`);return}if(Pr&&(ce.debug?.(s,"stopping previous subscription",u),Pr.emit("close")),Mn.length===0)return;let de=Mn[0],pe=a(Oe=>{if(Oe&&(de.replicateByDefault?!de.tables.includes(Oe.tableName):de.tables.includes(Oe.tableName)))return{table:Oe}},"tableToTableEntry"),ae={txnTime:0},Ie,He,De=1/0,rt,vn=a((Oe,Ft)=>{if(Oe.type==="end_txn"){ae.txnTime&&(o[i]!==66&&ce.error?.("Invalid encoding of message"),Xi(9),Xi(ug),p(rt=Ft),di()),i=c,ae.txnTime=0;return}let Nt=Oe.nodeId,yr=Oe.tableId,Rt=He[yr];if(!Rt&&(Rt=He[yr]=pe(m.tableById[yr]),!Rt))return ce.debug?.("Not subscribed to table",yr);let ls=Rt.table,wt=ls.primaryStore,vs=wt.encoder;(Oe.extendedType&Np||!vs.typedStructs)&&(vs._mergeStructures(vs.getStructures()),vs.typedStructs&&(vs.lastTypedStructuresLength=vs.typedStructs.length));let Kl=Ie[Nt];if(!(Kl&&Kl.startTime<Ft&&(!Kl.endTime||Kl.endTime>Ft)))return cg&&ce.trace?.(s,"skipping replication update",Oe.recordId,"to:",E,"from:",Nt,"subscribed:",Ie),uP();cg&&ce.trace?.(s,"sending replication update",Oe.recordId,"to:",E,"from:",Nt,"subscribed:",Ie);let eA=Oe.version;ae.txnTime!==eA&&(ae.txnTime&&(cg&&ce.trace?.(s,"new txn time, sending queued txn",ae.txnTime),o[i]!==66&&ce.error?.("Invalid encoding of message"),di()),ae.txnTime=eA,i=c,p(eA));let dc=Oe.residencyId,tA=rf(dc,ls),Cm;if(tA&&!tA.includes(E)){let Us=rf(Oe.previousResidencyId,ls);if(Us&&!Us.includes(E)&&(Oe.type==="put"||Oe.type==="patch")||ls.getResidencyById)return uP();let sf=Oe.recordId;ce.trace?.(s,"sending invalidation",sf,E,"from",Nt);let of=0;dc&&(of|=Lc),Oe.previousResidencyId&&(of|=Mc);let sA,Pm=null;for(let dP in ls.indices){if(!Pm){if(sA=Oe.getValue(wt,!0),!sA)break;Pm={}}Pm[dP]=sA[dP]}Cm=Pc(Oe.version,yr,sf,null,Nt,Oe.user,Oe.type==="put"||Oe.type==="patch"?"invalidate":Oe.type,vs.encode(Pm),of,dc,Oe.previousResidencyId,Oe.expiresAt)}function uP(){return ce.trace?.(s,"skipping audit record",Oe.recordId),W||(W=setTimeout(()=>{W=null,(rt||0)+xk/2<De&&(cg&&ce.trace?.(s,"sending skipped sequence update",De),e.send((0,Ze.encode)([Mk,De])))},xk).unref()),new Promise(setImmediate)}a(uP,"skipAuditRecord");let rA=vs.typedStructs,nA=vs.structures;if((rA?.length!=Rt.typed_length||nA?.length!=Rt.structure_length)&&(Rt.typed_length=rA?.length,Rt.structure_length=nA.length,ce.debug?.(s,"send table struct",Rt.typed_length,Rt.structure_length),Rt.sentName||(Rt.sentName=!0),e.send((0,Ze.encode)([PO,{typedStructs:rA,structures:nA,attributes:ls.attributes,schemaDefined:ls.schemaDefined},yr,Rt.table.tableName]))),dc&&!Jd[dc]&&(e.send((0,Ze.encode)([Dk,tA,dc])),Jd[dc]=!0),Cm)Xi(Cm.length),K(Cm);else{let Us=Oe.encoded;Oe.extendedType&Ur&&Uf(()=>Oe.getValue(wt),of=>cc(of,Oe.recordId),wt.rootStore);let sf=Us[0]===66?8:0;Xi(Us.length-sf),K(Us,sf),ce.trace?.("wrote record",Oe.recordId,"length:",Us.length)}return e._socket.writableNeedDrain?new Promise(Us=>{ce.debug?.(`Waiting for remote node ${E} to allow more commits ${e._socket.writableNeedDrain?"due to network backlog":"due to requested flow directive"}`),e._socket.once("drain",Us)}):Ht>wm?new Promise(Us=>{dt=Us}):new Promise(setImmediate)},"sendAuditRecord"),di=a(()=>{c-i>8?(e.send(o.subarray(i,c)),ce.debug?.(s,"Sent message, size:",c-i),Mt(c-i,"bytes-sent",`${E}.${u}`,"replication","egress")):ce.debug?.(s,"skipping empty transaction")},"sendQueuedData");Pr=new BO.EventEmitter,Pr.once("close",()=>{J=!0,oe?.end()});for(let{startTime:Oe}of Mn)Oe<De&&(De=Oe);(V||Promise.resolve()).then(async()=>{m=await m,d=m.auditStore,He=m.tableById.map(pe),Ie=[];for(let{name:Ft,startTime:Nt,endTime:yr}of Mn){let Rt=jE(Ft,d);ce.debug?.("subscription to",Ft,"using local id",Rt,"starting",Nt),Ie[Rt]={startTime:Nt,endTime:yr}}nf(u),Cr||(Cr=ll(Ft=>{Ft.databaseName===u&&nf(u)}),jd=rh(Ft=>{Ft===u&&(e.send((0,Ze.encode)([Ku])),cn())}),e.on("close",()=>{Cr?.remove(),jd?.remove()})),e.send((0,Ze.encode)([Pk,Y_(m.auditStore),Mn.map(({name:Ft})=>Ft)]));let Oe=!0;do{isFinite(De)||(ce.warn?.("Invalid sequence id "+De),cn(1008,"Invalid sequence id"+De));let Ft;if(Oe&&!J&&(Oe=!1,De===0)){let Nt=De,yr=fg(d);for(let Rt in S){if(!pe(Rt))continue;let ls=S[Rt];ce.warn?.(`Fully copying ${Rt} table to ${E}`);for(let wt of ls.primaryStore.getRange({snapshot:!1,versions:!0})){if(J)return;if(wt.localTime>=De){ce.trace?.(s,"Copying record from",u,Rt,wt.key,wt.localTime),Nt=Math.max(wt.localTime,Nt),Ft=!0,an()[eh]=1;let vs=Pc(wt.version,ls.tableId,wt.key,null,yr,null,"put",Uf(()=>ls.primaryStore.encoder.encode(wt.value),Kl=>cc(Kl,wt.key)),wt.metadataFlags&-256,wt.residencyId,null,wt.expiresAt);await vn({recordId:wt.key,tableId:ls.tableId,type:"put",getValue(){return wt.value},encoded:vs,version:wt.version,residencyId:wt.residencyId,nodeId:yr,extendedType:wt.metadataFlags},wt.localTime)}}}Ft&&vn({type:"end_txn"},De),an()[eh]=0,De=Nt}for(let{key:Nt,value:yr}of d.getRange({start:De||1,exclusiveStart:!0,snapshot:!1})){if(J)return;let Rt=St(yr);ce.debug?.("sending audit record",new Date(Nt)),an()[eh]=Nt,De=Nt,await vn(Rt,Nt),Pr.startTime=Nt,Ft=!0}Ft&&vn({type:"end_txn"},De),an()[eh]=0,await jk(d)}while(!J)}).catch(Oe=>{ce.error?.(s,"Error handling subscription to node",Oe),cn(1008,"Error handling subscription to node")});break}}return}y.position=8;let I=!0,b,U;do{an();let B=y.readInt();if(B===9&&y.getUint8(y.position)==ug){y.position++,T=U=y.readFloat64(),_[vO]=T,_[UO]=Date.now(),_[xO]=Wk,ce.trace?.("received remote sequence update",T,u);break}let w=y.position,D=St(A,w,w+B),G=oc[D.tableId];G||ce.error?.(`No table found with an id of ${D.tableId}`);let j;D.residencyId&&(j=Xd[D.residencyId],ce.trace?.(s,"received residency list",j,D.type,D.recordId));try{let Q=D.recordId;Ep(()=>{b={table:G.name,id:Q,type:D.type,nodeId:ac.get(D.nodeId),residencyList:j,timestamp:D.version,value:D.getValue(G),user:D.user,beginTxn:I,expiresAt:D.expiresAt}},d?.rootStore,F=>tf(F,Q))}catch(Q){throw Q.message+="typed structures for current decoder"+JSON.stringify(G.decoder.typedStructs),Q}I=!1,ce.trace?.(s,"received replication message",D.type,"id",b.id,"version",new Date(D.version),"nodeId",b.nodeId),_[vO]=D.version,_[UO]=Date.now(),_[xO]=zk,m.send(b),y.position=w+B}while(y.position<A.byteLength);Zd++,Mt(A.byteLength,"bytes-received",`${E}.${u}.${b?.table||"unknown_table"}`,"replication","ingest"),Zd>ZT&&!ef&&(ef=!0,e.pause(),ce.debug?.(`Commit backlog causing replication back-pressure, requesting that ${E} pause replication`)),m.send({type:"end_txn",localTime:T,remoteNodeIds:R,async onCommit(){if(b){let B=Date.now()-b.timestamp;Mt(B,"replication-latency",E+"."+u+"."+b.table,b.type,"ingest")}Zd--,ef&&(ef=!1,e.resume(),ce.debug?.(`Replication resuming ${E}`)),ye.length>0&&await Promise.all(ye),ce.trace?.("All blobs finished"),!N&&U&&(ce.trace?.(s,"queuing confirmation of a commit at",U),setTimeout(()=>{e.send((0,Ze.encode)([vk,N])),ce.trace?.(s,"sent confirmation of a commit at",N),N=null},Ese)),N=U,ce.debug?.("last sequence committed",new Date(U),u)}})}catch(y){ce.error?.(s,"Error handling incoming replication message",y)}}),e.on("ping",Ln),e.on("pong",()=>{t.connection&&(t.connection.latency=performance.now()-X,t.isSubscriptionConnection&&sl({name:E,database:u,url:t.url,latency:t.connection.latency})),X=null}),e.on("close",(A,y)=>{clearInterval(v),clearTimeout(H),clearInterval($),Pr&&Pr.emit("close"),Ji&&Ji.end();for(let[I,{reject:b}]of g)b(new Error(`Connection closed ${y?.toString()} ${A}`));ce.debug?.(s,"closed",A,y?.toString())});function cn(A,y){e.isFinished=!0,e.close(A,y),t.connection?.emit("finished")}a(cn,"close");let Dr=new Set;async function cc(A,y){let I=mp(A);if(Dr.has(I)){ce.debug?.("Blob already being sent",I);return}Dr.add(I);try{let b;Ht++;for await(let U of A.stream())b&&(ce.debug?.("Sending blob chunk",I,"length",b.length),e.send((0,Ze.encode)([og,{fileId:I,size:A.size},b]))),b=U,e._socket.writableNeedDrain&&(ce.debug?.("draining",I),await new Promise(B=>e._socket.once("drain",B)),ce.debug?.("drained",I)),Mt(U.length,"bytes-sent",`${E}.${u}`,"replication","blob");ce.debug?.("Sending final blob chunk",I,"length",b.length),e.send((0,Ze.encode)([og,{fileId:I,size:A.size,finished:!0},b]))}catch(b){ce.warn?.("Error sending blob",b,"blob id",I,"for record",y),e.send((0,Ze.encode)([og,{fileId:I,finished:!0,error:b.toString()},Buffer.alloc(0)]))}finally{Dr.delete(I),Ht--,Ht<wm&&dt?.()}}a(cc,"sendBlobs");function tf(A,y){let I=mp(A),b=me.get(I);ce.debug?.("Received transaction for record",y,"with blob",I,"has stream",!!b,"ended",!!b?.writableEnded),b?b.writableEnded&&me.delete(I):(b=new LO.PassThrough,me.set(I,b)),b.connectedToBlob=!0,b.lastChunk=Date.now(),b.recordId=y,A.size===void 0&&b.expectedSize&&(A.size=b.expectedSize);let U=b.blob??createBlob(b,A);b.blob=U;let B=no(()=>vf(U).saving,m.auditStore?.rootStore);return B&&(B.blobId=I,ye.push(B),B.finally(()=>{ce.debug?.(`Finished receiving blob stream ${I}`),ye.splice(ye.indexOf(B),1)})),U}a(tf,"receiveBlobs");function zo(){if(h||(h=!0,t.connection?.on("subscriptions-updated",zo)),t.connection?.isFinished)throw new Error("Can not make a subscription request on a connection that is already closed");let A=new Map;d||(d=m?.auditStore);try{for(let b of m?.dbisDB?.getRange({start:Symbol.for("seq"),end:[Symbol.for("seq"),Buffer.from([255])]})||[])for(let U of b.value.nodes||[])U.lastTxnTime>(A.get(U.id)??0)&&A.set(U.id,U.lastTxnTime)}catch(b){if(!b.message.includes("Can not re"))throw b}let y=t.connection?.nodeSubscriptions?.[0];R=[];let I=t.connection?.nodeSubscriptions?.map((b,U)=>{let B=[],{replicateByDefault:w}=b;if(b.subscriptions){for(let Q of b.subscriptions)if(Q.subscribe&&(Q.schema||Q.database)===u){let F=Q.table;S?.[F]?.replicate!==!1&&B.push(F)}w=!1}else for(let Q in S)(w?S[Q].replicate===!1:S[Q].replicate)&&B.push(Q);let D=d&&jE(b.name,d),G=m?.dbisDB?.get([Symbol.for("seq"),D])??1,j=Math.max(G?.seqId??1,(typeof b.start_time=="string"?new Date(b.start_time).getTime():b.start_time)??1);if(ce.debug?.("Starting time recorded in db",b.name,D,u,G?.seqId,"start time:",j,new Date(j)),y!==b){let Q=d&&jE(y.name,d),F=m?.dbisDB?.get([Symbol.for("seq"),Q])??1;for(let ve of F?.nodes||[])ve.name===b.name&&(j=ve.seqId,ce.debug?.("Using sequence id from proxy node",y.name,j))}if(D===void 0?ce.warn("Starting subscription request from node",b,"but no node id found"):R.push(D),A.get(D)>j&&(j=A.get(D),ce.debug?.("Updating start time from more recent txn recorded",y.name,j)),j===1&&ag)try{new URL(ag).hostname===b.name&&E===b.name?(ce.warn?.(`Requesting full copy of database ${u} from ${ag}`),j=0):j=Date.now()-6e4}catch(Q){ce.error?.("Error parsing leader URL",ag,Q)}return ce.trace?.(s,"defining subscription request",b.name,u,new Date(j)),{name:b.name,replicateByDefault:w,tables:B,startTime:j,endTime:b.end_time}});if(I)if(ce.debug?.(s,"sending subscription request",I,m?.dbisDB?.path),clearTimeout(z),I.length>0)e.send((0,Ze.encode)([Ik,I]));else{let b=a(()=>{let U=performance.now();z=setTimeout(()=>{fe<=U?cn(1008,"Connection has no subscriptions and is no longer used"):b()},se).unref()},"schedule_close");b()}}a(zo,"sendSubscriptionRequestUpdate");function rf(A,y){if(!A)return;let I=kt[A];return I||(I=y.getResidencyRecord(A),kt[A]=I),I}a(rf,"getResidence");function Qo(A){return!(Na&&Na!="*"&&!Na[A]&&!Na.includes?.(A)&&!Na.some?.(y=>y.name===A))}a(Qo,"checkDatabaseAccess");function jo(A){if(m=m||f.get(A),!Qo(A))throw new Error(`Access to database "${A}" is not permitted`);m||ce.warn?.(`No database named "${A}" was declared and registered`),d=m?.auditStore,S||(S=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 Im(y,A),!0}a(jo,"setDatabase");function Im(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}))})}ce.trace?.("Sending database info for node",A,"database name",y),e.send((0,Ze.encode)([Ck,A,y,b]))}a(Im,"sendNodeDBName");function nf(A){let y=Xe()?.[A],I=[];for(let b in y){if(Mn&&!Mn.some(B=>B.replicateByDefault?!B.tables.includes(b):B.tables.includes(b)))continue;let U=y[b];I.push({table:b,schemaDefined:U.schemaDefined,attributes:U.attributes.map(B=>({name:B.name,type:B.type,isPrimaryKey:B.isPrimaryKey}))})}e.send((0,Ze.encode)([Uk,I,A]))}a(nf,"sendDBSchema"),$=setInterval(()=>{for(let[A,y]of me)y.lastChunk+Ae<Date.now()&&(ce.warn?.(`Timeout waiting for blob stream to finish ${A} for record ${y.recordId??"unknown"} from ${E}`),me.delete(A),y.end())},Ae).unref();let lc=1,uc=[];return{end(){Ji&&Ji.end(),Pr&&Pr.emit("close")},getRecord(A){let y=lc++;return new Promise((I,b)=>{let U=[Lk,y,A.table.tableId,A.id];uc[A.table.tableId]||(U.push(A.table.tableName),uc[A.table.tableId]=!0),e.send((0,Ze.encode)(U)),fe=performance.now(),g.set(y,{tableId:A.table.tableId,key:A.id,resolve(B){let{table:w,entry:D}=A;if(I(B),B)return w._recordRelocate(D,B)},reject:b})})},sendOperation(A){let y=lc++;return A.requestId=y,e.send((0,Ze.encode)([MO,A])),new Promise((I,b)=>{g.set(y,{resolve:I,reject:b})})}};function Xi(A){O(5),A<128?o[c++]=A:A<16384?(l.setUint16(c,A|32768),c+=2):A<1056964608?(l.setUint32(c,A|3221225472),c+=4):(o[c]=255,l.setUint32(c+1,A),c+=5)}function K(A,y=0,I=A.length){let b=I-y;O(b),A.copy(o,c,y,I),c+=b}function p(A){O(8),l.setFloat64(c,A),c+=8}function O(A){if(A+16>o.length-c){let y=Buffer.allocUnsafeSlow(c+A-i+65536>>10<<11);o.copy(y,0,i,c),c=c-i,i=0,o=y,l=new DataView(o.buffer,0,o.length)}}function L(A,y){let I=A.database??"data";if(I!=="data"&&!We[I]){ce.warn?.("Database not found",A.database);return}y||(y={});let b=y.schemaDefined,U=!1,B=A.schemaDefined,w=y.attributes||[];for(let D=0;D<A.attributes?.length;D++){let G=A.attributes[D],j=w.find(Q=>Q.name===G.name);(!j||j.type!==G.type)&&(b?ce.error?.(`Schema for '${u}.${A.table}' is defined locally, but attribute '${G.name}: ${G.type}' from '${E}' does not match local attribute ${j?"'"+j.name+": "+j.type+"'":"which does not exist"}`):(U=!0,B||(G.indexed=!0),j?w[w.indexOf(j)]=G:w.push(G)))}return U?(ce.debug?.("(Re)creating",A),_t({table:A.table,database:A.database,schemaDefined:A.schemaDefined,attributes:w,...y})):y}}var kk,Ze,Fk,Gk,ce,BO,qk,$k,al,Vk,LO,Kk,Ik,Ck,Pk,Ku,Dk,PO,Lk,sg,MO,ig,Mk,vk,Uk,og,Yk,vO,UO,eh,xO,Wk,zk,pse,ag,HO,wa,cg,xk,Ese,Bk,DO,lg,Hk,Yu,kO=Re(()=>{xe();Ai();_O();FO();ps();kk=M(le());k();du();Ze=require("msgpackr"),Fk=require("ws"),Gk=require("worker_threads"),ce=M(Fs());J_();BO=require("events"),qk=M(ei()),$k=M(require("node:tls"));nl();al=M(require("node:process")),Vk=require("node:net");Li();gn();LO=require("node:stream"),Kk=M(require("minimist")),Ik=129,Ck=140,Pk=141,Ku=142,Dk=130,PO=132,Lk=133,sg=134,MO=136,ig=137,Mk=143,vk=144,Uk=145,og=146,Yk=0,vO=1,UO=2,eh=3,xO=4,Wk=0,zk=1,pse=(0,Kk.default)(al.argv),ag=pse.HDB_LEADER_URL??al.env.HDB_LEADER_URL,HO=new Map,wa=new Map,cg=!0,xk=300,Ese=2,Bk=3e4;a(dg,"createWebSocket");Hk=500,Yu=class extends BO.EventEmitter{constructor(r,n,s,i,o){super();this.url=r;this.subscription=n;this.databaseName=s;this.nodeName=i;this.authorization=o;this.nodeName=this.nodeName??Js(r)}static{a(this,"NodeReplicationConnection")}socket;startTime;retryTime=Hk;retries=0;isConnected=!0;isFinished=!1;nodeSubscriptions;latency=0;replicateTablesByDefault;session;sessionResolve;sessionReject;async connect(){this.session||this.resetSession();let r=[];this.socket=await dg(this.url,{serverName:this.nodeName,authorization:this.authorization});let n;ce.debug?.(`Connecting to ${this.url}, db: ${this.databaseName}, process ${al.pid}`),this.socket.on("open",()=>{this.socket._socket.unref(),ce[this.isConnected?"info":"warn"]?.(`Connected to ${this.url}, db: ${this.databaseName}`),this.retries=0,this.retryTime=Hk,this.nodeSubscriptions&&sl({name:this.nodeName,database:this.databaseName,url:this.url}),this.isConnected=!0,n=th(this.socket,{database:this.databaseName,subscription:this.subscription,url:this.url,connection:this,isSubscriptionConnection:this.nodeSubscriptions!==void 0},{replicates:!0}),this.sessionResolve(n)}),this.socket.on("error",s=>{s.code==="SELF_SIGNED_CERT_IN_CHAIN"?(ce.warn?.(`Can not connect to ${this.url}, this server does not have a certificate authority for the certificate provided by ${this.url}`),s.isHandled=!0):s.code!=="ECONNREFUSED"&&(s.code==="UNABLE_TO_VERIFY_LEAF_SIGNATURE"?ce.error?.(`Can not connect to ${this.url}, the certificate provided by ${this.url} is not trusted, this node needs to be added to the cluster, or a certificate authority needs to be added`):ce.error?.(`Error in connection to ${this.url} due to ${s.message}`)),this.sessionReject(s)}),this.socket.on("close",(s,i)=>{if(this.isConnected&&(this.nodeSubscriptions&&qu({name:this.nodeName,database:this.databaseName,url:this.url,finished:this.socket.isFinished}),this.isConnected=!1),this.removeAllListeners("subscriptions-updated"),this.socket.isFinished){this.isFinished=!0,n?.end(),this.emit("finished");return}if(++this.retries%20===1){let o=i?.toString();ce.warn?.(`${n?"Disconnected from":"Failed to connect to"} ${this.url} (db: "${this.databaseName}"), due to ${o?'"'+o+'" ':""}(code: ${s})`)}n=null,this.resetSession(),setTimeout(()=>{this.connect()},this.retryTime).unref(),this.retryTime+=this.retryTime>>8})}resetSession(){this.session=new Promise((r,n)=>{this.sessionResolve=r,this.sessionReject=n})}subscribe(r,n){this.nodeSubscriptions=r,this.replicateTablesByDefault=n,this.emit("subscriptions-updated",r)}unsubscribe(){this.socket.isFinished=!0,this.socket.close(1008,"No longer subscribed")}getRecord(r){return this.session.then(n=>n.getRecord(r))}};a(th,"replicateOverWS")});var Oa={};Ue(Oa,{clearThisNodeName:()=>Nse,disableReplication:()=>Ase,enabled_databases:()=>Na,forEachReplicatedDatabase:()=>Sa,getThisNodeId:()=>fg,getThisNodeName:()=>et,getThisNodeUrl:()=>Ta,hostnameToUrl:()=>Eg,lastTimeInAuditStore:()=>W_,monitorNodeCAs:()=>sF,replicateOperation:()=>Ise,replication_certificate_authorities:()=>Ro,sendOperationToNode:()=>nh,servers:()=>Sse,setReplicator:()=>oF,start:()=>Tse,startOnMainThread:()=>EO,subscribeToNode:()=>j_,unsubscribeFromNode:()=>eg,urlToNodeName:()=>Js});function Tse(e){if(e.port||(e.port=gs.default.get(x.OPERATIONSAPI_NETWORK_PORT)),e.securePort||(e.securePort=gs.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 Q_(e))t.set(Js(s.url),s);Rse(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(),th(s,e,i?.user),s.on("error",l=>{l.code!=="ECONNREFUSED"&&ar.error("Error in connection to "+this.url,l.message)})},e);e.runFirst=!0,Ye.http((s,i)=>{if(s.isWebSocket&&s.headers.get("Sec-WebSocket-Protocol")==="harperdb-replication-v1"){!s.authorized&&s._nodeRequest.socket.authorizationError&&ar.error(`Incoming client connection from ${s.ip} did not have valid certificate, you may need turn on enableRootCAs in the config if you are using a publicly signed certificate, or add the CA to the server's trusted CAs`,s._nodeRequest.socket.authorizationError);let o=ir().primaryStore;if(s.authorized&&s.peerCertificate.subject){let c=s.peerCertificate.subject,l=c&&(o.get(c.CN)||t.get(c.CN));if(l)if(l?.revoked_certificates?.includes(s.peerCertificate.serialNumber)){ar.warn("Revoked certificate used in attempt to connect to node",l.name,"certificate serial number",s.peerCertificate.serialNumber);return}else s.user=l;else ar.warn(`No node found for certificate common name ${c.CN}, available nodes are ${Array.from(o.getRange({}).filter(({value:u})=>u).map(({key:u})=>u)).join(", ")} and routes ${Array.from(t.keys()).join(", ")}, connection will require credentials.`)}else{let c=o.get(s.ip)||t.get(s.ip);c?s.user=c:ar.warn(`No node found for IP address ${s.ip}, available nodes are ${Array.from(new Set([...o.getKeys(),...t.keys()])).join(", ")}, connection will require credentials.`)}}return i(s)},e);let n=[];for(let s of r)if(s.secureContexts){let i=a(()=>{let o=new Set(s.secureContexts.values());s.defaultContext&&o.add(s.defaultContext);for(let c of o)try{let l=Array.from(Ro);c.options.availableCAs&&l.push(...c.options.availableCAs.values());let u={...c.options,ca:l};c.updatedContext=pg.createSecureContext(u)}catch(l){ar.error("Error creating replication TLS config",l)}},"updateContexts");s.secureContextsListeners.push(i),n.push(i),gs.default.get(x.REPLICATION_ENABLEROOTCAS)!==!1&&i()}sF(()=>{for(let s of n)s()})}function sF(e){let t=0;Fu(r=>{r?.ca&&(Ro.add(r.ca),Ro.size!==t&&(t=Ro.size,e?.()))})}function Ase(e=!0){nF=e}function Rse(e){nF||(Xe(),Na=e.databases,Sa(e,(t,r)=>{if(!t){let n=e.databaseSubscriptions||wa;for(let[s,i]of hg){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];oF(r,s,e),HO.get(s)?.forEach(i=>i(s))}}))}function oF(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 iF extends Kr{static{a(this,"Replicator")}static connection;static subscription;static async subscribe(){let i=r.databaseSubscriptions||wa,o=i.get(e),c=o?.tableById||[];c[t.tableId]=t;let l=o?.ready;if(ar.trace("Setting up replicator subscription to database",e),!o?.auditStore)return this.subscription=o=new Hn,i.set(e,o),o.tableById=c,o.auditStore=t.auditStore,o.dbisDB=t.dbisDB,o.databaseName=e,l&&l(o),o;this.subscription=o}static subscribeOnThisThread(i,o){return!0}static async load(i){if(i){let o=i.residencyId,c=i.residency||t.dbisDB.get([Symbol.for("residency_by_id"),o]);if(c){let l,u=new Set;do{let f;for(let _ of c){if(_===Ye.hostname)continue;let h=bse(_,iF.subscription,e);h?.isConnected&&!u.has(h)&&(!f||h.latency<f.latency)&&(f=h)}if(!f)throw l||new tF.ServerError("No connection to any other nodes are available",502);let d={requestId:gse++,table:t,entry:i,id:i.key};u.add(f);try{return await f.getRecord(d)}catch(_){if(f.isConnected)throw _;ar.warn("Error in load from node",mg,_),l||(l=_)}}while(!0)}}}static isReplicator=!0},{intermediateSource:!0})}function yse(e,t,r,n,s){let i=hg.get(e);i||(i=new Map,hg.set(e,i));let o=i.get(r);if(o)return o;if(t)return i.set(r,o=new Yu(e,t,r,n,s)),o.connect(),o.once("finished",()=>i.delete(r)),o}function bse(e,t,r){let n=Jk.get(e);n||(n=new Map,Jk.set(e,n));let s=n.get(r);if(s)return s;let i=ir().primaryStore.get(e);return i?.url&&(s=new Yu(i.url,t,r,e,i.authorization),n.set(r,s),s.connect(),s.once("finished",()=>n.delete(r))),s}async function nh(e,t,r){r||(r={}),r.serverName=e.name;let n=await dg(e.url,r),s=th(n,{},{});return new Promise((i,o)=>{n.on("open",()=>{i(s.sendOperation(t))}),n.on("error",c=>{o(c)}),n.on("close",c=>{ar.info("Sending operation connection to "+e.url+" closed",c)})}).finally(()=>{n.close()})}function j_(e){try{rF.isMainThread&&ar.trace("Subscribing on main thread (should not happen in multi-threaded instance)",e.nodes[0].url,e.database);let t=wa.get(e.database);if(!t){let n;t=new Promise(s=>{ar.info("Waiting for subscription to database "+e.database),n=s}),t.ready=n,wa.set(e.database,t)}let r=yse(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=>z_(n,e.database)),e.replicateByDefault)}catch(t){ar.error("Error in subscription to node",e.nodes[0]?.url,t)}}async function eg({name:e,url:t,database:r}){ar.trace("Unsubscribing from node",e,t,r,"nodes",Array.from(ir().primaryStore.getRange({})));let n=hg.get(t);if(n){let s=n.get(r);s&&(s.unsubscribe(),n.delete(r))}}function Ose(){if(GO!==void 0)return GO;let e=gs.default.get(x.OPERATIONSAPI_TLS_CERTIFICATE)||gs.default.get(x.TLS_CERTIFICATE);if(e)return GO=new Zk.X509Certificate((0,eF.readFileSync)(e)).subject?.match(/CN=(.*)/)?.[1]??null}function et(){return mg||(mg=gs.default.get("replication_hostname")??Js(gs.default.get("replication_url"))??Ose()??Xk("operationsapi_network_secureport")??Xk("operationsapi_network_port")??"127.0.0.1")}function Nse(){mg=void 0}function Xk(e){let t=gs.default.get(e),r=t?.lastIndexOf?.(":");if(r>0)return t.slice(0,r)}function _g(e){let t=gs.default.get(e),r=t?.lastIndexOf?.(":");return r>0?+t.slice(r+1).replace(/[\[\]]/g,""):+t}function fg(e){return Y_(e)?.[et()]}function Ta(){let e=gs.default.get("replication_url");return e||Eg(et())}function Eg(e){let t=_g("replication_port");if(t)return`ws://${e}:${t}`;if(t=_g("replication_secureport"),t)return`wss://${e}:${t}`;if(t=_g("operationsapi_network_port"),t)return`ws://${e}:${t}`;if(t=_g("operationsapi_network_secureport"),t)return`wss://${e}:${t}`}function Js(e){if(e)return new URL(e).hostname}function Sa(e,t){for(let n of Object.getOwnPropertyNames(We))r(n);return rh(n=>{r(n)}),ll((n,s)=>{r(n.databaseName)});function r(n){let s=We[n];ar.trace("Checking replication status of ",n,e?.databases),e?.databases===void 0||e.databases==="*"||e.databases.includes(n)||e.databases.some?.(i=>i.name===n)||!s?t(s,n,!0):wse(n)&&t(s,n,!1)}a(r,"forDatabase")}function wse(e){let t=We[e];for(let r in t)if(t[r].replicate)return!0}function W_(e){for(let t of e.getKeys({limit:1,reverse:!0}))return t}async function Ise(e){let t={message:""};if(e.replicated){e.replicated=!1,ar.trace?.("Replicating operation",e.operation,"to nodes",Ye.nodes.map(n=>n.name));let r=await Promise.allSettled(Ye.nodes.map(n=>nh(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 gs,ar,Zk,eF,pg,tF,rF,nF,gse,Sse,Ro,Na,hg,Jk,GO,mg,ps=Re(()=>{xe();ia();Jl();kO();Mr();gs=M(le()),ar=M(ee()),Zk=require("crypto"),eF=require("fs");J_();nl();k();_O();pg=M(require("node:tls")),tF=M(he()),rF=require("worker_threads"),gse=1,Sse=[],Ro=gs.default.get(x.REPLICATION_ENABLEROOTCAS)!==!1?new Set(pg.rootCertificates):new Set;a(Tse,"start");a(sF,"monitorNodeCAs");a(Ase,"disableReplication");a(Rse,"assignReplicationSource");a(oF,"setReplicator");hg=new Map;a(yse,"getSubscriptionConnection");Jk=new Map;a(bse,"getRetrievalConnectionByName");a(nh,"sendOperationToNode");a(j_,"subscribeToNode");a(eg,"unsubscribeFromNode");a(Ose,"getCommonNameFromCert");a(et,"getThisNodeName");a(Nse,"clearThisNodeName");Object.defineProperty(Ye,"hostname",{get(){return et()}});a(Xk,"getHostFromListeningPort");a(_g,"getPortFromListeningPort");a(fg,"getThisNodeId");Ye.replication={getThisNodeId:fg,exportIdMapping:Y_};a(Ta,"getThisNodeUrl");a(Eg,"hostnameToUrl");a(Js,"urlToNodeName");a(Sa,"forEachReplicatedDatabase");a(wse,"hasExplicitlyReplicatedTable");a(W_,"lastTimeInAuditStore");a(Ise,"replicateOperation")});var ih=C((qIe,dF)=>{"use strict";var Wu=SH(),{validateBySchema:sh}=it(),{common_validators:zu,schema_regex:qO}=Oi(),cr=require("joi"),Cse=ee(),Pse=require("uuid").v4,Tg=po(),Qu=(k(),P(q)),Dse=require("util"),Ia=Vn(),{handleHDBError:yo,hdb_errors:Lse,ClientError:ul}=he(),{HDB_ERROR_MSGS:gg,HTTP_STATUS_CODES:bo}=Lse,{SchemaEventMsg:Ag}=Ys(),aF=gr(),{getDatabases:Mse}=(xe(),P(ct)),{transformReq:ju}=ie(),{replicateOperation:cF}=(ps(),P(Oa)),{cleanupOrphans:GIe}=(gn(),P(lu)),Sg=cr.string().min(1).max(zu.schema_length.maximum).pattern(qO).messages({"string.pattern.base":"{:#label} "+zu.schema_format.message}),vse=cr.string().min(1).max(zu.schema_length.maximum).pattern(qO).messages({"string.pattern.base":"{:#label} "+zu.schema_format.message}).required(),Use=cr.string().min(1).max(zu.schema_length.maximum).pattern(qO).messages({"string.pattern.base":"{:#label} "+zu.schema_format.message,"any.required":"'primary_key' is required","string.base":"'primary_key' must be a string"}).required();dF.exports={createSchema:xse,createSchemaStructure:lF,createTable:Bse,createTableStructure:uF,createAttribute:qse,dropSchema:Hse,dropTable:kse,dropAttribute:Fse,getBackup:$se,cleanupOrphanBlobs:Vse};async function xse(e){let t=await lF(e);return Tg.signalSchemaChange(new Ag(process.pid,e.operation,e.schema)),t}a(xse,"createSchema");async function lF(e){let t=sh(e,cr.object({database:Sg,schema:Sg}));if(t)throw new ul(t.message);if(ju(e),!await Wu.checkSchemaExists(e.schema))throw yo(new Error,gg.SCHEMA_EXISTS_ERR(e.schema),bo.BAD_REQUEST,Qu.LOG_LEVELS.ERROR,gg.SCHEMA_EXISTS_ERR(e.schema),!0);return await Ia.createSchema(e),`database '${e.schema}' successfully created`}a(lF,"createSchemaStructure");async function Bse(e){return ju(e),e.hash_attribute=e.primary_key??e.hash_attribute,await uF(e)}a(Bse,"createTable");async function uF(e){let t=sh(e,cr.object({database:Sg,schema:Sg,table:vse,residence:cr.array().items(cr.string().min(1)).optional(),hash_attribute:Use}));if(t)throw new ul(t.message);if(!await Wu.checkSchemaTableExists(e.schema,e.table))throw yo(new Error,gg.TABLE_EXISTS_ERR(e.schema,e.table),bo.BAD_REQUEST,Qu.LOG_LEVELS.ERROR,gg.TABLE_EXISTS_ERR(e.schema,e.table),!0);let n={name:e.table,schema:e.schema,id:Pse(),hash_attribute:e.hash_attribute};try{if(e.residence)if(global.clustering_on)n.residence=e.residence,await Ia.createTable(n,e);else throw yo(new Error,"Clustering does not appear to be enabled. Cannot insert table with property 'residence'.",bo.BAD_REQUEST);else await Ia.createTable(n,e);return`table '${e.schema}.${e.table}' successfully created.`}catch(s){throw s}}a(uF,"createTableStructure");async function Hse(e){let t=sh(e,cr.object({database:cr.string(),schema:cr.string()}).or("database","schema").messages({"object.missing":"'database' is required"}));if(t)throw new ul(t.message);ju(e);let r=await Wu.checkSchemaExists(e.schema);if(r)throw yo(new Error,r,bo.NOT_FOUND,Qu.LOG_LEVELS.ERROR,r,!0);let n=await Wu.schema_describe.describeSchema({schema:e.schema}),s=Object.keys(global.hdb_schema[e.schema]);await Ia.dropSchema(e),Tg.signalSchemaChange(new Ag(process.pid,e.operation,e.schema)),await aF.purgeSchemaTableStreams(e.schema,s);let i=await cF(e);return i.message=`successfully deleted '${e.schema}'`,i}a(Hse,"dropSchema");async function kse(e){let t=sh(e,cr.object({database:cr.string(),schema:cr.string(),table:cr.string().required()}));if(t)throw new ul(t.message);ju(e);let r=await Wu.checkSchemaTableExists(e.schema,e.table);if(r)throw yo(new Error,r,bo.NOT_FOUND,Qu.LOG_LEVELS.ERROR,r,!0);await Ia.dropTable(e),await aF.purgeTableStream(e.schema,e.table);let n=await cF(e);return n.message=`successfully deleted table '${e.schema}.${e.table}'`,n}a(kse,"dropTable");async function Fse(e){let t=sh(e,cr.object({database:cr.string(),schema:cr.string(),table:cr.string().required(),attribute:cr.string().required()}));if(t)throw new ul(t.message);ju(e);let r=await Wu.checkSchemaTableExists(e.schema,e.table);if(r)throw yo(new Error,r,bo.NOT_FOUND,Qu.LOG_LEVELS.ERROR,r,!0);if(e.attribute===global.hdb_schema[e.schema][e.table].hash_attribute)throw yo(new Error,"You cannot drop a hash attribute",bo.BAD_REQUEST,void 0,void 0,!0);if(Qu.TIME_STAMP_NAMES.indexOf(e.attribute)>=0)throw yo(new Error,`cannot drop internal timestamp attribute: ${e.attribute}`,bo.BAD_REQUEST,void 0,void 0,!0);try{return await Ia.dropAttribute(e),Gse(e),Tg.signalSchemaChange(new Ag(process.pid,e.operation,e.schema,e.table,e.attribute)),`successfully deleted attribute '${e.attribute}'`}catch(n){throw Cse.error(`Got an error deleting attribute ${Dse.inspect(e)}.`),n}}a(Fse,"dropAttribute");function Gse(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(Gse,"dropAttributeFromGlobal");async function qse(e){ju(e);let t=Mse()[e.schema][e.table].attributes;for(let{name:r}of t)if(r===e.attribute)throw yo(new Error,`attribute '${e.attribute}' already exists in ${e.schema}.${e.table}`,bo.BAD_REQUEST,void 0,void 0,!0);return await Ia.createAttribute(e),Tg.signalSchemaChange(new Ag(process.pid,e.operation,e.schema,e.table,e.attribute)),`attribute '${e.schema}.${e.table}.${e.attribute}' successfully created.`}a(qse,"createAttribute");function $se(e){return Ia.getBackup(e)}a($se,"getBackup");function Vse(e){if(!e.database)throw new ul('Must provide "database" name for search for orphaned blobs');if(!databases[e.database])throw new ul(`Unknown database '${e.database}'`);let{cleanupOrphans:r}=(gn(),P(lu));return r(databases[e.database],e.database),{message:"Orphaned blobs cleanup started, check logs for progress"}}a(Vse,"cleanupOrphanBlobs")});var _F=C((VIe,fF)=>{"use strict";var{OPERATIONS_ENUM:Kse}=(k(),P(q)),$O=class{static{a(this,"ReadAuditLogObject")}constructor(t,r,n=void 0,s=void 0){this.operation=Kse.READ_AUDIT_LOG,this.schema=t,this.table=r,this.search_type=n,this.search_values=s}};fF.exports=$O});var VO=C((WIe,gF)=>{"use strict";var Yse=Vn(),YIe=_F(),Rg=ie(),yg=(k(),P(q)),Wse=le(),{handleHDBError:hF,hdb_errors:zse}=he(),{HDB_ERROR_MSGS:mF,HTTP_STATUS_CODES:pF}=zse,Qse=Object.values(yg.READ_AUDIT_LOG_SEARCH_TYPES_ENUM),EF="To use this operation audit log must be enabled in harperdb-config.yaml";gF.exports=jse;async function jse(e){if(Rg.isEmpty(e.schema))throw new Error(mF.SCHEMA_REQUIRED_ERR);if(Rg.isEmpty(e.table))throw new Error(mF.TABLE_REQUIRED_ERR);if(!Wse.get(yg.CONFIG_PARAMS.LOGGING_AUDITLOG))throw hF(new Error,EF,pF.BAD_REQUEST,yg.LOG_LEVELS.ERROR,EF,!0);let t=Rg.checkSchemaTableExist(e.schema,e.table);if(t)throw hF(new Error,t,pF.NOT_FOUND,yg.LOG_LEVELS.ERROR,t,!0);if(!Rg.isEmpty(e.search_type)&&Qse.indexOf(e.search_type)<0)throw new Error(`Invalid search_type '${e.search_type}'`);return await Yse.readAuditLog(e)}a(jse,"readAuditLog")});var TF=C((QIe,SF)=>{"use strict";var{OPERATIONS_ENUM:Jse}=(k(),P(q)),KO=class{static{a(this,"GetBackupObject")}constructor(t,r,n=void 0,s=void 0){this.operation=Jse.GET_BACKUP,this.schema=t,this.table=r}};SF.exports=KO});var yF=C((ZIe,RF)=>{"use strict";var Xse=Vn(),JIe=TF(),YO=ie(),Zse=(k(),P(q)),XIe=le(),{handleHDBError:eie,hdb_errors:tie}=he(),{HDB_ERROR_MSGS:AF,HTTP_STATUS_CODES:rie}=tie;RF.exports=nie;async function nie(e){if(YO.isEmpty(e.schema))throw new Error(AF.SCHEMA_REQUIRED_ERR);if(YO.isEmpty(e.table))throw new Error(AF.TABLE_REQUIRED_ERR);let t=YO.checkSchemaTableExist(e.schema,e.table);if(t)throw eie(new Error,t,rie.NOT_FOUND,Zse.LOG_LEVELS.ERROR,t,!0);return await Xse.getBackup(read_audit_log_object)}a(nie,"getBackup")});var wF=C((tCe,NF)=>{"use strict";var sie=le(),Ca=require("joi"),iie=it(),bF=require("moment"),oie=require("fs-extra"),WO=require("path"),aie=require("lodash"),oh=(k(),P(q)),{LOG_LEVELS:dl}=(k(),P(q)),cie="YYYY-MM-DD hh:mm:ss",lie=WO.resolve(__dirname,"../logs");NF.exports=function(e){return iie.validateBySchema(e,uie)};var uie=Ca.object({from:Ca.custom(OF),until:Ca.custom(OF),level:Ca.valid(dl.NOTIFY,dl.FATAL,dl.ERROR,dl.WARN,dl.INFO,dl.DEBUG,dl.TRACE),order:Ca.valid("asc","desc"),limit:Ca.number().min(1),start:Ca.number().min(0),log_name:Ca.custom(die)});function OF(e,t){if(bF(e,bF.ISO_8601).format(cie)==="Invalid date")return t.message(`'${t.state.path[0]}' date '${e}' is invalid.`)}a(OF,"validateDatetime");function die(e,t){if(aie.invert(oh.LOG_NAMES)[e]===void 0)return t.message(`'log_name' '${e}' is invalid.`);let n=sie.get(oh.HDB_SETTINGS_NAMES.LOG_PATH_KEY),s=e===void 0?oh.LOG_NAMES.HDB:e,i=s===oh.LOG_NAMES.INSTALL?WO.join(lie,oh.LOG_NAMES.INSTALL):WO.join(n,s);return oie.existsSync(i)?null:t.message(`'log_name' '${e}' does not exist.`)}a(die,"validateReadLogPath")});var QO=C((nCe,CF)=>{"use strict";var bg=(k(),P(q)),fie=ee(),_ie=le(),hie=wF(),zO=require("path"),IF=require("fs-extra"),{once:mie}=require("events"),{handleHDBError:pie,hdb_errors:Eie}=he(),{PACKAGE_ROOT:gie}=Et(),Sie=zO.join(gie,"logs"),Tie=1e3,Aie=200;CF.exports=Rie;async function Rie(e){let t=hie(e);if(t)throw pie(t,t.message,Eie.HTTP_STATUS_CODES.BAD_REQUEST,void 0,void 0,!0);let r=_ie.get(bg.HDB_SETTINGS_NAMES.LOG_PATH_KEY),n=e.log_name===void 0?bg.LOG_NAMES.HDB:e.log_name,s=n===bg.LOG_NAMES.INSTALL?zO.join(Sie,bg.LOG_NAMES.INSTALL):zO.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?Tie:e.limit,_=e.order===void 0?void 0:e.order,h=e.start===void 0?0:e.start,m=h+d,S=0;_==="desc"&&!l&&!f&&(S=Math.max(IF.statSync(s).size-(m+5)*Aie,0));let g=IF.createReadStream(s,{start:S});g.on("error",H=>{fie.error(H)});let R=0,E=[],T="",N;g.on("data",H=>{let X=/(?:^|\n)(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:[\d\.]+Z) \[(.+?)]: /g;H=T+H;let W=0,$;for(;($=X.exec(H))&&!g.destroyed;){N&&(N.message=H.slice(W,$.index),v(N));let[se,z,fe]=$,ue=fe.split("] ["),Z=ue[0],Ae=ue[1];ue.splice(0,2),N={timestamp:z,thread:Z,level:Ae,tags:ue,message:""},W=$.index+se.length}T=H.slice(W)}),g.on("end",H=>{g.destroyed||N&&(N.message=T.trim(),v(N))}),g.resume();function v(H){let X,W,$;switch(!0){case(i&&c&&u):X=new Date(H.timestamp),W=new Date(l),$=new Date(f),H.level===o&&X>=W&&X<=$&&R<h?R++:H.level===o&&X>=W&&X<=$&&(Pa(H,_,E),R++,R===m&&g.destroy());break;case(i&&c):X=new Date(H.timestamp),W=new Date(l),H.level===o&&X>=W&&R<h?R++:H.level===o&&X>=W&&(Pa(H,_,E),R++,R===m&&g.destroy());break;case(i&&u):X=new Date(H.timestamp),$=new Date(f),H.level===o&&X<=$&&R<h?R++:H.level===o&&X<=$&&(Pa(H,_,E),R++,R===m&&g.destroy());break;case(c&&u):X=new Date(H.timestamp),W=new Date(l),$=new Date(f),X>=W&&X<=$&&R<h?R++:X>=W&&X<=$&&(Pa(H,_,E),R++,R===m&&g.destroy());break;case i:H.level===o&&R<h?R++:H.level===o&&(Pa(H,_,E),R++,R===m&&g.destroy());break;case c:X=new Date(H.timestamp),W=new Date(l),X>=W&&R<h?R++:X>=W&&R>=h&&(Pa(H,_,E),R++,R===m&&g.destroy());break;case u:X=new Date(H.timestamp),$=new Date(f),X<=$&&R<h?R++:X<=$&&R>=h&&(Pa(H,_,E),R++,R===m&&g.destroy());break;default:R<h?R++:(Pa(H,_,E),R++,R===m&&g.destroy())}}return a(v,"onLogMessage"),await mie(g,"close"),E}a(Rie,"readLog");function Pa(e,t,r){t==="desc"?yie(e,r):t==="asc"?bie(e,r):r.push(e)}a(Pa,"pushLineToResult");function yie(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(yie,"insertDescending");function bie(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(bie,"insertAscending")});var Og=C((lCe,MF)=>{"use strict";var jO=require("joi"),{string:Ju,boolean:PF,date:Oie}=jO.types(),Nie=it(),{validateSchemaExists:iCe,validateTableExists:oCe,validateSchemaName:aCe}=Oi(),wie=(k(),P(q)),Iie=Lt(),DF=le();DF.initSync();var cCe=Ju.invalid(DF.get(wie.CONFIG_PARAMS.CLUSTERING_NODENAME)??"node_name").pattern(Iie.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),LF={operation:Ju.valid("add_node","update_node","set_node_replication"),node_name:Ju.optional(),subscriptions:jO.array().items({table:Ju.optional(),schema:Ju.optional(),database:Ju.optional(),subscribe:PF.required(),publish:PF.required().custom(Pie),start_time:Oie.iso()})};function Cie(e){return Nie.validateBySchema(e,jO.object(LF))}a(Cie,"addUpdateNodeValidator");function Pie(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(Pie,"checkForFalsy");MF.exports={addUpdateNodeValidator:Cie,validation_schema:LF}});var Xu=C((dCe,vF)=>{"use strict";var JO=class{static{a(this,"Node")}constructor(t,r,n){this.name=t,this.subscriptions=r,this.system_info=n}},XO=class{static{a(this,"NodeSubscription")}constructor(t,r,n,s){this.schema=t,this.table=r,this.publish=n,this.subscribe=s}};vF.exports={Node:JO,NodeSubscription:XO}});var xF=C((_Ce,UF)=>{"use strict";var Die=(k(),P(q)).OPERATIONS_ENUM,ZO=class{static{a(this,"UpsertObject")}constructor(t,r,n,s=void 0){this.operation=Die.UPSERT,this.schema=t,this.table=r,this.records=n,this.__origin=s}};UF.exports=ZO});var ah=C((mCe,BF)=>{"use strict";var eN=class{static{a(this,"RemotePayloadObject")}constructor(t,r,n,s){this.operation=t,this.node_name=r,this.subscriptions=n,this.system_info=s}},tN=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)}};BF.exports={RemotePayloadObject:eN,RemotePayloadSubscription:tN}});var kF=C((ECe,HF)=>{"use strict";var rN=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}};HF.exports=rN});var GF=C((yCe,FF)=>{"use strict";var Lie=kF(),SCe=Gt(),TCe=ht(),Mie=ee(),{getSchemaPath:ACe,getTransactionAuditStorePath:RCe}=gt(),{getDatabases:vie}=(xe(),P(ct));FF.exports=Uie;async function Uie(e){let t=new Lie;try{let r=vie()[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){Mie.warn(`unable to stat table dbi due to ${r}`)}return t}a(Uie,"lmdbGetTableSize")});var $F=C((OCe,qF)=>{"use strict";var nN=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}};qF.exports=nN});var ed=C((DCe,WF)=>{"use strict";var xie=require("fs-extra"),Bie=require("path"),Xr=require("systeminformation"),Da=ee(),VF=gr(),wCe=Lt(),Zu=(k(),P(q)),Hie=GF(),kie=ho(),{getThreadInfo:KF}=ot(),ch=le();ch.initSync();var Fie=$F(),{openEnvironment:ICe}=ht(),{getSchemaPath:CCe}=gt(),{database:PCe,databases:sN}=(xe(),P(ct)),Ng;WF.exports={getHDBProcessInfo:cN,getNetworkInfo:uN,getDiskInfo:lN,getMemoryInfo:aN,getCPUInfo:oN,getTimeInfo:iN,getSystemInformation:dN,systemInformation:Gie,getTableSize:fN,getMetrics:_N};function iN(){return Xr.time()}a(iN,"getTimeInfo");async function oN(){try{let{family:e,model:t,stepping:r,revision:n,voltage:s,speedmin:i,speedmax:o,governor:c,socket:l,cache:u,...f}=await Xr.cpu();f.cpu_speed=await Xr.cpuCurrentSpeed();let{raw_currentload:d,raw_currentload_idle:_,raw_currentload_irq:h,raw_currentload_nice:m,raw_currentload_system:S,raw_currentload_user:g,cpus:R,...E}=await Xr.currentLoad();return E.cpus=[],R.forEach(T=>{let{raw_load:N,raw_load_idle:v,raw_load_irq:H,raw_load_nice:X,raw_load_system:W,raw_load_user:$,...se}=T;E.cpus.push(se)}),f.current_load=E,f}catch(e){return Da.error(`error in getCPUInfo: ${e}`),{}}}a(oN,"getCPUInfo");async function aN(){try{let{buffers:e,cached:t,slab:r,buffcache:n,...s}=await Xr.mem();return Object.assign(s,process.memoryUsage())}catch(e){return Da.error(`error in getMemoryInfo: ${e}`),{}}}a(aN,"getMemoryInfo");async function cN(){let e={core:[],clustering:[]};try{let t=await Xr.processes(),r;try{r=Number.parseInt(await xie.readFile(Bie.join(ch.get(Zu.CONFIG_PARAMS.ROOTPATH),Zu.HDB_PID_FILE),"utf8"))}catch(n){if(n.code===Zu.NODE_ERROR_CODES.ENOENT)Da.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 Da.error(`error in getHDBProcessInfo: ${t}`),e}}a(cN,"getHDBProcessInfo");async function lN(){let e={};try{if(!ch.get(Zu.CONFIG_PARAMS.OPERATIONSAPI_SYSINFO_DISK))return e;let{rIO_sec:t,wIO_sec:r,tIO_sec:n,ms:s,...i}=await Xr.disksIO();e.io=i;let{rx_sec:o,tx_sec:c,wx_sec:l,...u}=await Xr.fsStats();return e.read_write=u,e.size=await Xr.fsSize(),e}catch(t){return Da.error(`error in getDiskInfo: ${t}`),e}}a(lN,"getDiskInfo");async function uN(){let e={default_interface:null,latency:{},interfaces:[],stats:[],connections:[]};try{return ch.get(Zu.CONFIG_PARAMS.OPERATIONSAPI_SYSINFO_NETWORK)&&(e.default_interface=await Xr.networkInterfaceDefault(),e.latency=await Xr.inetChecksite("google.com"),(await Xr.networkInterfaces()).forEach(n=>{let{internal:s,virtual:i,mtu:o,dhcp:c,dnsSuffix:l,ieee8021xAuth:u,ieee8021xState:f,carrier_changes:d,..._}=n;e.interfaces.push(_)}),(await Xr.networkStats()).forEach(n=>{let{rx_sec:s,tx_sec:i,ms:o,...c}=n;e.stats.push(c)})),e}catch(t){return Da.error(`error in getNetworkInfo: ${t}`),e}}a(uN,"getNetworkInfo");async function dN(){if(Ng!==void 0)return Ng;let e={};try{let{codepage:t,logofile:r,serial:n,build:s,servicepack:i,uefi:o,...c}=await Xr.osInfo();e=c;let l=await Xr.versions("node, npm");return e.node_version=l.node,e.npm_version=l.npm,Ng=e,Ng}catch(t){return Da.error(`error in getSystemInformation: ${t}`),e}}a(dN,"getSystemInformation");async function fN(){let e=[],t=await kie.describeAll();for(let r of Object.values(t))for(let n of Object.values(r))e.push(await Hie(n));return e}a(fN,"getTableSize");async function _N(){let e={};for(let t in sN){let r=e[t]={},n=r.tables={};for(let s in sN[t])try{let i=sN[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){Da.notify(`Error getting stats for table ${s}: ${i}`)}}return e}a(_N,"getMetrics");async function YF(){if(ch.get(Zu.CONFIG_PARAMS.CLUSTERING_ENABLED)){let{jsm:e}=await VF.getNATSReferences(),t=await VF.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(YF,"getNatsStreamInfo");async function Gie(e){let t=new Fie;if(!Array.isArray(e.attributes)||e.attributes.length===0)return t.system=await dN(),t.time=iN(),t.cpu=await oN(),t.memory=await aN(),t.disk=await lN(),t.network=await uN(),t.harperdb_processes=await cN(),t.table_size=await fN(),t.metrics=await _N(),t.threads=await KF(),t.replication=await YF(),t;for(let r=0;r<e.attributes.length;r++)switch(e.attributes[r]){case"system":t.system=await dN();break;case"time":t.time=iN();break;case"cpu":t.cpu=await oN();break;case"memory":t.memory=await aN();break;case"disk":t.disk=await lN();break;case"network":t.network=await uN();break;case"harperdb_processes":t.harperdb_processes=await cN();break;case"table_size":t.table_size=await fN();break;case"database_metrics":case"metrics":t.metrics=await _N();break;case"threads":t.threads=await KF();break;case"replication":t.replication=await YF();break;default:break}return t}a(Gie,"systemInformation")});var Oo=C((xCe,JF)=>{"use strict";var qie=An(),hN=ie(),$ie=require("util"),fl=(k(),P(q)),zF=le();zF.initSync();var Vie=Yb(),QF=Wr(),{Node:MCe,NodeSubscription:vCe}=Xu(),Kie=Ru(),Yie=xF(),{RemotePayloadObject:Wie,RemotePayloadSubscription:zie}=ah(),{handleHDBError:Qie,hdb_errors:jie}=he(),{HTTP_STATUS_CODES:Jie,HDB_ERROR_MSGS:Xie}=jie,Zie=Ws(),eoe=ed(),{packageJson:toe}=Et(),{getDatabases:roe}=(xe(),P(ct)),UCe=$ie.promisify(Vie.authorize),noe=QF.searchByHash,soe=QF.searchByValue;JF.exports={isEmpty:ioe,getNodeRecord:ooe,upsertNodeRecord:aoe,buildNodePayloads:coe,checkClusteringEnabled:loe,getAllNodeRecords:uoe,getSystemInfo:doe,reverseSubscription:jF};function ioe(e){return e==null}a(ioe,"isEmpty");async function ooe(e){let t=new Kie(fl.SYSTEM_SCHEMA_NAME,fl.SYSTEM_TABLE_NAMES.NODE_TABLE_NAME,[e],["*"]);return noe(t)}a(ooe,"getNodeRecord");async function aoe(e){let t=new Yie(fl.SYSTEM_SCHEMA_NAME,fl.SYSTEM_TABLE_NAMES.NODE_TABLE_NAME,[e]);return qie.upsert(t)}a(aoe,"upsertNodeRecord");function jF(e){if(hN.isEmpty(e.subscribe)||hN.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(jF,"reverseSubscription");function coe(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=hN.getTableHashAttribute(l,u),{subscribe:d,publish:_}=jF(c),h=roe()[l]?.[u],m=new zie(l,u,f,_,d,c.start_time,h.schemaDefined?h.attributes:void 0);s.push(m)}return new Wie(r,t,s,n)}a(coe,"buildNodePayloads");function loe(){if(!zF.get(fl.CONFIG_PARAMS.CLUSTERING_ENABLED))throw Qie(new Error,Xie.CLUSTERING_NOT_ENABLED,Jie.BAD_REQUEST,void 0,void 0,!0)}a(loe,"checkClusteringEnabled");async function uoe(){let e=new Zie(fl.SYSTEM_SCHEMA_NAME,fl.SYSTEM_TABLE_NAMES.NODE_TABLE_NAME,"name","*",void 0,["*"]);return Array.from(await soe(e))}a(uoe,"getAllNodeRecords");async function doe(){let e=await eoe.getSystemInformation();return{hdb_version:toe.version,node_version:e.node_version,platform:e.platform}}a(doe,"getSystemInfo")});var mN=C((HCe,iG)=>{"use strict";var wg=gr(),XF=ie(),ZF=Lt(),eG=(k(),P(q)),Ig=ee(),tG=ih(),foe=T_(),{RemotePayloadObject:_oe}=ah(),{handleHDBError:rG,hdb_errors:hoe}=he(),{HTTP_STATUS_CODES:nG}=hoe,{NodeSubscription:sG}=Xu();iG.exports=moe;async function moe(e,t){let r;try{r=await wg.request(`${t}.${ZF.REQUEST_SUFFIX}`,new _oe(eG.OPERATIONS_ENUM.DESCRIBE_ALL,t,void 0,void 0)),Ig.trace("Response from remote describe all request:",r)}catch(o){Ig.error(`addNode received error from describe all request to remote node: ${o}`);let c=wg.requestErrorHandler(o,"add_node",t);throw rG(new Error,c,nG.INTERNAL_SERVER_ERROR,"error",c)}if(r.status===ZF.UPDATE_REMOTE_RESPONSE_STATUSES.ERROR){let o=`Error returned from remote node ${t}: ${r.message}`;throw rG(new Error,o,nG.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===eG.SYSTEM_SCHEMA_NAME){await wg.createLocalTableStream(l,c);let m=new sG(l,c,o.publish,o.subscribe);m.start_time=o.start_time,i.push(m);continue}let u=XF.doesSchemaExist(l),f=n[l]!==void 0,d=c?XF.doesTableExist(l,c):!0,_=c?n?.[l]?.[c]!==void 0:!0;if(!u&&!f||!d&&!_){s.push(o);continue}if(!u&&f&&(Ig.trace(`addNode creating schema: ${l}`),await tG.createSchema({operation:"create_schema",schema:l})),!d&&_){Ig.trace(`addNode creating table: ${c} in schema: ${l} with attributes ${JSON.stringify(n[l][c].attributes)}`);let m=new foe(l,c,n[l][c].hash_attribute);n[l][c].attributes&&(m.attributes=n[l][c].attributes),await tG.createTable(m)}await wg.createLocalTableStream(l,c);let h=new sG(l,c,o.publish,o.subscribe);h.start_time=o.start_time,i.push(h)}return{added:i,skipped:s}}a(moe,"reviewSubscriptions")});var _l={};Ue(_l,{addNodeBack:()=>Toe,removeNodeBack:()=>Aoe,setNode:()=>Soe});async function Soe(e){e.node_name&&!e.hostname&&(e.hostname=e.node_name),e.verify_tls!==void 0&&(e.rejectUnauthorized=e.verify_tls);let{url:t,hostname:r}=e;t?r||(r=e.hostname=Js(t)):t=Eg(r);let n=(0,aG.validateBySchema)(e,goe);if(n)throw(0,No.handleHDBError)(n,n.message,Eoe.BAD_REQUEST,void 0,void 0,!0);if(e.operation==="remove_node"){if(!t&&!r)throw new No.ClientError("url or hostname is required for remove_node operation");let h=r,m=ir(),S=await m.get(h);if(!S)throw new No.ClientError(h+" does not exist");try{await nh({url:S.url},{operation:Wt.REMOVE_NODE_BACK,name:S?.subscriptions?.length>0?et():h},void 0)}catch(g){Xn.warn(`Error removing node from target node ${h}, if it is offline and we be online in the future, you may need to clean up this node manually, or retry:`,g)}return await m.delete(h),`Successfully removed '${h}' from cluster`}if(!t)throw new No.ClientError("url required for this operation");let s=Ta();if(s==null)throw new No.ClientError("replication url is missing from harperdb-config.yaml");let i,o,c;if(t?.startsWith("wss:")){i=await(0,Ss.getReplicationCert)();let h=await(0,Ss.getReplicationCertAuth)();if(!i)throw new Error("Unable to find a certificate to use for replication");i.options.is_self_signed?(o=await(0,Ss.createCsr)(),Xn.info("Sending CSR to target node:",t)):h&&(c=h.certificate,Xn.info("Sending CA named",h.name,"to target node",t))}let l={operation:Wt.ADD_NODE_BACK,hostname:(0,Ma.get)(x.REPLICATION_HOSTNAME),target_hostname:r,url:s,csr:o,cert_auth:c,authorization:e.retain_authorization?e.authorization:null};if((0,Ma.get)(x.REPLICATION_SHARD)!==void 0&&(l.shard=(0,Ma.get)(x.REPLICATION_SHARD)),e.subscriptions?l.subscriptions=e.subscriptions.map(oG):l.subscriptions=null,e.hasOwnProperty("subscribe")||e.hasOwnProperty("publish")){let h=oG(e);l.subscribe=h.subscribe,l.publish=h.publish}e?.authorization?.username&&e?.authorization?.password&&(e.authorization="Basic "+Buffer.from(e.authorization.username+":"+e.authorization.password).toString("base64"));let u,f;try{u=await nh({url:t},l,e)}catch(h){h.message=`Error returned from ${t}: `+h.message,Xn.warn("Error adding node:",t,"to cluster:",h),f=h}if(o&&(!u?.certificate||!u?.certificate?.includes?.("BEGIN CERTIFICATE")))throw f?(f.message+=" and connection was required to sign certificate",f):new Error(`Unexpected certificate signature response from node ${t} response: ${JSON.stringify(u)}`);o&&(Xn.info("CSR response received from node:",t,"saving certificate and CA in hdb_certificate"),await(0,Ss.setCertTable)({name:poe.certificateFromPem(u.signingCA).issuer.getField("CN").value,certificate:u.signingCA,is_authority:!0}),u.certificate&&await(0,Ss.setCertTable)({name:et(),uses:["https","operations","wss"],certificate:u.certificate,private_key_name:i?.options?.key_file,is_authority:!1,is_self_signed:!1}),c=u.signingCA);let d={url:t,ca:u?.usingCA};if(e.hostname&&(d.name=e.hostname),e.subscriptions?d.subscriptions=e.subscriptions:d.replicates=!0,e.start_time&&(d.start_time=typeof e.start_time=="string"?new Date(e.start_time).getTime():e.start_time),e.retain_authorization&&(d.authorization=e.authorization),e.revoked_certificates&&(d.revoked_certificates=e.revoked_certificates),u?.shard!==void 0?d.shard=u.shard:e.shard!==void 0&&(d.shard=e.shard),d.replicates){let h={url:s,ca:c,replicates:!0,subscriptions:null};(0,Ma.get)(x.REPLICATION_SHARD)!==void 0&&(h.shard=(0,Ma.get)(x.REPLICATION_SHARD)),e.retain_authorization&&(h.authorization=e.authorization),e.start_time&&(h.start_time=e.start_time),await To(et(),h)}await To(u?u.nodeName:d.name??Js(t),d);let _;return e.operation==="update_node"?_=`Successfully updated '${t}'`:_=`Successfully added '${t}' to cluster`,f&&(_+=" but there was an error updating target node: "+f.message),_}async function Toe(e){Xn.trace("addNodeBack received request:",e);let t=await(0,Ss.signCertificate)(e),r;e.csr?(r=t.signingCA,Xn.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,Xn.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,Ss.getReplicationCertAuth)();if(n.replicates){let i={url:Ta(),ca:s?.certificate,replicates:!0,subscriptions:null};(0,Ma.get)(x.REPLICATION_SHARD)!==void 0&&(i.shard=(0,Ma.get)(x.REPLICATION_SHARD),t.shard=i.shard),e.start_time&&(i.start_time=e.start_time),e.authorization&&(i.authorization=e.authorization),await To(et(),i)}return await To(e.hostname,n),t.nodeName=et(),t.usingCA=s?.certificate,Xn.info("addNodeBack responding to:",e.url,"with CA named:",s?.name),t}async function Aoe(e){Xn.trace("removeNodeBack received request:",e),await ir().delete(e.name)}function oG(e){let{subscribe:t,publish:r}=e;return{...e,subscribe:r,publish:t}}var Ss,aG,La,Ma,Xn,No,poe,Eoe,goe,hl=Re(()=>{Ss=M(ei()),aG=M(it()),La=M(require("joi")),Ma=M(le());k();J_();nl();ps();Xn=M(ee()),No=M(he()),{pki:poe}=require("node-forge"),{HTTP_STATUS_CODES:Eoe}=No.hdb_errors,goe=La.default.object({hostname:La.default.string(),verify_tls:La.default.boolean(),replicates:La.default.boolean(),subscriptions:La.default.array(),revoked_certificates:La.default.array(),shard:La.default.number()});a(Soe,"setNode");a(Toe,"addNodeBack");a(Aoe,"removeNodeBack");a(oG,"reverseSubscription")});var Mg=C((WCe,lG)=>{"use strict";var{handleHDBError:Cg,hdb_errors:Roe}=he(),{HTTP_STATUS_CODES:Pg}=Roe,{addUpdateNodeValidator:yoe}=Og(),Dg=ee(),Lg=(k(),P(q)),cG=Lt(),boe=ie(),lh=gr(),uh=Oo(),pN=le(),Ooe=mN(),{Node:Noe,NodeSubscription:woe}=Xu(),{broadcast:Ioe}=ot(),{setNode:Coe}=(hl(),P(_l)),KCe=le(),YCe=(k(),P(q)),Poe="Unable to create subscriptions due to schema and/or tables not existing on the local or remote node",Doe="Some subscriptions were unsuccessful due to schema and/or tables not existing on the local or remote node",Loe=pN.get(Lg.CONFIG_PARAMS.CLUSTERING_NODENAME);lG.exports=Moe;async function Moe(e,t=!1){if(Dg.trace("addNode called with:",e),pN.get(Lg.CONFIG_PARAMS.REPLICATION_URL)||pN.get(Lg.CONFIG_PARAMS.REPLICATION_HOSTNAME))return Coe(e);uh.checkClusteringEnabled();let r=yoe(e);if(r)throw Cg(r,r.message,Pg.BAD_REQUEST,void 0,void 0,!0);let n=e.node_name;if(!t){let d=await uh.getNodeRecord(n);if(!boe.isEmptyOrZeroLength(d))throw Cg(new Error,`Node '${n}' has already been added, perform update_node to proceed.`,Pg.BAD_REQUEST,void 0,void 0,!0)}let{added:s,skipped:i}=await Ooe(e.subscriptions,n),o={message:void 0,added:s,skipped:i};if(s.length===0)return o.message=Poe,o;let c=uh.buildNodePayloads(s,Loe,Lg.OPERATIONS_ENUM.ADD_NODE,await uh.getSystemInfo()),l=[];for(let d=0,_=s.length;d<_;d++){let h=s[d];s[d].start_time===void 0&&delete s[d].start_time,l.push(new woe(h.schema,h.table,h.publish,h.subscribe))}Dg.trace("addNode sending remote payload:",c);let u;try{u=await lh.request(`${n}.${cG.REQUEST_SUFFIX}`,c)}catch(d){Dg.error(`addNode received error from request: ${d}`);for(let h=0,m=s.length;h<m;h++){let S=s[h];S.publish=!1,S.subscribe=!1,await lh.updateRemoteConsumer(S,n)}let _=lh.requestErrorHandler(d,"add_node",n);throw Cg(new Error,_,Pg.INTERNAL_SERVER_ERROR,"error",_)}if(u.status===cG.UPDATE_REMOTE_RESPONSE_STATUSES.ERROR){let d=`Error returned from remote node ${n}: ${u.message}`;throw Cg(new Error,d,Pg.INTERNAL_SERVER_ERROR,"error",d)}Dg.trace(u);for(let d=0,_=s.length;d<_;d++){let h=s[d];await lh.updateRemoteConsumer(h,n),h.subscribe===!0&&await lh.updateConsumerIterator(h.schema,h.table,n,"start")}let f=new Noe(n,l,u.system_info);return await uh.upsertNodeRecord(f),Ioe({type:"nats_update"}),i.length>0?o.message=Doe:o.message=`Successfully added '${n}' to manifest`,o}a(Moe,"addNode")});var TN=C((jCe,dG)=>{"use strict";var{handleHDBError:EN,hdb_errors:voe}=he(),{HTTP_STATUS_CODES:gN}=voe,{addUpdateNodeValidator:Uoe}=Og(),dh=ee(),vg=(k(),P(q)),uG=Lt(),QCe=ie(),fh=gr(),_h=Oo(),SN=le(),{cloneDeep:xoe}=require("lodash"),Boe=mN(),{Node:Hoe,NodeSubscription:koe}=Xu(),{broadcast:Foe}=ot(),{setNode:Goe}=(hl(),P(_l)),qoe="Unable to update subscriptions due to schema and/or tables not existing on the local or remote node",$oe="Some subscriptions were unsuccessful due to schema and/or tables not existing on the local or remote node",Voe=SN.get(vg.CONFIG_PARAMS.CLUSTERING_NODENAME);dG.exports=Koe;async function Koe(e){if(dh.trace("updateNode called with:",e),SN.get(vg.CONFIG_PARAMS.REPLICATION_URL)??SN.get(vg.CONFIG_PARAMS.REPLICATION_HOSTNAME))return Goe(e);_h.checkClusteringEnabled();let t=Uoe(e);if(t)throw EN(t,t.message,gN.BAD_REQUEST,void 0,void 0,!0);let r=e.node_name,n,s=await _h.getNodeRecord(r);s.length>0&&(n=xoe(s));let{added:i,skipped:o}=await Boe(e.subscriptions,r),c={message:void 0,updated:i,skipped:o};if(i.length===0)return c.message=qoe,c;let l=_h.buildNodePayloads(i,Voe,vg.OPERATIONS_ENUM.UPDATE_NODE,await _h.getSystemInfo());for(let f=0,d=i.length;f<d;f++){let _=i[f];dh.trace(`updateNode updating work stream for node: ${r} subscription:`,_),i[f].start_time===void 0&&delete i[f].start_time}dh.trace("updateNode sending remote payload:",l);let u;try{u=await fh.request(`${r}.${uG.REQUEST_SUFFIX}`,l)}catch(f){dh.error(`updateNode received error from request: ${f}`);let d=fh.requestErrorHandler(f,"update_node",r);throw EN(new Error,d,gN.INTERNAL_SERVER_ERROR,"error",d)}if(u.status===uG.UPDATE_REMOTE_RESPONSE_STATUSES.ERROR){let f=`Error returned from remote node ${r}: ${u.message}`;throw EN(new Error,f,gN.INTERNAL_SERVER_ERROR,"error",f)}dh.trace(u);for(let f=0,d=i.length;f<d;f++){let _=i[f];await fh.updateRemoteConsumer(_,r),_.subscribe===!0?await fh.updateConsumerIterator(_.schema,_.table,r,"start"):await fh.updateConsumerIterator(_.schema,_.table,r,"stop")}return n||(n=[new Hoe(r,[],u.system_info)]),await Yoe(n[0],i,u.system_info),o.length>0?c.message=$oe:c.message=`Successfully updated '${r}'`,c}a(Koe,"updateNode");async function Yoe(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 koe(o.schema,o.table,o.publish,o.subscribe))}n.system_info=r,await _h.upsertNodeRecord(n),Foe({type:"nats_update"})}a(Yoe,"updateNodeTable")});var pG=C((XCe,mG)=>{"use strict";var hG=require("joi"),{string:fG}=hG.types(),Woe=it(),_G=(k(),P(q)),zoe=le(),Qoe=Lt();mG.exports=joe;function joe(e){let t=fG.invalid(zoe.get(_G.CONFIG_PARAMS.CLUSTERING_NODENAME)).pattern(Qoe.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=hG.object({operation:fG.valid(_G.OPERATIONS_ENUM.REMOVE_NODE).required(),node_name:t});return Woe.validateBySchema(e,r)}a(joe,"removeNodeValidator")});var Ug=C((ePe,AG)=>{"use strict";var{handleHDBError:EG,hdb_errors:Joe}=he(),{HTTP_STATUS_CODES:gG}=Joe,Xoe=pG(),hh=ee(),SG=Oo(),Zoe=ie(),td=(k(),P(q)),TG=Lt(),AN=gr(),RN=le(),{RemotePayloadObject:eae}=ah(),{NodeSubscription:tae}=Xu(),rae=S_(),nae=Gc(),{broadcast:sae}=ot(),{setNode:iae}=(hl(),P(_l)),oae=RN.get(td.CONFIG_PARAMS.CLUSTERING_NODENAME);AG.exports=aae;async function aae(e){if(hh.trace("removeNode called with:",e),RN.get(td.CONFIG_PARAMS.REPLICATION_URL)??RN.get(td.CONFIG_PARAMS.REPLICATION_HOSTNAME))return iae(e);SG.checkClusteringEnabled();let t=Xoe(e);if(t)throw EG(t,t.message,gG.BAD_REQUEST,void 0,void 0,!0);let r=e.node_name,n=await SG.getNodeRecord(r);if(Zoe.isEmptyOrZeroLength(n))throw EG(new Error,`Node '${r}' was not found.`,gG.BAD_REQUEST,void 0,void 0,!0);n=n[0];let s=new eae(td.OPERATIONS_ENUM.REMOVE_NODE,oae,[]),i,o=!1;for(let l=0,u=n.subscriptions.length;l<u;l++){let f=n.subscriptions[l];f.subscribe===!0&&await AN.updateConsumerIterator(f.schema,f.table,r,"stop");try{await AN.updateRemoteConsumer(new tae(f.schema,f.table,!1,!1),r)}catch(d){hh.error(d)}}try{i=await AN.request(`${r}.${TG.REQUEST_SUFFIX}`,s),hh.trace("Remove node reply from remote node:",r,i)}catch(l){hh.error("removeNode received error from request:",l),o=!0}let c=new rae(td.SYSTEM_SCHEMA_NAME,td.SYSTEM_TABLE_NAMES.NODE_TABLE_NAME,[r]);return await nae.deleteRecord(c),sae({type:"nats_update"}),i?.status===TG.UPDATE_REMOTE_RESPONSE_STATUSES.ERROR||o?(hh.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(aae,"removeNode")});var bG=C((rPe,yG)=>{"use strict";var RG=require("joi"),{string:cae,array:lae}=RG.types(),uae=it(),dae=Og();yG.exports=fae;function fae(e){let t=RG.object({operation:cae.valid("configure_cluster").required(),connections:lae.items(dae.validation_schema).required()});return uae.validateBySchema(e,t)}a(fae,"configureClusterValidator")});var yN=C((sPe,CG)=>{"use strict";var OG=(k(),P(q)),xg=ee(),_ae=ie(),hae=le(),mae=Ug(),pae=Mg(),Eae=Oo(),gae=bG(),{handleHDBError:NG,hdb_errors:Sae}=he(),{HTTP_STATUS_CODES:wG}=Sae,Tae="Configure cluster complete.",Aae="Failed to configure the cluster. Check the logs for more details.",Rae="Configure cluster was partially successful. Errors occurred when attempting to configure the following nodes. Check the logs for more details.";CG.exports=yae;async function yae(e){xg.trace("configure cluster called with:",e);let t=gae(e);if(t)throw NG(t,t.message,wG.BAD_REQUEST,void 0,void 0,!0);let r=await Eae.getAllNodeRecords(),n=[];if(hae.get(OG.CONFIG_PARAMS.CLUSTERING_ENABLED)){for(let f=0,d=r.length;f<d;f++){let _=await IG(mae,{operation:OG.OPERATIONS_ENUM.REMOVE_NODE,node_name:r[f].name},r[f].name);n.push(_)}xg.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 IG(pae,d,d.node_name);s.push(_)}xg.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"&&(xg.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(_ae.isEmptyOrZeroLength(o))return{message:Tae,connections:c};if(l)return{message:Rae,failed_nodes:o,connections:c};throw NG(new Error,Aae,wG.INTERNAL_SERVER_ERROR,void 0,void 0,!0)}a(yae,"configureCluster");async function IG(e,t,r){try{return{node_name:r,result:await e(t)}}catch(n){return{node_name:r,error:n,status:"rejected"}}}a(IG,"functionWrapper")});var MG=C((oPe,LG)=>{"use strict";var mh=require("joi"),bae=it(),{validateSchemaExists:PG,validateTableExists:Oae,validateSchemaName:DG}=Oi(),Nae=mh.object({operation:mh.string().valid("purge_stream"),schema:mh.string().custom(PG).custom(DG).optional(),database:mh.string().custom(PG).custom(DG).optional(),table:mh.string().custom(Oae).required()});function wae(e){return bae.validateBySchema(e,Nae)}a(wae,"purgeStreamValidator");LG.exports=wae});var bN=C((cPe,vG)=>{"use strict";var{handleHDBError:Iae,hdb_errors:Cae}=he(),{HTTP_STATUS_CODES:Pae}=Cae,Dae=MG(),Lae=gr(),Mae=Oo();vG.exports=vae;async function vae(e){e.schema=e.schema??e.database;let t=Dae(e);if(t)throw Iae(t,t.message,Pae.BAD_REQUEST,void 0,void 0,!0);Mae.checkClusteringEnabled();let{schema:r,table:n,options:s}=e;return await Lae.purgeTableStream(r,n,s),`Successfully purged table '${r}.${n}'`}a(vae,"purgeStream")});var wN=C((uPe,GG)=>{"use strict";var NN=Oo(),Uae=gr(),Hg=le(),rd=(k(),P(q)),ml=Lt(),xae=ie(),ON=ee(),{RemotePayloadObject:Bae}=ah(),{ErrorCode:UG}=require("nats"),{parentPort:xG}=require("worker_threads"),{onMessageByType:Hae}=ot(),{getThisNodeName:kae}=(ps(),P(Oa)),{requestClusterStatus:Fae}=(J_(),P(sk)),{getReplicationSharedStatus:Gae,getHDBNodeTable:qae}=(nl(),P(hO)),{CONFIRMATION_STATUS_POSITION:$ae,RECEIVED_VERSION_POSITION:Vae,RECEIVED_TIME_POSITION:Kae,SENDING_TIME_POSITION:Yae,RECEIVING_STATUS_POSITION:Wae,RECEIVING_STATUS_RECEIVING:zae}=(kO(),P(Qk)),BG=Hg.get(rd.CONFIG_PARAMS.CLUSTERING_ENABLED),HG=Hg.get(rd.CONFIG_PARAMS.CLUSTERING_NODENAME);GG.exports={clusterStatus:Qae,buildNodeStatus:FG};var kG;Hae("cluster-status",async e=>{kG(e)});async function Qae(){if(Hg.get(rd.CONFIG_PARAMS.REPLICATION_URL)||Hg.get(rd.CONFIG_PARAMS.REPLICATION_HOSTNAME)){let n;if(xG){xG.postMessage({type:"request-cluster-status"}),n=await new Promise(i=>{kG=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=Gae(u,l,o);c.lastCommitConfirmed=Bg(f[$ae]),c.lastReceivedRemoteTime=Bg(f[Vae]),c.lastReceivedLocalTime=Bg(f[Kae]),c.sendingMessage=Bg(f[Yae]),c.lastReceivedStatus=f[Wae]===zae?"Receiving":"Waiting"}}}else n=Fae();n.node_name=kae();let s=qae().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:HG,is_enabled:BG,connections:[]};if(!BG)return e;let t=await NN.getAllNodeRecords();if(xae.isEmptyOrZeroLength(t))return e;let r=[];for(let n=0,s=t.length;n<s;n++)r.push(FG(t[n],e.connections));return await Promise.allSettled(r),e}a(Qae,"clusterStatus");function Bg(e){return e?e===1?"Copying":new Date(e).toUTCString():void 0}a(Bg,"asDate");async function FG(e,t){let r=e.name,n=new Bae(rd.OPERATIONS_ENUM.CLUSTER_STATUS,HG,void 0,await NN.getSystemInfo()),s,i,o=ml.CLUSTER_STATUS_STATUSES.OPEN;try{let l=Date.now();s=await Uae.request(ml.REQUEST_SUBJECT(r),n),i=Date.now()-l,s.status===ml.UPDATE_REMOTE_RESPONSE_STATUSES.ERROR&&(o=ml.CLUSTER_STATUS_STATUSES.CLOSED,ON.error(`Error getting node status from ${r} `,s))}catch(l){ON.warn(`Error getting node status from ${r}`,l),l.code===UG.NoResponders?o=ml.CLUSTER_STATUS_STATUSES.NO_RESPONDERS:l.code===UG.Timeout?o=ml.CLUSTER_STATUS_STATUSES.TIMEOUT:o=ml.CLUSTER_STATUS_STATUSES.CLOSED}let c=new jae(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!==rd.PRE_4_0_0_VERSION&&await NN.upsertNodeRecord(l)}catch(l){ON.error("Cluster status encountered an error updating system info for node:",r,l)}t.push(c)}a(FG,"buildNodeStatus");function jae(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(jae,"NodeStatusObject")});var CN=C((fPe,qG)=>{"use strict";var{handleHDBError:Jae,hdb_errors:Xae}=he(),{HTTP_STATUS_CODES:Zae}=Xae,ece=gr(),tce=Oo(),IN=ie(),kg=require("joi"),rce=it(),nce=2e3,sce=kg.object({timeout:kg.number().min(1),connected_nodes:kg.boolean(),routes:kg.boolean()});qG.exports=ice;async function ice(e){tce.checkClusteringEnabled();let t=rce.validateBySchema(e,sce);if(t)throw Jae(t,t.message,Zae.BAD_REQUEST,void 0,void 0,!0);let{timeout:r,connected_nodes:n,routes:s}=e,i=n===void 0||IN.autoCastBoolean(n),o=s===void 0||IN.autoCastBoolean(s),c={nodes:[]},l=await ece.getServerList(r??nce),u={};if(i)for(let f=0,d=l.length;f<d;f++){let _=l[f].statsz;_&&(u[l[f].server.name]=_.routes)}for(let f=0,d=l.length;f<d;f++){if(l[f].statsz)continue;let _=l[f].server,h=l[f].data;if(_.name.endsWith("-hub")){let m={name:_.name.slice(0,-4),response_time:l[f].response_time};i&&(m.connected_nodes=[],u[_.name]&&u[_.name].forEach(S=>{m.connected_nodes.includes(S.name.slice(0,-4))||m.connected_nodes.push(S.name.slice(0,-4))})),o&&(m.routes=h.cluster?.urls?h.cluster?.urls.map(S=>({host:S.split(":")[0],port:IN.autoCast(S.split(":")[1])})):[]),c.nodes.push(m)}}return c}a(ice,"clusterNetwork")});var YG=C((hPe,KG)=>{"use strict";var PN=require("joi"),$G=it(),{route_constraints:VG}=OA();KG.exports={setRoutesValidator:oce,deleteRoutesValidator:ace};function oce(e){let t=PN.object({server:PN.valid("hub","leaf"),routes:VG.required()});return $G.validateBySchema(e,t)}a(oce,"setRoutesValidator");function ace(e){let t=PN.object({routes:VG.required()});return $G.validateBySchema(e,t)}a(ace,"deleteRoutesValidator")});var Fg=C((pPe,ZG)=>{"use strict";var wo=Ct(),DN=ie(),Ts=(k(),P(q)),nd=le(),WG=YG(),{handleHDBError:zG,hdb_errors:cce}=he(),{HTTP_STATUS_CODES:QG}=cce,jG="cluster routes successfully set",JG="cluster routes successfully deleted";ZG.exports={setRoutes:uce,getRoutes:dce,deleteRoutes:fce};function lce(e){let t=wo.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=DN.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"?wo.updateConfigValue(Ts.CONFIG_PARAMS.CLUSTERING_HUBSERVER_CLUSTER_NETWORK_ROUTES,r):wo.updateConfigValue(Ts.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_NETWORK_ROUTES,r),{message:jG,set:i,skipped:s}}a(lce,"setRoutesNats");function uce(e){let t=WG.setRoutesValidator(e);if(t)throw zG(t,t.message,QG.BAD_REQUEST,void 0,void 0,!0);if(nd.get(Ts.CONFIG_PARAMS.CLUSTERING_ENABLED))return lce(e);let r=[],n=[],s=nd.get(Ts.CONFIG_PARAMS.REPLICATION_ROUTES)??[];return e.routes.forEach(i=>{XG(s,i)?n.push(i):(s.push(i),r.push(i))}),wo.updateConfigValue(Ts.CONFIG_PARAMS.REPLICATION_ROUTES,s),{message:jG,set:r,skipped:n}}a(uce,"setRoutes");function XG(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(XG,"existsInArray");function dce(){if(nd.get(Ts.CONFIG_PARAMS.CLUSTERING_ENABLED)){let e=wo.getClusteringRoutes();return{hub:e.hub_routes,leaf:e.leaf_routes}}else return nd.get(Ts.CONFIG_PARAMS.REPLICATION_ROUTES)??[]}a(dce,"getRoutes");function fce(e){let t=WG.deleteRoutesValidator(e);if(t)throw zG(t,t.message,QG.BAD_REQUEST,void 0,void 0,!0);if(nd.get(Ts.CONFIG_PARAMS.CLUSTERING_ENABLED))return _ce(e);let r=[],n=[],s=nd.get(Ts.CONFIG_PARAMS.REPLICATION_ROUTES)??[],i=[];return s.forEach(o=>{XG(e.routes,o)?r.push(o):(i.push(o),n.push(o))}),wo.updateConfigValue(Ts.CONFIG_PARAMS.REPLICATION_ROUTES,i),{message:JG,deleted:r,skipped:n}}a(fce,"deleteRoutes");function _ce(e){let t=wo.getClusteringRoutes(),r=t.hub_routes,n=t.leaf_routes,s=[],i=[],o=!1,c=!1;for(let l=0,u=e.routes.length;l<u;l++){let f=e.routes[l],d=!1;for(let _=0,h=r.length;_<h;_++){let m=r[_];if(f.host===m.host&&f.port===m.port){r.splice(_,1),d=!0,o=!0,s.push(f);break}}if(!d){let _=!0;for(let h=0,m=n.length;h<m;h++){let S=n[h];if(f.host===S.host&&f.port===S.port){n.splice(h,1),c=!0,_=!1,s.push(f);break}}_&&i.push(f)}}return o&&(r=DN.isEmptyOrZeroLength(r)?null:r,wo.updateConfigValue(Ts.CONFIG_PARAMS.CLUSTERING_HUBSERVER_CLUSTER_NETWORK_ROUTES,r)),c&&(n=DN.isEmptyOrZeroLength(n)?null:n,wo.updateConfigValue(Ts.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_NETWORK_ROUTES,n)),{message:JG,deleted:s,skipped:i}}a(_ce,"deleteRoutesNats")});var tq=C((gPe,eq)=>{"use strict";var ph=require("alasql"),pl=require("recursive-iterator"),ti=ee(),hce=ie(),Eh=(k(),P(q)),LN=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,pce(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=>Eh.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=>!Eh.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][Eh.PERMS_CRUD_ENUM.READ]){let c;t[i].tables[o].attribute_permissions.length>0?c=mce(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=>!Eh.SEARCH_WILDCARDS.includes(u));c.forEach(({attribute_name:u})=>{let f=new ph.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 mce(e){return e.filter(t=>t[Eh.PERMS_CRUD_ENUM.READ])}a(mce,"filterReadRestrictedAttrs");function pce(e,t,r,n,s){Ece(e,t,r,n,s)}a(pce,"interpretAST");function gh(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(gh,"addSchemaTableToMap");function Ece(e,t,r,n,s){if(!e){ti.info("getRecordAttributesAST: invalid SQL syntax tree");return}e instanceof ph.yy.Insert?Ace(e,t,r):e instanceof ph.yy.Select?gce(e,t,r,n,s):e instanceof ph.yy.Update?Sce(e,t,r):e instanceof ph.yy.Delete?Tce(e,t,r):ti.error("AST in getRecordAttributesAST() is not a valid SQL type.")}a(Ece,"getRecordAttributesAST");function gce(e,t,r,n,s){if(!e){ti.info("getSelectAttributes: invalid SQL syntax tree");return}if(!e.from||e.from[0]===void 0)return;let i=e.from[0].databaseid;if(hce.isEmptyOrZeroLength(i)){ti.error("No schema specified");return}e.from.forEach(c=>{gh(c,t,r,n,s)}),e.joins&&e.joins.forEach(c=>{c.as&&(c.table.as=c.as),gh(c.table,t,r,n,s)});let o=new pl(e.columns);for(let{node:c}of o)if(c&&c.columnid){let l=c.tableid,u=n.has(l)?n.get(l):i;if(l||(l=e.from[0].tableid),!t.get(u).has(l))if(r.has(l))l=r.get(l);else{ti.info(`table specified as ${l} not found.`);return}t.get(u).get(l).indexOf(c.columnid)<0&&t.get(u).get(l).push(c.columnid)}if(e.where){let c=new pl(e.where),l=e.from[0].tableid;for(let{node:u}of c)if(u&&u.columnid){let f=u.tableid?u.tableid:l;if(!t.get(i).has(f))if(r.has(f))f=r.get(f);else{ti.info(`table specified as ${f} not found.`);continue}t.get(i).get(f).indexOf(u.columnid)<0&&t.get(i).get(f).push(u.columnid)}}if(e.joins&&e.joins.forEach(c=>{let l=new pl(c.on);for(let{node:u}of l)if(u&&u.columnid){let f=u.tableid,d=s.get(f);if(!t.get(d).has(f))if(r.has(f))f=r.get(f);else{ti.info(`table specified as ${f} not found.`);continue}t.get(d).get(f).indexOf(u.columnid)<0&&t.get(d).get(f).push(u.columnid)}}),e.order){let c=new pl(e.order);for(let{node:l}of c)if(l&&l.columnid){let u=l.tableid,f=n.has(u)?n.get(u):i;if(u||(u=e.from[0].tableid),!t.get(f).has(u))if(r.has(u))u=r.get(u);else{ti.info(`table specified as ${u} not found.`);return}t.get(f).get(u).indexOf(l.columnid)<0&&t.get(f).get(u).push(l.columnid)}}}a(gce,"getSelectAttributes");function Sce(e,t,r){if(!e){ti.info("getUpdateAttributes: invalid SQL syntax tree");return}let n=new pl(e.columns),s=e.table.databaseid;gh(e.table,t,r);for(let{node:i}of n)i&&i.columnid&&MN(e.table.tableid,s,i.columnid,t,r)}a(Sce,"getUpdateAttributes");function Tce(e,t,r){if(!e){ti.info("getDeleteAttributes: invalid SQL syntax tree");return}let n=new pl(e.where),s=e.table.databaseid;gh(e.table,t,r);for(let{node:i}of n)i&&i.columnid&&MN(e.table.tableid,s,i.columnid,t,r)}a(Tce,"getDeleteAttributes");function Ace(e,t,r){if(!e){ti.info("getInsertAttributes: invalid SQL syntax tree");return}let n=new pl(e.columns),s=e.into.databaseid;gh(e.into,t,r);for(let{node:i}of n)i&&i.columnid&&MN(e.into.tableid,s,i.columnid,t,r)}a(Ace,"getInsertAttributes");function MN(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(MN,"pushAttribute");eq.exports=LN});var nq=C((TPe,rq)=>{"use strict";var Gg=(k(),P(q)),qg=class{static{a(this,"BaseLicense")}constructor(t=0,r=Gg.RAM_ALLOCATION_ENUM.DEFAULT,n=Gg.LICENSE_VALUES.VERSION_DEFAULT,s){this.exp_date=t,this.ram_allocation=r,this.version=n,this.fingerprint=s}},vN=class extends qg{static{a(this,"ExtendedLicense")}constructor(t=0,r=Gg.RAM_ALLOCATION_ENUM.DEFAULT,n=Gg.LICENSE_VALUES.VERSION_DEFAULT,s,i=!1){super(t,r,n,s),this.enterprise=i}};rq.exports={BaseLicense:qg,ExtendedLicense:vN}});var od=C((RPe,lq)=>{"use strict";var id=require("fs-extra"),$g=(Yp(),P(Kp)),iq=require("crypto"),Rce=require("moment"),yce=require("uuid").v4,Zr=ee(),xN=require("path"),bce=ie(),El=(k(),P(q)),{totalmem:sq}=require("os"),Oce=nq().ExtendedLicense,sd="invalid license key format",Nce="061183",wce="mofi25",Ice="aes-256-cbc",Cce=16,Pce=32,oq=le(),{resolvePath:aq}=Ct();oq.initSync();var UN;lq.exports={validateLicense:cq,generateFingerPrint:Lce,licenseSearch:kN,getLicense:Uce,checkMemoryLimit:xce};function BN(){return xN.join(oq.getHdbBasePath(),El.LICENSE_KEY_DIR_NAME,El.LICENSE_FILE_NAME)}a(BN,"getLicenseDirPath");function Dce(){let e=BN();return aq(xN.join(e,El.LICENSE_FILE_NAME))}a(Dce,"getLicenseFilePath");function HN(){let e=BN();return aq(xN.join(e,El.REG_KEY_FILE_NAME))}a(HN,"getFingerPrintFilePath");async function Lce(){let e=HN();try{return await id.readFile(e,"utf8")}catch(t){if(t.code==="ENOENT")return await Mce();throw Zr.error(`Error writing fingerprint file to ${e}`),Zr.error(t),new Error("There was an error generating the fingerprint")}}a(Lce,"generateFingerPrint");async function Mce(){let e=yce(),t=$g.hash(e,$g.HASH_FUNCTION.MD5),r=HN();try{await id.mkdirp(BN()),await id.writeFile(r,t)}catch(n){if(n.code==="EEXIST")return t;throw Zr.error(`Error writing fingerprint file to ${r}`),Zr.error(n),new Error("There was an error generating the fingerprint")}return t}a(Mce,"writeFingerprint");function cq(e,t){let r={valid_license:!1,valid_date:!1,valid_machine:!1,exp_date:null,ram_allocation:El.RAM_ALLOCATION_ENUM.DEFAULT,version:El.LICENSE_VALUES.VERSION_DEFAULT};if(!e)return Zr.error("empty license key passed to validate."),r;let n=HN(),s=!1;try{s=id.statSync(n)}catch(i){Zr.error(i)}if(s){let i;try{i=id.readFileSync(n,"utf8")}catch{Zr.error("error validating this machine in the license"),r.valid_machine=!1;return}let o=e.split(wce),c=o[1];c=Buffer.concat([Buffer.from(c)],Cce);let l=Buffer.concat([Buffer.from(i)],Pce),u=iq.createDecipheriv(Ice,l,c);r.valid_date=!0,r.valid_license=!0,r.valid_machine=!0;let f=null;try{f=u.update(o[0],"hex","utf8"),f.trim(),f+=u.final("utf8")}catch{let h=vce(o[0],i);if(h)f=h;else throw r.valid_license=!1,r.valid_machine=!1,console.error(sd),Zr.error(sd),new Error(sd)}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(sd),Zr.error(sd),new Error(sd)}else r.exp_date=f;r.exp_date<Rce().valueOf()&&(r.valid_date=!1),$g.validate(o[1],`${Nce}${i}${t}`,$g.HASH_FUNCTION.MD5)||(r.valid_license=!1)}else r.valid_license=!1,r.valid_machine=!1;return r.valid_license&&r.valid_machine&&r.valid_date||Zr.error("Invalid licence"),r}a(cq,"validateLicense");function vce(e,t){try{let r=iq.createDecipher("aes192",t),n=r.update(e,"hex","utf8");return n.trim(),n+=r.final("utf8"),n}catch{Zr.warn("Check old license failed")}}a(vce,"checkOldLicense");function kN(){let e=new Oce,t=[];try{t=id.readFileSync(Dce(),"utf-8").split(`\r
|
|
24
|
-
`)}catch(r){r.code==="ENOENT"?Zr.debug("no license file found"):Zr.error(`could not search for licenses due to: '${r.message}`)}for(let r=0;r<t.length;++r){let n=t[r];try{if(bce.isEmptyOrZeroLength(n))continue;let s=JSON.parse(n),i=cq(s.license_key,s.company);i.valid_machine===!0&&i.valid_date===!0&&i.valid_machine===!0&&(e.exp_date=i.exp_date>e.exp_date?i.exp_date:e.exp_date,e.ram_allocation=i.ram_allocation,e.enterprise=!0)}catch(s){Zr.error("There was an error parsing the license string."),Zr.error(s),e.ram_allocation=El.RAM_ALLOCATION_ENUM.DEFAULT,e.enterprise=!1}}return UN=e,e}a(kN,"licenseSearch");async function Uce(){return UN||await kN(),UN}a(Uce,"getLicense");function xce(){let e=kN().ram_allocation,t=process.constrainedMemory?.()||sq();if(t=Math.round(Math.min(t,sq())/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(xce,"checkMemoryLimit")});var qN=C((bPe,_q)=>{var Vg=od(),uq=require("chalk"),Zn=ee(),dq=require("prompt"),{promisify:Bce}=require("util"),FN=(k(),P(q)),Hce=require("fs-extra"),kce=require("path"),Fce=ie(),{packageJson:Gce}=Et(),fq=le();fq.initSync();var qce=require("moment"),$ce=Bce(dq.get),Vce=kce.join(fq.getHdbBasePath(),FN.LICENSE_KEY_DIR_NAME,FN.LICENSE_FILE_NAME,FN.LICENSE_FILE_NAME);_q.exports={getFingerprint:Yce,setLicense:Kce,parseLicense:GN,register:Wce,getRegistrationInfo:Qce};async function Kce(e){if(e&&e.key&&e.company){try{Zn.info(`parsing license key: ${e.key} and `);let t=e.company.toString();await GN(e.key.trim(),t.trim())}catch(t){let r="There was an error parsing the license key.";throw Zn.error(r),Zn.error(t),new Error(r)}return"Wrote license key file. Registration successful."}throw new Error("Invalid key or company specified for license file.")}a(Kce,"setLicense");async function Yce(){let e={};try{e=await Vg.generateFingerPrint()}catch(t){let r="Error generating fingerprint.";throw Zn.error(r),Zn.error(t),new Error(r)}return e}a(Yce,"getFingerprint");async function GN(e,t){if(!e||!t)throw new Error("Invalid entries for License Key and Customer Company");Zn.info("Validating license input...");let r=Vg.validateLicense(e,t);if(Zn.info("checking for valid license..."),!r.valid_license)throw new Error("Invalid license found.");if(Zn.info("checking valid license date..."),!r.valid_date)throw new Error("This License has expired.");if(Zn.info(`checking for valid machine license ${r.valid_machine}`),!r.valid_machine)throw new Error("This license is in use on another machine.");try{Zn.info("writing license to disk"),await Hce.writeFile(Vce,JSON.stringify({license_key:e,company:t}))}catch(n){throw Zn.error("Failed to write License"),n}return"Registration successful."}a(GN,"parseLicense");async function Wce(){let e=await zce();return GN(e.HDB_LICENSE,e.CUSTOMER_COMPANY)}a(Wce,"register");async function zce(){let e=await Vg.generateFingerPrint(),t={properties:{CUSTOMER_COMPANY:{description:uq.magenta("[COMPANY] Please enter your company name"),required:!0},HDB_LICENSE:{description:uq.magenta(`[HDB_LICENSE] Your fingerprint is ${e} Please enter your license key`),required:!0}}};try{dq.start()}catch(n){Zn.error(n)}let r;try{r=await $ce(t)}catch(n){throw console.error("There was a problem prompting for registration input. Exiting."),n}return r}a(zce,"promptForRegistration");async function Qce(){let e={registered:!1,version:null,ram_allocation:null,license_expiration_date:null},t;try{t=await Vg.getLicense()}catch(r){throw Zn.error(`There was an error when searching licenses due to: ${r.message}`),r}if(Fce.isEmptyOrZeroLength(t))throw new Error("There were no licenses found.");if(e.registered=t.enterprise,e.version=Gce.version,e.ram_allocation=t.ram_allocation,isNaN(t.exp_date))e.license_expiration_date=t.enterprise?t.exp_date:null;else{let r=qce.utc(t.exp_date).format("YYYY-MM-DD");e.license_expiration_date=t.enterprise?r:null}return e}a(Qce,"getRegistrationInfo")});var mq=C((NPe,hq)=>{"use strict";var jce=Lt(),$N=class{static{a(this,"HubConfigObject")}constructor(t,r,n,s,i,o,c,l,u,f,d,_,h,m){this.port=t,o===null&&(o=void 0),this.server_name=r+jce.SERVER_SUFFIX.HUB,this.pid_file=n,this.max_payload=67108864,this.reconnect_error_reports=100,this.jetstream={enabled:!1},this.tls={cert_file:s,key_file:i,ca_file:o,insecure:c,verify:l},this.leafnodes={port:u,tls:{cert_file:s,key_file:i,ca_file:o,insecure:c}},this.cluster={name:f,port:d,routes:_,tls:{cert_file:s,key_file:i,ca_file:o,insecure:c,verify:l}},this.accounts={SYS:{users:h},HDB:{users:m}},this.system_account="SYS"}};hq.exports=$N});var gq=C((IPe,Eq)=>{"use strict";var pq=Lt(),VN=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+pq.SERVER_SUFFIX.LEAF,this.pid_file=n,this.max_payload=67108864,this.jetstream={enabled:!0,store_dir:s,domain:r+pq.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"}};Eq.exports=VN});var Tq=C((PPe,Sq)=>{"use strict";var KN=class{static{a(this,"HdbUserObject")}constructor(t,r){this.user=t,this.password=r}};Sq.exports=KN});var Rq=C((LPe,Aq)=>{"use strict";var Jce=Lt(),YN=class{static{a(this,"SysUserObject")}constructor(t,r){this.user=t+Jce.SERVER_SUFFIX.ADMIN,this.password=r}};Aq.exports=YN});var zg=C((vPe,Oq)=>{"use strict";var gl=require("path"),Sl=require("fs-extra"),Xce=mq(),Zce=gq(),ele=Tq(),tle=Rq(),WN=Kn(),cd=ie(),On=Ct(),Yg=(k(),P(q)),Sh=Lt(),{CONFIG_PARAMS:Jt}=Yg,ld=ee(),Th=le(),yq=_o(),zN=gr(),rle=ei(),ad="clustering",nle=1e4,bq=50;Oq.exports={generateNatsConfig:ile,removeNatsConfig:ole,getHubConfigPath:sle};function sle(){let e=Th.get(Jt.ROOTPATH);return gl.join(e,ad,Sh.NATS_CONFIG_FILES.HUB_SERVER)}a(sle,"getHubConfigPath");async function ile(e=!1,t=void 0){let r=Th.get(Jt.ROOTPATH);Sl.ensureDirSync(gl.join(r,"clustering","leaf")),Th.initSync();let n=On.getConfigFromFile(Jt.CLUSTERING_TLS_CERT_AUTH),s=On.getConfigFromFile(Jt.CLUSTERING_TLS_PRIVATEKEY),i=On.getConfigFromFile(Jt.CLUSTERING_TLS_CERTIFICATE);!await Sl.exists(i)&&!await Sl.exists(!n)&&await rle.createNatsCerts();let o=gl.join(r,ad,Sh.PID_FILES.HUB),c=gl.join(r,ad,Sh.PID_FILES.LEAF),l=On.getConfigFromFile(Jt.CLUSTERING_LEAFSERVER_STREAMS_PATH),u=gl.join(r,ad,Sh.NATS_CONFIG_FILES.HUB_SERVER),f=gl.join(r,ad,Sh.NATS_CONFIG_FILES.LEAF_SERVER),d=On.getConfigFromFile(Jt.CLUSTERING_TLS_INSECURE),_=On.getConfigFromFile(Jt.CLUSTERING_TLS_VERIFY),h=On.getConfigFromFile(Jt.CLUSTERING_NODENAME),m=On.getConfigFromFile(Jt.CLUSTERING_HUBSERVER_LEAFNODES_NETWORK_PORT);await zN.checkNATSServerInstalled()||Wg("nats-server dependency is either missing or the wrong version. Run 'npm install' to fix");let S=await WN.listUsers(),g=On.getConfigFromFile(Jt.CLUSTERING_USER),R=await WN.getClusterUser();(cd.isEmpty(R)||R.active!==!0)&&Wg(`Invalid cluster user '${g}'. A valid user with the role 'cluster_user' must be defined under clustering.user in harperdb-config.yaml`),e||(await Kg(Jt.CLUSTERING_HUBSERVER_CLUSTER_NETWORK_PORT),await Kg(Jt.CLUSTERING_HUBSERVER_LEAFNODES_NETWORK_PORT),await Kg(Jt.CLUSTERING_HUBSERVER_NETWORK_PORT),await Kg(Jt.CLUSTERING_LEAFSERVER_NETWORK_PORT));let E=[],T=[];for(let[se,z]of S.entries())z.role?.role===Yg.ROLE_TYPES_ENUM.CLUSTER_USER&&z.active&&(E.push(new tle(z.username,yq.decrypt(z.hash))),T.push(new ele(z.username,yq.decrypt(z.hash))));let N=[],{hub_routes:v}=On.getClusteringRoutes();if(!cd.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 Xce(On.getConfigFromFile(Jt.CLUSTERING_HUBSERVER_NETWORK_PORT),h,o,i,s,n,d,_,m,On.getConfigFromFile(Jt.CLUSTERING_HUBSERVER_CLUSTER_NAME),On.getConfigFromFile(Jt.CLUSTERING_HUBSERVER_CLUSTER_NETWORK_PORT),N,E,T);n==null&&(delete H.tls.ca_file,delete H.leafnodes.tls.ca_file),t=cd.isEmpty(t)?void 0:t.toLowerCase(),(t===void 0||t===Yg.PROCESS_DESCRIPTORS.CLUSTERING_HUB.toLowerCase())&&(await Sl.writeJson(u,H),ld.trace(`Hub server config written to ${u}`));let X=`tls://${R.sys_name_encoded}:${R.uri_encoded_d_hash}@0.0.0.0:${m}`,W=`tls://${R.uri_encoded_name}:${R.uri_encoded_d_hash}@0.0.0.0:${m}`,$=new Zce(On.getConfigFromFile(Jt.CLUSTERING_LEAFSERVER_NETWORK_PORT),h,c,l,[X],[W],E,T,i,s,n,d);n==null&&delete $.tls.ca_file,(t===void 0||t===Yg.PROCESS_DESCRIPTORS.CLUSTERING_LEAF.toLowerCase())&&(await Sl.writeJson(f,$),ld.trace(`Leaf server config written to ${f}`))}a(ile,"generateNatsConfig");async function Kg(e){let t=Th.get(e);return cd.isEmpty(t)&&Wg(`port undefined for '${e}'`),await cd.isPortTaken(t)&&Wg(`'${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(Kg,"isPortAvailable");function Wg(e){let t=`Error generating clustering config: ${e}`;ld.error(t),console.error(t),process.exit(1)}a(Wg,"generateNatsConfigError");async function ole(e){let{port:t,config_file:r}=zN.getServerConfig(e),{username:n,decrypt_hash:s}=await WN.getClusterUser(),i=0,o=2e3;for(;i<bq;){try{let f=await zN.createConnection(t,n,s,!1);if(f.protocol.connected===!0){f.close();break}}catch(f){ld.trace(`removeNatsConfig waiting for ${e}. Caught and swallowed error ${f}`)}if(i++,i>=bq)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&&ld.notify("Operations API waiting for Nats server connection. This could be caused by large Nats streams or incorrect clustering config."),await cd.async_set_timeout(u)}let c="0".repeat(nle),l=gl.join(Th.get(Jt.ROOTPATH),ad,r);await Sl.writeFile(l,c),await Sl.remove(l),ld.notify(e,"started.")}a(ole,"removeNatsConfig")});var JN={};Ue(JN,{compactOnStart:()=>ale,copyDb:()=>Dq});async function ale(){va.notify("Running compact on start"),console.log("Running compact on start");let e=(0,QN.get)(x.ROOTPATH),t=new Map,r=Xe();(0,jN.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,Qg.join)(e,"backup",n+".mdb"),o=(0,Qg.join)(e,fc,n+"-copy.mdb"),c=0;try{c=await Nq(n),console.log("Database",n,"before compact has a total record count of",c)}catch(l){va.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 Dq(n,o),console.log("Backing up",n,"to",i),await(0,Tl.move)(s,i,{overwrite:!0})}try{dd()}catch(n){va.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,Tl.move)(i,s,{overwrite:!0}),await(0,Tl.remove)((0,Qg.join)(e,fc,`${n}-copy.mdb-lock`));try{dd()}catch(n){va.error("Error resetting databases after backup",n),console.error("Error resetting databases after backup",n),process.exit(0)}}catch(n){va.error("Error compacting database, rolling back operation",n),console.error("Error compacting database, rolling back operation",n),(0,jN.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,Tl.move)(o,i,{overwrite:!0})}catch(c){console.error(c)}}throw dd(),n}for(let[n,{backup_dest:s,record_count:i}]of t){let o=!0,c=await Nq(n);if(console.log("Database",n,"after compact has a total record count of",c),i!==c){o=!1;let l=`There is a discrepancy between pre and post compact record count for database ${n}.
|
|
25
|
-
Total record count before compaction: ${i}, total after: ${
|
|
26
|
-
Database backup has not been removed and can be found here: ${s}`;va.error(
|
|
24
|
+
`)}catch(r){r.code==="ENOENT"?Zr.debug("no license file found"):Zr.error(`could not search for licenses due to: '${r.message}`)}for(let r=0;r<t.length;++r){let n=t[r];try{if(bce.isEmptyOrZeroLength(n))continue;let s=JSON.parse(n),i=cq(s.license_key,s.company);i.valid_machine===!0&&i.valid_date===!0&&i.valid_machine===!0&&(e.exp_date=i.exp_date>e.exp_date?i.exp_date:e.exp_date,e.ram_allocation=i.ram_allocation,e.enterprise=!0)}catch(s){Zr.error("There was an error parsing the license string."),Zr.error(s),e.ram_allocation=El.RAM_ALLOCATION_ENUM.DEFAULT,e.enterprise=!1}}return UN=e,e}a(kN,"licenseSearch");async function Uce(){return UN||await kN(),UN}a(Uce,"getLicense");function xce(){let e=kN().ram_allocation,t=process.constrainedMemory?.()||sq();if(t=Math.round(Math.min(t,sq())/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(xce,"checkMemoryLimit")});var qN=C((bPe,_q)=>{var Vg=od(),uq=require("chalk"),Zn=ee(),dq=require("prompt"),{promisify:Bce}=require("util"),FN=(k(),P(q)),Hce=require("fs-extra"),kce=require("path"),Fce=ie(),{packageJson:Gce}=Et(),fq=le();fq.initSync();var qce=require("moment"),$ce=Bce(dq.get),Vce=kce.join(fq.getHdbBasePath(),FN.LICENSE_KEY_DIR_NAME,FN.LICENSE_FILE_NAME,FN.LICENSE_FILE_NAME);_q.exports={getFingerprint:Yce,setLicense:Kce,parseLicense:GN,register:Wce,getRegistrationInfo:Qce};async function Kce(e){if(e&&e.key&&e.company){try{Zn.info(`parsing license key: ${e.key} and `);let t=e.company.toString();await GN(e.key.trim(),t.trim())}catch(t){let r="There was an error parsing the license key.";throw Zn.error(r),Zn.error(t),new Error(r)}return"Wrote license key file. Registration successful."}throw new Error("Invalid key or company specified for license file.")}a(Kce,"setLicense");async function Yce(){let e={};try{e=await Vg.generateFingerPrint()}catch(t){let r="Error generating fingerprint.";throw Zn.error(r),Zn.error(t),new Error(r)}return e}a(Yce,"getFingerprint");async function GN(e,t){if(!e||!t)throw new Error("Invalid entries for License Key and Customer Company");Zn.info("Validating license input...");let r=Vg.validateLicense(e,t);if(Zn.info("checking for valid license..."),!r.valid_license)throw new Error("Invalid license found.");if(Zn.info("checking valid license date..."),!r.valid_date)throw new Error("This License has expired.");if(Zn.info(`checking for valid machine license ${r.valid_machine}`),!r.valid_machine)throw new Error("This license is in use on another machine.");try{Zn.info("writing license to disk"),await Hce.writeFile(Vce,JSON.stringify({license_key:e,company:t}))}catch(n){throw Zn.error("Failed to write License"),n}return"Registration successful."}a(GN,"parseLicense");async function Wce(){let e=await zce();return GN(e.HDB_LICENSE,e.CUSTOMER_COMPANY)}a(Wce,"register");async function zce(){let e=await Vg.generateFingerPrint(),t={properties:{CUSTOMER_COMPANY:{description:uq.magenta("[COMPANY] Please enter your company name"),required:!0},HDB_LICENSE:{description:uq.magenta(`[HDB_LICENSE] Your fingerprint is ${e} Please enter your license key`),required:!0}}};try{dq.start()}catch(n){Zn.error(n)}let r;try{r=await $ce(t)}catch(n){throw console.error("There was a problem prompting for registration input. Exiting."),n}return r}a(zce,"promptForRegistration");async function Qce(){let e={registered:!1,version:null,ram_allocation:null,license_expiration_date:null},t;try{t=await Vg.getLicense()}catch(r){throw Zn.error(`There was an error when searching licenses due to: ${r.message}`),r}if(Fce.isEmptyOrZeroLength(t))throw new Error("There were no licenses found.");if(e.registered=t.enterprise,e.version=Gce.version,e.ram_allocation=t.ram_allocation,isNaN(t.exp_date))e.license_expiration_date=t.enterprise?t.exp_date:null;else{let r=qce.utc(t.exp_date).format("YYYY-MM-DD");e.license_expiration_date=t.enterprise?r:null}return e}a(Qce,"getRegistrationInfo")});var mq=C((NPe,hq)=>{"use strict";var jce=Lt(),$N=class{static{a(this,"HubConfigObject")}constructor(t,r,n,s,i,o,c,l,u,f,d,_,h,m){this.port=t,o===null&&(o=void 0),this.server_name=r+jce.SERVER_SUFFIX.HUB,this.pid_file=n,this.max_payload=67108864,this.reconnect_error_reports=100,this.jetstream={enabled:!1},this.tls={cert_file:s,key_file:i,ca_file:o,insecure:c,verify:l},this.leafnodes={port:u,tls:{cert_file:s,key_file:i,ca_file:o,insecure:c}},this.cluster={name:f,port:d,routes:_,tls:{cert_file:s,key_file:i,ca_file:o,insecure:c,verify:l}},this.accounts={SYS:{users:h},HDB:{users:m}},this.system_account="SYS"}};hq.exports=$N});var gq=C((IPe,Eq)=>{"use strict";var pq=Lt(),VN=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+pq.SERVER_SUFFIX.LEAF,this.pid_file=n,this.max_payload=67108864,this.jetstream={enabled:!0,store_dir:s,domain:r+pq.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"}};Eq.exports=VN});var Tq=C((PPe,Sq)=>{"use strict";var KN=class{static{a(this,"HdbUserObject")}constructor(t,r){this.user=t,this.password=r}};Sq.exports=KN});var Rq=C((LPe,Aq)=>{"use strict";var Jce=Lt(),YN=class{static{a(this,"SysUserObject")}constructor(t,r){this.user=t+Jce.SERVER_SUFFIX.ADMIN,this.password=r}};Aq.exports=YN});var zg=C((vPe,Oq)=>{"use strict";var gl=require("path"),Sl=require("fs-extra"),Xce=mq(),Zce=gq(),ele=Tq(),tle=Rq(),WN=Kn(),cd=ie(),On=Ct(),Yg=(k(),P(q)),Sh=Lt(),{CONFIG_PARAMS:Jt}=Yg,ld=ee(),Th=le(),yq=_o(),zN=gr(),rle=ei(),ad="clustering",nle=1e4,bq=50;Oq.exports={generateNatsConfig:ile,removeNatsConfig:ole,getHubConfigPath:sle};function sle(){let e=Th.get(Jt.ROOTPATH);return gl.join(e,ad,Sh.NATS_CONFIG_FILES.HUB_SERVER)}a(sle,"getHubConfigPath");async function ile(e=!1,t=void 0){let r=Th.get(Jt.ROOTPATH);Sl.ensureDirSync(gl.join(r,"clustering","leaf")),Th.initSync();let n=On.getConfigFromFile(Jt.CLUSTERING_TLS_CERT_AUTH),s=On.getConfigFromFile(Jt.CLUSTERING_TLS_PRIVATEKEY),i=On.getConfigFromFile(Jt.CLUSTERING_TLS_CERTIFICATE);!await Sl.exists(i)&&!await Sl.exists(!n)&&await rle.createNatsCerts();let o=gl.join(r,ad,Sh.PID_FILES.HUB),c=gl.join(r,ad,Sh.PID_FILES.LEAF),l=On.getConfigFromFile(Jt.CLUSTERING_LEAFSERVER_STREAMS_PATH),u=gl.join(r,ad,Sh.NATS_CONFIG_FILES.HUB_SERVER),f=gl.join(r,ad,Sh.NATS_CONFIG_FILES.LEAF_SERVER),d=On.getConfigFromFile(Jt.CLUSTERING_TLS_INSECURE),_=On.getConfigFromFile(Jt.CLUSTERING_TLS_VERIFY),h=On.getConfigFromFile(Jt.CLUSTERING_NODENAME),m=On.getConfigFromFile(Jt.CLUSTERING_HUBSERVER_LEAFNODES_NETWORK_PORT);await zN.checkNATSServerInstalled()||Wg("nats-server dependency is either missing or the wrong version. Run 'npm install' to fix");let S=await WN.listUsers(),g=On.getConfigFromFile(Jt.CLUSTERING_USER),R=await WN.getClusterUser();(cd.isEmpty(R)||R.active!==!0)&&Wg(`Invalid cluster user '${g}'. A valid user with the role 'cluster_user' must be defined under clustering.user in harperdb-config.yaml`),e||(await Kg(Jt.CLUSTERING_HUBSERVER_CLUSTER_NETWORK_PORT),await Kg(Jt.CLUSTERING_HUBSERVER_LEAFNODES_NETWORK_PORT),await Kg(Jt.CLUSTERING_HUBSERVER_NETWORK_PORT),await Kg(Jt.CLUSTERING_LEAFSERVER_NETWORK_PORT));let E=[],T=[];for(let[se,z]of S.entries())z.role?.role===Yg.ROLE_TYPES_ENUM.CLUSTER_USER&&z.active&&(E.push(new tle(z.username,yq.decrypt(z.hash))),T.push(new ele(z.username,yq.decrypt(z.hash))));let N=[],{hub_routes:v}=On.getClusteringRoutes();if(!cd.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 Xce(On.getConfigFromFile(Jt.CLUSTERING_HUBSERVER_NETWORK_PORT),h,o,i,s,n,d,_,m,On.getConfigFromFile(Jt.CLUSTERING_HUBSERVER_CLUSTER_NAME),On.getConfigFromFile(Jt.CLUSTERING_HUBSERVER_CLUSTER_NETWORK_PORT),N,E,T);n==null&&(delete H.tls.ca_file,delete H.leafnodes.tls.ca_file),t=cd.isEmpty(t)?void 0:t.toLowerCase(),(t===void 0||t===Yg.PROCESS_DESCRIPTORS.CLUSTERING_HUB.toLowerCase())&&(await Sl.writeJson(u,H),ld.trace(`Hub server config written to ${u}`));let X=`tls://${R.sys_name_encoded}:${R.uri_encoded_d_hash}@0.0.0.0:${m}`,W=`tls://${R.uri_encoded_name}:${R.uri_encoded_d_hash}@0.0.0.0:${m}`,$=new Zce(On.getConfigFromFile(Jt.CLUSTERING_LEAFSERVER_NETWORK_PORT),h,c,l,[X],[W],E,T,i,s,n,d);n==null&&delete $.tls.ca_file,(t===void 0||t===Yg.PROCESS_DESCRIPTORS.CLUSTERING_LEAF.toLowerCase())&&(await Sl.writeJson(f,$),ld.trace(`Leaf server config written to ${f}`))}a(ile,"generateNatsConfig");async function Kg(e){let t=Th.get(e);return cd.isEmpty(t)&&Wg(`port undefined for '${e}'`),await cd.isPortTaken(t)&&Wg(`'${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(Kg,"isPortAvailable");function Wg(e){let t=`Error generating clustering config: ${e}`;ld.error(t),console.error(t),process.exit(1)}a(Wg,"generateNatsConfigError");async function ole(e){let{port:t,config_file:r}=zN.getServerConfig(e),{username:n,decrypt_hash:s}=await WN.getClusterUser(),i=0,o=2e3;for(;i<bq;){try{let f=await zN.createConnection(t,n,s,!1);if(f.protocol.connected===!0){f.close();break}}catch(f){ld.trace(`removeNatsConfig waiting for ${e}. Caught and swallowed error ${f}`)}if(i++,i>=bq)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&&ld.notify("Operations API waiting for Nats server connection. This could be caused by large Nats streams or incorrect clustering config."),await cd.async_set_timeout(u)}let c="0".repeat(nle),l=gl.join(Th.get(Jt.ROOTPATH),ad,r);await Sl.writeFile(l,c),await Sl.remove(l),ld.notify(e,"started.")}a(ole,"removeNatsConfig")});var JN={};Ue(JN,{compactOnStart:()=>ale,copyDb:()=>Dq});async function ale(){va.notify("Running compact on start"),console.log("Running compact on start");let e=(0,QN.get)(x.ROOTPATH),t=new Map,r=Xe();(0,jN.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,Qg.join)(e,"backup",n+".mdb"),o=(0,Qg.join)(e,fc,n+"-copy.mdb"),c=0;try{c=await Nq(n),console.log("Database",n,"before compact has a total record count of",c)}catch(l){va.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 Dq(n,o),console.log("Backing up",n,"to",i),await(0,Tl.move)(s,i,{overwrite:!0}),console.log("Moving copy compacted",n,"to",s),await(0,Tl.move)(o,s,{overwrite:!0}),await(0,Tl.remove)((0,Qg.join)(e,fc,`${n}-copy.mdb-lock`))}try{dd()}catch(n){va.error("Error resetting databases after backup",n),console.error("Error resetting databases after backup",n)}try{dd()}catch(n){va.error("Error resetting databases after backup",n),console.error("Error resetting databases after backup",n),process.exit(0)}}catch(n){va.error("Error compacting database, rolling back operation",n),console.error("Error compacting database, rolling back operation",n),(0,jN.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,Tl.move)(o,i,{overwrite:!0})}catch(c){console.error(c)}}throw dd(),n}for(let[n,{backup_dest:s,record_count:i}]of t){let o=await Nq(n);if(console.log("Database",n,"after compact has a total record count of",o),i!==o){let c=`There is a discrepancy between pre and post compact record count for database ${n}.
|
|
25
|
+
Total record count before compaction: ${i}, total after: ${o}.
|
|
26
|
+
Database backup has not been removed and can be found here: ${s}`;va.error(c),console.error(c)}(0,QN.get)(x.STORAGE_COMPACTONSTARTKEEPBACKUP)!==!0&&(console.log("Removing backup",s),await(0,Tl.remove)(s))}}async function Nq(e){let t=await(0,Pq.describeSchema)({database:e}),r=0;for(let n in t)r+=t[n].record_count;return r}function ud(){}async function Dq(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=ud,_.primaryStore.remove=ud;for(let h in _.indices){let m=_.indices[h];m.put=ud,m.remove=ud}_.auditStore&&(_.auditStore.put=ud,_.auditStore.remove=ud),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,wq.open)(new Iq.default(t)),c=o.openDB(jg.INTERNAL_DBIS_NAME),l,u=0,f=s.useReadTransaction();try{for(let{key:_,value:h}of s.getRange({transaction:f})){let m=h.is_hash_attribute||h.isPrimaryKey,S,g;if(m&&(S=h.compression,g=Jg(),g?h.compression=g:delete h.compression,S?.dictionary?.toString()===g?.dictionary?.toString()&&(S=null,g=null)),c.put(_,h),!(m||h.indexed))continue;let R=new Cq.default(!m,m);R.encoding="binary",R.compression=S;let E=n.openDB(_,R);E.decoder=null,E.decoderCopies=!1,E.encoding="binary",R.compression=g;let T=o.openDB(_,R);T.encoder=null,console.log("copying",_,"from",e,"to",t),await d(E,T,m,f)}if(i){let _=n.openDB(jg.AUDIT_STORE_NAME,Ah);console.log("copying audit log for",e,"to",t),d(i,_,!1,f)}async function d(_,h,m,S){let g=0,R=0,E=0,T=1e7,N=null;for(;T-- >0;)try{for(let v of _.getKeys({start:N,transaction:S}))try{N=v;let{value:H,version:X}=_.getEntry(v,{transaction:S});if(H?.length<14&&m){E++;continue}l=h.put(v,H,m?X:void 0),g++,S.openTimer&&(S.openTimer=0),R+=(v?.length||10)+H.length,u++>5e3&&(await l,console.log("copied",g,"entries, skipped",E,"delete records,",R,"bytes"),u=0)}catch(H){console.error("Error copying record",typeof v=="symbol"?"symbol":v,"from",e,"to",t,H)}console.log("finish copying, copied",g,"entries, skipped",E,"delete records,",R,"bytes");return}catch{if(typeof N=="string"){if(N==="z")return console.error("Reached end of dbi",N,"for",e,"to",t);N=N.slice(0,-2)+"z"}else if(typeof N=="number")N++;else return console.error("Unknown key type",N,"for",e,"to",t)}}a(d,"copyDbi"),await l,console.log("copied database "+e+" to "+t)}finally{f.done(),o.close()}}var wq,Qg,Tl,QN,Iq,Cq,jg,Pq,jN,va,XN=Re(()=>{xe();wq=require("lmdb"),Qg=require("path"),Tl=require("fs-extra"),QN=M(le()),Iq=M(Wf()),Cq=M(Yf()),jg=M(Gt());k();Ai();Pq=M(ho()),jN=M(Ct()),va=M(ee());a(ale,"compactOnStart");a(Nq,"getTotalDBRecordCount");a(ud,"noop");a(Dq,"copyDb")});var _d=C(($Pe,Hq)=>{"use strict";var cle=require("minimist"),{isMainThread:ew,parentPort:yh,threadId:FPe}=require("worker_threads"),at=(k(),P(q)),Hi=ee(),tw=ie(),Zg=zg(),Xg=gr(),GPe=Lt(),Uq=Ct(),ri=hd(),Lq=ed(),{compactOnStart:lle}=(XN(),P(JN)),ule=_c(),{restartWorkers:eS,onMessageByType:dle}=ot(),{handleHDBError:fle,hdb_errors:_le}=he(),{HTTP_STATUS_CODES:hle}=_le,bh=le(),{sendOperationToNode:Mq,getThisNodeName:mle,monitorNodeCAs:ple}=(ps(),P(Oa)),{getHDBNodeTable:qPe}=(nl(),P(hO));bh.initSync();var Rh=`Restarting HarperDB. This may take up to ${at.RESTART_TIMEOUT_MS/1e3} seconds.`,Ele="Restart is not available from the CLI when running in non-pm2 mode. Either call restart from the API or stop and start HarperDB.",vq="Clustering is not enabled so cannot be restarted",gle="Invalid service",fd,As;Hq.exports={restart:xq,restartService:rw};ew&&dle(at.ITC_EVENT_TYPES.RESTART,async(e,t)=>{e.workerType?await rw({service:e.workerType}):xq({operation:"restart"}),t.postMessage({type:"restart-complete"})});async function xq(e){As=Object.keys(e).length===0,fd=await ri.isServiceRegistered(at.PROCESS_DESCRIPTORS.HDB);let t=cle(process.argv);if(t.service){await rw(t);return}if(As&&!fd){console.error(Ele);return}if(As&&console.log(Rh),fd){ri.enterPM2Mode(),Hi.notify(Rh);let r=ule(Object.keys(at.CONFIG_PARAM_MAP),!0);return tw.isEmptyOrZeroLength(Object.keys(r))||Uq.updateConfigValue(void 0,void 0,r,!0,!0),Sle(),Rh}return ew?(Hi.notify(Rh),bh.get(at.CONFIG_PARAMS.STORAGE_COMPACTONSTART)&&await lle(),process.env.HARPER_EXIT_ON_RESTART&&process.exit(0),setTimeout(()=>{eS()},50)):yh.postMessage({type:at.ITC_EVENT_TYPES.RESTART}),Rh}a(xq,"restart");async function rw(e){let{service:t}=e;if(at.HDB_PROCESS_SERVICES[t]===void 0)throw fle(new Error,gle,hle.BAD_REQUEST,void 0,void 0,!0);if(ri.expectedRestartOfChildren(),fd=await ri.isServiceRegistered(at.PROCESS_DESCRIPTORS.HDB),!ew){e.replicated&&ple(),yh.postMessage({type:at.ITC_EVENT_TYPES.RESTART,workerType:t}),yh.ref(),await new Promise(s=>{yh.on("message",i=>{i.type==="restart-complete"&&(s(),yh.unref())})});let n;if(e.replicated){e.replicated=!1,n=[];for(let s of server.nodes){if(s.name===mle())continue;let i;try{({job_id:i}=await Mq(s,e))}catch(o){n.push({node:s.name,message:o.message});continue}n.push(await new Promise((o,c)=>{let u=2400,f=setInterval(async()=>{if(u--<=0){clearInterval(f);let h=new Error("Timed out waiting for restart job to complete");h.replicated=n,c(h)}let _=(await Mq(s,{operation:"get_job",id:i})).results[0];if(_.status==="COMPLETE"&&(clearInterval(f),o({node:s.name,message:_.message})),_.status==="ERROR"){clearInterval(f);let h=new Error(_.message);h.replicated=n,c(h)}},250)}))}return{replicated:n}}return}let r;switch(t){case at.HDB_PROCESS_SERVICES.clustering:if(!bh.get(at.CONFIG_PARAMS.CLUSTERING_ENABLED)){r=vq;break}As&&console.log("Restarting clustering"),Hi.notify("Restarting clustering"),await Bq();break;case at.HDB_PROCESS_SERVICES.clustering_config:case at.HDB_PROCESS_SERVICES["clustering config"]:if(!bh.get(at.CONFIG_PARAMS.CLUSTERING_ENABLED)){r=vq;break}As&&console.log("Restarting clustering_config"),Hi.notify("Restarting clustering_config"),await ri.reloadClustering();break;case"custom_functions":case"custom functions":case at.HDB_PROCESS_SERVICES.harperdb:case at.HDB_PROCESS_SERVICES.http_workers:case at.HDB_PROCESS_SERVICES.http:if(As&&!fd){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}As&&console.log("Restarting http_workers"),Hi.notify("Restarting http_workers"),As?await ri.restart(at.PROCESS_DESCRIPTORS.HDB):await eS("http");break;default:r=`Unrecognized service: ${t}`;break}return r?(Hi.error(r),As&&console.error(r),r):(t==="custom_functions"&&(t="Custom Functions"),`Restarting ${t}`)}a(rw,"restartService");async function Sle(){await Bq(),await ri.restart(at.PROCESS_DESCRIPTORS.HDB),await tw.async_set_timeout(2e3),bh.get(at.CONFIG_PARAMS.CLUSTERING_ENABLED)&&await ZN(),As&&(await Xg.closeConnection(),process.exit(0))}a(Sle,"restartPM2Mode");async function Bq(){if(!Uq.getConfigFromFile(at.CONFIG_PARAMS.CLUSTERING_ENABLED))return;if((await Lq.getHDBProcessInfo()).clustering.length===0)Hi.trace("Clustering not running, restart will start clustering services"),await Zg.generateNatsConfig(!0),await ri.startClusteringProcesses(),await ri.startClusteringThreads(),await ZN(),As&&await Xg.closeConnection();else{await Zg.generateNatsConfig(!0),fd?(Hi.trace("Restart clustering restarting PM2 managed Hub and Leaf servers"),await ri.restart(at.PROCESS_DESCRIPTORS.CLUSTERING_HUB),await ri.restart(at.PROCESS_DESCRIPTORS.CLUSTERING_LEAF)):(await Lq.getHDBProcessInfo()).clustering.forEach(s=>{Hi.trace("Restart clustering killing process pid",s.pid),process.kill(s.pid)}),await tw.async_set_timeout(3e3),await ZN(),await Xg.updateLocalStreams(),As&&await Xg.closeConnection(),Hi.trace("Restart clustering restarting ingest and reply service threads");let t=eS(at.LAUNCH_SERVICE_SCRIPTS.NATS_INGEST_SERVICE),r=eS(at.LAUNCH_SERVICE_SCRIPTS.NATS_REPLY_SERVICE);await t,await r}}a(Bq,"restartClustering");async function ZN(){await Zg.removeNatsConfig(at.PROCESS_DESCRIPTORS.CLUSTERING_HUB),await Zg.removeNatsConfig(at.PROCESS_DESCRIPTORS.CLUSTERING_LEAF)}a(ZN,"removeNatsConfig")});var Qq=C((YPe,zq)=>{"use strict";var KPe=require("lodash"),Nn=(k(),P(q)),{handleHDBError:kq,hdb_errors:Tle}=he(),{HDB_ERROR_MSGS:Ale,HTTP_STATUS_CODES:Rle}=Tle,nw=ee();zq.exports={getRolePermissions:ble};var Al=Object.create(null),yle=a(e=>({key:e,perms:{}}),"perms_template_obj"),$q=a((e=!1)=>({describe:e,tables:{}}),"schema_perms_template"),Vq=a((e=!1,t=!1,r=!1,n=!1)=>({[Nn.PERMS_CRUD_ENUM.READ]:e,[Nn.PERMS_CRUD_ENUM.INSERT]:t,[Nn.PERMS_CRUD_ENUM.UPDATE]:r,[Nn.PERMS_CRUD_ENUM.DELETE]:n}),"permissions_template"),sw=a((e=!1,t=!1,r=!1,n=!1,s=!1)=>({attribute_permissions:[],describe:e,...Vq(t,r,n,s)}),"table_perms_template"),Fq=a((e,t=Vq())=>({attribute_name:e,describe:Wq(t),[Oh]:t[Oh],[iw]:t[iw],[ow]:t[ow]}),"attr_perms_template"),Gq=a((e,t=!1)=>({attribute_name:e,describe:t,[Oh]:t}),"timestamp_attr_perms_template"),{READ:Oh,INSERT:iw,UPDATE:ow}=Nn.PERMS_CRUD_ENUM,Kq=Object.values(Nn.PERMS_CRUD_ENUM),Yq=[Oh,iw,ow];function ble(e){let t;try{if(e.permission.super_user||e.permission.cluster_user)return e.permission;let r={...global.hdb_schema};delete r[Nn.SYSTEM_SCHEMA_NAME],t=e.role;let n=JSON.stringify([e.__updatedtime__,r]);if(Al[t]&&Al[t].key===n)return Al[t].perms;let s=Ole(e,r);return Al[t]?Al[t].key=n:Al[t]=yle(n),Al[t].perms=s,s}catch(r){if(!e[Nn.TIME_STAMP_NAMES_ENUM.UPDATED_TIME]||e[Nn.TIME_STAMP_NAMES_ENUM.UPDATED_TIME]<Nn.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 nw.error(n),nw.debug(r),kq(new Error,Ale.OUTDATED_PERMS_TRANSLATION_ERROR,Rle.BAD_REQUEST)}else{let n=`There was an error while translating role permissions for role: ${t}.
|
|
27
27
|
${r.stack}`;throw nw.error(n),kq(new Error)}}}a(ble,"getRolePermissions");function Ole(e,t){let r=Object.create(null);r.super_user=!1;let n=e.permission;r[Nn.SYSTEM_SCHEMA_NAME]=n[Nn.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]=Nle(t[i]);return}r[i]=$q(),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=wle(c,l);r[i].describe||Kq.forEach(f=>{u[f]&&(r[i].describe=!0)}),r[i].tables[o]=u}else r[i].tables[o]=sw()})):Object.keys(t[i]).forEach(o=>{r[i].tables[o]=sw()})}),r}a(Ole,"translateRolePermissions");function Nle(e){let t=$q(!0);return Object.keys(e).forEach(r=>{t.tables[r]=sw(!0,!0,!0,!0,!0)}),t}a(Nle,"createStructureUserPermissions");function wle(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 Nn.TIME_STAMP_NAMES.includes(d)&&(_=Gq(d,f[Oh])),u[d]=_,u},{}),o=t.primaryKey||t.hash_attribute,c=!!i[o],l=Fq(o);return t.attributes.forEach(({attribute:u})=>{if(i[u]){let f=i[u];f.describe=Wq(f),s.attribute_permissions.push(f),c||Ile(f,l)}else if(u!==o){let f;Nn.TIME_STAMP_NAMES.includes(u)?f=Gq(u):f=Fq(u),s.attribute_permissions.push(f)}}),c||s.attribute_permissions.push(l),s.describe=qq(s),s}else return e.describe=qq(e),e}a(wle,"getTableAttrPerms");function qq(e){return Kq.filter(t=>e[t]).length>0}a(qq,"getSchemaTableDescribePerm");function Wq(e){return Yq.filter(t=>e[t]).length>0}a(Wq,"getAttributeDescribePerm");function Ile(e,t){Yq.forEach(r=>{e[r]&&!t[r]&&(t[r]=!0,t.describe=!0)})}a(Ile,"checkForHashPerms")});var Nh={};Ue(Nh,{authentication:()=>r$,bypassAuth:()=>xle,login:()=>Hle,logout:()=>kle,start:()=>Ble});function xle(){t$=!0}async function r$(e,t){let r=e.headers.asObject,n=r.authorization,s=r.cookie,i=r.origin,o=[];try{if(i){let h=e.isOperationsServer?Lle?Dle:[]:Ple?Cle:[];if(h.includes(i)||h.includes("*")){if(e.method==="OPTIONS"){let m=en.get(x.HTTP_CORSACCESSCONTROLALLOWHEADERS)??"Accept, Content-Type, Authorization",S=new So([["Access-Control-Allow-Methods","POST, GET, PUT, DELETE, PATCH, OPTIONS"],["Access-Control-Allow-Headers",m],["Access-Control-Allow-Origin",i]]);return tS&&S.set("Access-Control-Allow-Credentials","true"),{status:200,headers:S}}o.push("Access-Control-Allow-Origin",i),tS&&o.push("Access-Control-Allow-Credentials","true")}}let l,u;if(tS){i||(i=r.host);let h=(i?i.replace(/^https?:\/\//,"").replace(/\W/,"_")+"-":"")+"hdb-session=",m=s?.split(/;\s+/)||[];for(let S of m)if(S.startsWith(h)){let g=S.indexOf(";");l=S.slice(h.length,g===-1?S.length:g),u=await jq.get(l);break}e.session=u||(u={})}let f=a((h,m,S)=>{let g=new md.AuthAuditLog(h,m,Jo.AUTHENTICATION,r["x-forwarded-for"]??e.ip,e.method,e.pathname);g.auth_strategy=S,l&&(g.session_id=l),r.referer&&(g.referer=r.referer),r.origin&&(g.origin=r.origin),m===xs.SUCCESS?aw.notify(g):aw.error(g)},"authAuditLog");if(!e.authorized&&e.mtlsConfig&&e.peerCertificate.subject&&e?._nodeRequest?.socket?.authorizationError&&aw.error("Authorization error:",e._nodeRequest.socket.authorizationError),e.mtlsConfig&&e.authorized&&e.peerCertificate.subject){let h=e.mtlsConfig.user;h!==null?((h===void 0||h==="Common Name"||h==="CN")&&(h=e.peerCertificate.subject.CN),e.user=await Ye.getUser(h,null,e),f(h,xs.SUCCESS,"mTLS")):(0,md.debug)("HTTPS/WSS mTLS authorized connection (mTLS did not authorize a user)","from",e.ip)}let d;if(!e.user)if(n){if(d=Rl.get(n),!d){let h=n.indexOf(" "),m=n.slice(0,h),S=n.slice(h+1),g,R;try{switch(m){case"Basic":let E=atob(S),T=E.indexOf(":");g=E.slice(0,T),R=E.slice(T+1),d=g||R?await Ye.getUser(g,R,e):null;break;case"Bearer":try{d=await Kb(S)}catch(N){if(N.message==="invalid token")try{return await HE(S),c({status:-1})}catch{throw N}}break}}catch(E){return vle&&(Rl.get(S)||(Rl.set(S,S),f(g,xs.FAILURE,m))),c({status:401,body:la({error:E.message},e)})}Rl.set(n,d),Mle&&f(d.username,xs.SUCCESS,m)}e.user=d}else u?.user?e.user=await Ye.getUser(u.user,null,e):(t$&&(e.ip?.includes("127.0.0.")||e.ip=="::1")||e?._nodeRequest?.socket?.server?._pipeName&&e.ip===void 0)&&(e.user=await(0,Xq.getSuperUser)());tS&&(e.session.update=function(h){let m=en.get(x.AUTHENTICATION_COOKIE_EXPIRES);if(!l){l=(0,Zq.v4)();let S=en.get(x.AUTHENTICATION_COOKIE_DOMAINS),g=m?new Date(Date.now()+(0,cw.convertToMS)(m)).toUTCString():Ule,R=S?.find(N=>r.host?.endsWith(N)),T=`${(i?i.replace(/^https?:\/\//,"").replace(/\W/,"_")+"-":"")+"hdb-session="}${l}; Path=/; Expires=${g}; ${R?"Domain="+R+"; ":""}HttpOnly${e.protocol==="https"?"; SameSite=None; Secure":""}`;o?o.push("Set-Cookie",T):_?.headers?.set&&_.headers.set("Set-Cookie",T)}return e.protocol==="https"&&(o?(i&&o.push("Access-Control-Expose-Headers","X-Hdb-Session"),o.push("X-Hdb-Session","Secure")):_?.headers?.set&&(i&&_.headers.set("Access-Control-Expose-Headers","X-Hdb-Session"),_.headers.set("X-Hdb-Session","Secure"))),h.id=l,jq.put(h,{expiresAt:m?Date.now()+(0,cw.convertToMS)(m):void 0})},e.login=async function(h,m){let S=e.user=await Ye.authenticateUser(h,m,e);e.session.update({user:S&&(S.getId?.()??S.username)})});let _=await t(e);return _&&(_.status===401&&(r["user-agent"]?.startsWith("Mozilla")&&r.accept?.startsWith("text/html")&&_s.loginPath?(_.status=302,_.headers.set("Location",_s.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 So);for(let d=0;d<u;){let _=o[d++];f.set(_,o[d++])}}return o=null,l}a(c,"applyResponseHeaders")}function Ble({server:e,port:t,securePort:r}){e.http(r$,t||r?{port:t,securePort:r}:{port:"all"}),Jq||(Jq=!0,setInterval(()=>{Rl=new Map},en.get(x.AUTHENTICATION_CACHETTL)).unref(),e$.user.addListener(()=>{Rl=new Map}))}async function Hle(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 kle(e){if(!e.baseRequest.session)throw new Error("No session for logout");return await e.baseRequest.session.update({user:null}),"Logout successful"}var Xq,Zq,en,md,e$,cw,aw,Cle,Ple,Dle,Lle,jq,tS,t$,Mle,vle,Ule,Rl,Jq,rS=Re(()=>{Xq=M(Kn());Mr();nu();Mu();xe();Zq=require("uuid"),en=M(le());k();md=M(ee()),e$=M(u_());v_();cw=M(ie());so();aw=(0,md.loggerWithTag)("auth-event");en.initSync();Cle=en.get(x.HTTP_CORSACCESSLIST),Ple=en.get(x.HTTP_CORS),Dle=en.get(x.OPERATIONSAPI_NETWORK_CORSACCESSLIST),Lle=en.get(x.OPERATIONSAPI_NETWORK_CORS),jq=_t({table:"hdb_session",database:"system",attributes:[{name:"id",isPrimaryKey:!0},{name:"user"}]}),tS=en.get(x.AUTHENTICATION_ENABLESESSIONS)??!0,t$=process.env.AUTHENTICATION_AUTHORIZELOCAL??en.get(x.AUTHENTICATION_AUTHORIZELOCAL)??process.env.DEV_MODE,Mle=en.get(x.LOGGING_AUDITAUTHEVENTS_LOGSUCCESSFUL)??!1,vle=en.get(x.LOGGING_AUDITAUTHEVENTS_LOGFAILED)??!1,Ule="Tue, 01 Oct 8307 19:33:20 GMT",Rl=new Map;Ye.onInvalidatedUser(()=>{Rl=new Map});a(xle,"bypassAuth");a(r$,"authentication");a(Ble,"start");a(Hle,"login");a(kle,"logout")});var l$=C((rDe,c$)=>{"use strict";var Ne=require("joi"),n$=require("fs-extra"),s$=require("path"),es=it(),i$=le(),o$=(k(),P(q)),a$=ee(),{hdb_errors:Fle}=he(),{HDB_ERROR_MSGS:tn}=Fle,Io=/^[a-zA-Z0-9-_]+$/,Gle=/^[a-zA-Z0-9-_]+$/;c$.exports={getDropCustomFunctionValidator:$le,setCustomFunctionValidator:Vle,addComponentValidator:zle,dropCustomFunctionProjectValidator:Qle,packageComponentValidator:jle,deployComponentValidator:Jle,setComponentFileValidator:Kle,getComponentFileValidator:Wle,dropComponentFileValidator:Yle,addSSHKeyValidator:Xle,updateSSHKeyValidator:Zle,deleteSSHKeyValidator:eue,setSSHKnownHostsValidator:tue};function nS(e,t,r){try{let n=i$.get(o$.CONFIG_PARAMS.COMPONENTSROOT),s=s$.join(n,t);return n$.existsSync(s)?e?t:r.message(tn.PROJECT_EXISTS):e?r.message(tn.NO_PROJECT):t}catch(n){return a$.error(n),r.message(tn.VALIDATION_ERR)}}a(nS,"checkProjectExists");function wh(e,t){return e.includes("..")?t.message("Invalid file path"):e}a(wh,"checkFilePath");function qle(e,t,r,n){try{let s=i$.get(o$.CONFIG_PARAMS.COMPONENTSROOT),i=s$.join(s,e,t,r+".js");return n$.existsSync(i)?r:n.message(tn.NO_FILE)}catch(s){return a$.error(s),n.message(tn.VALIDATION_ERR)}}a(qle,"checkFileExists");function $le(e){let t=Ne.object({project:Ne.string().pattern(Io).custom(nS.bind(null,!0)).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),type:Ne.string().valid("helpers","routes").required(),file:Ne.string().pattern(Io).custom(qle.bind(null,e.project,e.type)).custom(wh).required().messages({"string.pattern.base":tn.BAD_FILE_NAME})});return es.validateBySchema(e,t)}a($le,"getDropCustomFunctionValidator");function Vle(e){let t=Ne.object({project:Ne.string().pattern(Io).custom(nS.bind(null,!0)).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),type:Ne.string().valid("helpers","routes").required(),file:Ne.string().custom(wh).required(),function_content:Ne.string().required()});return es.validateBySchema(e,t)}a(Vle,"setCustomFunctionValidator");function Kle(e){let t=Ne.object({project:Ne.string().pattern(Io).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),file:Ne.string().custom(wh).required(),payload:Ne.string().allow("").optional(),encoding:Ne.string().valid("utf8","ASCII","binary","hex","base64","utf16le","latin1","ucs2").optional()});return es.validateBySchema(e,t)}a(Kle,"setComponentFileValidator");function Yle(e){let t=Ne.object({project:Ne.string().pattern(Io).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),file:Ne.string().custom(wh).optional()});return es.validateBySchema(e,t)}a(Yle,"dropComponentFileValidator");function Wle(e){let t=Ne.object({project:Ne.string().required(),file:Ne.string().custom(wh).required(),encoding:Ne.string().valid("utf8","ASCII","binary","hex","base64","utf16le","latin1","ucs2").optional()});return es.validateBySchema(e,t)}a(Wle,"getComponentFileValidator");function zle(e){let t=Ne.object({project:Ne.string().pattern(Io).custom(nS.bind(null,!1)).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME})});return es.validateBySchema(e,t)}a(zle,"addComponentValidator");function Qle(e){let t=Ne.object({project:Ne.string().pattern(Io).custom(nS.bind(null,!0)).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME})});return es.validateBySchema(e,t)}a(Qle,"dropCustomFunctionProjectValidator");function jle(e){let t=Ne.object({project:Ne.string().pattern(Io).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),skip_node_modules:Ne.boolean(),skip_symlinks:Ne.boolean()});return es.validateBySchema(e,t)}a(jle,"packageComponentValidator");function Jle(e){let t=Ne.object({project:Ne.string().pattern(Io).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),package:Ne.string().optional(),restart:Ne.alternatives().try(Ne.boolean(),Ne.string().valid("rolling")).optional()});return es.validateBySchema(e,t)}a(Jle,"deployComponentValidator");function Xle(e){let t=Ne.object({name:Ne.string().pattern(Gle).required().messages({"string.pattern.base":tn.BAD_SSH_KEY_NAME}),key:Ne.string().required(),host:Ne.string().required(),hostname:Ne.string().required(),known_hosts:Ne.string().optional()});return es.validateBySchema(e,t)}a(Xle,"addSSHKeyValidator");function Zle(e){let t=Ne.object({name:Ne.string().required(),key:Ne.string().required()});return es.validateBySchema(e,t)}a(Zle,"updateSSHKeyValidator");function eue(e){let t=Ne.object({name:Ne.string().required()});return es.validateBySchema(e,t)}a(eue,"deleteSSHKeyValidator");function tue(e){let t=Ne.object({known_hosts:Ne.string().required()});return es.validateBySchema(e,t)}a(tue,"setSSHKnownHostsValidator")});var Ph=C((sDe,h$)=>{"use strict";var sS=require("joi"),Ua=require("path"),pd=require("fs-extra"),{exec:rue,spawn:nue}=require("child_process"),sue=require("util"),iue=sue.promisify(rue),Ed=(k(),P(q)),{PACKAGE_ROOT:oue}=Et(),{handleHDBError:Ih,hdb_errors:aue}=he(),{HTTP_STATUS_CODES:Ch}=aue,yl=le(),cue=it(),xa=ee(),{once:lue}=require("events");yl.initSync();var lw=yl.get(Ed.CONFIG_PARAMS.COMPONENTSROOT),u$="npm install --force --omit=dev --json",uue=`${u$} --dry-run`,due=yl.get(Ed.CONFIG_PARAMS.ROOTPATH),iS=Ua.join(due,"ssh");h$.exports={installModules:mue,auditModules:pue,installAllRootModules:fue,uninstallRootModule:_ue,linkHarperdb:hue,runCommand:gd};async function fue(e=!1,t=yl.get(Ed.CONFIG_PARAMS.ROOTPATH)){await oS();let r=!1,n=process.env;pd.pathExistsSync(iS)&&pd.readdirSync(iS).forEach(s=>{s.includes(".key")&&!r&&(n={GIT_SSH_COMMAND:"ssh -F "+Ua.join(iS,"config")+" -o UserKnownHostsFile="+Ua.join(iS,"known_hosts"),...process.env},r=!0)});try{let s=yl.get(Ed.CONFIG_PARAMS.ROOTPATH),i=Ua.join(s,"node_modules","harperdb");pd.lstatSync(i).isSymbolicLink()&&pd.unlinkSync(i)}catch(s){s.code!=="ENOENT"&&xa.error("Error removing symlink:",s)}await gd(e?"npm install --force --ignore-scripts":"npm install --force",t,n)}a(fue,"installAllRootModules");async function _ue(e){await gd(`npm uninstall ${e}`,yl.get(Ed.CONFIG_PARAMS.ROOTPATH))}a(_ue,"uninstallRootModule");async function hue(){await oS(),await gd(`npm link ${oue}`,yl.get(Ed.CONFIG_PARAMS.ROOTPATH))}a(hue,"linkHarperdb");async function gd(e,t=void 0,r=process.env){xa.debug({tagName:"npm_run_command"},`running command: \`${e}\``);let n=nue(e,{shell:!0,cwd:t,env:r,stdio:["ignore","pipe","pipe"]}),s="",i="";n.stdout.on("data",c=>{let l=c.toString();xa.debug({tagName:"npm_run_command:stdout"},l),s+=l}),n.stderr.on("data",c=>{let l=c.toString();xa.error({tagName:"npm_run_command:stderr"},l),i+=l});let[o]=await lue(n,"close");if(o!==0)throw new Error(`Command \`${e}\` exited with code ${o}.${i===""?"":` Error: ${i}`}`);return s||void 0}a(gd,"runCommand");async function mue(e){let t="install_node_modules is deprecated. Dependencies are automatically installed on deploy, and install_node_modules can lead to inconsistent behavior";xa.warn(t,e.projects);let r=_$(e);if(r)throw Ih(r,r.message,Ch.BAD_REQUEST);let{projects:n,dry_run:s}=e,i=s===!0?uue:u$;await oS(),await f$(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=Ua.join(lw,u),d,_=null;try{let{stdout:h,stderr:m}=await iue(i,{cwd:f});d=h?h.replace(`
|
|
28
28
|
`,""):null,_=m?m.replace(`
|
|
29
29
|
`,""):null}catch(h){h.stderr?o[u].npm_error=d$(h.stderr):o[u].npm_error=h.message;continue}try{o[u].npm_output=JSON.parse(d)}catch{o[u].npm_output=d}try{o[u].npm_error=JSON.parse(_)}catch{o[u].npm_error=_}}return xa.info(`finished installModules with response ${o}`),o.warning=t,o}a(mue,"installModules");function d$(e){let t='"error": {',r=e.indexOf('"error": {'),n=e.indexOf(`}
|
/package/studio/build-local/static/js/{main.ce641166.js.LICENSE.txt → main.eae3e997.js.LICENSE.txt}
RENAMED
|
File without changes
|