harperdb 4.5.8 → 4.5.9
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 +1 -1
- package/bin/lite.js +1 -1
- package/launchServiceScripts/launchNatsIngestService.js +1 -1
- package/launchServiceScripts/launchNatsReplyService.js +1 -1
- package/launchServiceScripts/launchUpdateNodes4-0-0.js +1 -1
- package/npm-shrinkwrap.json +116 -124
- package/package.json +1 -1
- package/server/jobs/jobProcess.js +1 -1
- package/server/threads/threadServer.js +1 -1
- package/studio/build-local/asset-manifest.json +34 -34
- package/studio/build-local/index.html +1 -1
- package/studio/build-local/static/js/164.a89f3fc2.chunk.js +1 -0
- package/studio/build-local/static/js/{101.de926db6.chunk.js → 504.6e6ee908.chunk.js} +2 -2
- package/studio/build-local/static/js/833.e460eaf4.chunk.js +1 -0
- package/studio/build-local/static/js/browse-csvupload.84fd1ae9.chunk.js +1 -0
- package/studio/build-local/static/js/browse-datatable.21e650e1.chunk.js +1 -0
- package/studio/build-local/static/js/browse-entitymanager.4547c0d8.chunk.js +1 -0
- package/studio/build-local/static/js/browse-jsonviewer.71355c20.chunk.js +1 -0
- package/studio/build-local/static/js/custom-functions.31d65bca.chunk.js +1 -0
- package/studio/build-local/static/js/instance-cluster.031dcced.chunk.js +1 -0
- package/studio/build-local/static/js/instance-config.9a23d6ae.chunk.js +1 -0
- package/studio/build-local/static/js/instance-logs.fdaf96ec.chunk.js +1 -0
- package/studio/build-local/static/js/instance-roles.984ced56.chunk.js +1 -0
- package/studio/build-local/static/js/{instance-status.2f3aaaf7.chunk.js → instance-status.192a5e2f.chunk.js} +1 -1
- package/studio/build-local/static/js/instance-users-datatable.40846e47.chunk.js +1 -0
- package/studio/build-local/static/js/instance-users-edit.f10344c8.chunk.js +1 -0
- package/studio/build-local/static/js/instance-users.adc43a74.chunk.js +1 -0
- package/studio/build-local/static/js/instance.9689d62b.chunk.js +1 -0
- package/studio/build-local/static/js/instances.f28e5ce7.chunk.js +1 -0
- package/studio/build-local/static/js/{main.44262b30.js → main.491129ee.js} +2 -2
- package/studio/build-local/static/js/offline-app.5bc1159b.chunk.js +1 -0
- package/studio/build-local/static/js/online-app.22102869.chunk.js +1 -0
- package/studio/build-local/static/js/organization-billing.56e7e051.chunk.js +1 -0
- package/studio/build-local/static/js/organization-users.b46b9e8f.chunk.js +1 -0
- package/studio/build-local/static/js/organization.eab64d57.chunk.js +1 -0
- package/studio/build-local/static/js/organizations.4567ae59.chunk.js +1 -0
- package/studio/build-local/static/js/profile.d45cd6b3.chunk.js +1 -0
- package/studio/build-local/static/js/resetPassword.812fc880.chunk.js +1 -0
- package/studio/build-local/static/js/roles-jsonviewer.73c8bb9d.chunk.js +1 -0
- package/studio/build-local/static/js/signIn.32766fa9.chunk.js +1 -0
- package/studio/build-local/static/js/signUp.07fd6662.chunk.js +1 -0
- package/studio/build-local/static/js/structure-reloader.ce2b39d2.chunk.js +1 -0
- package/studio/build-local/static/js/topnav.e661156c.chunk.js +1 -0
- package/studio/build-local/static/js/updatePassword.dcac970c.chunk.js +1 -0
- package/utility/scripts/restartHdb.js +1 -1
- package/studio/build-local/static/js/164.13a1ca36.chunk.js +0 -1
- package/studio/build-local/static/js/833.475ee615.chunk.js +0 -1
- package/studio/build-local/static/js/browse-csvupload.cfcf1c79.chunk.js +0 -1
- package/studio/build-local/static/js/browse-datatable.85de5169.chunk.js +0 -1
- package/studio/build-local/static/js/browse-entitymanager.dddb5da8.chunk.js +0 -1
- package/studio/build-local/static/js/browse-jsonviewer.059b4189.chunk.js +0 -1
- package/studio/build-local/static/js/custom-functions.2c2e634c.chunk.js +0 -1
- package/studio/build-local/static/js/instance-cluster.daef89d8.chunk.js +0 -1
- package/studio/build-local/static/js/instance-config.ba645bea.chunk.js +0 -1
- package/studio/build-local/static/js/instance-logs.33ace406.chunk.js +0 -1
- package/studio/build-local/static/js/instance-roles.0276d83f.chunk.js +0 -1
- package/studio/build-local/static/js/instance-users-datatable.f75cf637.chunk.js +0 -1
- package/studio/build-local/static/js/instance-users-edit.3a3bc76f.chunk.js +0 -1
- package/studio/build-local/static/js/instance-users.70ee5db2.chunk.js +0 -1
- package/studio/build-local/static/js/instance.0bbb9d0e.chunk.js +0 -1
- package/studio/build-local/static/js/instances.e86d288b.chunk.js +0 -1
- package/studio/build-local/static/js/offline-app.edb4be85.chunk.js +0 -1
- package/studio/build-local/static/js/online-app.45440c0e.chunk.js +0 -1
- package/studio/build-local/static/js/organization-billing.3ff0b995.chunk.js +0 -1
- package/studio/build-local/static/js/organization-users.710f96e7.chunk.js +0 -1
- package/studio/build-local/static/js/organization.1aa3da8e.chunk.js +0 -1
- package/studio/build-local/static/js/organizations.259e09d3.chunk.js +0 -1
- package/studio/build-local/static/js/profile.c1840496.chunk.js +0 -1
- package/studio/build-local/static/js/resetPassword.37769fbe.chunk.js +0 -1
- package/studio/build-local/static/js/roles-jsonviewer.b8cc0628.chunk.js +0 -1
- package/studio/build-local/static/js/signIn.061b438e.chunk.js +0 -1
- package/studio/build-local/static/js/signUp.cabe1d80.chunk.js +0 -1
- package/studio/build-local/static/js/structure-reloader.fd360bad.chunk.js +0 -1
- package/studio/build-local/static/js/topnav.1fce7836.chunk.js +0 -1
- package/studio/build-local/static/js/updatePassword.dc41627a.chunk.js +0 -1
- /package/studio/build-local/static/js/{101.de926db6.chunk.js.LICENSE.txt → 504.6e6ee908.chunk.js.LICENSE.txt} +0 -0
- /package/studio/build-local/static/js/{main.44262b30.js.LICENSE.txt → main.491129ee.js.LICENSE.txt} +0 -0
|
@@ -24,7 +24,7 @@ Caused by:`));else if(typeof u=="object")try{n+=JSON.stringify(u)}catch{n+="Obje
|
|
|
24
24
|
`)}catch(r){r.code==="ENOENT"?Xr.debug("no license file found"):Xr.error(`could not search for licenses due to: '${r.message}`)}for(let r=0;r<t.length;++r){let n=t[r];try{if(lce.isEmptyOrZeroLength(n))continue;let s=JSON.parse(n),i=tq(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){Xr.error("There was an error parsing the license string."),Xr.error(s),e.ram_allocation=il.RAM_ALLOCATION_ENUM.DEFAULT,e.enterprise=!1}}return CN=e,e}a(MN,"licenseSearch");async function Tce(){return CN||await MN(),CN}a(Tce,"getLicense");function Ace(){let e=MN().ram_allocation,t=process.constrainedMemory?.()||JG();if(t=Math.round(Math.min(t,JG())/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(Ace,"checkMemoryLimit")});var xN=P((sPe,oq)=>{var kg=Zu(),nq=require("chalk"),zn=j(),sq=require("prompt"),{promisify:Rce}=require("util"),vN=(H(),D($)),yce=require("fs-extra"),bce=require("path"),Oce=oe(),{packageJson:Nce}=pt(),iq=ue();iq.initSync();var wce=require("moment"),Ice=Rce(sq.get),Cce=bce.join(iq.getHdbBasePath(),vN.LICENSE_KEY_DIR_NAME,vN.LICENSE_FILE_NAME,vN.LICENSE_FILE_NAME);oq.exports={getFingerprint:Dce,setLicense:Pce,parseLicense:UN,register:Lce,getRegistrationInfo:vce};async function Pce(e){if(e&&e.key&&e.company){try{zn.info(`parsing license key: ${e.key} and `);let t=e.company.toString();await UN(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(Pce,"setLicense");async function Dce(){let e={};try{e=await kg.generateFingerPrint()}catch(t){let r="Error generating fingerprint.";throw zn.error(r),zn.error(t),new Error(r)}return e}a(Dce,"getFingerprint");async function UN(e,t){if(!e||!t)throw new Error("Invalid entries for License Key and Customer Company");zn.info("Validating license input...");let r=kg.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 yce.writeFile(Cce,JSON.stringify({license_key:e,company:t}))}catch(n){throw zn.error("Failed to write License"),n}return"Registration successful."}a(UN,"parseLicense");async function Lce(){let e=await Mce();return UN(e.HDB_LICENSE,e.CUSTOMER_COMPANY)}a(Lce,"register");async function Mce(){let e=await kg.generateFingerPrint(),t={properties:{CUSTOMER_COMPANY:{description:nq.magenta("[COMPANY] Please enter your company name"),required:!0},HDB_LICENSE:{description:nq.magenta(`[HDB_LICENSE] Your fingerprint is ${e} Please enter your license key`),required:!0}}};try{sq.start()}catch(n){zn.error(n)}let r;try{r=await Ice(t)}catch(n){throw console.error("There was a problem prompting for registration input. Exiting."),n}return r}a(Mce,"promptForRegistration");async function vce(){let e={registered:!1,version:null,ram_allocation:null,license_expiration_date:null},t;try{t=await kg.getLicense()}catch(r){throw zn.error(`There was an error when searching licenses due to: ${r.message}`),r}if(Oce.isEmptyOrZeroLength(t))throw new Error("There were no licenses found.");if(e.registered=t.enterprise,e.version=Nce.version,e.ram_allocation=t.ram_allocation,isNaN(t.exp_date))e.license_expiration_date=t.enterprise?t.exp_date:null;else{let r=wce.utc(t.exp_date).format("YYYY-MM-DD");e.license_expiration_date=t.enterprise?r:null}return e}a(vce,"getRegistrationInfo")});var cq=P((oPe,aq)=>{"use strict";var Uce=It(),BN=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+Uce.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"}};aq.exports=BN});var dq=P((cPe,uq)=>{"use strict";var lq=It(),HN=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+lq.SERVER_SUFFIX.LEAF,this.pid_file=n,this.max_payload=67108864,this.jetstream={enabled:!0,store_dir:s,domain:r+lq.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"}};uq.exports=HN});var _q=P((uPe,fq)=>{"use strict";var kN=class{static{a(this,"HdbUserObject")}constructor(t,r){this.user=t,this.password=r}};fq.exports=kN});var mq=P((fPe,hq)=>{"use strict";var xce=It(),FN=class{static{a(this,"SysUserObject")}constructor(t,r){this.user=t+xce.SERVER_SUFFIX.ADMIN,this.password=r}};hq.exports=FN});var $g=P((hPe,gq)=>{"use strict";var ol=require("path"),al=require("fs-extra"),Bce=cq(),Hce=dq(),kce=_q(),Fce=mq(),GN=Sn(),td=oe(),bn=Ot(),Gg=(H(),D($)),sh=It(),{CONFIG_PARAMS:Yt}=Gg,rd=j(),ih=ue(),pq=io(),qN=rr(),Gce=js(),ed="clustering",qce=1e4,Eq=50;gq.exports={generateNatsConfig:Vce,removeNatsConfig:Kce,getHubConfigPath:$ce};function $ce(){let e=ih.get(Yt.ROOTPATH);return ol.join(e,ed,sh.NATS_CONFIG_FILES.HUB_SERVER)}a($ce,"getHubConfigPath");async function Vce(e=!1,t=void 0){let r=ih.get(Yt.ROOTPATH);al.ensureDirSync(ol.join(r,"clustering","leaf")),ih.initSync();let n=bn.getConfigFromFile(Yt.CLUSTERING_TLS_CERT_AUTH),s=bn.getConfigFromFile(Yt.CLUSTERING_TLS_PRIVATEKEY),i=bn.getConfigFromFile(Yt.CLUSTERING_TLS_CERTIFICATE);!await al.exists(i)&&!await al.exists(!n)&&await Gce.createNatsCerts();let o=ol.join(r,ed,sh.PID_FILES.HUB),c=ol.join(r,ed,sh.PID_FILES.LEAF),l=bn.getConfigFromFile(Yt.CLUSTERING_LEAFSERVER_STREAMS_PATH),u=ol.join(r,ed,sh.NATS_CONFIG_FILES.HUB_SERVER),f=ol.join(r,ed,sh.NATS_CONFIG_FILES.LEAF_SERVER),d=bn.getConfigFromFile(Yt.CLUSTERING_TLS_INSECURE),_=bn.getConfigFromFile(Yt.CLUSTERING_TLS_VERIFY),h=bn.getConfigFromFile(Yt.CLUSTERING_NODENAME),m=bn.getConfigFromFile(Yt.CLUSTERING_HUBSERVER_LEAFNODES_NETWORK_PORT);await qN.checkNATSServerInstalled()||qg("nats-server dependency is either missing or the wrong version. Run 'npm install' to fix");let S=await GN.listUsers(),g=bn.getConfigFromFile(Yt.CLUSTERING_USER),R=await GN.getClusterUser();(td.isEmpty(R)||R.active!==!0)&&qg(`Invalid cluster user '${g}'. A valid user with the role 'cluster_user' must be defined under clustering.user in harperdb-config.yaml`),e||(await Fg(Yt.CLUSTERING_HUBSERVER_CLUSTER_NETWORK_PORT),await Fg(Yt.CLUSTERING_HUBSERVER_LEAFNODES_NETWORK_PORT),await Fg(Yt.CLUSTERING_HUBSERVER_NETWORK_PORT),await Fg(Yt.CLUSTERING_LEAFSERVER_NETWORK_PORT));let E=[],T=[];for(let[ie,W]of S.entries())W.role?.role===Gg.ROLE_TYPES_ENUM.CLUSTER_USER&&W.active&&(E.push(new Fce(W.username,pq.decrypt(W.hash))),T.push(new kce(W.username,pq.decrypt(W.hash))));let N=[],{hub_routes:v}=bn.getClusteringRoutes();if(!td.isEmptyOrZeroLength(v))for(let ie of v)N.push(`tls://${R.sys_name_encoded}:${R.uri_encoded_d_hash}@${ie.host}:${ie.port}`);let k=new Bce(bn.getConfigFromFile(Yt.CLUSTERING_HUBSERVER_NETWORK_PORT),h,o,i,s,n,d,_,m,bn.getConfigFromFile(Yt.CLUSTERING_HUBSERVER_CLUSTER_NAME),bn.getConfigFromFile(Yt.CLUSTERING_HUBSERVER_CLUSTER_NETWORK_PORT),N,E,T);n==null&&(delete k.tls.ca_file,delete k.leafnodes.tls.ca_file),t=td.isEmpty(t)?void 0:t.toLowerCase(),(t===void 0||t===Gg.PROCESS_DESCRIPTORS.CLUSTERING_HUB.toLowerCase())&&(await al.writeJson(u,k),rd.trace(`Hub server config written to ${u}`));let G=`tls://${R.sys_name_encoded}:${R.uri_encoded_d_hash}@0.0.0.0:${m}`,Y=`tls://${R.uri_encoded_name}:${R.uri_encoded_d_hash}@0.0.0.0:${m}`,X=new Hce(bn.getConfigFromFile(Yt.CLUSTERING_LEAFSERVER_NETWORK_PORT),h,c,l,[G],[Y],E,T,i,s,n,d);n==null&&delete X.tls.ca_file,(t===void 0||t===Gg.PROCESS_DESCRIPTORS.CLUSTERING_LEAF.toLowerCase())&&(await al.writeJson(f,X),rd.trace(`Leaf server config written to ${f}`))}a(Vce,"generateNatsConfig");async function Fg(e){let t=ih.get(e);return td.isEmpty(t)&&qg(`port undefined for '${e}'`),await td.isPortTaken(t)&&qg(`'${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(Fg,"isPortAvailable");function qg(e){let t=`Error generating clustering config: ${e}`;rd.error(t),console.error(t),process.exit(1)}a(qg,"generateNatsConfigError");async function Kce(e){let{port:t,config_file:r}=qN.getServerConfig(e),{username:n,decrypt_hash:s}=await GN.getClusterUser(),i=0,o=2e3;for(;i<Eq;){try{let f=await qN.createConnection(t,n,s,!1);if(f.protocol.connected===!0){f.close();break}}catch(f){rd.trace(`removeNatsConfig waiting for ${e}. Caught and swallowed error ${f}`)}if(i++,i>=Eq)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&&rd.notify("Operations API waiting for Nats server connection. This could be caused by large Nats streams or incorrect clustering config."),await td.async_set_timeout(u)}let c="0".repeat(qce),l=ol.join(ih.get(Yt.ROOTPATH),ed,r);await al.writeFile(l,c),await al.remove(l),rd.notify(e,"started.")}a(Kce,"removeNatsConfig")});var bq=P((pPe,yq)=>{"use strict";var jn=ue(),Yce=Zu(),Ge=(H(),D($)),oh=It(),Ao=require("path"),{PACKAGE_ROOT:Kg}=pt(),Sq=ue(),Vg=oe(),nd="/dev/null",Wce=Ao.join(Kg,"launchServiceScripts"),Tq=Ao.join(Kg,"utility/scripts"),zce=Ao.join(Tq,Ge.HDB_RESTART_SCRIPT),Aq=Ao.resolve(Kg,"dependencies",`${process.platform}-${process.arch}`,oh.NATS_BINARY_NAME);function Rq(){let t=Yce.licenseSearch().ram_allocation||Ge.RAM_ALLOCATION_ENUM.DEFAULT,r=Ge.MEM_SETTING_KEY+t,n={[Ge.PROCESS_NAME_ENV_PROP]:Ge.PROCESS_DESCRIPTORS.HDB,IS_SCRIPTED_SERVICE:!0};return Vg.noBootFile()&&(n[Ge.CONFIG_PARAMS.ROOTPATH.toUpperCase()]=Vg.getEnvCliRootPath()),{name:Ge.PROCESS_DESCRIPTORS.HDB,script:Ge.LAUNCH_SERVICE_SCRIPTS.MAIN,exec_mode:"fork",env:n,node_args:r,cwd:Kg}}a(Rq,"generateMainServerConfig");var jce=9930;function Qce(){jn.initSync(!0);let e=jn.get(Ge.CONFIG_PARAMS.ROOTPATH),t=Ao.join(e,"clustering",oh.NATS_CONFIG_FILES.HUB_SERVER),r=Ao.join(jn.get(Ge.HDB_SETTINGS_NAMES.LOG_PATH_KEY),Ge.LOG_NAMES.HDB),n=Sq.get(Ge.CONFIG_PARAMS.CLUSTERING_HUBSERVER_NETWORK_PORT),s=oh.LOG_LEVEL_FLAGS[jn.get(Ge.CONFIG_PARAMS.CLUSTERING_LOGLEVEL)]??void 0,i={name:Ge.PROCESS_DESCRIPTORS.CLUSTERING_HUB+(n!==jce?"-"+n:""),script:Aq,args:s?`${s} -c ${t}`:`-c ${t}`,exec_mode:"fork",env:{[Ge.PROCESS_NAME_ENV_PROP]:Ge.PROCESS_DESCRIPTORS.CLUSTERING_HUB},merge_logs:!0,out_file:r,error_file:r,instances:1};return jn.get(Ge.HDB_SETTINGS_NAMES.LOG_TO_FILE)||(i.out_file=nd,i.error_file=nd),i}a(Qce,"generateNatsHubServerConfig");var Jce=9940;function Xce(){jn.initSync(!0);let e=jn.get(Ge.CONFIG_PARAMS.ROOTPATH),t=Ao.join(e,"clustering",oh.NATS_CONFIG_FILES.LEAF_SERVER),r=Ao.join(jn.get(Ge.HDB_SETTINGS_NAMES.LOG_PATH_KEY),Ge.LOG_NAMES.HDB),n=Sq.get(Ge.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_NETWORK_PORT),s=oh.LOG_LEVEL_FLAGS[jn.get(Ge.CONFIG_PARAMS.CLUSTERING_LOGLEVEL)]??void 0,i={name:Ge.PROCESS_DESCRIPTORS.CLUSTERING_LEAF+(n!==Jce?"-"+n:""),script:Aq,args:s?`${s} -c ${t}`:`-c ${t}`,exec_mode:"fork",env:{[Ge.PROCESS_NAME_ENV_PROP]:Ge.PROCESS_DESCRIPTORS.CLUSTERING_LEAF},merge_logs:!0,out_file:r,error_file:r,instances:1};return jn.get(Ge.HDB_SETTINGS_NAMES.LOG_TO_FILE)||(i.out_file=nd,i.error_file=nd),i}a(Xce,"generateNatsLeafServerConfig");function Zce(){jn.initSync();let e=Ao.join(jn.get(Ge.CONFIG_PARAMS.LOGGING_ROOT),Ge.LOG_NAMES.HDB),t={name:Ge.PROCESS_DESCRIPTORS.CLUSTERING_UPGRADE_4_0_0,script:Ge.LAUNCH_SERVICE_SCRIPTS.NODES_UPGRADE_4_0_0,exec_mode:"fork",env:{[Ge.PROCESS_NAME_ENV_PROP]:Ge.PROCESS_DESCRIPTORS.CLUSTERING_UPGRADE_4_0_0},merge_logs:!0,out_file:e,error_file:e,instances:1,cwd:Wce,autorestart:!1};return jn.get(Ge.HDB_SETTINGS_NAMES.LOG_TO_FILE)||(t.out_file=nd,t.error_file=nd),t}a(Zce,"generateClusteringUpgradeV4ServiceConfig");function ele(){let e={[Ge.PROCESS_NAME_ENV_PROP]:Ge.PROCESS_DESCRIPTORS.RESTART_HDB};return Vg.noBootFile()&&(e[Ge.CONFIG_PARAMS.ROOTPATH.toUpperCase()]=Vg.getEnvCliRootPath()),{...{name:Ge.PROCESS_DESCRIPTORS.RESTART_HDB,exec_mode:"fork",env:e,instances:1,autorestart:!1,cwd:Tq},script:zce}}a(ele,"generateRestart");function tle(){return{apps:[Rq()]}}a(tle,"generateAllServiceConfigs");yq.exports={generateAllServiceConfigs:tle,generateMainServerConfig:Rq,generateRestart:ele,generateNatsHubServerConfig:Qce,generateNatsLeafServerConfig:Xce,generateClusteringUpgradeV4ServiceConfig:Zce}});var ch=P((SPe,Hq)=>{"use strict";var et=(H(),D($)),rle=oe(),yo=$g(),Yg=rr(),Ro=It(),Na=bq(),Wg=ue(),cl=j(),nle=go(),{startWorker:Oq,onMessageFromWorkers:sle}=rt(),ile=Wu(),gPe=require("util"),ole=require("child_process"),ale=require("fs"),{execFile:cle}=ole,We;Hq.exports={enterPM2Mode:lle,start:wa,stop:$N,reload:wq,restart:Iq,list:VN,describe:Dq,connect:bo,kill:hle,startAllServices:mle,startService:KN,getUniqueServicesList:Lq,restartAllServices:ple,isServiceRegistered:Mq,reloadStopStart:vq,restartHdb:Pq,deleteProcess:fle,startClusteringProcesses:xq,startClusteringThreads:Bq,isHdbRestartRunning:_le,isClusteringRunning:gle,stopClustering:Ele,reloadClustering:Sle,expectedRestartOfChildren:Cq};var ah=!1;sle(e=>{e.type==="restart"&&Wg.initSync(!0)});function lle(){ah=!0}a(lle,"enterPM2Mode");function bo(){return We||(We=require("pm2")),new Promise((e,t)=>{We.connect((r,n)=>{r&&t(r),e(n)})})}a(bo,"connect");var Zr,ule=10,Nq;function wa(e,t=!1){if(ah)return dle(e);let r=cle(e.script,e.args.split(" "),e);r.name=e.name,r.config=e,r.on("exit",async i=>{let o=Zr.indexOf(r);o>-1&&Zr.splice(o,1),!Nq&&i!==0&&(e.restarts=(e.restarts||0)+1,e.restarts<ule&&(ale.existsSync(yo.getHubConfigPath())?wa(e):(await yo.generateNatsConfig(!0),wa(e),await new Promise(c=>setTimeout(c,3e3)),await yo.removeNatsConfig(et.PROCESS_DESCRIPTORS.CLUSTERING_HUB),await yo.removeNatsConfig(et.PROCESS_DESCRIPTORS.CLUSTERING_LEAF))))});let n={serviceName:e.name.replace(/ /g,"-")};function s(i){let o=Wg.get(et.CONFIG_PARAMS.CLUSTERING_LOGLEVEL),c=/\[\d+][^\[]+\[(\w+)]/g,l,u=0,f;for(;l=c.exec(i);){if(l.index&&Ro.LOG_LEVEL_HIERARCHY[o]>=Ro.LOG_LEVEL_HIERARCHY[f||"info"]){let h=f===Ro.LOG_LEVELS.ERR||f===Ro.LOG_LEVELS.WRN?cl.OUTPUTS.STDERR:cl.OUTPUTS.STDOUT;cl.logCustomLevel(f||"info",h,n,i.slice(u,l.index).trim())}let[d,_]=l;u=l.index+d.length,f=Ro.LOG_LEVELS[_]}if(Ro.LOG_LEVEL_HIERARCHY[o]>=Ro.LOG_LEVEL_HIERARCHY[f||"info"]){let d=f===Ro.LOG_LEVELS.ERR||f===Ro.LOG_LEVELS.WRN?cl.OUTPUTS.STDERR:cl.OUTPUTS.STDOUT;cl.logCustomLevel(f||"info",d,n,i.slice(u).trim())}}if(a(s,"extractMessages"),r.stdout.on("data",s),r.stderr.on("data",s),r.unref(),!Zr&&(Zr=[],!t)){let i=a(()=>{Nq=!0,Zr&&(Zr.map(o=>o.kill()),process.exit(0))},"kill_children");process.on("exit",i),process.on("SIGINT",i),process.on("SIGQUIT",i),process.on("SIGTERM",i)}Zr.push(r)}a(wa,"start");function dle(e){return new Promise(async(t,r)=>{try{await bo()}catch(n){r(n)}We.start(e,(n,s)=>{n&&(We.disconnect(),r(n)),We.disconnect(),t(s)})})}a(dle,"startWithPM2");function $N(e){if(!ah){for(let t of Zr||[])t.name===e&&(Zr.splice(Zr.indexOf(t),1),t.kill());return}return new Promise(async(t,r)=>{try{await bo()}catch(n){r(n)}We.stop(e,async(n,s)=>{n&&(We.disconnect(),r(n)),We.delete(e,(i,o)=>{i&&(We.disconnect(),r(n)),We.disconnect(),t(o)})})})}a($N,"stop");function wq(e){return new Promise(async(t,r)=>{try{await bo()}catch(n){r(n)}We.reload(e,(n,s)=>{n&&(We.disconnect(),r(n)),We.disconnect(),t(s)})})}a(wq,"reload");function Iq(e){if(!ah){Cq();for(let t of Zr||[])t.name===e&&t.kill()}return new Promise(async(t,r)=>{try{await bo()}catch(n){r(n)}We.restart(e,(n,s)=>{We.disconnect(),t(s)})})}a(Iq,"restart");function Cq(){for(let e of Zr||[])e.config&&(e.config.restarts=0)}a(Cq,"expectedRestartOfChildren");function fle(e){return new Promise(async(t,r)=>{try{await bo()}catch(n){r(n)}We.delete(e,(n,s)=>{n&&(We.disconnect(),r(n)),We.disconnect(),t(s)})})}a(fle,"deleteProcess");async function Pq(){await wa(Na.generateRestart())}a(Pq,"restartHdb");async function _le(){let e=await VN();for(let t in e)if(e[t].name===et.PROCESS_DESCRIPTORS.RESTART_HDB)return!0;return!1}a(_le,"isHdbRestartRunning");function VN(){return new Promise(async(e,t)=>{try{await bo()}catch(r){t(r)}We.list((r,n)=>{r&&(We.disconnect(),t(r)),We.disconnect(),e(n)})})}a(VN,"list");function Dq(e){return new Promise(async(t,r)=>{try{await bo()}catch(n){r(n)}We.describe(e,(n,s)=>{n&&(We.disconnect(),r(n)),We.disconnect(),t(s)})})}a(Dq,"describe");function hle(){if(!ah){for(let e of Zr||[])e.kill();Zr=[];return}return new Promise(async(e,t)=>{try{await bo()}catch(r){t(r)}We.killDaemon((r,n)=>{r&&(We.disconnect(),t(r)),We.disconnect(),e(n)})})}a(hle,"kill");async function mle(){try{await xq(),await Bq(),await wa(Na.generateAllServiceConfigs())}catch(e){throw We?.disconnect(),e}}a(mle,"startAllServices");async function KN(e,t=!1){try{let r;switch(e=e.toLowerCase(),e){case et.PROCESS_DESCRIPTORS.HDB.toLowerCase():r=Na.generateMainServerConfig();break;case et.PROCESS_DESCRIPTORS.CLUSTERING_INGEST_SERVICE.toLowerCase():r=Na.generateNatsIngestServiceConfig();break;case et.PROCESS_DESCRIPTORS.CLUSTERING_REPLY_SERVICE.toLowerCase():r=Na.generateNatsReplyServiceConfig();break;case et.PROCESS_DESCRIPTORS.CLUSTERING_HUB.toLowerCase():r=Na.generateNatsHubServerConfig(),await wa(r,t),await yo.removeNatsConfig(e);return;case et.PROCESS_DESCRIPTORS.CLUSTERING_LEAF.toLowerCase():r=Na.generateNatsLeafServerConfig(),await wa(r,t),await yo.removeNatsConfig(e);return;case et.PROCESS_DESCRIPTORS.CLUSTERING_UPGRADE_4_0_0.toLowerCase():r=Na.generateClusteringUpgradeV4ServiceConfig();break;default:throw new Error(`Start service called with unknown service config: ${e}`)}await wa(r)}catch(r){throw We?.disconnect(),r}}a(KN,"startService");async function Lq(){try{let e=await VN(),t={};for(let r=0,n=e.length;r<n;r++){let s=e[r];t[s.name]===void 0&&(t[s.name]={name:s.name,exec_mode:s.pm2_env.exec_mode})}return t}catch(e){throw We?.disconnect(),e}}a(Lq,"getUniqueServicesList");async function ple(e=[]){try{let t=!1,r=await Lq();for(let n=0,s=Object.values(r).length;n<s;n++){let o=Object.values(r)[n].name;e.includes(o)||(o===et.PROCESS_DESCRIPTORS.HDB?t=!0:await Iq(o))}t&&await vq(et.PROCESS_DESCRIPTORS.HDB)}catch(t){throw We?.disconnect(),t}}a(ple,"restartAllServices");async function Mq(e){if(Zr?.find(r=>r.name===e))return!0;let t=await ile.getHDBProcessInfo();return t.core.length&&t.core[0]?.parent==="PM2"}a(Mq,"isServiceRegistered");async function vq(e){let t=Wg.get(et.CONFIG_PARAMS.THREADS_COUNT)??Wg.get(et.CONFIG_PARAMS.THREADS),r=await Dq(e),n=rle.isEmptyOrZeroLength(r)?0:r.length;t!==n?(await $N(e),await KN(e)):e===et.PROCESS_DESCRIPTORS.HDB?await Pq():await wq(e)}a(vq,"reloadStopStart");var Uq;async function xq(e=!1){for(let t in et.CLUSTERING_PROCESSES){let r=et.CLUSTERING_PROCESSES[t];await KN(r,e)}}a(xq,"startClusteringProcesses");async function Bq(){Uq=Oq(et.LAUNCH_SERVICE_SCRIPTS.NATS_REPLY_SERVICE,{name:et.PROCESS_DESCRIPTORS.CLUSTERING_REPLY_SERVICE});try{await Yg.deleteLocalStream("__HARPERDB_WORK_QUEUE__")}catch{}await Yg.updateLocalStreams();let e=await nle.getAllNodeRecords();for(let t=0,r=e.length;t<r;t++)if(e[t].system_info?.hdb_version===et.PRE_4_0_0_VERSION){cl.info("Starting clustering upgrade 4.0.0 process"),Oq(et.LAUNCH_SERVICE_SCRIPTS.NODES_UPGRADE_4_0_0,{name:"Upgrade-4-0-0"});break}}a(Bq,"startClusteringThreads");async function Ele(){for(let e in et.CLUSTERING_PROCESSES)if(e!==et.CLUSTERING_PROCESSES.CLUSTERING_INGEST_PROC_DESCRIPTOR)if(e===et.CLUSTERING_PROCESSES.CLUSTERING_REPLY_SERVICE_DESCRIPTOR)await Uq.terminate();else{let t=et.CLUSTERING_PROCESSES[e];await $N(t)}}a(Ele,"stopClustering");async function gle(){for(let e in et.CLUSTERING_PROCESSES){let t=et.CLUSTERING_PROCESSES[e];if(await Mq(t)===!1)return!1}return!0}a(gle,"isClusteringRunning");async function Sle(){await yo.generateNatsConfig(!0),await Yg.reloadNATSHub(),await Yg.reloadNATSLeaf(),await yo.removeNatsConfig(et.PROCESS_DESCRIPTORS.CLUSTERING_HUB.toLowerCase()),await yo.removeNatsConfig(et.PROCESS_DESCRIPTORS.CLUSTERING_LEAF.toLowerCase())}a(Sle,"reloadClustering")});var zN={};Ue(zN,{compactOnStart:()=>Tle,copyDb:()=>Vq});async function Tle(){Ia.notify("Running compact on start"),console.log("Running compact on start");let e=(0,YN.get)(U.ROOTPATH),t=new Map,r=Xe();(0,WN.updateConfigValue)(U.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,zg.join)(e,"backup",n+".mdb"),o=(0,zg.join)(e,rc,n+"-copy.mdb"),c=0;try{c=await kq(n),console.log("Database",n,"before compact has a total record count of",c)}catch(l){Ia.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 Vq(n,o),console.log("Backing up",n,"to",i),await(0,ll.move)(s,i,{overwrite:!0})}try{sd()}catch(n){Ia.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,ll.move)(i,s,{overwrite:!0}),await(0,ll.remove)((0,zg.join)(e,rc,`${n}-copy.mdb-lock`));try{sd()}catch(n){Ia.error("Error resetting databases after backup",n),console.error("Error resetting databases after backup",n),process.exit(0)}}catch(n){Ia.error("Error compacting database, rolling back operation",n),console.error("Error compacting database, rolling back operation",n),(0,WN.updateConfigValue)(U.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,ll.move)(o,i,{overwrite:!0})}catch(c){console.error(c)}}throw sd(),n}for(let[n,{backup_dest:s,record_count:i}]of t){let o=!0,c=await kq(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
25
|
Total record count before compaction: ${i}, total after: ${c}.
|
|
26
26
|
Database backup has not been removed and can be found here: ${s}`;Ia.error(l),console.error(l)}(0,YN.get)(U.STORAGE_COMPACTONSTARTKEEPBACKUP)===!0||o===!1||(console.log("Removing backup",s),await(0,ll.remove)(s))}}async function kq(e){let t=await(0,$q.describeSchema)({database:e}),r=0;for(let n in t)r+=t[n].record_count;return r}async function Vq(e,t){console.log("copyDb start");let r=Xe()[e],n;for(let d in r){n=r[d].primaryStore.rootStore;break}let s=n.dbisDb,i=n.auditStore,o=(0,Fq.open)(new Gq.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=Qg(),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 qq.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,lh);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=1e7,T=null;for(;E-- >0;)try{for(let N of _.getKeys({start:T,transaction:S}))try{T=N;let{value:v,version:k}=_.getEntry(N,{transaction:S});l=h.put(N,v,m?k:void 0),g++,S.openTimer&&(S.openTimer=0),R+=(N?.length||10)+v.length,u++>5e3&&(await l,console.log("copied",g,"entries",R,"bytes"),u=0)}catch(v){console.error("Error copying record",typeof N=="symbol"?"symbol":N,"from",e,"to",t,v)}console.log("finish copying, copied",g,"entries",R,"bytes");return}catch{if(typeof T=="string"){if(T==="z")return console.error("Reached end of dbi",T,"for",e,"to",t);T=T.slice(0,-2)+"z"}else if(typeof T=="number")T++;else return console.error("Unknown key type",T,"for",e,"to",t)}}a(d,"copyDbi"),await l,console.log("copied database "+e+" to "+t)}finally{f.done(),o.close()}}var Fq,zg,ll,YN,Gq,qq,jg,$q,WN,Ia,jN=ye(()=>{Me();Fq=require("lmdb"),zg=require("path"),ll=require("fs-extra"),YN=M(ue()),Gq=M(Lf()),qq=M(Df()),jg=M(Ut());H();eo();$q=M(oo()),WN=M(Ot()),Ia=M(j());a(Tle,"compactOnStart");a(kq,"getTotalDBRecordCount");a(Vq,"copyDb")});var od=P((IPe,Jq)=>{"use strict";var Ale=require("minimist"),{isMainThread:JN,parentPort:dh,threadId:OPe}=require("worker_threads"),nt=(H(),D($)),Pi=j(),XN=oe(),Xg=$g(),Jg=rr(),NPe=It(),zq=Ot(),Js=ch(),Kq=Wu(),{compactOnStart:Rle}=(jN(),D(zN)),yle=nc(),{restartWorkers:Zg,onMessageByType:ble}=rt(),{handleHDBError:Ole,hdb_errors:Nle}=me(),{HTTP_STATUS_CODES:wle}=Nle,fh=ue(),{sendOperationToNode:Yq,getThisNodeName:Ile,monitorNodeCAs:Cle}=(fs(),D(Ea)),{getHDBNodeTable:wPe}=(Yc(),D(lO));fh.initSync();var uh=`Restarting HarperDB. This may take up to ${nt.RESTART_TIMEOUT_MS/1e3} seconds.`,Ple="Restart is not available from the CLI when running in non-pm2 mode. Either call restart from the API or stop and start HarperDB.",Wq="Clustering is not enabled so cannot be restarted",Dle="Invalid service",id,gs;Jq.exports={restart:jq,restartService:ZN};JN&&ble(nt.ITC_EVENT_TYPES.RESTART,async(e,t)=>{e.workerType?await ZN({service:e.workerType}):jq({operation:"restart"}),t.postMessage({type:"restart-complete"})});async function jq(e){gs=Object.keys(e).length===0,id=await Js.isServiceRegistered(nt.PROCESS_DESCRIPTORS.HDB);let t=Ale(process.argv);if(t.service){await ZN(t);return}if(gs&&!id){console.error(Ple);return}if(gs&&console.log(uh),id){Js.enterPM2Mode(),Pi.notify(uh);let r=yle(Object.keys(nt.CONFIG_PARAM_MAP),!0);return XN.isEmptyOrZeroLength(Object.keys(r))||zq.updateConfigValue(void 0,void 0,r,!0,!0),Lle(),uh}return JN?(Pi.notify(uh),fh.get(nt.CONFIG_PARAMS.STORAGE_COMPACTONSTART)&&await Rle(),process.env.HARPER_EXIT_ON_RESTART&&process.exit(0),setTimeout(()=>{Zg()},50)):dh.postMessage({type:nt.ITC_EVENT_TYPES.RESTART}),uh}a(jq,"restart");async function ZN(e){let{service:t}=e;if(nt.HDB_PROCESS_SERVICES[t]===void 0)throw Ole(new Error,Dle,wle.BAD_REQUEST,void 0,void 0,!0);if(Js.expectedRestartOfChildren(),id=await Js.isServiceRegistered(nt.PROCESS_DESCRIPTORS.HDB),!JN){e.replicated&&Cle(),dh.postMessage({type:nt.ITC_EVENT_TYPES.RESTART,workerType:t}),dh.ref(),await new Promise(s=>{dh.on("message",i=>{i.type==="restart-complete"&&(s(),dh.unref())})});let n;if(e.replicated){e.replicated=!1,n=[];for(let s of server.nodes){if(s.name===Ile())continue;let i;try{({job_id:i}=await Yq(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 Yq(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 nt.HDB_PROCESS_SERVICES.clustering:if(!fh.get(nt.CONFIG_PARAMS.CLUSTERING_ENABLED)){r=Wq;break}gs&&console.log("Restarting clustering"),Pi.notify("Restarting clustering"),await Qq();break;case nt.HDB_PROCESS_SERVICES.clustering_config:case nt.HDB_PROCESS_SERVICES["clustering config"]:if(!fh.get(nt.CONFIG_PARAMS.CLUSTERING_ENABLED)){r=Wq;break}gs&&console.log("Restarting clustering_config"),Pi.notify("Restarting clustering_config"),await Js.reloadClustering();break;case"custom_functions":case"custom functions":case nt.HDB_PROCESS_SERVICES.harperdb:case nt.HDB_PROCESS_SERVICES.http_workers:case nt.HDB_PROCESS_SERVICES.http:if(gs&&!id){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}gs&&console.log("Restarting http_workers"),Pi.notify("Restarting http_workers"),gs?await Js.restart(nt.PROCESS_DESCRIPTORS.HDB):await Zg("http");break;default:r=`Unrecognized service: ${t}`;break}return r?(Pi.error(r),gs&&console.error(r),r):(t==="custom_functions"&&(t="Custom Functions"),`Restarting ${t}`)}a(ZN,"restartService");async function Lle(){await Qq(),await Js.restart(nt.PROCESS_DESCRIPTORS.HDB),await XN.async_set_timeout(2e3),fh.get(nt.CONFIG_PARAMS.CLUSTERING_ENABLED)&&await QN(),gs&&(await Jg.closeConnection(),process.exit(0))}a(Lle,"restartPM2Mode");async function Qq(){if(!zq.getConfigFromFile(nt.CONFIG_PARAMS.CLUSTERING_ENABLED))return;if((await Kq.getHDBProcessInfo()).clustering.length===0)Pi.trace("Clustering not running, restart will start clustering services"),await Xg.generateNatsConfig(!0),await Js.startClusteringProcesses(),await Js.startClusteringThreads(),await QN(),gs&&await Jg.closeConnection();else{await Xg.generateNatsConfig(!0),id?(Pi.trace("Restart clustering restarting PM2 managed Hub and Leaf servers"),await Js.restart(nt.PROCESS_DESCRIPTORS.CLUSTERING_HUB),await Js.restart(nt.PROCESS_DESCRIPTORS.CLUSTERING_LEAF)):(await Kq.getHDBProcessInfo()).clustering.forEach(s=>{Pi.trace("Restart clustering killing process pid",s.pid),process.kill(s.pid)}),await XN.async_set_timeout(3e3),await QN(),await Jg.updateLocalStreams(),gs&&await Jg.closeConnection(),Pi.trace("Restart clustering restarting ingest and reply service threads");let t=Zg(nt.LAUNCH_SERVICE_SCRIPTS.NATS_INGEST_SERVICE),r=Zg(nt.LAUNCH_SERVICE_SCRIPTS.NATS_REPLY_SERVICE);await t,await r}}a(Qq,"restartClustering");async function QN(){await Xg.removeNatsConfig(nt.PROCESS_DESCRIPTORS.CLUSTERING_HUB),await Xg.removeNatsConfig(nt.PROCESS_DESCRIPTORS.CLUSTERING_LEAF)}a(QN,"removeNatsConfig")});var c$=P((DPe,a$)=>{"use strict";var PPe=require("lodash"),On=(H(),D($)),{handleHDBError:Xq,hdb_errors:Mle}=me(),{HDB_ERROR_MSGS:vle,HTTP_STATUS_CODES:Ule}=Mle,ew=j();a$.exports={getRolePermissions:Ble};var ul=Object.create(null),xle=a(e=>({key:e,perms:{}}),"perms_template_obj"),r$=a((e=!1)=>({describe:e,tables:{}}),"schema_perms_template"),n$=a((e=!1,t=!1,r=!1,n=!1)=>({[On.PERMS_CRUD_ENUM.READ]:e,[On.PERMS_CRUD_ENUM.INSERT]:t,[On.PERMS_CRUD_ENUM.UPDATE]:r,[On.PERMS_CRUD_ENUM.DELETE]:n}),"permissions_template"),tw=a((e=!1,t=!1,r=!1,n=!1,s=!1)=>({attribute_permissions:[],describe:e,...n$(t,r,n,s)}),"table_perms_template"),Zq=a((e,t=n$())=>({attribute_name:e,describe:o$(t),[_h]:t[_h],[rw]:t[rw],[nw]:t[nw]}),"attr_perms_template"),e$=a((e,t=!1)=>({attribute_name:e,describe:t,[_h]:t}),"timestamp_attr_perms_template"),{READ:_h,INSERT:rw,UPDATE:nw}=On.PERMS_CRUD_ENUM,s$=Object.values(On.PERMS_CRUD_ENUM),i$=[_h,rw,nw];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[On.SYSTEM_SCHEMA_NAME],t=e.role;let n=JSON.stringify([e.__updatedtime__,r]);if(ul[t]&&ul[t].key===n)return ul[t].perms;let s=Hle(e,r);return ul[t]?ul[t].key=n:ul[t]=xle(n),ul[t].perms=s,s}catch(r){if(!e[On.TIME_STAMP_NAMES_ENUM.UPDATED_TIME]||e[On.TIME_STAMP_NAMES_ENUM.UPDATED_TIME]<On.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 ew.error(n),ew.debug(r),Xq(new Error,vle.OUTDATED_PERMS_TRANSLATION_ERROR,Ule.BAD_REQUEST)}else{let n=`There was an error while translating role permissions for role: ${t}.
|
|
27
|
-
${r.stack}`;throw ew.error(n),Xq(new Error)}}}a(Ble,"getRolePermissions");function Hle(e,t){let r=Object.create(null);r.super_user=!1;let n=e.permission;r[On.SYSTEM_SCHEMA_NAME]=n[On.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]=kle(t[i]);return}r[i]=r$(),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=Fle(c,l);r[i].describe||s$.forEach(f=>{u[f]&&(r[i].describe=!0)}),r[i].tables[o]=u}else r[i].tables[o]=tw()})):Object.keys(t[i]).forEach(o=>{r[i].tables[o]=tw()})}),r}a(Hle,"translateRolePermissions");function kle(e){let t=r$(!0);return Object.keys(e).forEach(r=>{t.tables[r]=tw(!0,!0,!0,!0,!0)}),t}a(kle,"createStructureUserPermissions");function Fle(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 On.TIME_STAMP_NAMES.includes(d)&&(_=e$(d,f[_h])),u[d]=_,u},{}),o=t.primaryKey||t.hash_attribute,c=!!i[o],l=Zq(o);return t.attributes.forEach(({attribute:u})=>{if(i[u]){let f=i[u];f.describe=o$(f),s.attribute_permissions.push(f),c||Gle(f,l)}else if(u!==o){let f;On.TIME_STAMP_NAMES.includes(u)?f=e$(u):f=Zq(u),s.attribute_permissions.push(f)}}),c||s.attribute_permissions.push(l),s.describe=t$(s),s}else return e.describe=t$(e),e}a(Fle,"getTableAttrPerms");function t$(e){return s$.filter(t=>e[t]).length>0}a(t$,"getSchemaTableDescribePerm");function o$(e){return i$.filter(t=>e[t]).length>0}a(o$,"getAttributeDescribePerm");function Gle(e,t){i$.forEach(r=>{e[r]&&!t[r]&&(t[r]=!0,t.describe=!0)})}a(Gle,"checkForHashPerms")});var hh={};Ue(hh,{authentication:()=>m$,bypassAuth:()=>jle,login:()=>Jle,logout:()=>Xle,start:()=>Qle});function jle(){h$=!0}async function m$(e,t){let r=e.headers.asObject,n=r.authorization,s=r.cookie,i=r.origin,o=[];try{if(i){let h=e.isOperationsServer?Kle?Vle:[]:$le?qle:[];if(h.includes(i)||h.includes("*")){if(e.method==="OPTIONS"){let m=en.get(U.HTTP_CORSACCESSCONTROLALLOWHEADERS)??"Accept, Content-Type, Authorization",S=new fo([["Access-Control-Allow-Methods","POST, GET, PUT, DELETE, PATCH, OPTIONS"],["Access-Control-Allow-Headers",m],["Access-Control-Allow-Origin",i]]);return eS&&S.set("Access-Control-Allow-Credentials","true"),{status:200,headers:S}}o.push("Access-Control-Allow-Origin",i),eS&&o.push("Access-Control-Allow-Credentials","true")}}let l,u;if(eS){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 l$.get(l);break}e.session=u||(u={})}let f=a((h,m,S)=>{let g=new ad.AuthAuditLog(h,m,$o.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===Ls.SUCCESS?sw.notify(g):sw.error(g)},"authAuditLog");if(!e.authorized&&e.mtlsConfig&&e.peerCertificate.subject&&e?._nodeRequest?.socket?.authorizationError&&sw.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 ze.getUser(h,null,e),f(h,Ls.SUCCESS,"mTLS")):(0,ad.debug)("HTTPS/WSS mTLS authorized connection (mTLS did not authorize a user)","from",e.ip)}let d;if(!e.user)if(n){if(d=dl.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 ze.getUser(g,R,e):null;break;case"Bearer":try{d=await Fb(S)}catch(N){if(N.message==="invalid token")try{return await vE(S),c({status:-1})}catch{throw N}}break}}catch(E){return Wle&&(dl.get(S)||(dl.set(S,S),f(g,Ls.FAILURE,m))),c({status:401,body:ra({error:E.message},e)})}dl.set(n,d),Yle&&f(d.username,Ls.SUCCESS,m)}e.user=d}else u?.user?e.user=await ze.getUser(u.user,null,e):(h$&&(e.ip?.includes("127.0.0.")||e.ip=="::1")||e?._nodeRequest?.socket?.server?._pipeName&&e.ip===void 0)&&(e.user=await(0,d$.getSuperUser)());eS&&(e.session.update=function(h){let m=en.get(U.AUTHENTICATION_COOKIE_EXPIRES);if(!l){l=(0,f$.v4)();let S=en.get(U.AUTHENTICATION_COOKIE_DOMAINS),g=m?new Date(Date.now()+(0,iw.convertToMS)(m)).toUTCString():zle,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,l$.put(h,{expiresAt:m?Date.now()+(0,iw.convertToMS)(m):void 0})},e.login=async function(h,m){let S=e.user=await ze.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")&&fi.loginPath?(_.status=302,_.headers.set("Location",fi.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 fo);for(let d=0;d<u;){let _=o[d++];f.set(_,o[d++])}}return o=null,l}a(c,"applyResponseHeaders")}function Qle({server:e,port:t,securePort:r}){e.http(m$,t||r?{port:t,securePort:r}:{port:"all"}),u$||(u$=!0,setInterval(()=>{dl=new Map},en.get(U.AUTHENTICATION_CACHETTL)).unref(),_$.user.addListener(()=>{dl=new Map}))}async function Jle(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 Xle(e){if(!e.baseRequest.session)throw new Error("No session for logout");return await e.baseRequest.session.update({user:null}),"Logout successful"}var d$,f$,en,ad,_$,iw,sw,qle,$le,Vle,Kle,l$,eS,h$,Yle,Wle,zle,dl,u$,tS=ye(()=>{d$=M(Sn());qr();Jl();bu();Me();f$=require("uuid"),en=M(ue());H();ad=M(j()),_$=M(jf());S_();iw=M(oe());Qi();sw=(0,ad.loggerWithTag)("auth-event");en.initSync();qle=en.get(U.HTTP_CORSACCESSLIST),$le=en.get(U.HTTP_CORS),Vle=en.get(U.OPERATIONSAPI_NETWORK_CORSACCESSLIST),Kle=en.get(U.OPERATIONSAPI_NETWORK_CORS),l$=ut({table:"hdb_session",database:"system",attributes:[{name:"id",isPrimaryKey:!0},{name:"user"}]}),eS=en.get(U.AUTHENTICATION_ENABLESESSIONS)??!0,h$=process.env.AUTHENTICATION_AUTHORIZELOCAL??en.get(U.AUTHENTICATION_AUTHORIZELOCAL)??process.env.DEV_MODE,Yle=en.get(U.LOGGING_AUDITAUTHEVENTS_LOGSUCCESSFUL)??!1,Wle=en.get(U.LOGGING_AUDITAUTHEVENTS_LOGFAILED)??!1,zle="Tue, 01 Oct 8307 19:33:20 GMT",dl=new Map;ze.onInvalidatedUser(()=>{dl=new Map});a(jle,"bypassAuth");a(m$,"authentication");a(Qle,"start");a(Jle,"login");a(Xle,"logout")});var R$=P((GPe,A$)=>{"use strict";var Ne=require("joi"),p$=require("fs-extra"),E$=require("path"),Qn=tt(),g$=ue(),S$=(H(),D($)),T$=j(),{hdb_errors:Zle}=me(),{HDB_ERROR_MSGS:tn}=Zle,Oo=/^[a-zA-Z0-9-_]+$/,eue=/^[a-zA-Z0-9-_]+$/;A$.exports={getDropCustomFunctionValidator:rue,setCustomFunctionValidator:nue,addComponentValidator:aue,dropCustomFunctionProjectValidator:cue,packageComponentValidator:lue,deployComponentValidator:uue,setComponentFileValidator:sue,getComponentFileValidator:oue,dropComponentFileValidator:iue,addSSHKeyValidator:due,updateSSHKeyValidator:fue,deleteSSHKeyValidator:_ue,setSSHKnownHostsValidator:hue};function rS(e,t,r){try{let n=g$.get(S$.CONFIG_PARAMS.COMPONENTSROOT),s=E$.join(n,t);return p$.existsSync(s)?e?t:r.message(tn.PROJECT_EXISTS):e?r.message(tn.NO_PROJECT):t}catch(n){return T$.error(n),r.message(tn.VALIDATION_ERR)}}a(rS,"checkProjectExists");function mh(e,t){return e.includes("..")?t.message("Invalid file path"):e}a(mh,"checkFilePath");function tue(e,t,r,n){try{let s=g$.get(S$.CONFIG_PARAMS.COMPONENTSROOT),i=E$.join(s,e,t,r+".js");return p$.existsSync(i)?r:n.message(tn.NO_FILE)}catch(s){return T$.error(s),n.message(tn.VALIDATION_ERR)}}a(tue,"checkFileExists");function rue(e){let t=Ne.object({project:Ne.string().pattern(Oo).custom(rS.bind(null,!0)).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),type:Ne.string().valid("helpers","routes").required(),file:Ne.string().pattern(Oo).custom(tue.bind(null,e.project,e.type)).custom(mh).required().messages({"string.pattern.base":tn.BAD_FILE_NAME})});return Qn.validateBySchema(e,t)}a(rue,"getDropCustomFunctionValidator");function nue(e){let t=Ne.object({project:Ne.string().pattern(Oo).custom(rS.bind(null,!0)).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),type:Ne.string().valid("helpers","routes").required(),file:Ne.string().custom(mh).required(),function_content:Ne.string().required()});return Qn.validateBySchema(e,t)}a(nue,"setCustomFunctionValidator");function sue(e){let t=Ne.object({project:Ne.string().pattern(Oo).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),file:Ne.string().custom(mh).required(),payload:Ne.string().allow("").optional(),encoding:Ne.string().valid("utf8","ASCII","binary","hex","base64","utf16le","latin1","ucs2").optional()});return Qn.validateBySchema(e,t)}a(sue,"setComponentFileValidator");function iue(e){let t=Ne.object({project:Ne.string().pattern(Oo).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),file:Ne.string().custom(mh).optional()});return Qn.validateBySchema(e,t)}a(iue,"dropComponentFileValidator");function oue(e){let t=Ne.object({project:Ne.string().required(),file:Ne.string().custom(mh).required(),encoding:Ne.string().valid("utf8","ASCII","binary","hex","base64","utf16le","latin1","ucs2").optional()});return Qn.validateBySchema(e,t)}a(oue,"getComponentFileValidator");function aue(e){let t=Ne.object({project:Ne.string().pattern(Oo).custom(rS.bind(null,!1)).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME})});return Qn.validateBySchema(e,t)}a(aue,"addComponentValidator");function cue(e){let t=Ne.object({project:Ne.string().pattern(Oo).custom(rS.bind(null,!0)).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME})});return Qn.validateBySchema(e,t)}a(cue,"dropCustomFunctionProjectValidator");function lue(e){let t=Ne.object({project:Ne.string().pattern(Oo).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),skip_node_modules:Ne.boolean(),skip_symlinks:Ne.boolean()});return Qn.validateBySchema(e,t)}a(lue,"packageComponentValidator");function uue(e){let t=Ne.object({project:Ne.string().pattern(Oo).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 Qn.validateBySchema(e,t)}a(uue,"deployComponentValidator");function due(e){let t=Ne.object({name:Ne.string().pattern(eue).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 Qn.validateBySchema(e,t)}a(due,"addSSHKeyValidator");function fue(e){let t=Ne.object({name:Ne.string().required(),key:Ne.string().required()});return Qn.validateBySchema(e,t)}a(fue,"updateSSHKeyValidator");function _ue(e){let t=Ne.object({name:Ne.string().required()});return Qn.validateBySchema(e,t)}a(_ue,"deleteSSHKeyValidator");function hue(e){let t=Ne.object({known_hosts:Ne.string().required()});return Qn.validateBySchema(e,t)}a(hue,"setSSHKnownHostsValidator")});var gh=P(($Pe,w$)=>{"use strict";var nS=require("joi"),Ca=require("path"),cd=require("fs-extra"),{exec:mue,spawn:pue}=require("child_process"),Eue=require("util"),gue=Eue.promisify(mue),ld=(H(),D($)),{PACKAGE_ROOT:Sue}=pt(),{handleHDBError:ph,hdb_errors:Tue}=me(),{HTTP_STATUS_CODES:Eh}=Tue,fl=ue(),Aue=tt(),Pa=j(),{once:Rue}=require("events");fl.initSync();var ow=fl.get(ld.CONFIG_PARAMS.COMPONENTSROOT),y$="npm install --force --omit=dev --json",yue=`${y$} --dry-run`,bue=fl.get(ld.CONFIG_PARAMS.ROOTPATH),sS=Ca.join(bue,"ssh");w$.exports={installModules:Iue,auditModules:Cue,installAllRootModules:Oue,uninstallRootModule:Nue,linkHarperdb:wue,runCommand:ud};async function Oue(e=!1,t=fl.get(ld.CONFIG_PARAMS.ROOTPATH)){await iS();let r=!1,n=process.env;cd.pathExistsSync(sS)&&cd.readdirSync(sS).forEach(s=>{s.includes(".key")&&!r&&(n={GIT_SSH_COMMAND:"ssh -F "+Ca.join(sS,"config")+" -o UserKnownHostsFile="+Ca.join(sS,"known_hosts"),...process.env},r=!0)});try{let s=fl.get(ld.CONFIG_PARAMS.ROOTPATH),i=Ca.join(s,"node_modules","harperdb");cd.lstatSync(i).isSymbolicLink()&&cd.unlinkSync(i)}catch(s){s.code!=="ENOENT"&&Pa.error("Error removing symlink:",s)}await ud(e?"npm install --force --ignore-scripts --no-bin-links":"npm install --force --no-bin-links",t,n)}a(Oue,"installAllRootModules");async function Nue(e){await ud(`npm uninstall ${e}`,fl.get(ld.CONFIG_PARAMS.ROOTPATH))}a(Nue,"uninstallRootModule");async function wue(){await iS(),await ud(`npm link ${Sue}`,fl.get(ld.CONFIG_PARAMS.ROOTPATH))}a(wue,"linkHarperdb");async function ud(e,t=void 0,r=process.env){Pa.debug({tagName:"npm_run_command"},`running command: \`${e}\``);let n=pue(e,{shell:!0,cwd:t,env:r,stdio:["ignore","pipe","pipe"]}),s="",i="";n.stdout.on("data",c=>{let l=c.toString();Pa.debug({tagName:"npm_run_command:stdout"},l),s+=l}),n.stderr.on("data",c=>{let l=c.toString();Pa.error({tagName:"npm_run_command:stderr"},l),i+=l});let[o]=await Rue(n,"close");if(o!==0)throw new Error(`Command \`${e}\` exited with code ${o}.${i===""?"":` Error: ${i}`}`);return s||void 0}a(ud,"runCommand");async function Iue(e){let t="install_node_modules is deprecated. Dependencies are automatically installed on deploy, and install_node_modules can lead to inconsistent behavior";Pa.warn(t,e.projects);let r=N$(e);if(r)throw ph(r,r.message,Eh.BAD_REQUEST);let{projects:n,dry_run:s}=e,i=s===!0?yue:y$;await iS(),await O$(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=Ca.join(ow,u),d,_=null;try{let{stdout:h,stderr:m}=await gue(i,{cwd:f});d=h?h.replace(`
|
|
27
|
+
${r.stack}`;throw ew.error(n),Xq(new Error)}}}a(Ble,"getRolePermissions");function Hle(e,t){let r=Object.create(null);r.super_user=!1;let n=e.permission;r[On.SYSTEM_SCHEMA_NAME]=n[On.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]=kle(t[i]);return}r[i]=r$(),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=Fle(c,l);r[i].describe||s$.forEach(f=>{u[f]&&(r[i].describe=!0)}),r[i].tables[o]=u}else r[i].tables[o]=tw()})):Object.keys(t[i]).forEach(o=>{r[i].tables[o]=tw()})}),r}a(Hle,"translateRolePermissions");function kle(e){let t=r$(!0);return Object.keys(e).forEach(r=>{t.tables[r]=tw(!0,!0,!0,!0,!0)}),t}a(kle,"createStructureUserPermissions");function Fle(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 On.TIME_STAMP_NAMES.includes(d)&&(_=e$(d,f[_h])),u[d]=_,u},{}),o=t.primaryKey||t.hash_attribute,c=!!i[o],l=Zq(o);return t.attributes.forEach(({attribute:u})=>{if(i[u]){let f=i[u];f.describe=o$(f),s.attribute_permissions.push(f),c||Gle(f,l)}else if(u!==o){let f;On.TIME_STAMP_NAMES.includes(u)?f=e$(u):f=Zq(u),s.attribute_permissions.push(f)}}),c||s.attribute_permissions.push(l),s.describe=t$(s),s}else return e.describe=t$(e),e}a(Fle,"getTableAttrPerms");function t$(e){return s$.filter(t=>e[t]).length>0}a(t$,"getSchemaTableDescribePerm");function o$(e){return i$.filter(t=>e[t]).length>0}a(o$,"getAttributeDescribePerm");function Gle(e,t){i$.forEach(r=>{e[r]&&!t[r]&&(t[r]=!0,t.describe=!0)})}a(Gle,"checkForHashPerms")});var hh={};Ue(hh,{authentication:()=>m$,bypassAuth:()=>jle,login:()=>Jle,logout:()=>Xle,start:()=>Qle});function jle(){h$=!0}async function m$(e,t){let r=e.headers.asObject,n=r.authorization,s=r.cookie,i=r.origin,o=[];try{if(i){let h=e.isOperationsServer?Kle?Vle:[]:$le?qle:[];if(h.includes(i)||h.includes("*")){if(e.method==="OPTIONS"){let m=en.get(U.HTTP_CORSACCESSCONTROLALLOWHEADERS)??"Accept, Content-Type, Authorization",S=new fo([["Access-Control-Allow-Methods","POST, GET, PUT, DELETE, PATCH, OPTIONS"],["Access-Control-Allow-Headers",m],["Access-Control-Allow-Origin",i]]);return eS&&S.set("Access-Control-Allow-Credentials","true"),{status:200,headers:S}}o.push("Access-Control-Allow-Origin",i),eS&&o.push("Access-Control-Allow-Credentials","true")}}let l,u;if(eS){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 l$.get(l);break}e.session=u||(u={})}let f=a((h,m,S)=>{let g=new ad.AuthAuditLog(h,m,$o.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===Ls.SUCCESS?sw.notify(g):sw.error(g)},"authAuditLog");if(!e.authorized&&e.mtlsConfig&&e.peerCertificate.subject&&e?._nodeRequest?.socket?.authorizationError&&sw.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 ze.getUser(h,null,e),f(h,Ls.SUCCESS,"mTLS")):(0,ad.debug)("HTTPS/WSS mTLS authorized connection (mTLS did not authorize a user)","from",e.ip)}let d;if(!e.user)if(n){if(d=dl.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 ze.getUser(g,R,e):null;break;case"Bearer":try{d=await Fb(S)}catch(N){if(N.message==="invalid token")try{return await vE(S),c({status:-1})}catch{throw N}}break}}catch(E){return Wle&&(dl.get(S)||(dl.set(S,S),f(g,Ls.FAILURE,m))),c({status:401,body:ra({error:E.message},e)})}dl.set(n,d),Yle&&f(d.username,Ls.SUCCESS,m)}e.user=d}else u?.user?e.user=await ze.getUser(u.user,null,e):(h$&&(e.ip?.includes("127.0.0.")||e.ip=="::1")||e?._nodeRequest?.socket?.server?._pipeName&&e.ip===void 0)&&(e.user=await(0,d$.getSuperUser)());eS&&(e.session.update=function(h){let m=en.get(U.AUTHENTICATION_COOKIE_EXPIRES);if(!l){l=(0,f$.v4)();let S=en.get(U.AUTHENTICATION_COOKIE_DOMAINS),g=m?new Date(Date.now()+(0,iw.convertToMS)(m)).toUTCString():zle,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,l$.put(h,{expiresAt:m?Date.now()+(0,iw.convertToMS)(m):void 0})},e.login=async function(h,m){let S=e.user=await ze.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")&&fi.loginPath?(_.status=302,_.headers.set("Location",fi.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 fo);for(let d=0;d<u;){let _=o[d++];f.set(_,o[d++])}}return o=null,l}a(c,"applyResponseHeaders")}function Qle({server:e,port:t,securePort:r}){e.http(m$,t||r?{port:t,securePort:r}:{port:"all"}),u$||(u$=!0,setInterval(()=>{dl=new Map},en.get(U.AUTHENTICATION_CACHETTL)).unref(),_$.user.addListener(()=>{dl=new Map}))}async function Jle(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 Xle(e){if(!e.baseRequest.session)throw new Error("No session for logout");return await e.baseRequest.session.update({user:null}),"Logout successful"}var d$,f$,en,ad,_$,iw,sw,qle,$le,Vle,Kle,l$,eS,h$,Yle,Wle,zle,dl,u$,tS=ye(()=>{d$=M(Sn());qr();Jl();bu();Me();f$=require("uuid"),en=M(ue());H();ad=M(j()),_$=M(jf());S_();iw=M(oe());Qi();sw=(0,ad.loggerWithTag)("auth-event");en.initSync();qle=en.get(U.HTTP_CORSACCESSLIST),$le=en.get(U.HTTP_CORS),Vle=en.get(U.OPERATIONSAPI_NETWORK_CORSACCESSLIST),Kle=en.get(U.OPERATIONSAPI_NETWORK_CORS),l$=ut({table:"hdb_session",database:"system",attributes:[{name:"id",isPrimaryKey:!0},{name:"user"}]}),eS=en.get(U.AUTHENTICATION_ENABLESESSIONS)??!0,h$=process.env.AUTHENTICATION_AUTHORIZELOCAL??en.get(U.AUTHENTICATION_AUTHORIZELOCAL)??process.env.DEV_MODE,Yle=en.get(U.LOGGING_AUDITAUTHEVENTS_LOGSUCCESSFUL)??!1,Wle=en.get(U.LOGGING_AUDITAUTHEVENTS_LOGFAILED)??!1,zle="Tue, 01 Oct 8307 19:33:20 GMT",dl=new Map;ze.onInvalidatedUser(()=>{dl=new Map});a(jle,"bypassAuth");a(m$,"authentication");a(Qle,"start");a(Jle,"login");a(Xle,"logout")});var R$=P((GPe,A$)=>{"use strict";var Ne=require("joi"),p$=require("fs-extra"),E$=require("path"),Qn=tt(),g$=ue(),S$=(H(),D($)),T$=j(),{hdb_errors:Zle}=me(),{HDB_ERROR_MSGS:tn}=Zle,Oo=/^[a-zA-Z0-9-_]+$/,eue=/^[a-zA-Z0-9-_]+$/;A$.exports={getDropCustomFunctionValidator:rue,setCustomFunctionValidator:nue,addComponentValidator:aue,dropCustomFunctionProjectValidator:cue,packageComponentValidator:lue,deployComponentValidator:uue,setComponentFileValidator:sue,getComponentFileValidator:oue,dropComponentFileValidator:iue,addSSHKeyValidator:due,updateSSHKeyValidator:fue,deleteSSHKeyValidator:_ue,setSSHKnownHostsValidator:hue};function rS(e,t,r){try{let n=g$.get(S$.CONFIG_PARAMS.COMPONENTSROOT),s=E$.join(n,t);return p$.existsSync(s)?e?t:r.message(tn.PROJECT_EXISTS):e?r.message(tn.NO_PROJECT):t}catch(n){return T$.error(n),r.message(tn.VALIDATION_ERR)}}a(rS,"checkProjectExists");function mh(e,t){return e.includes("..")?t.message("Invalid file path"):e}a(mh,"checkFilePath");function tue(e,t,r,n){try{let s=g$.get(S$.CONFIG_PARAMS.COMPONENTSROOT),i=E$.join(s,e,t,r+".js");return p$.existsSync(i)?r:n.message(tn.NO_FILE)}catch(s){return T$.error(s),n.message(tn.VALIDATION_ERR)}}a(tue,"checkFileExists");function rue(e){let t=Ne.object({project:Ne.string().pattern(Oo).custom(rS.bind(null,!0)).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),type:Ne.string().valid("helpers","routes").required(),file:Ne.string().pattern(Oo).custom(tue.bind(null,e.project,e.type)).custom(mh).required().messages({"string.pattern.base":tn.BAD_FILE_NAME})});return Qn.validateBySchema(e,t)}a(rue,"getDropCustomFunctionValidator");function nue(e){let t=Ne.object({project:Ne.string().pattern(Oo).custom(rS.bind(null,!0)).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),type:Ne.string().valid("helpers","routes").required(),file:Ne.string().custom(mh).required(),function_content:Ne.string().required()});return Qn.validateBySchema(e,t)}a(nue,"setCustomFunctionValidator");function sue(e){let t=Ne.object({project:Ne.string().pattern(Oo).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),file:Ne.string().custom(mh).required(),payload:Ne.string().allow("").optional(),encoding:Ne.string().valid("utf8","ASCII","binary","hex","base64","utf16le","latin1","ucs2").optional()});return Qn.validateBySchema(e,t)}a(sue,"setComponentFileValidator");function iue(e){let t=Ne.object({project:Ne.string().pattern(Oo).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),file:Ne.string().custom(mh).optional()});return Qn.validateBySchema(e,t)}a(iue,"dropComponentFileValidator");function oue(e){let t=Ne.object({project:Ne.string().required(),file:Ne.string().custom(mh).required(),encoding:Ne.string().valid("utf8","ASCII","binary","hex","base64","utf16le","latin1","ucs2").optional()});return Qn.validateBySchema(e,t)}a(oue,"getComponentFileValidator");function aue(e){let t=Ne.object({project:Ne.string().pattern(Oo).custom(rS.bind(null,!1)).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME})});return Qn.validateBySchema(e,t)}a(aue,"addComponentValidator");function cue(e){let t=Ne.object({project:Ne.string().pattern(Oo).custom(rS.bind(null,!0)).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME})});return Qn.validateBySchema(e,t)}a(cue,"dropCustomFunctionProjectValidator");function lue(e){let t=Ne.object({project:Ne.string().pattern(Oo).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),skip_node_modules:Ne.boolean(),skip_symlinks:Ne.boolean()});return Qn.validateBySchema(e,t)}a(lue,"packageComponentValidator");function uue(e){let t=Ne.object({project:Ne.string().pattern(Oo).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 Qn.validateBySchema(e,t)}a(uue,"deployComponentValidator");function due(e){let t=Ne.object({name:Ne.string().pattern(eue).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 Qn.validateBySchema(e,t)}a(due,"addSSHKeyValidator");function fue(e){let t=Ne.object({name:Ne.string().required(),key:Ne.string().required()});return Qn.validateBySchema(e,t)}a(fue,"updateSSHKeyValidator");function _ue(e){let t=Ne.object({name:Ne.string().required()});return Qn.validateBySchema(e,t)}a(_ue,"deleteSSHKeyValidator");function hue(e){let t=Ne.object({known_hosts:Ne.string().required()});return Qn.validateBySchema(e,t)}a(hue,"setSSHKnownHostsValidator")});var gh=P(($Pe,w$)=>{"use strict";var nS=require("joi"),Ca=require("path"),cd=require("fs-extra"),{exec:mue,spawn:pue}=require("child_process"),Eue=require("util"),gue=Eue.promisify(mue),ld=(H(),D($)),{PACKAGE_ROOT:Sue}=pt(),{handleHDBError:ph,hdb_errors:Tue}=me(),{HTTP_STATUS_CODES:Eh}=Tue,fl=ue(),Aue=tt(),Pa=j(),{once:Rue}=require("events");fl.initSync();var ow=fl.get(ld.CONFIG_PARAMS.COMPONENTSROOT),y$="npm install --force --omit=dev --json",yue=`${y$} --dry-run`,bue=fl.get(ld.CONFIG_PARAMS.ROOTPATH),sS=Ca.join(bue,"ssh");w$.exports={installModules:Iue,auditModules:Cue,installAllRootModules:Oue,uninstallRootModule:Nue,linkHarperdb:wue,runCommand:ud};async function Oue(e=!1,t=fl.get(ld.CONFIG_PARAMS.ROOTPATH)){await iS();let r=!1,n=process.env;cd.pathExistsSync(sS)&&cd.readdirSync(sS).forEach(s=>{s.includes(".key")&&!r&&(n={GIT_SSH_COMMAND:"ssh -F "+Ca.join(sS,"config")+" -o UserKnownHostsFile="+Ca.join(sS,"known_hosts"),...process.env},r=!0)});try{let s=fl.get(ld.CONFIG_PARAMS.ROOTPATH),i=Ca.join(s,"node_modules","harperdb");cd.lstatSync(i).isSymbolicLink()&&cd.unlinkSync(i)}catch(s){s.code!=="ENOENT"&&Pa.error("Error removing symlink:",s)}await ud(e?"npm install --force --ignore-scripts":"npm install --force",t,n)}a(Oue,"installAllRootModules");async function Nue(e){await ud(`npm uninstall ${e}`,fl.get(ld.CONFIG_PARAMS.ROOTPATH))}a(Nue,"uninstallRootModule");async function wue(){await iS(),await ud(`npm link ${Sue}`,fl.get(ld.CONFIG_PARAMS.ROOTPATH))}a(wue,"linkHarperdb");async function ud(e,t=void 0,r=process.env){Pa.debug({tagName:"npm_run_command"},`running command: \`${e}\``);let n=pue(e,{shell:!0,cwd:t,env:r,stdio:["ignore","pipe","pipe"]}),s="",i="";n.stdout.on("data",c=>{let l=c.toString();Pa.debug({tagName:"npm_run_command:stdout"},l),s+=l}),n.stderr.on("data",c=>{let l=c.toString();Pa.error({tagName:"npm_run_command:stderr"},l),i+=l});let[o]=await Rue(n,"close");if(o!==0)throw new Error(`Command \`${e}\` exited with code ${o}.${i===""?"":` Error: ${i}`}`);return s||void 0}a(ud,"runCommand");async function Iue(e){let t="install_node_modules is deprecated. Dependencies are automatically installed on deploy, and install_node_modules can lead to inconsistent behavior";Pa.warn(t,e.projects);let r=N$(e);if(r)throw ph(r,r.message,Eh.BAD_REQUEST);let{projects:n,dry_run:s}=e,i=s===!0?yue:y$;await iS(),await O$(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=Ca.join(ow,u),d,_=null;try{let{stdout:h,stderr:m}=await gue(i,{cwd:f});d=h?h.replace(`
|
|
28
28
|
`,""):null,_=m?m.replace(`
|
|
29
29
|
`,""):null}catch(h){h.stderr?o[u].npm_error=b$(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 Pa.info(`finished installModules with response ${o}`),o.warning=t,o}a(Iue,"installModules");function b$(e){let t='"error": {',r=e.indexOf('"error": {'),n=e.indexOf(`}
|
|
30
30
|
`);return r>-1&&n>-1?JSON.parse(e.substring(r+t.length-1,n+1)):e}a(b$,"parseNPMStdErr");async function Cue(e){Pa.info(`starting auditModules for request: ${e}`);let t=N$(e);if(t)throw ph(t,t.message,Eh.BAD_REQUEST);let{projects:r}=e;await iS(),await O$(r);let n={};for(let s=0,i=r.length;s<i;s++){let o=r[s],c=Ca.join(ow,o);n[o]={npm_output:null,npm_error:null};try{let l=await ud("npm audit --json",c);n[o].npm_output=JSON.parse(l)}catch(l){n[o].npm_error=b$(l.stderr)}}return Pa.info(`finished auditModules with response ${n}`),n}a(Cue,"auditModules");async function iS(){return await ud("npm -v"),!0}a(iS,"checkNPMInstalled");async function O$(e){if(!Array.isArray(e)||e.length===0)throw ph(new Error,"projects argument must be an array with at least 1 element",Eh.BAD_REQUEST,void 0,void 0,!0);let t=[],r=[];for(let n=0,s=e.length;n<s;n++){let i=e[n],o=Ca.join(ow,i.toString());if(!await cd.pathExists(o)){t.push(i);continue}let l=Ca.join(o,"package.json");await cd.pathExists(l)||r.push(i)}if(t.length>0)throw ph(new Error,`Unable to install project dependencies: custom function projects '${t.join(",")}' does not exist.`,Eh.BAD_REQUEST,void 0,void 0,!0);if(r.length>0)throw ph(new Error,`Unable to install project dependencies: custom function projects '${r.join(",")}' do not have a package.json file.`,Eh.BAD_REQUEST,void 0,void 0,!0)}a(O$,"checkProjectPaths");function N$(e){let t=nS.object({projects:nS.array().min(1).items(nS.string()).required(),dry_run:nS.boolean().default(!1)});return Aue.validateBySchema(e,t)}a(N$,"modulesValidator")});var cw=P((KPe,M$)=>{"use strict";var Ss=require("fs-extra"),Th=require("path"),Sh=j(),I$=oe(),{PACKAGE_ROOT:Pue}=pt(),aw=(H(),D($)),L$=ue(),Due=Ot();M$.exports=Lue;async function Lue(){let e=Mue(),t=L$.get(aw.CONFIG_PARAMS.ROOTPATH),r=Th.join(t,"package.json"),n={dependencies:{harperdb:"file:"+Pue}},s=Th.join(t,"node_modules");Ss.ensureDirSync(s);let i,o=!0,c=!1;try{i=Ss.readJsonSync(r)}catch(l){if(I$.isEmptyOrZeroLength(e))return;if(l.code!==aw.NODE_ERROR_CODES.ENOENT)throw l;o=!1}if(!I$.isEmptyOrZeroLength(e)){for(let{name:l,package:u}of e){let f=P$(u);n.dependencies[l]=f+u}if(!o){Sh.notify("Installing components"),await D$(r,n,null),await C$(t,e);return}for(let{name:l,package:u}of e){let f=i.dependencies[l],d=P$(u);if(f===void 0||f!==d+u){c=!0;break}if(u.startsWith("file:"))try{if(Ss.statSync(new URL(u+"/package.json")).mtimeMs>Ss.statSync(r).mtimeMs){c=!0;break}}catch(_){Sh.info(`Error checking ${u}/package.json modification time`,_);break}}}for(let l in i.dependencies)n.dependencies[l]===void 0&&(Sh.notify("Removing component",l),c=!0);c&&(Sh.notify("Updating components."),await D$(r,n,i),await C$(t,e))}a(Lue,"installComponents");function C$(e,t){return Promise.all(t.map(({name:r})=>{let n=Th.join(e,"node_modules",r),s=Th.join(e,"components",r);if(Ss.existsSync(n)&&Ss.lstatSync(n).isDirectory())return Ss.move(n,s,{overwrite:!0}).then(()=>{Ss.symlink(s,n)})}))}a(C$,"moveModuleToComponents");function Mue(){let e=Due.getConfiguration(),t=[];for(let r in e)e[r]?.package&&t.push(Object.assign(e[r],{name:r}));return t}a(Mue,"getComponentsConfig");function P$(e){return e.includes(":")?"":e.startsWith("@")||!e.startsWith("@")&&!e.includes("/")?"npm:":Th.extname(e)||Ss.existsSync(e)?"file:":"github:"}a(P$,"getPkgPrefix");async function D$(e,t,r){Sh.trace("npm installing components package.json",t),Ss.writeFileSync(e,JSON.stringify(t,null," "));try{await gh().installAllRootModules(L$.get(aw.CONFIG_PARAMS.IGNORE_SCRIPTS)===!0)}catch(n){throw r?Ss.writeFileSync(e,JSON.stringify(r,null," ")):Ss.unlinkSync(e),n}}a(D$,"installPackages")});var B$={};Ue(B$,{packageDirectory:()=>vue});function vue(e,t={skip_node_modules:!1,skip_symlinks:!1}){return new Promise((r,n)=>{let s=[];U$.default.pack(e,{dereference:!t.skip_symlinks,ignore:t.skip_node_modules?i=>i.includes("node_modules")||i.includes((0,v$.join)("cache","webpack")):void 0}).pipe((0,x$.createGzip)()).on("data",i=>s.push(i)).on("end",()=>{r(Buffer.concat(s))}).on("error",n)})}var v$,U$,x$,H$=ye(()=>{v$=require("path"),U$=M(require("tar-fs")),x$=require("node:zlib");a(vue,"packageDirectory")});var dw=P(q$=>{"use strict";var be=require("fs-extra"),lw=require("fast-glob"),Ie=require("path"),Uue=require("tar-fs"),xue=require("gunzip-maybe"),uw=require("normalize-path"),Nn=R$(),xt=j(),ot=(H(),D($)),Wt=ue(),oS=Ot(),Bue=oe(),{PACKAGE_ROOT:Hue}=pt(),{handleHDBError:Bt,hdb_errors:kue}=me(),{basename:Fue}=require("path"),Gue=cw(),F$=ue(),{Readable:que}=require("stream"),{isMainThread:$ue}=require("worker_threads"),{HDB_ERROR_MSGS:_l,HTTP_STATUS_CODES:Ht}=kue,G$=rt(),{replicateOperation:Xs}=(fs(),D(Ea)),{packageDirectory:Vue}=(H$(),D(B$)),k$=gh(),Kue=Ie.join(Hue,"application-template"),Yue=Wt.get(ot.CONFIG_PARAMS.ROOTPATH),Da=Ie.join(Yue,"ssh"),No=Ie.join(Da,"known_hosts");function Wue(){xt.trace("getting custom api status");let e={};try{e={port:Wt.get(ot.CONFIG_PARAMS.HTTP_PORT),directory:Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT),is_enabled:!0}}catch(t){throw Bt(new Error,_l.FUNCTION_STATUS,Ht.INTERNAL_SERVER_ERROR,xt.ERR,t)}return e}a(Wue,"customFunctionsStatus");function zue(){xt.trace("getting custom api endpoints");let e={},t=Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT);try{lw.sync(uw(`${t}/*`),{onlyDirectories:!0}).forEach(n=>{let s=n.split("/").pop();e[s]={routes:lw.sync(uw(`${n}/routes/*.js`)).map(i=>i.split("/").pop().split(".js")[0]),helpers:lw.sync(uw(`${n}/helpers/*.js`)).map(i=>i.split("/").pop().split(".js")[0])}})}catch(r){throw Bt(new Error,_l.GET_FUNCTIONS,Ht.INTERNAL_SERVER_ERROR,xt.ERR,r)}return e}a(zue,"getCustomFunctions");function jue(e){e.project&&(e.project=Ie.parse(e.project).name),e.file&&(e.file=Ie.parse(e.file).name);let t=Nn.getDropCustomFunctionValidator(e);if(t)throw Bt(t,t.message,Ht.BAD_REQUEST);xt.trace("getting custom api endpoint file content");let r=Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT),{project:n,type:s,file:i}=e,o=Ie.join(r,n,s,i+".js");try{return be.readFileSync(o,{encoding:"utf8"})}catch(c){throw Bt(new Error,_l.GET_FUNCTION,Ht.INTERNAL_SERVER_ERROR,xt.ERR,c)}}a(jue,"getCustomFunction");async function Que(e){e.project&&(e.project=Ie.parse(e.project).name),e.file&&(e.file=Ie.parse(e.file).name);let t=Nn.setCustomFunctionValidator(e);if(t)throw Bt(t,t.message,Ht.BAD_REQUEST);xt.trace("setting custom function file content");let r=Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT),{project:n,type:s,file:i,function_content:o}=e;try{be.outputFileSync(Ie.join(r,n,s,i+".js"),o);let c=await Xs(e);return c.message=`Successfully updated custom function: ${i}.js`,c}catch(c){throw Bt(new Error,_l.SET_FUNCTION,Ht.INTERNAL_SERVER_ERROR,xt.ERR,c)}}a(Que,"setCustomFunction");async function Jue(e){e.project&&(e.project=Ie.parse(e.project).name),e.file&&(e.file=Ie.parse(e.file).name);let t=Nn.getDropCustomFunctionValidator(e);if(t)throw Bt(t,t.message,Ht.BAD_REQUEST);xt.trace("dropping custom function file");let r=Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT),{project:n,type:s,file:i}=e;try{be.unlinkSync(Ie.join(r,n,s,i+".js"));let o=await Xs(e);return o.message=`Successfully deleted custom function: ${i}.js`,o}catch(o){throw Bt(new Error,_l.DROP_FUNCTION,Ht.INTERNAL_SERVER_ERROR,xt.ERR,o)}}a(Jue,"dropCustomFunction");async function Xue(e){e.project&&(e.project=Ie.parse(e.project).name);let t=Nn.addComponentValidator(e);if(t)throw Bt(t,t.message,Ht.BAD_REQUEST);xt.trace("adding component");let r=Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT),{project:n}=e;try{let s=Ie.join(r,n);be.mkdirSync(s,{recursive:!0}),be.copySync(Kue,s);let i=await Xs(e);return i.message=`Successfully added project: ${n}`,i}catch(s){throw Bt(new Error,_l.ADD_FUNCTION,Ht.INTERNAL_SERVER_ERROR,xt.ERR,s)}}a(Xue,"addComponent");async function Zue(e){e.project&&(e.project=Ie.parse(e.project).name);let t=Nn.dropCustomFunctionProjectValidator(e);if(t)throw Bt(t,t.message,Ht.BAD_REQUEST);xt.trace("dropping custom function project");let r=Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT),{project:n}=e,s=Wt.get(ot.CONFIG_PARAMS.APPS);if(!Bue.isEmptyOrZeroLength(s)){let i=!1;for(let[o,c]of s.entries())if(c.name===n){s.splice(o,1),i=!0;break}if(i)return oS.updateConfigValue(ot.CONFIG_PARAMS.APPS,s),`Successfully deleted project: ${n}`}try{let i=Ie.join(r,n);be.rmSync(i,{recursive:!0});let o=await Xs(e);return o.message=`Successfully deleted project: ${n}`,o}catch(i){throw Bt(new Error,_l.DROP_FUNCTION_PROJECT,Ht.INTERNAL_SERVER_ERROR,xt.ERR,i)}}a(Zue,"dropCustomFunctionProject");async function ede(e){e.project&&(e.project=Ie.parse(e.project).name);let t=Nn.packageComponentValidator(e);if(t)throw Bt(t,t.message,Ht.BAD_REQUEST);let r=Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT),{project:n}=e;xt.trace("packaging component",n);let s;try{s=await be.realpath(Ie.join(r,n))}catch(o){if(o.code!==ot.NODE_ERROR_CODES.ENOENT)throw o;try{s=await be.realpath(Ie.join(Wt.get(ot.CONFIG_PARAMS.ROOTPATH),"node_modules",n))}catch(c){if(c.code===ot.NODE_ERROR_CODES.ENOENT)throw new Error(`Unable to locate project '${n}'`)}}let i=(await Vue(s,e)).toString("base64");return{project:n,payload:i}}a(ede,"packageComponent");async function tde(e){e.project?e.project=Ie.parse(e.project).name:e.package&&(e.project=rde(e.package));let t=Nn.deployComponentValidator(e);if(t)throw Bt(t,t.message,Ht.BAD_REQUEST);let r=Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT),{project:n,payload:s,package:i,install_command:o}=e;if(xt.trace("deploying component",n),!s&&!i)throw new Error("'payload' or 'package' must be provided");let c;if(s){c=Ie.join(r,n),i="file:"+c,await be.emptyDir(c);let S=que.from(s instanceof Buffer?s:Buffer.from(s,"base64"));await new Promise((E,T)=>{S.pipe(xue()).pipe(Uue.extract(c,{finish:E})).on("error",T)});let g=await be.readdir(c);g.length===1&&g[0]==="package"&&(await be.copy(Ie.join(c,"package"),c),await be.remove(Ie.join(c,"package")));let R=Ie.join(c,"node_modules");o?await k$.runCommand(o,c):be.existsSync(R)||await k$.installAllRootModules(!1,c)}else{await oS.addConfig(n,{package:i}),await Gue();let S=F$.get(ot.CONFIG_PARAMS.ROOTPATH);c=Ie.join(S,"node_modules",n)}if($ue)return;let l=new Map;l.isWorker=!0;let u=(Rh(),D(Ah)),f;u.setErrorReporter(S=>f=S);let d=Fue(c),_=u.component_errors.get(d);try{await u.loadComponent(c,l)}finally{u.component_errors.set(d,_)}if(f)throw f;xt.info("Installed component");let h=e.restart==="rolling";e.restart=h?!1:e.restart;let m=await Xs(e);if(e.restart===!0)G$.restartWorkers("http"),m.message=`Successfully deployed: ${n}, restarting HarperDB`;else if(h){let g=await aS().executeJob({operation:"restart_service",service:"http",replicated:!0});m.restartJobId=g.job_id,m.message=`Successfully deployed: ${n}, restarting HarperDB`}else m.message=`Successfully deployed: ${n}`;return m}a(tde,"deployComponent");function rde(e){if(e.startsWith("git+ssh://"))return Ie.basename(e.split("#")[0].replace(/\.git$/,""));if(e.startsWith("http://")||e.startsWith("https://"))return Ie.basename(new URL(e.replace(/\.git$/,"")).pathname);if(e.startsWith("file://"))try{let{name:t}=JSON.parse(be.readFileSync(Ie.join(e,"package.json"),"utf8"));return Ie.basename(t)}catch{}return Ie.basename(e)}a(rde,"getProjectNameFromPackage");async function nde(){let e=a(async(s,i)=>{try{let o=await be.readdir(s,{withFileTypes:!0});for(let c of o){let l=c.name;if(l.startsWith(".")||l==="node_modules")continue;let u=Ie.join(s,l);if(c.isDirectory()||c.isSymbolicLink()){let f={name:l,entries:[]};i.entries.push(f),await e(u,f)}else{let f=await be.stat(u),d={name:Ie.basename(l),mtime:f.mtime,size:f.size};i.entries.push(d)}}return i}catch(o){return xt.warn("Error loading package",o),{error:o.toString(),entries:[]}}},"walkDir"),t=await e(Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT),{name:Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT).split(Ie.sep).slice(-1).pop(),entries:[]}),n=(Rh(),D(Ah)).component_errors;for(let s of t.entries){let i=n.get(s.name);i?s.error=n.get(s.name):i===void 0&&(s.error="The component has not been loaded yet (may need a restart)")}return t}a(nde,"getComponents");async function sde(e){let t=Nn.getComponentFileValidator(e);if(t)throw Bt(t,t.message,Ht.BAD_REQUEST);let n=oS.getConfigObj()[e.project]||e.project==="harperdb"?Ie.join(F$.get(ot.CONFIG_PARAMS.ROOTPATH),"node_modules"):Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT),s=e.encoding?{encoding:e.encoding}:{encoding:"utf8"};try{let i=await be.stat(Ie.join(n,e.project,e.file));return{message:await be.readFile(Ie.join(n,e.project,e.file),s),size:i.size,birthtime:i.birthtime,mtime:i.mtime}}catch(i){throw i.code===ot.NODE_ERROR_CODES.ENOENT?new Error(`Component file not found '${Ie.join(e.project,e.file)}'`):i}}a(sde,"getComponentFile");async function ide(e){let t=Nn.setComponentFileValidator(e);if(t)throw Bt(t,t.message,Ht.BAD_REQUEST);let r=e.encoding?{encoding:e.encoding}:{encoding:"utf8"},n=Ie.join(Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT),e.project,e.file);e.payload!==void 0?(await be.ensureFile(n),await be.outputFile(n,e.payload,r)):await be.ensureDir(n);let s=await Xs(e);return s.message="Successfully set component: "+e.file,s}a(ide,"setComponentFile");async function ode(e){let t=Nn.dropComponentFileValidator(e);if(t)throw Bt(t,t.message,Ht.BAD_REQUEST);let{project:r,file:n}=e,s=e.file?Ie.join(r,n):r,i=Ie.join(Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT),s),o=Ie.join(Wt.get(ot.CONFIG_PARAMS.ROOTPATH),"node_modules",r);await be.pathExists(o)&&await be.unlink(o),await be.pathExists(i)&&await be.remove(i);let c=Ie.join(Wt.get(ot.CONFIG_PARAMS.ROOTPATH),"package.json");if(await be.pathExists(c)){let u=JSON.parse(await be.readFile(c,"utf8"));u?.dependencies?.[r]&&delete u.dependencies[r],await be.writeFile(c,JSON.stringify(u,null,2),"utf8")}oS.deleteConfigFromFile([r]);let l=await Xs(e);return e.restart===!0?(G$.restartWorkers("http"),l.message=`Successfully dropped: ${s}, restarting HarperDB`):l.message=`Successfully dropped: ${s}`,l}a(ode,"dropComponent");async function ade(e){let t=Nn.addSSHKeyValidator(e);if(t)throw Bt(t,t.message,Ht.BAD_REQUEST);let{name:r,key:n,host:s,hostname:i,known_hosts:o}=e;xt.trace("adding ssh key",r);let c=Ie.join(Da,r+".key"),l=Ie.join(Da,"config");if(await be.pathExists(c))throw new Error("Key already exists. Use update_ssh_key or delete_ssh_key and then add_ssh_key");await be.outputFile(c,n),await be.chmod(c,"0600");let u=`#${r}
|
|
@@ -24,7 +24,7 @@ Caused by:`));else if(typeof u=="object")try{n+=JSON.stringify(u)}catch{n+="Obje
|
|
|
24
24
|
`)}catch(r){r.code==="ENOENT"?Xr.debug("no license file found"):Xr.error(`could not search for licenses due to: '${r.message}`)}for(let r=0;r<t.length;++r){let n=t[r];try{if(Bae.isEmptyOrZeroLength(n))continue;let s=JSON.parse(n),i=MG(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){Xr.error("There was an error parsing the license string."),Xr.error(s),e.ram_allocation=rl.RAM_ALLOCATION_ENUM.DEFAULT,e.enterprise=!1}}return TN=e,e}a(bN,"licenseSearch");async function zae(){return TN||await bN(),TN}a(zae,"getLicense");function Qae(){let e=bN().ram_allocation,t=process.constrainedMemory?.()||CG();if(t=Math.round(Math.min(t,CG())/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(Qae,"checkMemoryLimit")});var wN=P((FCe,HG)=>{var wg=ju(),UG=require("chalk"),zn=j(),xG=require("prompt"),{promisify:jae}=require("util"),ON=(H(),D($)),Jae=require("fs-extra"),Xae=require("path"),Zae=oe(),{packageJson:ece}=pt(),BG=ue();BG.initSync();var tce=require("moment"),rce=jae(xG.get),nce=Xae.join(BG.getHdbBasePath(),ON.LICENSE_KEY_DIR_NAME,ON.LICENSE_FILE_NAME,ON.LICENSE_FILE_NAME);HG.exports={getFingerprint:ice,setLicense:sce,parseLicense:NN,register:oce,getRegistrationInfo:cce};async function sce(e){if(e&&e.key&&e.company){try{zn.info(`parsing license key: ${e.key} and `);let t=e.company.toString();await NN(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(sce,"setLicense");async function ice(){let e={};try{e=await wg.generateFingerPrint()}catch(t){let r="Error generating fingerprint.";throw zn.error(r),zn.error(t),new Error(r)}return e}a(ice,"getFingerprint");async function NN(e,t){if(!e||!t)throw new Error("Invalid entries for License Key and Customer Company");zn.info("Validating license input...");let r=wg.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 Jae.writeFile(nce,JSON.stringify({license_key:e,company:t}))}catch(n){throw zn.error("Failed to write License"),n}return"Registration successful."}a(NN,"parseLicense");async function oce(){let e=await ace();return NN(e.HDB_LICENSE,e.CUSTOMER_COMPANY)}a(oce,"register");async function ace(){let e=await wg.generateFingerPrint(),t={properties:{CUSTOMER_COMPANY:{description:UG.magenta("[COMPANY] Please enter your company name"),required:!0},HDB_LICENSE:{description:UG.magenta(`[HDB_LICENSE] Your fingerprint is ${e} Please enter your license key`),required:!0}}};try{xG.start()}catch(n){zn.error(n)}let r;try{r=await rce(t)}catch(n){throw console.error("There was a problem prompting for registration input. Exiting."),n}return r}a(ace,"promptForRegistration");async function cce(){let e={registered:!1,version:null,ram_allocation:null,license_expiration_date:null},t;try{t=await wg.getLicense()}catch(r){throw zn.error(`There was an error when searching licenses due to: ${r.message}`),r}if(Zae.isEmptyOrZeroLength(t))throw new Error("There were no licenses found.");if(e.registered=t.enterprise,e.version=ece.version,e.ram_allocation=t.ram_allocation,isNaN(t.exp_date))e.license_expiration_date=t.enterprise?t.exp_date:null;else{let r=tce.utc(t.exp_date).format("YYYY-MM-DD");e.license_expiration_date=t.enterprise?r:null}return e}a(cce,"getRegistrationInfo")});var FG=P((qCe,kG)=>{"use strict";var lce=Nt(),IN=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+lce.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"}};kG.exports=IN});var $G=P((VCe,qG)=>{"use strict";var GG=Nt(),CN=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+GG.SERVER_SUFFIX.LEAF,this.pid_file=n,this.max_payload=67108864,this.jetstream={enabled:!0,store_dir:s,domain:r+GG.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"}};qG.exports=CN});var KG=P((YCe,VG)=>{"use strict";var PN=class{static{a(this,"HdbUserObject")}constructor(t,r){this.user=t,this.password=r}};VG.exports=PN});var WG=P((zCe,YG)=>{"use strict";var uce=Nt(),DN=class{static{a(this,"SysUserObject")}constructor(t,r){this.user=t+uce.SERVER_SUFFIX.ADMIN,this.password=r}};YG.exports=DN});var Dg=P((jCe,jG)=>{"use strict";var nl=require("path"),sl=require("fs-extra"),dce=FG(),fce=$G(),_ce=KG(),hce=WG(),LN=Gn(),Xu=oe(),An=It(),Cg=(H(),D($)),X_=Nt(),{CONFIG_PARAMS:Yt}=Cg,Zu=j(),Z_=ue(),zG=ro(),MN=pr(),mce=zs(),Ju="clustering",pce=1e4,QG=50;jG.exports={generateNatsConfig:gce,removeNatsConfig:Sce,getHubConfigPath:Ece};function Ece(){let e=Z_.get(Yt.ROOTPATH);return nl.join(e,Ju,X_.NATS_CONFIG_FILES.HUB_SERVER)}a(Ece,"getHubConfigPath");async function gce(e=!1,t=void 0){let r=Z_.get(Yt.ROOTPATH);sl.ensureDirSync(nl.join(r,"clustering","leaf")),Z_.initSync();let n=An.getConfigFromFile(Yt.CLUSTERING_TLS_CERT_AUTH),s=An.getConfigFromFile(Yt.CLUSTERING_TLS_PRIVATEKEY),i=An.getConfigFromFile(Yt.CLUSTERING_TLS_CERTIFICATE);!await sl.exists(i)&&!await sl.exists(!n)&&await mce.createNatsCerts();let o=nl.join(r,Ju,X_.PID_FILES.HUB),c=nl.join(r,Ju,X_.PID_FILES.LEAF),l=An.getConfigFromFile(Yt.CLUSTERING_LEAFSERVER_STREAMS_PATH),u=nl.join(r,Ju,X_.NATS_CONFIG_FILES.HUB_SERVER),f=nl.join(r,Ju,X_.NATS_CONFIG_FILES.LEAF_SERVER),d=An.getConfigFromFile(Yt.CLUSTERING_TLS_INSECURE),_=An.getConfigFromFile(Yt.CLUSTERING_TLS_VERIFY),h=An.getConfigFromFile(Yt.CLUSTERING_NODENAME),m=An.getConfigFromFile(Yt.CLUSTERING_HUBSERVER_LEAFNODES_NETWORK_PORT);await MN.checkNATSServerInstalled()||Pg("nats-server dependency is either missing or the wrong version. Run 'npm install' to fix");let S=await LN.listUsers(),g=An.getConfigFromFile(Yt.CLUSTERING_USER),R=await LN.getClusterUser();(Xu.isEmpty(R)||R.active!==!0)&&Pg(`Invalid cluster user '${g}'. A valid user with the role 'cluster_user' must be defined under clustering.user in harperdb-config.yaml`),e||(await Ig(Yt.CLUSTERING_HUBSERVER_CLUSTER_NETWORK_PORT),await Ig(Yt.CLUSTERING_HUBSERVER_LEAFNODES_NETWORK_PORT),await Ig(Yt.CLUSTERING_HUBSERVER_NETWORK_PORT),await Ig(Yt.CLUSTERING_LEAFSERVER_NETWORK_PORT));let E=[],T=[];for(let[ie,W]of S.entries())W.role?.role===Cg.ROLE_TYPES_ENUM.CLUSTER_USER&&W.active&&(E.push(new hce(W.username,zG.decrypt(W.hash))),T.push(new _ce(W.username,zG.decrypt(W.hash))));let N=[],{hub_routes:v}=An.getClusteringRoutes();if(!Xu.isEmptyOrZeroLength(v))for(let ie of v)N.push(`tls://${R.sys_name_encoded}:${R.uri_encoded_d_hash}@${ie.host}:${ie.port}`);let k=new dce(An.getConfigFromFile(Yt.CLUSTERING_HUBSERVER_NETWORK_PORT),h,o,i,s,n,d,_,m,An.getConfigFromFile(Yt.CLUSTERING_HUBSERVER_CLUSTER_NAME),An.getConfigFromFile(Yt.CLUSTERING_HUBSERVER_CLUSTER_NETWORK_PORT),N,E,T);n==null&&(delete k.tls.ca_file,delete k.leafnodes.tls.ca_file),t=Xu.isEmpty(t)?void 0:t.toLowerCase(),(t===void 0||t===Cg.PROCESS_DESCRIPTORS.CLUSTERING_HUB.toLowerCase())&&(await sl.writeJson(u,k),Zu.trace(`Hub server config written to ${u}`));let G=`tls://${R.sys_name_encoded}:${R.uri_encoded_d_hash}@0.0.0.0:${m}`,Y=`tls://${R.uri_encoded_name}:${R.uri_encoded_d_hash}@0.0.0.0:${m}`,X=new fce(An.getConfigFromFile(Yt.CLUSTERING_LEAFSERVER_NETWORK_PORT),h,c,l,[G],[Y],E,T,i,s,n,d);n==null&&delete X.tls.ca_file,(t===void 0||t===Cg.PROCESS_DESCRIPTORS.CLUSTERING_LEAF.toLowerCase())&&(await sl.writeJson(f,X),Zu.trace(`Leaf server config written to ${f}`))}a(gce,"generateNatsConfig");async function Ig(e){let t=Z_.get(e);return Xu.isEmpty(t)&&Pg(`port undefined for '${e}'`),await Xu.isPortTaken(t)&&Pg(`'${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(Ig,"isPortAvailable");function Pg(e){let t=`Error generating clustering config: ${e}`;Zu.error(t),console.error(t),process.exit(1)}a(Pg,"generateNatsConfigError");async function Sce(e){let{port:t,config_file:r}=MN.getServerConfig(e),{username:n,decrypt_hash:s}=await LN.getClusterUser(),i=0,o=2e3;for(;i<QG;){try{let f=await MN.createConnection(t,n,s,!1);if(f.protocol.connected===!0){f.close();break}}catch(f){Zu.trace(`removeNatsConfig waiting for ${e}. Caught and swallowed error ${f}`)}if(i++,i>=QG)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&&Zu.notify("Operations API waiting for Nats server connection. This could be caused by large Nats streams or incorrect clustering config."),await Xu.async_set_timeout(u)}let c="0".repeat(pce),l=nl.join(Z_.get(Yt.ROOTPATH),Ju,r);await sl.writeFile(l,c),await sl.remove(l),Zu.notify(e,"started.")}a(Sce,"removeNatsConfig")});var rq=P((XCe,tq)=>{"use strict";var Qn=ue(),Tce=ju(),Ge=(H(),D($)),eh=Nt(),go=require("path"),{PACKAGE_ROOT:Mg}=pt(),JG=ue(),Lg=oe(),ed="/dev/null",Ace=go.join(Mg,"launchServiceScripts"),XG=go.join(Mg,"utility/scripts"),Rce=go.join(XG,Ge.HDB_RESTART_SCRIPT),ZG=go.resolve(Mg,"dependencies",`${process.platform}-${process.arch}`,eh.NATS_BINARY_NAME);function eq(){let t=Tce.licenseSearch().ram_allocation||Ge.RAM_ALLOCATION_ENUM.DEFAULT,r=Ge.MEM_SETTING_KEY+t,n={[Ge.PROCESS_NAME_ENV_PROP]:Ge.PROCESS_DESCRIPTORS.HDB,IS_SCRIPTED_SERVICE:!0};return Lg.noBootFile()&&(n[Ge.CONFIG_PARAMS.ROOTPATH.toUpperCase()]=Lg.getEnvCliRootPath()),{name:Ge.PROCESS_DESCRIPTORS.HDB,script:Ge.LAUNCH_SERVICE_SCRIPTS.MAIN,exec_mode:"fork",env:n,node_args:r,cwd:Mg}}a(eq,"generateMainServerConfig");var yce=9930;function bce(){Qn.initSync(!0);let e=Qn.get(Ge.CONFIG_PARAMS.ROOTPATH),t=go.join(e,"clustering",eh.NATS_CONFIG_FILES.HUB_SERVER),r=go.join(Qn.get(Ge.HDB_SETTINGS_NAMES.LOG_PATH_KEY),Ge.LOG_NAMES.HDB),n=JG.get(Ge.CONFIG_PARAMS.CLUSTERING_HUBSERVER_NETWORK_PORT),s=eh.LOG_LEVEL_FLAGS[Qn.get(Ge.CONFIG_PARAMS.CLUSTERING_LOGLEVEL)]??void 0,i={name:Ge.PROCESS_DESCRIPTORS.CLUSTERING_HUB+(n!==yce?"-"+n:""),script:ZG,args:s?`${s} -c ${t}`:`-c ${t}`,exec_mode:"fork",env:{[Ge.PROCESS_NAME_ENV_PROP]:Ge.PROCESS_DESCRIPTORS.CLUSTERING_HUB},merge_logs:!0,out_file:r,error_file:r,instances:1};return Qn.get(Ge.HDB_SETTINGS_NAMES.LOG_TO_FILE)||(i.out_file=ed,i.error_file=ed),i}a(bce,"generateNatsHubServerConfig");var Oce=9940;function Nce(){Qn.initSync(!0);let e=Qn.get(Ge.CONFIG_PARAMS.ROOTPATH),t=go.join(e,"clustering",eh.NATS_CONFIG_FILES.LEAF_SERVER),r=go.join(Qn.get(Ge.HDB_SETTINGS_NAMES.LOG_PATH_KEY),Ge.LOG_NAMES.HDB),n=JG.get(Ge.CONFIG_PARAMS.CLUSTERING_LEAFSERVER_NETWORK_PORT),s=eh.LOG_LEVEL_FLAGS[Qn.get(Ge.CONFIG_PARAMS.CLUSTERING_LOGLEVEL)]??void 0,i={name:Ge.PROCESS_DESCRIPTORS.CLUSTERING_LEAF+(n!==Oce?"-"+n:""),script:ZG,args:s?`${s} -c ${t}`:`-c ${t}`,exec_mode:"fork",env:{[Ge.PROCESS_NAME_ENV_PROP]:Ge.PROCESS_DESCRIPTORS.CLUSTERING_LEAF},merge_logs:!0,out_file:r,error_file:r,instances:1};return Qn.get(Ge.HDB_SETTINGS_NAMES.LOG_TO_FILE)||(i.out_file=ed,i.error_file=ed),i}a(Nce,"generateNatsLeafServerConfig");function wce(){Qn.initSync();let e=go.join(Qn.get(Ge.CONFIG_PARAMS.LOGGING_ROOT),Ge.LOG_NAMES.HDB),t={name:Ge.PROCESS_DESCRIPTORS.CLUSTERING_UPGRADE_4_0_0,script:Ge.LAUNCH_SERVICE_SCRIPTS.NODES_UPGRADE_4_0_0,exec_mode:"fork",env:{[Ge.PROCESS_NAME_ENV_PROP]:Ge.PROCESS_DESCRIPTORS.CLUSTERING_UPGRADE_4_0_0},merge_logs:!0,out_file:e,error_file:e,instances:1,cwd:Ace,autorestart:!1};return Qn.get(Ge.HDB_SETTINGS_NAMES.LOG_TO_FILE)||(t.out_file=ed,t.error_file=ed),t}a(wce,"generateClusteringUpgradeV4ServiceConfig");function Ice(){let e={[Ge.PROCESS_NAME_ENV_PROP]:Ge.PROCESS_DESCRIPTORS.RESTART_HDB};return Lg.noBootFile()&&(e[Ge.CONFIG_PARAMS.ROOTPATH.toUpperCase()]=Lg.getEnvCliRootPath()),{...{name:Ge.PROCESS_DESCRIPTORS.RESTART_HDB,exec_mode:"fork",env:e,instances:1,autorestart:!1,cwd:XG},script:Rce}}a(Ice,"generateRestart");function Cce(){return{apps:[eq()]}}a(Cce,"generateAllServiceConfigs");tq.exports={generateAllServiceConfigs:Cce,generateMainServerConfig:eq,generateRestart:Ice,generateNatsHubServerConfig:bce,generateNatsLeafServerConfig:Nce,generateClusteringUpgradeV4ServiceConfig:wce}});var rh=P((tPe,pq)=>{"use strict";var et=(H(),D($)),Pce=oe(),To=Dg(),vg=pr(),So=Nt(),Oa=rq(),Ug=ue(),il=j(),Dce=mo(),{startWorker:nq,onMessageFromWorkers:Lce}=tt(),Mce=Vu(),ePe=require("util"),vce=require("child_process"),Uce=require("fs"),{execFile:xce}=vce,Ye;pq.exports={enterPM2Mode:Bce,start:Na,stop:vN,reload:iq,restart:oq,list:UN,describe:lq,connect:Ao,kill:qce,startAllServices:$ce,startService:xN,getUniqueServicesList:uq,restartAllServices:Vce,isServiceRegistered:dq,reloadStopStart:fq,restartHdb:cq,deleteProcess:Fce,startClusteringProcesses:hq,startClusteringThreads:mq,isHdbRestartRunning:Gce,isClusteringRunning:Yce,stopClustering:Kce,reloadClustering:Wce,expectedRestartOfChildren:aq};var th=!1;Lce(e=>{e.type==="restart"&&Ug.initSync(!0)});function Bce(){th=!0}a(Bce,"enterPM2Mode");function Ao(){return Ye||(Ye=require("pm2")),new Promise((e,t)=>{Ye.connect((r,n)=>{r&&t(r),e(n)})})}a(Ao,"connect");var Zr,Hce=10,sq;function Na(e,t=!1){if(th)return kce(e);let r=xce(e.script,e.args.split(" "),e);r.name=e.name,r.config=e,r.on("exit",async i=>{let o=Zr.indexOf(r);o>-1&&Zr.splice(o,1),!sq&&i!==0&&(e.restarts=(e.restarts||0)+1,e.restarts<Hce&&(Uce.existsSync(To.getHubConfigPath())?Na(e):(await To.generateNatsConfig(!0),Na(e),await new Promise(c=>setTimeout(c,3e3)),await To.removeNatsConfig(et.PROCESS_DESCRIPTORS.CLUSTERING_HUB),await To.removeNatsConfig(et.PROCESS_DESCRIPTORS.CLUSTERING_LEAF))))});let n={serviceName:e.name.replace(/ /g,"-")};function s(i){let o=Ug.get(et.CONFIG_PARAMS.CLUSTERING_LOGLEVEL),c=/\[\d+][^\[]+\[(\w+)]/g,l,u=0,f;for(;l=c.exec(i);){if(l.index&&So.LOG_LEVEL_HIERARCHY[o]>=So.LOG_LEVEL_HIERARCHY[f||"info"]){let h=f===So.LOG_LEVELS.ERR||f===So.LOG_LEVELS.WRN?il.OUTPUTS.STDERR:il.OUTPUTS.STDOUT;il.logCustomLevel(f||"info",h,n,i.slice(u,l.index).trim())}let[d,_]=l;u=l.index+d.length,f=So.LOG_LEVELS[_]}if(So.LOG_LEVEL_HIERARCHY[o]>=So.LOG_LEVEL_HIERARCHY[f||"info"]){let d=f===So.LOG_LEVELS.ERR||f===So.LOG_LEVELS.WRN?il.OUTPUTS.STDERR:il.OUTPUTS.STDOUT;il.logCustomLevel(f||"info",d,n,i.slice(u).trim())}}if(a(s,"extractMessages"),r.stdout.on("data",s),r.stderr.on("data",s),r.unref(),!Zr&&(Zr=[],!t)){let i=a(()=>{sq=!0,Zr&&(Zr.map(o=>o.kill()),process.exit(0))},"kill_children");process.on("exit",i),process.on("SIGINT",i),process.on("SIGQUIT",i),process.on("SIGTERM",i)}Zr.push(r)}a(Na,"start");function kce(e){return new Promise(async(t,r)=>{try{await Ao()}catch(n){r(n)}Ye.start(e,(n,s)=>{n&&(Ye.disconnect(),r(n)),Ye.disconnect(),t(s)})})}a(kce,"startWithPM2");function vN(e){if(!th){for(let t of Zr||[])t.name===e&&(Zr.splice(Zr.indexOf(t),1),t.kill());return}return new Promise(async(t,r)=>{try{await Ao()}catch(n){r(n)}Ye.stop(e,async(n,s)=>{n&&(Ye.disconnect(),r(n)),Ye.delete(e,(i,o)=>{i&&(Ye.disconnect(),r(n)),Ye.disconnect(),t(o)})})})}a(vN,"stop");function iq(e){return new Promise(async(t,r)=>{try{await Ao()}catch(n){r(n)}Ye.reload(e,(n,s)=>{n&&(Ye.disconnect(),r(n)),Ye.disconnect(),t(s)})})}a(iq,"reload");function oq(e){if(!th){aq();for(let t of Zr||[])t.name===e&&t.kill()}return new Promise(async(t,r)=>{try{await Ao()}catch(n){r(n)}Ye.restart(e,(n,s)=>{Ye.disconnect(),t(s)})})}a(oq,"restart");function aq(){for(let e of Zr||[])e.config&&(e.config.restarts=0)}a(aq,"expectedRestartOfChildren");function Fce(e){return new Promise(async(t,r)=>{try{await Ao()}catch(n){r(n)}Ye.delete(e,(n,s)=>{n&&(Ye.disconnect(),r(n)),Ye.disconnect(),t(s)})})}a(Fce,"deleteProcess");async function cq(){await Na(Oa.generateRestart())}a(cq,"restartHdb");async function Gce(){let e=await UN();for(let t in e)if(e[t].name===et.PROCESS_DESCRIPTORS.RESTART_HDB)return!0;return!1}a(Gce,"isHdbRestartRunning");function UN(){return new Promise(async(e,t)=>{try{await Ao()}catch(r){t(r)}Ye.list((r,n)=>{r&&(Ye.disconnect(),t(r)),Ye.disconnect(),e(n)})})}a(UN,"list");function lq(e){return new Promise(async(t,r)=>{try{await Ao()}catch(n){r(n)}Ye.describe(e,(n,s)=>{n&&(Ye.disconnect(),r(n)),Ye.disconnect(),t(s)})})}a(lq,"describe");function qce(){if(!th){for(let e of Zr||[])e.kill();Zr=[];return}return new Promise(async(e,t)=>{try{await Ao()}catch(r){t(r)}Ye.killDaemon((r,n)=>{r&&(Ye.disconnect(),t(r)),Ye.disconnect(),e(n)})})}a(qce,"kill");async function $ce(){try{await hq(),await mq(),await Na(Oa.generateAllServiceConfigs())}catch(e){throw Ye?.disconnect(),e}}a($ce,"startAllServices");async function xN(e,t=!1){try{let r;switch(e=e.toLowerCase(),e){case et.PROCESS_DESCRIPTORS.HDB.toLowerCase():r=Oa.generateMainServerConfig();break;case et.PROCESS_DESCRIPTORS.CLUSTERING_INGEST_SERVICE.toLowerCase():r=Oa.generateNatsIngestServiceConfig();break;case et.PROCESS_DESCRIPTORS.CLUSTERING_REPLY_SERVICE.toLowerCase():r=Oa.generateNatsReplyServiceConfig();break;case et.PROCESS_DESCRIPTORS.CLUSTERING_HUB.toLowerCase():r=Oa.generateNatsHubServerConfig(),await Na(r,t),await To.removeNatsConfig(e);return;case et.PROCESS_DESCRIPTORS.CLUSTERING_LEAF.toLowerCase():r=Oa.generateNatsLeafServerConfig(),await Na(r,t),await To.removeNatsConfig(e);return;case et.PROCESS_DESCRIPTORS.CLUSTERING_UPGRADE_4_0_0.toLowerCase():r=Oa.generateClusteringUpgradeV4ServiceConfig();break;default:throw new Error(`Start service called with unknown service config: ${e}`)}await Na(r)}catch(r){throw Ye?.disconnect(),r}}a(xN,"startService");async function uq(){try{let e=await UN(),t={};for(let r=0,n=e.length;r<n;r++){let s=e[r];t[s.name]===void 0&&(t[s.name]={name:s.name,exec_mode:s.pm2_env.exec_mode})}return t}catch(e){throw Ye?.disconnect(),e}}a(uq,"getUniqueServicesList");async function Vce(e=[]){try{let t=!1,r=await uq();for(let n=0,s=Object.values(r).length;n<s;n++){let o=Object.values(r)[n].name;e.includes(o)||(o===et.PROCESS_DESCRIPTORS.HDB?t=!0:await oq(o))}t&&await fq(et.PROCESS_DESCRIPTORS.HDB)}catch(t){throw Ye?.disconnect(),t}}a(Vce,"restartAllServices");async function dq(e){if(Zr?.find(r=>r.name===e))return!0;let t=await Mce.getHDBProcessInfo();return t.core.length&&t.core[0]?.parent==="PM2"}a(dq,"isServiceRegistered");async function fq(e){let t=Ug.get(et.CONFIG_PARAMS.THREADS_COUNT)??Ug.get(et.CONFIG_PARAMS.THREADS),r=await lq(e),n=Pce.isEmptyOrZeroLength(r)?0:r.length;t!==n?(await vN(e),await xN(e)):e===et.PROCESS_DESCRIPTORS.HDB?await cq():await iq(e)}a(fq,"reloadStopStart");var _q;async function hq(e=!1){for(let t in et.CLUSTERING_PROCESSES){let r=et.CLUSTERING_PROCESSES[t];await xN(r,e)}}a(hq,"startClusteringProcesses");async function mq(){_q=nq(et.LAUNCH_SERVICE_SCRIPTS.NATS_REPLY_SERVICE,{name:et.PROCESS_DESCRIPTORS.CLUSTERING_REPLY_SERVICE});try{await vg.deleteLocalStream("__HARPERDB_WORK_QUEUE__")}catch{}await vg.updateLocalStreams();let e=await Dce.getAllNodeRecords();for(let t=0,r=e.length;t<r;t++)if(e[t].system_info?.hdb_version===et.PRE_4_0_0_VERSION){il.info("Starting clustering upgrade 4.0.0 process"),nq(et.LAUNCH_SERVICE_SCRIPTS.NODES_UPGRADE_4_0_0,{name:"Upgrade-4-0-0"});break}}a(mq,"startClusteringThreads");async function Kce(){for(let e in et.CLUSTERING_PROCESSES)if(e!==et.CLUSTERING_PROCESSES.CLUSTERING_INGEST_PROC_DESCRIPTOR)if(e===et.CLUSTERING_PROCESSES.CLUSTERING_REPLY_SERVICE_DESCRIPTOR)await _q.terminate();else{let t=et.CLUSTERING_PROCESSES[e];await vN(t)}}a(Kce,"stopClustering");async function Yce(){for(let e in et.CLUSTERING_PROCESSES){let t=et.CLUSTERING_PROCESSES[e];if(await dq(t)===!1)return!1}return!0}a(Yce,"isClusteringRunning");async function Wce(){await To.generateNatsConfig(!0),await vg.reloadNATSHub(),await vg.reloadNATSLeaf(),await To.removeNatsConfig(et.PROCESS_DESCRIPTORS.CLUSTERING_HUB.toLowerCase()),await To.removeNatsConfig(et.PROCESS_DESCRIPTORS.CLUSTERING_LEAF.toLowerCase())}a(Wce,"reloadClustering")});var kN={};Ue(kN,{compactOnStart:()=>zce,copyDb:()=>Rq});async function zce(){wa.notify("Running compact on start"),console.log("Running compact on start");let e=(0,BN.get)(U.ROOTPATH),t=new Map,r=Xe();(0,HN.updateConfigValue)(U.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,xg.join)(e,"backup",n+".mdb"),o=(0,xg.join)(e,tc,n+"-copy.mdb"),c=0;try{c=await Eq(n),console.log("Database",n,"before compact has a total record count of",c)}catch(l){wa.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 Rq(n,o),console.log("Backing up",n,"to",i),await(0,ol.move)(s,i,{overwrite:!0})}try{td()}catch(n){wa.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,ol.move)(i,s,{overwrite:!0}),await(0,ol.remove)((0,xg.join)(e,tc,`${n}-copy.mdb-lock`));try{td()}catch(n){wa.error("Error resetting databases after backup",n),console.error("Error resetting databases after backup",n),process.exit(0)}}catch(n){wa.error("Error compacting database, rolling back operation",n),console.error("Error compacting database, rolling back operation",n),(0,HN.updateConfigValue)(U.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,ol.move)(o,i,{overwrite:!0})}catch(c){console.error(c)}}throw td(),n}for(let[n,{backup_dest:s,record_count:i}]of t){let o=!0,c=await Eq(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
25
|
Total record count before compaction: ${i}, total after: ${c}.
|
|
26
26
|
Database backup has not been removed and can be found here: ${s}`;wa.error(l),console.error(l)}(0,BN.get)(U.STORAGE_COMPACTONSTARTKEEPBACKUP)===!0||o===!1||(console.log("Removing backup",s),await(0,ol.remove)(s))}}async function Eq(e){let t=await(0,Aq.describeSchema)({database:e}),r=0;for(let n in t)r+=t[n].record_count;return r}async function Rq(e,t){console.log("copyDb start");let r=Xe()[e],n;for(let d in r){n=r[d].primaryStore.rootStore;break}let s=n.dbisDb,i=n.auditStore,o=(0,gq.open)(new Sq.default(t)),c=o.openDB(Bg.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=Hg(),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 Tq.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(Bg.AUDIT_STORE_NAME,nh);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=1e7,T=null;for(;E-- >0;)try{for(let N of _.getKeys({start:T,transaction:S}))try{T=N;let{value:v,version:k}=_.getEntry(N,{transaction:S});l=h.put(N,v,m?k:void 0),g++,S.openTimer&&(S.openTimer=0),R+=(N?.length||10)+v.length,u++>5e3&&(await l,console.log("copied",g,"entries",R,"bytes"),u=0)}catch(v){console.error("Error copying record",typeof N=="symbol"?"symbol":N,"from",e,"to",t,v)}console.log("finish copying, copied",g,"entries",R,"bytes");return}catch{if(typeof T=="string"){if(T==="z")return console.error("Reached end of dbi",T,"for",e,"to",t);T=T.slice(0,-2)+"z"}else if(typeof T=="number")T++;else return console.error("Unknown key type",T,"for",e,"to",t)}}a(d,"copyDbi"),await l,console.log("copied database "+e+" to "+t)}finally{f.done(),o.close()}}var gq,xg,ol,BN,Sq,Tq,Bg,Aq,HN,wa,FN=ye(()=>{Me();gq=require("lmdb"),xg=require("path"),ol=require("fs-extra"),BN=M(ue()),Sq=M(bf()),Tq=M(yf()),Bg=M(Ut());H();Ji();Aq=M(no()),HN=M(It()),wa=M(j());a(zce,"compactOnStart");a(Eq,"getTotalDBRecordCount");a(Rq,"copyDb")});var nd=P((uPe,Cq)=>{"use strict";var Qce=require("minimist"),{isMainThread:qN,parentPort:ih,threadId:aPe}=require("worker_threads"),nt=(H(),D($)),Pi=j(),$N=oe(),Fg=Dg(),kg=pr(),cPe=Nt(),Nq=It(),js=rh(),yq=Vu(),{compactOnStart:jce}=(FN(),D(kN)),Jce=rc(),{restartWorkers:Gg,onMessageByType:Xce}=tt(),{handleHDBError:Zce,hdb_errors:ele}=me(),{HTTP_STATUS_CODES:tle}=ele,oh=ue(),{sendOperationToNode:bq,getThisNodeName:rle,monitorNodeCAs:nle}=(ds(),D(pa)),{getHDBNodeTable:lPe}=($c(),D(eO));oh.initSync();var sh=`Restarting HarperDB. This may take up to ${nt.RESTART_TIMEOUT_MS/1e3} seconds.`,sle="Restart is not available from the CLI when running in non-pm2 mode. Either call restart from the API or stop and start HarperDB.",Oq="Clustering is not enabled so cannot be restarted",ile="Invalid service",rd,Es;Cq.exports={restart:wq,restartService:VN};qN&&Xce(nt.ITC_EVENT_TYPES.RESTART,async(e,t)=>{e.workerType?await VN({service:e.workerType}):wq({operation:"restart"}),t.postMessage({type:"restart-complete"})});async function wq(e){Es=Object.keys(e).length===0,rd=await js.isServiceRegistered(nt.PROCESS_DESCRIPTORS.HDB);let t=Qce(process.argv);if(t.service){await VN(t);return}if(Es&&!rd){console.error(sle);return}if(Es&&console.log(sh),rd){js.enterPM2Mode(),Pi.notify(sh);let r=Jce(Object.keys(nt.CONFIG_PARAM_MAP),!0);return $N.isEmptyOrZeroLength(Object.keys(r))||Nq.updateConfigValue(void 0,void 0,r,!0,!0),ole(),sh}return qN?(Pi.notify(sh),oh.get(nt.CONFIG_PARAMS.STORAGE_COMPACTONSTART)&&await jce(),process.env.HARPER_EXIT_ON_RESTART&&process.exit(0),setTimeout(()=>{Gg()},50)):ih.postMessage({type:nt.ITC_EVENT_TYPES.RESTART}),sh}a(wq,"restart");async function VN(e){let{service:t}=e;if(nt.HDB_PROCESS_SERVICES[t]===void 0)throw Zce(new Error,ile,tle.BAD_REQUEST,void 0,void 0,!0);if(js.expectedRestartOfChildren(),rd=await js.isServiceRegistered(nt.PROCESS_DESCRIPTORS.HDB),!qN){e.replicated&&nle(),ih.postMessage({type:nt.ITC_EVENT_TYPES.RESTART,workerType:t}),ih.ref(),await new Promise(s=>{ih.on("message",i=>{i.type==="restart-complete"&&(s(),ih.unref())})});let n;if(e.replicated){e.replicated=!1,n=[];for(let s of server.nodes){if(s.name===rle())continue;let i;try{({job_id:i}=await bq(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 bq(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 nt.HDB_PROCESS_SERVICES.clustering:if(!oh.get(nt.CONFIG_PARAMS.CLUSTERING_ENABLED)){r=Oq;break}Es&&console.log("Restarting clustering"),Pi.notify("Restarting clustering"),await Iq();break;case nt.HDB_PROCESS_SERVICES.clustering_config:case nt.HDB_PROCESS_SERVICES["clustering config"]:if(!oh.get(nt.CONFIG_PARAMS.CLUSTERING_ENABLED)){r=Oq;break}Es&&console.log("Restarting clustering_config"),Pi.notify("Restarting clustering_config"),await js.reloadClustering();break;case"custom_functions":case"custom functions":case nt.HDB_PROCESS_SERVICES.harperdb:case nt.HDB_PROCESS_SERVICES.http_workers:case nt.HDB_PROCESS_SERVICES.http:if(Es&&!rd){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}Es&&console.log("Restarting http_workers"),Pi.notify("Restarting http_workers"),Es?await js.restart(nt.PROCESS_DESCRIPTORS.HDB):await Gg("http");break;default:r=`Unrecognized service: ${t}`;break}return r?(Pi.error(r),Es&&console.error(r),r):(t==="custom_functions"&&(t="Custom Functions"),`Restarting ${t}`)}a(VN,"restartService");async function ole(){await Iq(),await js.restart(nt.PROCESS_DESCRIPTORS.HDB),await $N.async_set_timeout(2e3),oh.get(nt.CONFIG_PARAMS.CLUSTERING_ENABLED)&&await GN(),Es&&(await kg.closeConnection(),process.exit(0))}a(ole,"restartPM2Mode");async function Iq(){if(!Nq.getConfigFromFile(nt.CONFIG_PARAMS.CLUSTERING_ENABLED))return;if((await yq.getHDBProcessInfo()).clustering.length===0)Pi.trace("Clustering not running, restart will start clustering services"),await Fg.generateNatsConfig(!0),await js.startClusteringProcesses(),await js.startClusteringThreads(),await GN(),Es&&await kg.closeConnection();else{await Fg.generateNatsConfig(!0),rd?(Pi.trace("Restart clustering restarting PM2 managed Hub and Leaf servers"),await js.restart(nt.PROCESS_DESCRIPTORS.CLUSTERING_HUB),await js.restart(nt.PROCESS_DESCRIPTORS.CLUSTERING_LEAF)):(await yq.getHDBProcessInfo()).clustering.forEach(s=>{Pi.trace("Restart clustering killing process pid",s.pid),process.kill(s.pid)}),await $N.async_set_timeout(3e3),await GN(),await kg.updateLocalStreams(),Es&&await kg.closeConnection(),Pi.trace("Restart clustering restarting ingest and reply service threads");let t=Gg(nt.LAUNCH_SERVICE_SCRIPTS.NATS_INGEST_SERVICE),r=Gg(nt.LAUNCH_SERVICE_SCRIPTS.NATS_REPLY_SERVICE);await t,await r}}a(Iq,"restartClustering");async function GN(){await Fg.removeNatsConfig(nt.PROCESS_DESCRIPTORS.CLUSTERING_HUB),await Fg.removeNatsConfig(nt.PROCESS_DESCRIPTORS.CLUSTERING_LEAF)}a(GN,"removeNatsConfig")});var Fq=P((_Pe,kq)=>{"use strict";var fPe=require("lodash"),Rn=(H(),D($)),{handleHDBError:Pq,hdb_errors:ale}=me(),{HDB_ERROR_MSGS:cle,HTTP_STATUS_CODES:lle}=ale,KN=j();kq.exports={getRolePermissions:dle};var al=Object.create(null),ule=a(e=>({key:e,perms:{}}),"perms_template_obj"),vq=a((e=!1)=>({describe:e,tables:{}}),"schema_perms_template"),Uq=a((e=!1,t=!1,r=!1,n=!1)=>({[Rn.PERMS_CRUD_ENUM.READ]:e,[Rn.PERMS_CRUD_ENUM.INSERT]:t,[Rn.PERMS_CRUD_ENUM.UPDATE]:r,[Rn.PERMS_CRUD_ENUM.DELETE]:n}),"permissions_template"),YN=a((e=!1,t=!1,r=!1,n=!1,s=!1)=>({attribute_permissions:[],describe:e,...Uq(t,r,n,s)}),"table_perms_template"),Dq=a((e,t=Uq())=>({attribute_name:e,describe:Hq(t),[ah]:t[ah],[WN]:t[WN],[zN]:t[zN]}),"attr_perms_template"),Lq=a((e,t=!1)=>({attribute_name:e,describe:t,[ah]:t}),"timestamp_attr_perms_template"),{READ:ah,INSERT:WN,UPDATE:zN}=Rn.PERMS_CRUD_ENUM,xq=Object.values(Rn.PERMS_CRUD_ENUM),Bq=[ah,WN,zN];function dle(e){let t;try{if(e.permission.super_user||e.permission.cluster_user)return e.permission;let r={...global.hdb_schema};delete r[Rn.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=fle(e,r);return al[t]?al[t].key=n:al[t]=ule(n),al[t].perms=s,s}catch(r){if(!e[Rn.TIME_STAMP_NAMES_ENUM.UPDATED_TIME]||e[Rn.TIME_STAMP_NAMES_ENUM.UPDATED_TIME]<Rn.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 KN.error(n),KN.debug(r),Pq(new Error,cle.OUTDATED_PERMS_TRANSLATION_ERROR,lle.BAD_REQUEST)}else{let n=`There was an error while translating role permissions for role: ${t}.
|
|
27
|
-
${r.stack}`;throw KN.error(n),Pq(new Error)}}}a(dle,"getRolePermissions");function fle(e,t){let r=Object.create(null);r.super_user=!1;let n=e.permission;r[Rn.SYSTEM_SCHEMA_NAME]=n[Rn.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]=_le(t[i]);return}r[i]=vq(),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=hle(c,l);r[i].describe||xq.forEach(f=>{u[f]&&(r[i].describe=!0)}),r[i].tables[o]=u}else r[i].tables[o]=YN()})):Object.keys(t[i]).forEach(o=>{r[i].tables[o]=YN()})}),r}a(fle,"translateRolePermissions");function _le(e){let t=vq(!0);return Object.keys(e).forEach(r=>{t.tables[r]=YN(!0,!0,!0,!0,!0)}),t}a(_le,"createStructureUserPermissions");function hle(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 Rn.TIME_STAMP_NAMES.includes(d)&&(_=Lq(d,f[ah])),u[d]=_,u},{}),o=t.primaryKey||t.hash_attribute,c=!!i[o],l=Dq(o);return t.attributes.forEach(({attribute:u})=>{if(i[u]){let f=i[u];f.describe=Hq(f),s.attribute_permissions.push(f),c||mle(f,l)}else if(u!==o){let f;Rn.TIME_STAMP_NAMES.includes(u)?f=Lq(u):f=Dq(u),s.attribute_permissions.push(f)}}),c||s.attribute_permissions.push(l),s.describe=Mq(s),s}else return e.describe=Mq(e),e}a(hle,"getTableAttrPerms");function Mq(e){return xq.filter(t=>e[t]).length>0}a(Mq,"getSchemaTableDescribePerm");function Hq(e){return Bq.filter(t=>e[t]).length>0}a(Hq,"getAttributeDescribePerm");function mle(e,t){Bq.forEach(r=>{e[r]&&!t[r]&&(t[r]=!0,t.describe=!0)})}a(mle,"checkForHashPerms")});var ch={};Ue(ch,{authentication:()=>Wq,bypassAuth:()=>yle,login:()=>Ole,logout:()=>Nle,start:()=>ble});function yle(){Yq=!0}async function Wq(e,t){let r=e.headers.asObject,n=r.authorization,s=r.cookie,i=r.origin,o=[];try{if(i){let h=e.isOperationsServer?Sle?gle:[]:Ele?ple:[];if(h.includes(i)||h.includes("*")){if(e.method==="OPTIONS"){let m=en.get(U.HTTP_CORSACCESSCONTROLALLOWHEADERS)??"Accept, Content-Type, Authorization",S=new co([["Access-Control-Allow-Methods","POST, GET, PUT, DELETE, PATCH, OPTIONS"],["Access-Control-Allow-Headers",m],["Access-Control-Allow-Origin",i]]);return qg&&S.set("Access-Control-Allow-Credentials","true"),{status:200,headers:S}}o.push("Access-Control-Allow-Origin",i),qg&&o.push("Access-Control-Allow-Credentials","true")}}let l,u;if(qg){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 Gq.get(l);break}e.session=u||(u={})}let f=a((h,m,S)=>{let g=new sd.AuthAuditLog(h,m,$o.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===Ds.SUCCESS?QN.notify(g):QN.error(g)},"authAuditLog");if(!e.authorized&&e.mtlsConfig&&e.peerCertificate.subject&&e?._nodeRequest?.socket?.authorizationError&&QN.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 ze.getUser(h,null,e),f(h,Ds.SUCCESS,"mTLS")):(0,sd.debug)("HTTPS/WSS mTLS authorized connection (mTLS did not authorize a user)","from",e.ip)}let d;if(!e.user)if(n){if(d=cl.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 ze.getUser(g,R,e):null;break;case"Bearer":try{d=await Db(S)}catch(N){if(N.message==="invalid token")try{return await gE(S),c({status:-1})}catch{throw N}}break}}catch(E){return Ale&&(cl.get(S)||(cl.set(S,S),f(g,Ds.FAILURE,m))),c({status:401,body:Xo({error:E.message},e)})}cl.set(n,d),Tle&&f(d.username,Ds.SUCCESS,m)}e.user=d}else u?.user?e.user=await ze.getUser(u.user,null,e):(Yq&&(e.ip?.includes("127.0.0.")||e.ip=="::1")||e?._nodeRequest?.socket?.server?._pipeName&&e.ip===void 0)&&(e.user=await(0,$q.getSuperUser)());qg&&(e.session.update=function(h){let m=en.get(U.AUTHENTICATION_COOKIE_EXPIRES);if(!l){l=(0,Vq.v4)();let S=en.get(U.AUTHENTICATION_COOKIE_DOMAINS),g=m?new Date(Date.now()+(0,jN.convertToMS)(m)).toUTCString():Rle,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,Gq.put(h,{expiresAt:m?Date.now()+(0,jN.convertToMS)(m):void 0})},e.login=async function(h,m){let S=e.user=await ze.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")&&di.loginPath?(_.status=302,_.headers.set("Location",di.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 co);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(Wq,t||r?{port:t,securePort:r}:{port:"all"}),qq||(qq=!0,setInterval(()=>{cl=new Map},en.get(U.AUTHENTICATION_CACHETTL)).unref(),Kq.user.addListener(()=>{cl=new Map}))}async function Ole(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 Nle(e){if(!e.baseRequest.session)throw new Error("No session for logout");return await e.baseRequest.session.update({user:null}),"Logout successful"}var $q,Vq,en,sd,Kq,jN,QN,ple,Ele,gle,Sle,Gq,qg,Yq,Tle,Ale,Rle,cl,qq,$g=ye(()=>{$q=M(Gn());$r();Wl();Au();Me();Vq=require("uuid"),en=M(ue());H();sd=M(j()),Kq=M($f());__();jN=M(oe());ji();QN=(0,sd.loggerWithTag)("auth-event");en.initSync();ple=en.get(U.HTTP_CORSACCESSLIST),Ele=en.get(U.HTTP_CORS),gle=en.get(U.OPERATIONSAPI_NETWORK_CORSACCESSLIST),Sle=en.get(U.OPERATIONSAPI_NETWORK_CORS),Gq=lt({table:"hdb_session",database:"system",attributes:[{name:"id",isPrimaryKey:!0},{name:"user"}]}),qg=en.get(U.AUTHENTICATION_ENABLESESSIONS)??!0,Yq=process.env.AUTHENTICATION_AUTHORIZELOCAL??en.get(U.AUTHENTICATION_AUTHORIZELOCAL)??process.env.DEV_MODE,Tle=en.get(U.LOGGING_AUDITAUTHEVENTS_LOGSUCCESSFUL)??!1,Ale=en.get(U.LOGGING_AUDITAUTHEVENTS_LOGFAILED)??!1,Rle="Tue, 01 Oct 8307 19:33:20 GMT",cl=new Map;ze.onInvalidatedUser(()=>{cl=new Map});a(yle,"bypassAuth");a(Wq,"authentication");a(ble,"start");a(Ole,"login");a(Nle,"logout")});var e$=P((yPe,Zq)=>{"use strict";var Ne=require("joi"),zq=require("fs-extra"),Qq=require("path"),jn=rt(),jq=ue(),Jq=(H(),D($)),Xq=j(),{hdb_errors:wle}=me(),{HDB_ERROR_MSGS:tn}=wle,Ro=/^[a-zA-Z0-9-_]+$/,Ile=/^[a-zA-Z0-9-_]+$/;Zq.exports={getDropCustomFunctionValidator:Ple,setCustomFunctionValidator:Dle,addComponentValidator:Ule,dropCustomFunctionProjectValidator:xle,packageComponentValidator:Ble,deployComponentValidator:Hle,setComponentFileValidator:Lle,getComponentFileValidator:vle,dropComponentFileValidator:Mle,addSSHKeyValidator:kle,updateSSHKeyValidator:Fle,deleteSSHKeyValidator:Gle,setSSHKnownHostsValidator:qle};function Vg(e,t,r){try{let n=jq.get(Jq.CONFIG_PARAMS.COMPONENTSROOT),s=Qq.join(n,t);return zq.existsSync(s)?e?t:r.message(tn.PROJECT_EXISTS):e?r.message(tn.NO_PROJECT):t}catch(n){return Xq.error(n),r.message(tn.VALIDATION_ERR)}}a(Vg,"checkProjectExists");function lh(e,t){return e.includes("..")?t.message("Invalid file path"):e}a(lh,"checkFilePath");function Cle(e,t,r,n){try{let s=jq.get(Jq.CONFIG_PARAMS.COMPONENTSROOT),i=Qq.join(s,e,t,r+".js");return zq.existsSync(i)?r:n.message(tn.NO_FILE)}catch(s){return Xq.error(s),n.message(tn.VALIDATION_ERR)}}a(Cle,"checkFileExists");function Ple(e){let t=Ne.object({project:Ne.string().pattern(Ro).custom(Vg.bind(null,!0)).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),type:Ne.string().valid("helpers","routes").required(),file:Ne.string().pattern(Ro).custom(Cle.bind(null,e.project,e.type)).custom(lh).required().messages({"string.pattern.base":tn.BAD_FILE_NAME})});return jn.validateBySchema(e,t)}a(Ple,"getDropCustomFunctionValidator");function Dle(e){let t=Ne.object({project:Ne.string().pattern(Ro).custom(Vg.bind(null,!0)).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),type:Ne.string().valid("helpers","routes").required(),file:Ne.string().custom(lh).required(),function_content:Ne.string().required()});return jn.validateBySchema(e,t)}a(Dle,"setCustomFunctionValidator");function Lle(e){let t=Ne.object({project:Ne.string().pattern(Ro).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),file:Ne.string().custom(lh).required(),payload:Ne.string().allow("").optional(),encoding:Ne.string().valid("utf8","ASCII","binary","hex","base64","utf16le","latin1","ucs2").optional()});return jn.validateBySchema(e,t)}a(Lle,"setComponentFileValidator");function Mle(e){let t=Ne.object({project:Ne.string().pattern(Ro).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),file:Ne.string().custom(lh).optional()});return jn.validateBySchema(e,t)}a(Mle,"dropComponentFileValidator");function vle(e){let t=Ne.object({project:Ne.string().required(),file:Ne.string().custom(lh).required(),encoding:Ne.string().valid("utf8","ASCII","binary","hex","base64","utf16le","latin1","ucs2").optional()});return jn.validateBySchema(e,t)}a(vle,"getComponentFileValidator");function Ule(e){let t=Ne.object({project:Ne.string().pattern(Ro).custom(Vg.bind(null,!1)).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME})});return jn.validateBySchema(e,t)}a(Ule,"addComponentValidator");function xle(e){let t=Ne.object({project:Ne.string().pattern(Ro).custom(Vg.bind(null,!0)).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME})});return jn.validateBySchema(e,t)}a(xle,"dropCustomFunctionProjectValidator");function Ble(e){let t=Ne.object({project:Ne.string().pattern(Ro).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),skip_node_modules:Ne.boolean(),skip_symlinks:Ne.boolean()});return jn.validateBySchema(e,t)}a(Ble,"packageComponentValidator");function Hle(e){let t=Ne.object({project:Ne.string().pattern(Ro).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 jn.validateBySchema(e,t)}a(Hle,"deployComponentValidator");function kle(e){let t=Ne.object({name:Ne.string().pattern(Ile).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 jn.validateBySchema(e,t)}a(kle,"addSSHKeyValidator");function Fle(e){let t=Ne.object({name:Ne.string().required(),key:Ne.string().required()});return jn.validateBySchema(e,t)}a(Fle,"updateSSHKeyValidator");function Gle(e){let t=Ne.object({name:Ne.string().required()});return jn.validateBySchema(e,t)}a(Gle,"deleteSSHKeyValidator");function qle(e){let t=Ne.object({known_hosts:Ne.string().required()});return jn.validateBySchema(e,t)}a(qle,"setSSHKnownHostsValidator")});var fh=P((OPe,i$)=>{"use strict";var Kg=require("joi"),Ia=require("path"),id=require("fs-extra"),{exec:$le,spawn:Vle}=require("child_process"),Kle=require("util"),Yle=Kle.promisify($le),od=(H(),D($)),{PACKAGE_ROOT:Wle}=pt(),{handleHDBError:uh,hdb_errors:zle}=me(),{HTTP_STATUS_CODES:dh}=zle,ll=ue(),Qle=rt(),Ca=j(),{once:jle}=require("events");ll.initSync();var JN=ll.get(od.CONFIG_PARAMS.COMPONENTSROOT),t$="npm install --force --omit=dev --json",Jle=`${t$} --dry-run`,Xle=ll.get(od.CONFIG_PARAMS.ROOTPATH),Yg=Ia.join(Xle,"ssh");i$.exports={installModules:rue,auditModules:nue,installAllRootModules:Zle,uninstallRootModule:eue,linkHarperdb:tue,runCommand:ad};async function Zle(e=!1,t=ll.get(od.CONFIG_PARAMS.ROOTPATH)){await Wg();let r=!1,n=process.env;id.pathExistsSync(Yg)&&id.readdirSync(Yg).forEach(s=>{s.includes(".key")&&!r&&(n={GIT_SSH_COMMAND:"ssh -F "+Ia.join(Yg,"config")+" -o UserKnownHostsFile="+Ia.join(Yg,"known_hosts"),...process.env},r=!0)});try{let s=ll.get(od.CONFIG_PARAMS.ROOTPATH),i=Ia.join(s,"node_modules","harperdb");id.lstatSync(i).isSymbolicLink()&&id.unlinkSync(i)}catch(s){s.code!=="ENOENT"&&Ca.error("Error removing symlink:",s)}await ad(e?"npm install --force --ignore-scripts --no-bin-links":"npm install --force --no-bin-links",t,n)}a(Zle,"installAllRootModules");async function eue(e){await ad(`npm uninstall ${e}`,ll.get(od.CONFIG_PARAMS.ROOTPATH))}a(eue,"uninstallRootModule");async function tue(){await Wg(),await ad(`npm link ${Wle}`,ll.get(od.CONFIG_PARAMS.ROOTPATH))}a(tue,"linkHarperdb");async function ad(e,t=void 0,r=process.env){Ca.debug({tagName:"npm_run_command"},`running command: \`${e}\``);let n=Vle(e,{shell:!0,cwd:t,env:r,stdio:["ignore","pipe","pipe"]}),s="",i="";n.stdout.on("data",c=>{let l=c.toString();Ca.debug({tagName:"npm_run_command:stdout"},l),s+=l}),n.stderr.on("data",c=>{let l=c.toString();Ca.error({tagName:"npm_run_command:stderr"},l),i+=l});let[o]=await jle(n,"close");if(o!==0)throw new Error(`Command \`${e}\` exited with code ${o}.${i===""?"":` Error: ${i}`}`);return s||void 0}a(ad,"runCommand");async function rue(e){let t="install_node_modules is deprecated. Dependencies are automatically installed on deploy, and install_node_modules can lead to inconsistent behavior";Ca.warn(t,e.projects);let r=s$(e);if(r)throw uh(r,r.message,dh.BAD_REQUEST);let{projects:n,dry_run:s}=e,i=s===!0?Jle:t$;await Wg(),await n$(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=Ia.join(JN,u),d,_=null;try{let{stdout:h,stderr:m}=await Yle(i,{cwd:f});d=h?h.replace(`
|
|
27
|
+
${r.stack}`;throw KN.error(n),Pq(new Error)}}}a(dle,"getRolePermissions");function fle(e,t){let r=Object.create(null);r.super_user=!1;let n=e.permission;r[Rn.SYSTEM_SCHEMA_NAME]=n[Rn.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]=_le(t[i]);return}r[i]=vq(),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=hle(c,l);r[i].describe||xq.forEach(f=>{u[f]&&(r[i].describe=!0)}),r[i].tables[o]=u}else r[i].tables[o]=YN()})):Object.keys(t[i]).forEach(o=>{r[i].tables[o]=YN()})}),r}a(fle,"translateRolePermissions");function _le(e){let t=vq(!0);return Object.keys(e).forEach(r=>{t.tables[r]=YN(!0,!0,!0,!0,!0)}),t}a(_le,"createStructureUserPermissions");function hle(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 Rn.TIME_STAMP_NAMES.includes(d)&&(_=Lq(d,f[ah])),u[d]=_,u},{}),o=t.primaryKey||t.hash_attribute,c=!!i[o],l=Dq(o);return t.attributes.forEach(({attribute:u})=>{if(i[u]){let f=i[u];f.describe=Hq(f),s.attribute_permissions.push(f),c||mle(f,l)}else if(u!==o){let f;Rn.TIME_STAMP_NAMES.includes(u)?f=Lq(u):f=Dq(u),s.attribute_permissions.push(f)}}),c||s.attribute_permissions.push(l),s.describe=Mq(s),s}else return e.describe=Mq(e),e}a(hle,"getTableAttrPerms");function Mq(e){return xq.filter(t=>e[t]).length>0}a(Mq,"getSchemaTableDescribePerm");function Hq(e){return Bq.filter(t=>e[t]).length>0}a(Hq,"getAttributeDescribePerm");function mle(e,t){Bq.forEach(r=>{e[r]&&!t[r]&&(t[r]=!0,t.describe=!0)})}a(mle,"checkForHashPerms")});var ch={};Ue(ch,{authentication:()=>Wq,bypassAuth:()=>yle,login:()=>Ole,logout:()=>Nle,start:()=>ble});function yle(){Yq=!0}async function Wq(e,t){let r=e.headers.asObject,n=r.authorization,s=r.cookie,i=r.origin,o=[];try{if(i){let h=e.isOperationsServer?Sle?gle:[]:Ele?ple:[];if(h.includes(i)||h.includes("*")){if(e.method==="OPTIONS"){let m=en.get(U.HTTP_CORSACCESSCONTROLALLOWHEADERS)??"Accept, Content-Type, Authorization",S=new co([["Access-Control-Allow-Methods","POST, GET, PUT, DELETE, PATCH, OPTIONS"],["Access-Control-Allow-Headers",m],["Access-Control-Allow-Origin",i]]);return qg&&S.set("Access-Control-Allow-Credentials","true"),{status:200,headers:S}}o.push("Access-Control-Allow-Origin",i),qg&&o.push("Access-Control-Allow-Credentials","true")}}let l,u;if(qg){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 Gq.get(l);break}e.session=u||(u={})}let f=a((h,m,S)=>{let g=new sd.AuthAuditLog(h,m,$o.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===Ds.SUCCESS?QN.notify(g):QN.error(g)},"authAuditLog");if(!e.authorized&&e.mtlsConfig&&e.peerCertificate.subject&&e?._nodeRequest?.socket?.authorizationError&&QN.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 ze.getUser(h,null,e),f(h,Ds.SUCCESS,"mTLS")):(0,sd.debug)("HTTPS/WSS mTLS authorized connection (mTLS did not authorize a user)","from",e.ip)}let d;if(!e.user)if(n){if(d=cl.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 ze.getUser(g,R,e):null;break;case"Bearer":try{d=await Db(S)}catch(N){if(N.message==="invalid token")try{return await gE(S),c({status:-1})}catch{throw N}}break}}catch(E){return Ale&&(cl.get(S)||(cl.set(S,S),f(g,Ds.FAILURE,m))),c({status:401,body:Xo({error:E.message},e)})}cl.set(n,d),Tle&&f(d.username,Ds.SUCCESS,m)}e.user=d}else u?.user?e.user=await ze.getUser(u.user,null,e):(Yq&&(e.ip?.includes("127.0.0.")||e.ip=="::1")||e?._nodeRequest?.socket?.server?._pipeName&&e.ip===void 0)&&(e.user=await(0,$q.getSuperUser)());qg&&(e.session.update=function(h){let m=en.get(U.AUTHENTICATION_COOKIE_EXPIRES);if(!l){l=(0,Vq.v4)();let S=en.get(U.AUTHENTICATION_COOKIE_DOMAINS),g=m?new Date(Date.now()+(0,jN.convertToMS)(m)).toUTCString():Rle,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,Gq.put(h,{expiresAt:m?Date.now()+(0,jN.convertToMS)(m):void 0})},e.login=async function(h,m){let S=e.user=await ze.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")&&di.loginPath?(_.status=302,_.headers.set("Location",di.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 co);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(Wq,t||r?{port:t,securePort:r}:{port:"all"}),qq||(qq=!0,setInterval(()=>{cl=new Map},en.get(U.AUTHENTICATION_CACHETTL)).unref(),Kq.user.addListener(()=>{cl=new Map}))}async function Ole(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 Nle(e){if(!e.baseRequest.session)throw new Error("No session for logout");return await e.baseRequest.session.update({user:null}),"Logout successful"}var $q,Vq,en,sd,Kq,jN,QN,ple,Ele,gle,Sle,Gq,qg,Yq,Tle,Ale,Rle,cl,qq,$g=ye(()=>{$q=M(Gn());$r();Wl();Au();Me();Vq=require("uuid"),en=M(ue());H();sd=M(j()),Kq=M($f());__();jN=M(oe());ji();QN=(0,sd.loggerWithTag)("auth-event");en.initSync();ple=en.get(U.HTTP_CORSACCESSLIST),Ele=en.get(U.HTTP_CORS),gle=en.get(U.OPERATIONSAPI_NETWORK_CORSACCESSLIST),Sle=en.get(U.OPERATIONSAPI_NETWORK_CORS),Gq=lt({table:"hdb_session",database:"system",attributes:[{name:"id",isPrimaryKey:!0},{name:"user"}]}),qg=en.get(U.AUTHENTICATION_ENABLESESSIONS)??!0,Yq=process.env.AUTHENTICATION_AUTHORIZELOCAL??en.get(U.AUTHENTICATION_AUTHORIZELOCAL)??process.env.DEV_MODE,Tle=en.get(U.LOGGING_AUDITAUTHEVENTS_LOGSUCCESSFUL)??!1,Ale=en.get(U.LOGGING_AUDITAUTHEVENTS_LOGFAILED)??!1,Rle="Tue, 01 Oct 8307 19:33:20 GMT",cl=new Map;ze.onInvalidatedUser(()=>{cl=new Map});a(yle,"bypassAuth");a(Wq,"authentication");a(ble,"start");a(Ole,"login");a(Nle,"logout")});var e$=P((yPe,Zq)=>{"use strict";var Ne=require("joi"),zq=require("fs-extra"),Qq=require("path"),jn=rt(),jq=ue(),Jq=(H(),D($)),Xq=j(),{hdb_errors:wle}=me(),{HDB_ERROR_MSGS:tn}=wle,Ro=/^[a-zA-Z0-9-_]+$/,Ile=/^[a-zA-Z0-9-_]+$/;Zq.exports={getDropCustomFunctionValidator:Ple,setCustomFunctionValidator:Dle,addComponentValidator:Ule,dropCustomFunctionProjectValidator:xle,packageComponentValidator:Ble,deployComponentValidator:Hle,setComponentFileValidator:Lle,getComponentFileValidator:vle,dropComponentFileValidator:Mle,addSSHKeyValidator:kle,updateSSHKeyValidator:Fle,deleteSSHKeyValidator:Gle,setSSHKnownHostsValidator:qle};function Vg(e,t,r){try{let n=jq.get(Jq.CONFIG_PARAMS.COMPONENTSROOT),s=Qq.join(n,t);return zq.existsSync(s)?e?t:r.message(tn.PROJECT_EXISTS):e?r.message(tn.NO_PROJECT):t}catch(n){return Xq.error(n),r.message(tn.VALIDATION_ERR)}}a(Vg,"checkProjectExists");function lh(e,t){return e.includes("..")?t.message("Invalid file path"):e}a(lh,"checkFilePath");function Cle(e,t,r,n){try{let s=jq.get(Jq.CONFIG_PARAMS.COMPONENTSROOT),i=Qq.join(s,e,t,r+".js");return zq.existsSync(i)?r:n.message(tn.NO_FILE)}catch(s){return Xq.error(s),n.message(tn.VALIDATION_ERR)}}a(Cle,"checkFileExists");function Ple(e){let t=Ne.object({project:Ne.string().pattern(Ro).custom(Vg.bind(null,!0)).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),type:Ne.string().valid("helpers","routes").required(),file:Ne.string().pattern(Ro).custom(Cle.bind(null,e.project,e.type)).custom(lh).required().messages({"string.pattern.base":tn.BAD_FILE_NAME})});return jn.validateBySchema(e,t)}a(Ple,"getDropCustomFunctionValidator");function Dle(e){let t=Ne.object({project:Ne.string().pattern(Ro).custom(Vg.bind(null,!0)).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),type:Ne.string().valid("helpers","routes").required(),file:Ne.string().custom(lh).required(),function_content:Ne.string().required()});return jn.validateBySchema(e,t)}a(Dle,"setCustomFunctionValidator");function Lle(e){let t=Ne.object({project:Ne.string().pattern(Ro).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),file:Ne.string().custom(lh).required(),payload:Ne.string().allow("").optional(),encoding:Ne.string().valid("utf8","ASCII","binary","hex","base64","utf16le","latin1","ucs2").optional()});return jn.validateBySchema(e,t)}a(Lle,"setComponentFileValidator");function Mle(e){let t=Ne.object({project:Ne.string().pattern(Ro).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),file:Ne.string().custom(lh).optional()});return jn.validateBySchema(e,t)}a(Mle,"dropComponentFileValidator");function vle(e){let t=Ne.object({project:Ne.string().required(),file:Ne.string().custom(lh).required(),encoding:Ne.string().valid("utf8","ASCII","binary","hex","base64","utf16le","latin1","ucs2").optional()});return jn.validateBySchema(e,t)}a(vle,"getComponentFileValidator");function Ule(e){let t=Ne.object({project:Ne.string().pattern(Ro).custom(Vg.bind(null,!1)).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME})});return jn.validateBySchema(e,t)}a(Ule,"addComponentValidator");function xle(e){let t=Ne.object({project:Ne.string().pattern(Ro).custom(Vg.bind(null,!0)).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME})});return jn.validateBySchema(e,t)}a(xle,"dropCustomFunctionProjectValidator");function Ble(e){let t=Ne.object({project:Ne.string().pattern(Ro).required().messages({"string.pattern.base":tn.BAD_PROJECT_NAME}),skip_node_modules:Ne.boolean(),skip_symlinks:Ne.boolean()});return jn.validateBySchema(e,t)}a(Ble,"packageComponentValidator");function Hle(e){let t=Ne.object({project:Ne.string().pattern(Ro).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 jn.validateBySchema(e,t)}a(Hle,"deployComponentValidator");function kle(e){let t=Ne.object({name:Ne.string().pattern(Ile).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 jn.validateBySchema(e,t)}a(kle,"addSSHKeyValidator");function Fle(e){let t=Ne.object({name:Ne.string().required(),key:Ne.string().required()});return jn.validateBySchema(e,t)}a(Fle,"updateSSHKeyValidator");function Gle(e){let t=Ne.object({name:Ne.string().required()});return jn.validateBySchema(e,t)}a(Gle,"deleteSSHKeyValidator");function qle(e){let t=Ne.object({known_hosts:Ne.string().required()});return jn.validateBySchema(e,t)}a(qle,"setSSHKnownHostsValidator")});var fh=P((OPe,i$)=>{"use strict";var Kg=require("joi"),Ia=require("path"),id=require("fs-extra"),{exec:$le,spawn:Vle}=require("child_process"),Kle=require("util"),Yle=Kle.promisify($le),od=(H(),D($)),{PACKAGE_ROOT:Wle}=pt(),{handleHDBError:uh,hdb_errors:zle}=me(),{HTTP_STATUS_CODES:dh}=zle,ll=ue(),Qle=rt(),Ca=j(),{once:jle}=require("events");ll.initSync();var JN=ll.get(od.CONFIG_PARAMS.COMPONENTSROOT),t$="npm install --force --omit=dev --json",Jle=`${t$} --dry-run`,Xle=ll.get(od.CONFIG_PARAMS.ROOTPATH),Yg=Ia.join(Xle,"ssh");i$.exports={installModules:rue,auditModules:nue,installAllRootModules:Zle,uninstallRootModule:eue,linkHarperdb:tue,runCommand:ad};async function Zle(e=!1,t=ll.get(od.CONFIG_PARAMS.ROOTPATH)){await Wg();let r=!1,n=process.env;id.pathExistsSync(Yg)&&id.readdirSync(Yg).forEach(s=>{s.includes(".key")&&!r&&(n={GIT_SSH_COMMAND:"ssh -F "+Ia.join(Yg,"config")+" -o UserKnownHostsFile="+Ia.join(Yg,"known_hosts"),...process.env},r=!0)});try{let s=ll.get(od.CONFIG_PARAMS.ROOTPATH),i=Ia.join(s,"node_modules","harperdb");id.lstatSync(i).isSymbolicLink()&&id.unlinkSync(i)}catch(s){s.code!=="ENOENT"&&Ca.error("Error removing symlink:",s)}await ad(e?"npm install --force --ignore-scripts":"npm install --force",t,n)}a(Zle,"installAllRootModules");async function eue(e){await ad(`npm uninstall ${e}`,ll.get(od.CONFIG_PARAMS.ROOTPATH))}a(eue,"uninstallRootModule");async function tue(){await Wg(),await ad(`npm link ${Wle}`,ll.get(od.CONFIG_PARAMS.ROOTPATH))}a(tue,"linkHarperdb");async function ad(e,t=void 0,r=process.env){Ca.debug({tagName:"npm_run_command"},`running command: \`${e}\``);let n=Vle(e,{shell:!0,cwd:t,env:r,stdio:["ignore","pipe","pipe"]}),s="",i="";n.stdout.on("data",c=>{let l=c.toString();Ca.debug({tagName:"npm_run_command:stdout"},l),s+=l}),n.stderr.on("data",c=>{let l=c.toString();Ca.error({tagName:"npm_run_command:stderr"},l),i+=l});let[o]=await jle(n,"close");if(o!==0)throw new Error(`Command \`${e}\` exited with code ${o}.${i===""?"":` Error: ${i}`}`);return s||void 0}a(ad,"runCommand");async function rue(e){let t="install_node_modules is deprecated. Dependencies are automatically installed on deploy, and install_node_modules can lead to inconsistent behavior";Ca.warn(t,e.projects);let r=s$(e);if(r)throw uh(r,r.message,dh.BAD_REQUEST);let{projects:n,dry_run:s}=e,i=s===!0?Jle:t$;await Wg(),await n$(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=Ia.join(JN,u),d,_=null;try{let{stdout:h,stderr:m}=await Yle(i,{cwd:f});d=h?h.replace(`
|
|
28
28
|
`,""):null,_=m?m.replace(`
|
|
29
29
|
`,""):null}catch(h){h.stderr?o[u].npm_error=r$(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 Ca.info(`finished installModules with response ${o}`),o.warning=t,o}a(rue,"installModules");function r$(e){let t='"error": {',r=e.indexOf('"error": {'),n=e.indexOf(`}
|
|
30
30
|
`);return r>-1&&n>-1?JSON.parse(e.substring(r+t.length-1,n+1)):e}a(r$,"parseNPMStdErr");async function nue(e){Ca.info(`starting auditModules for request: ${e}`);let t=s$(e);if(t)throw uh(t,t.message,dh.BAD_REQUEST);let{projects:r}=e;await Wg(),await n$(r);let n={};for(let s=0,i=r.length;s<i;s++){let o=r[s],c=Ia.join(JN,o);n[o]={npm_output:null,npm_error:null};try{let l=await ad("npm audit --json",c);n[o].npm_output=JSON.parse(l)}catch(l){n[o].npm_error=r$(l.stderr)}}return Ca.info(`finished auditModules with response ${n}`),n}a(nue,"auditModules");async function Wg(){return await ad("npm -v"),!0}a(Wg,"checkNPMInstalled");async function n$(e){if(!Array.isArray(e)||e.length===0)throw uh(new Error,"projects argument must be an array with at least 1 element",dh.BAD_REQUEST,void 0,void 0,!0);let t=[],r=[];for(let n=0,s=e.length;n<s;n++){let i=e[n],o=Ia.join(JN,i.toString());if(!await id.pathExists(o)){t.push(i);continue}let l=Ia.join(o,"package.json");await id.pathExists(l)||r.push(i)}if(t.length>0)throw uh(new Error,`Unable to install project dependencies: custom function projects '${t.join(",")}' does not exist.`,dh.BAD_REQUEST,void 0,void 0,!0);if(r.length>0)throw uh(new Error,`Unable to install project dependencies: custom function projects '${r.join(",")}' do not have a package.json file.`,dh.BAD_REQUEST,void 0,void 0,!0)}a(n$,"checkProjectPaths");function s$(e){let t=Kg.object({projects:Kg.array().min(1).items(Kg.string()).required(),dry_run:Kg.boolean().default(!1)});return Qle.validateBySchema(e,t)}a(s$,"modulesValidator")});var ZN=P((wPe,d$)=>{"use strict";var gs=require("fs-extra"),hh=require("path"),_h=j(),o$=oe(),{PACKAGE_ROOT:sue}=pt(),XN=(H(),D($)),u$=ue(),iue=It();d$.exports=oue;async function oue(){let e=aue(),t=u$.get(XN.CONFIG_PARAMS.ROOTPATH),r=hh.join(t,"package.json"),n={dependencies:{harperdb:"file:"+sue}},s=hh.join(t,"node_modules");gs.ensureDirSync(s);let i,o=!0,c=!1;try{i=gs.readJsonSync(r)}catch(l){if(o$.isEmptyOrZeroLength(e))return;if(l.code!==XN.NODE_ERROR_CODES.ENOENT)throw l;o=!1}if(!o$.isEmptyOrZeroLength(e)){for(let{name:l,package:u}of e){let f=c$(u);n.dependencies[l]=f+u}if(!o){_h.notify("Installing components"),await l$(r,n,null),await a$(t,e);return}for(let{name:l,package:u}of e){let f=i.dependencies[l],d=c$(u);if(f===void 0||f!==d+u){c=!0;break}if(u.startsWith("file:"))try{if(gs.statSync(new URL(u+"/package.json")).mtimeMs>gs.statSync(r).mtimeMs){c=!0;break}}catch(_){_h.info(`Error checking ${u}/package.json modification time`,_);break}}}for(let l in i.dependencies)n.dependencies[l]===void 0&&(_h.notify("Removing component",l),c=!0);c&&(_h.notify("Updating components."),await l$(r,n,i),await a$(t,e))}a(oue,"installComponents");function a$(e,t){return Promise.all(t.map(({name:r})=>{let n=hh.join(e,"node_modules",r),s=hh.join(e,"components",r);if(gs.existsSync(n)&&gs.lstatSync(n).isDirectory())return gs.move(n,s,{overwrite:!0}).then(()=>{gs.symlink(s,n)})}))}a(a$,"moveModuleToComponents");function aue(){let e=iue.getConfiguration(),t=[];for(let r in e)e[r]?.package&&t.push(Object.assign(e[r],{name:r}));return t}a(aue,"getComponentsConfig");function c$(e){return e.includes(":")?"":e.startsWith("@")||!e.startsWith("@")&&!e.includes("/")?"npm:":hh.extname(e)||gs.existsSync(e)?"file:":"github:"}a(c$,"getPkgPrefix");async function l$(e,t,r){_h.trace("npm installing components package.json",t),gs.writeFileSync(e,JSON.stringify(t,null," "));try{await fh().installAllRootModules(u$.get(XN.CONFIG_PARAMS.IGNORE_SCRIPTS)===!0)}catch(n){throw r?gs.writeFileSync(e,JSON.stringify(r,null," ")):gs.unlinkSync(e),n}}a(l$,"installPackages")});var m$={};Ue(m$,{packageDirectory:()=>cue});function cue(e,t={skip_node_modules:!1,skip_symlinks:!1}){return new Promise((r,n)=>{let s=[];_$.default.pack(e,{dereference:!t.skip_symlinks,ignore:t.skip_node_modules?i=>i.includes("node_modules")||i.includes((0,f$.join)("cache","webpack")):void 0}).pipe((0,h$.createGzip)()).on("data",i=>s.push(i)).on("end",()=>{r(Buffer.concat(s))}).on("error",n)})}var f$,_$,h$,p$=ye(()=>{f$=require("path"),_$=M(require("tar-fs")),h$=require("node:zlib");a(cue,"packageDirectory")});var rw=P(T$=>{"use strict";var be=require("fs-extra"),ew=require("fast-glob"),Ie=require("path"),lue=require("tar-fs"),uue=require("gunzip-maybe"),tw=require("normalize-path"),yn=e$(),xt=j(),ot=(H(),D($)),Wt=ue(),zg=It(),due=oe(),{PACKAGE_ROOT:fue}=pt(),{handleHDBError:Bt,hdb_errors:_ue}=me(),{basename:hue}=require("path"),mue=ZN(),g$=ue(),{Readable:pue}=require("stream"),{isMainThread:Eue}=require("worker_threads"),{HDB_ERROR_MSGS:ul,HTTP_STATUS_CODES:Ht}=_ue,S$=tt(),{replicateOperation:Js}=(ds(),D(pa)),{packageDirectory:gue}=(p$(),D(m$)),E$=fh(),Sue=Ie.join(fue,"application-template"),Tue=Wt.get(ot.CONFIG_PARAMS.ROOTPATH),Pa=Ie.join(Tue,"ssh"),yo=Ie.join(Pa,"known_hosts");function Aue(){xt.trace("getting custom api status");let e={};try{e={port:Wt.get(ot.CONFIG_PARAMS.HTTP_PORT),directory:Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT),is_enabled:!0}}catch(t){throw Bt(new Error,ul.FUNCTION_STATUS,Ht.INTERNAL_SERVER_ERROR,xt.ERR,t)}return e}a(Aue,"customFunctionsStatus");function Rue(){xt.trace("getting custom api endpoints");let e={},t=Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT);try{ew.sync(tw(`${t}/*`),{onlyDirectories:!0}).forEach(n=>{let s=n.split("/").pop();e[s]={routes:ew.sync(tw(`${n}/routes/*.js`)).map(i=>i.split("/").pop().split(".js")[0]),helpers:ew.sync(tw(`${n}/helpers/*.js`)).map(i=>i.split("/").pop().split(".js")[0])}})}catch(r){throw Bt(new Error,ul.GET_FUNCTIONS,Ht.INTERNAL_SERVER_ERROR,xt.ERR,r)}return e}a(Rue,"getCustomFunctions");function yue(e){e.project&&(e.project=Ie.parse(e.project).name),e.file&&(e.file=Ie.parse(e.file).name);let t=yn.getDropCustomFunctionValidator(e);if(t)throw Bt(t,t.message,Ht.BAD_REQUEST);xt.trace("getting custom api endpoint file content");let r=Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT),{project:n,type:s,file:i}=e,o=Ie.join(r,n,s,i+".js");try{return be.readFileSync(o,{encoding:"utf8"})}catch(c){throw Bt(new Error,ul.GET_FUNCTION,Ht.INTERNAL_SERVER_ERROR,xt.ERR,c)}}a(yue,"getCustomFunction");async function bue(e){e.project&&(e.project=Ie.parse(e.project).name),e.file&&(e.file=Ie.parse(e.file).name);let t=yn.setCustomFunctionValidator(e);if(t)throw Bt(t,t.message,Ht.BAD_REQUEST);xt.trace("setting custom function file content");let r=Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT),{project:n,type:s,file:i,function_content:o}=e;try{be.outputFileSync(Ie.join(r,n,s,i+".js"),o);let c=await Js(e);return c.message=`Successfully updated custom function: ${i}.js`,c}catch(c){throw Bt(new Error,ul.SET_FUNCTION,Ht.INTERNAL_SERVER_ERROR,xt.ERR,c)}}a(bue,"setCustomFunction");async function Oue(e){e.project&&(e.project=Ie.parse(e.project).name),e.file&&(e.file=Ie.parse(e.file).name);let t=yn.getDropCustomFunctionValidator(e);if(t)throw Bt(t,t.message,Ht.BAD_REQUEST);xt.trace("dropping custom function file");let r=Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT),{project:n,type:s,file:i}=e;try{be.unlinkSync(Ie.join(r,n,s,i+".js"));let o=await Js(e);return o.message=`Successfully deleted custom function: ${i}.js`,o}catch(o){throw Bt(new Error,ul.DROP_FUNCTION,Ht.INTERNAL_SERVER_ERROR,xt.ERR,o)}}a(Oue,"dropCustomFunction");async function Nue(e){e.project&&(e.project=Ie.parse(e.project).name);let t=yn.addComponentValidator(e);if(t)throw Bt(t,t.message,Ht.BAD_REQUEST);xt.trace("adding component");let r=Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT),{project:n}=e;try{let s=Ie.join(r,n);be.mkdirSync(s,{recursive:!0}),be.copySync(Sue,s);let i=await Js(e);return i.message=`Successfully added project: ${n}`,i}catch(s){throw Bt(new Error,ul.ADD_FUNCTION,Ht.INTERNAL_SERVER_ERROR,xt.ERR,s)}}a(Nue,"addComponent");async function wue(e){e.project&&(e.project=Ie.parse(e.project).name);let t=yn.dropCustomFunctionProjectValidator(e);if(t)throw Bt(t,t.message,Ht.BAD_REQUEST);xt.trace("dropping custom function project");let r=Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT),{project:n}=e,s=Wt.get(ot.CONFIG_PARAMS.APPS);if(!due.isEmptyOrZeroLength(s)){let i=!1;for(let[o,c]of s.entries())if(c.name===n){s.splice(o,1),i=!0;break}if(i)return zg.updateConfigValue(ot.CONFIG_PARAMS.APPS,s),`Successfully deleted project: ${n}`}try{let i=Ie.join(r,n);be.rmSync(i,{recursive:!0});let o=await Js(e);return o.message=`Successfully deleted project: ${n}`,o}catch(i){throw Bt(new Error,ul.DROP_FUNCTION_PROJECT,Ht.INTERNAL_SERVER_ERROR,xt.ERR,i)}}a(wue,"dropCustomFunctionProject");async function Iue(e){e.project&&(e.project=Ie.parse(e.project).name);let t=yn.packageComponentValidator(e);if(t)throw Bt(t,t.message,Ht.BAD_REQUEST);let r=Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT),{project:n}=e;xt.trace("packaging component",n);let s;try{s=await be.realpath(Ie.join(r,n))}catch(o){if(o.code!==ot.NODE_ERROR_CODES.ENOENT)throw o;try{s=await be.realpath(Ie.join(Wt.get(ot.CONFIG_PARAMS.ROOTPATH),"node_modules",n))}catch(c){if(c.code===ot.NODE_ERROR_CODES.ENOENT)throw new Error(`Unable to locate project '${n}'`)}}let i=(await gue(s,e)).toString("base64");return{project:n,payload:i}}a(Iue,"packageComponent");async function Cue(e){e.project?e.project=Ie.parse(e.project).name:e.package&&(e.project=Pue(e.package));let t=yn.deployComponentValidator(e);if(t)throw Bt(t,t.message,Ht.BAD_REQUEST);let r=Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT),{project:n,payload:s,package:i,install_command:o}=e;if(xt.trace("deploying component",n),!s&&!i)throw new Error("'payload' or 'package' must be provided");let c;if(s){c=Ie.join(r,n),i="file:"+c,await be.emptyDir(c);let S=pue.from(s instanceof Buffer?s:Buffer.from(s,"base64"));await new Promise((E,T)=>{S.pipe(uue()).pipe(lue.extract(c,{finish:E})).on("error",T)});let g=await be.readdir(c);g.length===1&&g[0]==="package"&&(await be.copy(Ie.join(c,"package"),c),await be.remove(Ie.join(c,"package")));let R=Ie.join(c,"node_modules");o?await E$.runCommand(o,c):be.existsSync(R)||await E$.installAllRootModules(!1,c)}else{await zg.addConfig(n,{package:i}),await mue();let S=g$.get(ot.CONFIG_PARAMS.ROOTPATH);c=Ie.join(S,"node_modules",n)}if(Eue)return;let l=new Map;l.isWorker=!0;let u=(ph(),D(mh)),f;u.setErrorReporter(S=>f=S);let d=hue(c),_=u.component_errors.get(d);try{await u.loadComponent(c,l)}finally{u.component_errors.set(d,_)}if(f)throw f;xt.info("Installed component");let h=e.restart==="rolling";e.restart=h?!1:e.restart;let m=await Js(e);if(e.restart===!0)S$.restartWorkers("http"),m.message=`Successfully deployed: ${n}, restarting HarperDB`;else if(h){let g=await nw().executeJob({operation:"restart_service",service:"http",replicated:!0});m.restartJobId=g.job_id,m.message=`Successfully deployed: ${n}, restarting HarperDB`}else m.message=`Successfully deployed: ${n}`;return m}a(Cue,"deployComponent");function Pue(e){if(e.startsWith("git+ssh://"))return Ie.basename(e.split("#")[0].replace(/\.git$/,""));if(e.startsWith("http://")||e.startsWith("https://"))return Ie.basename(new URL(e.replace(/\.git$/,"")).pathname);if(e.startsWith("file://"))try{let{name:t}=JSON.parse(be.readFileSync(Ie.join(e,"package.json"),"utf8"));return Ie.basename(t)}catch{}return Ie.basename(e)}a(Pue,"getProjectNameFromPackage");async function Due(){let e=a(async(s,i)=>{try{let o=await be.readdir(s,{withFileTypes:!0});for(let c of o){let l=c.name;if(l.startsWith(".")||l==="node_modules")continue;let u=Ie.join(s,l);if(c.isDirectory()||c.isSymbolicLink()){let f={name:l,entries:[]};i.entries.push(f),await e(u,f)}else{let f=await be.stat(u),d={name:Ie.basename(l),mtime:f.mtime,size:f.size};i.entries.push(d)}}return i}catch(o){return xt.warn("Error loading package",o),{error:o.toString(),entries:[]}}},"walkDir"),t=await e(Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT),{name:Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT).split(Ie.sep).slice(-1).pop(),entries:[]}),n=(ph(),D(mh)).component_errors;for(let s of t.entries){let i=n.get(s.name);i?s.error=n.get(s.name):i===void 0&&(s.error="The component has not been loaded yet (may need a restart)")}return t}a(Due,"getComponents");async function Lue(e){let t=yn.getComponentFileValidator(e);if(t)throw Bt(t,t.message,Ht.BAD_REQUEST);let n=zg.getConfigObj()[e.project]||e.project==="harperdb"?Ie.join(g$.get(ot.CONFIG_PARAMS.ROOTPATH),"node_modules"):Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT),s=e.encoding?{encoding:e.encoding}:{encoding:"utf8"};try{let i=await be.stat(Ie.join(n,e.project,e.file));return{message:await be.readFile(Ie.join(n,e.project,e.file),s),size:i.size,birthtime:i.birthtime,mtime:i.mtime}}catch(i){throw i.code===ot.NODE_ERROR_CODES.ENOENT?new Error(`Component file not found '${Ie.join(e.project,e.file)}'`):i}}a(Lue,"getComponentFile");async function Mue(e){let t=yn.setComponentFileValidator(e);if(t)throw Bt(t,t.message,Ht.BAD_REQUEST);let r=e.encoding?{encoding:e.encoding}:{encoding:"utf8"},n=Ie.join(Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT),e.project,e.file);e.payload!==void 0?(await be.ensureFile(n),await be.outputFile(n,e.payload,r)):await be.ensureDir(n);let s=await Js(e);return s.message="Successfully set component: "+e.file,s}a(Mue,"setComponentFile");async function vue(e){let t=yn.dropComponentFileValidator(e);if(t)throw Bt(t,t.message,Ht.BAD_REQUEST);let{project:r,file:n}=e,s=e.file?Ie.join(r,n):r,i=Ie.join(Wt.get(ot.CONFIG_PARAMS.COMPONENTSROOT),s),o=Ie.join(Wt.get(ot.CONFIG_PARAMS.ROOTPATH),"node_modules",r);await be.pathExists(o)&&await be.unlink(o),await be.pathExists(i)&&await be.remove(i);let c=Ie.join(Wt.get(ot.CONFIG_PARAMS.ROOTPATH),"package.json");if(await be.pathExists(c)){let u=JSON.parse(await be.readFile(c,"utf8"));u?.dependencies?.[r]&&delete u.dependencies[r],await be.writeFile(c,JSON.stringify(u,null,2),"utf8")}zg.deleteConfigFromFile([r]);let l=await Js(e);return e.restart===!0?(S$.restartWorkers("http"),l.message=`Successfully dropped: ${s}, restarting HarperDB`):l.message=`Successfully dropped: ${s}`,l}a(vue,"dropComponent");async function Uue(e){let t=yn.addSSHKeyValidator(e);if(t)throw Bt(t,t.message,Ht.BAD_REQUEST);let{name:r,key:n,host:s,hostname:i,known_hosts:o}=e;xt.trace("adding ssh key",r);let c=Ie.join(Pa,r+".key"),l=Ie.join(Pa,"config");if(await be.pathExists(c))throw new Error("Key already exists. Use update_ssh_key or delete_ssh_key and then add_ssh_key");await be.outputFile(c,n),await be.chmod(c,"0600");let u=`#${r}
|
|
@@ -1,48 +1,48 @@
|
|
|
1
1
|
{
|
|
2
2
|
"files": {
|
|
3
3
|
"main.css": "/static/css/main.34b26890.css",
|
|
4
|
-
"main.js": "/static/js/main.
|
|
5
|
-
"online-app.js": "/static/js/online-app.
|
|
6
|
-
"offline-app.js": "/static/js/offline-app.
|
|
7
|
-
"topnav.js": "/static/js/topnav.
|
|
8
|
-
"signUp.js": "/static/js/signUp.
|
|
9
|
-
"signIn.js": "/static/js/signIn.
|
|
10
|
-
"resetPassword.js": "/static/js/resetPassword.
|
|
11
|
-
"updatePassword.js": "/static/js/updatePassword.
|
|
12
|
-
"organization.js": "/static/js/organization.
|
|
13
|
-
"organizations.js": "/static/js/organizations.
|
|
14
|
-
"instances.js": "/static/js/instances.
|
|
15
|
-
"instance.js": "/static/js/instance.
|
|
16
|
-
"profile.js": "/static/js/profile.
|
|
17
|
-
"organization-users.js": "/static/js/organization-users.
|
|
18
|
-
"organization-billing.js": "/static/js/organization-billing.
|
|
19
|
-
"instance-cluster.js": "/static/js/instance-cluster.
|
|
20
|
-
"instance-config.js": "/static/js/instance-config.
|
|
21
|
-
"instance-status.js": "/static/js/instance-status.
|
|
22
|
-
"instance-logs.js": "/static/js/instance-logs.
|
|
23
|
-
"instance-users.js": "/static/js/instance-users.
|
|
24
|
-
"instance-roles.js": "/static/js/instance-roles.
|
|
25
|
-
"custom-functions.js": "/static/js/custom-functions.
|
|
26
|
-
"browse-datatable.js": "/static/js/browse-datatable.
|
|
27
|
-
"browse-entitymanager.js": "/static/js/browse-entitymanager.
|
|
28
|
-
"browse-jsonviewer.js": "/static/js/browse-jsonviewer.
|
|
29
|
-
"browse-csvupload.js": "/static/js/browse-csvupload.
|
|
30
|
-
"structure-reloader.js": "/static/js/structure-reloader.
|
|
31
|
-
"instance-users-datatable.js": "/static/js/instance-users-datatable.
|
|
32
|
-
"instance-users-edit.js": "/static/js/instance-users-edit.
|
|
33
|
-
"roles-jsonviewer.js": "/static/js/roles-jsonviewer.
|
|
4
|
+
"main.js": "/static/js/main.491129ee.js",
|
|
5
|
+
"online-app.js": "/static/js/online-app.22102869.chunk.js",
|
|
6
|
+
"offline-app.js": "/static/js/offline-app.5bc1159b.chunk.js",
|
|
7
|
+
"topnav.js": "/static/js/topnav.e661156c.chunk.js",
|
|
8
|
+
"signUp.js": "/static/js/signUp.07fd6662.chunk.js",
|
|
9
|
+
"signIn.js": "/static/js/signIn.32766fa9.chunk.js",
|
|
10
|
+
"resetPassword.js": "/static/js/resetPassword.812fc880.chunk.js",
|
|
11
|
+
"updatePassword.js": "/static/js/updatePassword.dcac970c.chunk.js",
|
|
12
|
+
"organization.js": "/static/js/organization.eab64d57.chunk.js",
|
|
13
|
+
"organizations.js": "/static/js/organizations.4567ae59.chunk.js",
|
|
14
|
+
"instances.js": "/static/js/instances.f28e5ce7.chunk.js",
|
|
15
|
+
"instance.js": "/static/js/instance.9689d62b.chunk.js",
|
|
16
|
+
"profile.js": "/static/js/profile.d45cd6b3.chunk.js",
|
|
17
|
+
"organization-users.js": "/static/js/organization-users.b46b9e8f.chunk.js",
|
|
18
|
+
"organization-billing.js": "/static/js/organization-billing.56e7e051.chunk.js",
|
|
19
|
+
"instance-cluster.js": "/static/js/instance-cluster.031dcced.chunk.js",
|
|
20
|
+
"instance-config.js": "/static/js/instance-config.9a23d6ae.chunk.js",
|
|
21
|
+
"instance-status.js": "/static/js/instance-status.192a5e2f.chunk.js",
|
|
22
|
+
"instance-logs.js": "/static/js/instance-logs.fdaf96ec.chunk.js",
|
|
23
|
+
"instance-users.js": "/static/js/instance-users.adc43a74.chunk.js",
|
|
24
|
+
"instance-roles.js": "/static/js/instance-roles.984ced56.chunk.js",
|
|
25
|
+
"custom-functions.js": "/static/js/custom-functions.31d65bca.chunk.js",
|
|
26
|
+
"browse-datatable.js": "/static/js/browse-datatable.21e650e1.chunk.js",
|
|
27
|
+
"browse-entitymanager.js": "/static/js/browse-entitymanager.4547c0d8.chunk.js",
|
|
28
|
+
"browse-jsonviewer.js": "/static/js/browse-jsonviewer.71355c20.chunk.js",
|
|
29
|
+
"browse-csvupload.js": "/static/js/browse-csvupload.84fd1ae9.chunk.js",
|
|
30
|
+
"structure-reloader.js": "/static/js/structure-reloader.ce2b39d2.chunk.js",
|
|
31
|
+
"instance-users-datatable.js": "/static/js/instance-users-datatable.40846e47.chunk.js",
|
|
32
|
+
"instance-users-edit.js": "/static/js/instance-users-edit.f10344c8.chunk.js",
|
|
33
|
+
"roles-jsonviewer.js": "/static/js/roles-jsonviewer.73c8bb9d.chunk.js",
|
|
34
34
|
"static/js/43.73dc432d.chunk.js": "/static/js/43.73dc432d.chunk.js",
|
|
35
35
|
"static/js/851.4c6536d6.chunk.js": "/static/js/851.4c6536d6.chunk.js",
|
|
36
36
|
"static/js/759.7c5150cd.chunk.js": "/static/js/759.7c5150cd.chunk.js",
|
|
37
|
-
"static/js/
|
|
37
|
+
"static/js/504.6e6ee908.chunk.js": "/static/js/504.6e6ee908.chunk.js",
|
|
38
38
|
"static/js/239.183c6cbc.chunk.js": "/static/js/239.183c6cbc.chunk.js",
|
|
39
39
|
"static/js/279.7dfac9c5.chunk.js": "/static/js/279.7dfac9c5.chunk.js",
|
|
40
40
|
"static/js/23.3b9f7144.chunk.js": "/static/js/23.3b9f7144.chunk.js",
|
|
41
|
-
"static/js/164.
|
|
41
|
+
"static/js/164.a89f3fc2.chunk.js": "/static/js/164.a89f3fc2.chunk.js",
|
|
42
42
|
"static/js/545.046f5738.chunk.js": "/static/js/545.046f5738.chunk.js",
|
|
43
43
|
"static/js/860.727e7fc8.chunk.js": "/static/js/860.727e7fc8.chunk.js",
|
|
44
44
|
"static/js/805.6aab06e2.chunk.js": "/static/js/805.6aab06e2.chunk.js",
|
|
45
|
-
"static/js/833.
|
|
45
|
+
"static/js/833.e460eaf4.chunk.js": "/static/js/833.e460eaf4.chunk.js",
|
|
46
46
|
"static/media/PPRadioGrotesk-Bold.woff": "/static/media/PPRadioGrotesk-Bold.31436818ea74a78b55af.woff",
|
|
47
47
|
"static/media/logo_harper_db_studio.png": "/static/media/logo_harper_db_studio.81490e70fa4af6879c2e.png",
|
|
48
48
|
"index.html": "/index.html",
|
|
@@ -50,6 +50,6 @@
|
|
|
50
50
|
},
|
|
51
51
|
"entrypoints": [
|
|
52
52
|
"static/css/main.34b26890.css",
|
|
53
|
-
"static/js/main.
|
|
53
|
+
"static/js/main.491129ee.js"
|
|
54
54
|
]
|
|
55
55
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="theme-color" content="#480b8a"/><meta charset="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"/><link id="dynamic-favicon" rel="shortcut icon" href="/images/favicon_purple.png"><link rel="canonical" href=""/><link href="/fontawesome/fontawesome.css" rel="stylesheet"><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Ubuntu:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,700&display=swap" rel="stylesheet"><link rel="manifest" href="/manifest.json"/><meta name="description" content="HarperDB is a full-featured data management platform that runs from edge to cloud, and anywhere in between. "><title>Studio :: HarperDB</title><script defer="defer" src="/static/js/main.
|
|
1
|
+
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="theme-color" content="#480b8a"/><meta charset="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"/><link id="dynamic-favicon" rel="shortcut icon" href="/images/favicon_purple.png"><link rel="canonical" href=""/><link href="/fontawesome/fontawesome.css" rel="stylesheet"><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Ubuntu:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,700&display=swap" rel="stylesheet"><link rel="manifest" href="/manifest.json"/><meta name="description" content="HarperDB is a full-featured data management platform that runs from edge to cloud, and anywhere in between. "><title>Studio :: HarperDB</title><script defer="defer" src="/static/js/main.491129ee.js"></script><link href="/static/css/main.34b26890.css" rel="stylesheet"></head><body><div id="app"></div></body><script src="/fontawesome/fontawesome.js" crossorigin="anonymous" defer="defer"></script><script src="/js/kissmetrics.js" defer="defer"></script><script src="/js/linkedin.js" defer="defer"></script></html>
|