@medplum/cli 4.3.0 → 4.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/index.cjs.map +2 -2
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/index.mjs.map +2 -2
- package/package.json +5 -5
package/dist/cjs/index.cjs
CHANGED
|
@@ -11,7 +11,7 @@ Configuration values come from a file named **medplum.<tag>.config.server.json**
|
|
|
11
11
|
`+ae.yellow("**Services must be restarted to apply changes.**"))).argument("<tag>","The Medplum stack tag").option("--file [file]",rr("File to provide overrides for **apiPort**, **baseUrl**, **appDomainName** and **storageDomainName** values that appear in the config file.")).option("--dryrun","Displays the operations that would be performed using the specified command without actually running them.").option("--yes","Automatically confirm the update").action(qs),y(t,new g("update-server").alias("deploy-server").description("Update the server image").argument("<tag>","The Medplum stack tag").option("--file [file]","Specifies the config file to use. If not specified, the file is based on the tag.").option("--to-version [version]","Specifies the version of the configuration to update. If not specified, the latest version is updated.").action(Vs)),t.command("update-app").alias("deploy-app").description("Update the app site").argument("<tag>","The Medplum stack tag").option("--file [file]","Specifies the config file to use. If not specified, the file is based on the tag.").option("--to-version [version]","Specifies the version of the configuration to update. If not specified, the latest version is updated.").option("--dryrun","Displays the operations that would be performed using the specified command without actually running them.").option("--tar-path [tarPath]","Specifies the path to the extracted tarball of the @medplum/app package.").action(Fs),t.command("update-bucket-policies").description("Update S3 bucket policies").argument("<tag>","The Medplum stack tag").option("--file [file]","Specifies the config file to use. If not specified, the file is based on the tag.").option("--dryrun","Displays the operations that would be performed using the specified command without actually running them.").action(Ks),t}var Xs=new g("save"),zs=new g("deploy"),Ys=new g("create"),Ke=new g("bot");y(Ke,Xs);y(Ke,zs);y(Ke,Ys);var br=new g("save-bot"),Pr=new g("deploy-bot"),Cr=new g("create-bot");Xs.description("Saving the bot").argument("<botName>").action(async(t,e)=>{let r=await R(e);await Ot(r,t)});zs.description("Deploy the app to AWS").argument("<botName>").action(async(t,e)=>{let r=await R(e);await Ot(r,t,!0)});Ys.arguments("<botName> <projectId> <sourceFile> <distFile>").description("Creating a bot").option("--runtime-version <runtimeVersion>","Runtime version (awslambda, vmcontext)").option("--no-write-config","Do not write bot to config").action(async(t,e,r,o,n)=>{let s=await R(n);await zt(s,t,e,r,o,n.runtimeVersion,!!n.writeConfig)});async function Ot(t,e,r=!1){let o=fo(e),n=[],s=[],i=0,c=0;for(let l of o)try{let u=await t.readResource("Bot",l.id);await Jt(t,l,u),i++,r&&(await Xt(t,l,u),c++)}catch(u){n.push(u),s.push(`${l.name} [${l.id}]`)}if(console.log(`Number of bots saved: ${i}`),console.log(`Number of bots deployed: ${c}`),console.log(`Number of errors: ${n.length}`),n.length)throw new Error(`${n.length} bot(s) had failures. Bots with failures:
|
|
12
12
|
|
|
13
13
|
${s.join(`
|
|
14
|
-
`)}`,{cause:n})}br.description("Saves the bot").argument("<botName>").action(async(t,e)=>{let r=await R(e);await Ot(r,t)});Pr.description("Deploy the bot to AWS").argument("<botName>").action(async(t,e)=>{let r=await R(e);await Ot(r,t,!0)});Cr.arguments("<botName> <projectId> <sourceFile> <distFile>").description("Creates and saves the bot").action(async(t,e,r,o,n)=>{let s=await R(n);await zt(s,t,e,r,o)});var xt=require("node:fs"),Tr=require("node:path"),Qs=require("node:readline");var ei=new g("export"),ti=new g("import"),$t=new g("bulk");y($t,ei);y($t,ti);ei.option("-e, --export-level <exportLevel>",'Optional export level. Defaults to system level export. "Group/:id" - Group of Patients, "Patient" - All Patients.').option("-t, --types <types>","optional resource types to export").option("-s, --since <since>","optional Resources will be included in the response if their state has changed after the supplied time (e.g. if Resource.meta.lastUpdated is later than the supplied _since time).").option("-d, --target-directory <targetDirectory>","optional target directory to save files from the bulk export operations.").action(async t=>{let{exportLevel:e,types:r,since:o,targetDirectory:n}=t,s=await R(t);(await s.bulkExport(e,r,o,{pollStatusOnAccepted:!0})).output?.forEach(async({type:c,url:l})=>{let u=new URL(l),h=await s.download(l),f=`${c}_${u.pathname}`.replace(/[^a-zA-Z0-9]+/g,"_")+".ndjson",S=(0,Tr.resolve)(n??"",f);(0,xt.writeFile)(`${S}`,await h.text(),()=>{console.log(`${S} is created`)})})});ti.argument("<filename>","File Name").option("--num-resources-per-request <numResourcesPerRequest>","optional number of resources to import per batch request. Defaults to 25.","25").option("--add-extensions-for-missing-values","optional flag to add extensions for missing values in a resource",!1).option("-d, --target-directory <targetDirectory>","optional target directory of file to be imported").action(async(t,e)=>{let{numResourcesPerRequest:r,addExtensionsForMissingValues:o,targetDirectory:n}=e,s=(0,Tr.resolve)(n??process.cwd(),t),i=await R(e);await Wu(s,Number.parseInt(r,10),i,o)});async function Wu(t,e,r,o){let n=[],s=(0,xt.createReadStream)(t),i=(0,Qs.createInterface)({input:s});for await(let c of i){let l=Ku(c,o);n.push({resource:l,request:{method:"POST",url:l.resourceType}}),n.length%e===0&&(await Zs(n,r),n=[])}n.length>0&&await Zs(n,r)}async function Zs(t,e){(await e.executeBatch({resourceType:"Bundle",type:"transaction",entry:t})).entry?.forEach(o=>{J(o.response)})}function Ku(t,e){let r=JSON.parse(t);return e?qu(r):r}function qu(t){return t.resourceType==="ExplanationOfBenefit"?Hu(t):t}function Hu(t){return t.provider||(t.provider=Yt()),t.item?.forEach(e=>{e?.productOrService||(e.productOrService=Yt())}),t}var Lt=require("@medplum/core");var oi=require("node:net"),ni=require("@medplum/core"),Or=$(require("iconv-lite"),1),ci=require("@medplum/core"),li=$(require("node:net"),1),ri=class extends EventTarget{addEventListener(t,e,r){super.addEventListener(t,e,r)}removeEventListener(t,e,r){super.removeEventListener(t,e,r)}};var Gu=class extends Event{constructor(t,e){super("message"),this.connection=t,this.message=e}},Nt=class extends Event{constructor(t){super("error"),this.error=t}},si=class extends Event{constructor(){super("close")}},ii=class extends ri{constructor(t,e="utf-8",r=!1){super(),this.chunks=[],this.messageQueue=[],this.socket=t,this.encoding=e,this.enhancedMode=r,t.on("data",o=>{try{if(this.appendData(o),o.at(-2)===28&&o.at(-1)===13){let n=Buffer.concat(this.chunks),s=n.subarray(1,n.length-2),i=Or.default.decode(s,this.encoding),c=ni.Hl7Message.parse(i);this.dispatchEvent(new Gu(this,c)),this.resetBuffer()}}catch(n){this.dispatchEvent(new Nt(n))}}),t.on("error",o=>{this.resetBuffer(),this.dispatchEvent(new Nt(o))}),t.on("end",()=>{this.close()}),this.addEventListener("message",o=>{r&&this.send(o.message.buildAck({ackCode:"CA"}));let n=this.messageQueue.shift();if(!n){this.dispatchEvent(new Nt(new Error(`Received a message when no pending messages were in the queue. Message: ${o.message}`)));return}n.resolve?.(o.message)})}sendImpl(t,e){this.messageQueue.push(e);let r=t.toString(),o=Or.default.encode(r,this.encoding),n=Buffer.alloc(o.length+3);n.writeInt8(11,0),o.copy(n,1),n.writeInt8(28,o.length+1),n.writeInt8(13,o.length+2),this.socket.write(n)}send(t){this.sendImpl(t,{message:t})}async sendAndWait(t){return new Promise((e,r)=>{let o={message:t,resolve:e,reject:r};this.sendImpl(t,o)})}close(){this.socket.end(),this.socket.destroy(),this.dispatchEvent(new si)}appendData(t){this.chunks.push(t)}resetBuffer(){this.chunks=[]}},ai=class extends ri{constructor(t){super(),this.options=t,this.host=this.options.host,this.port=this.options.port,this.encoding=this.options.encoding,this.keepAlive=this.options.keepAlive??!1,this.connectTimeout=this.options.connectTimeout??3e4}connect(){return this.connection?Promise.resolve(this.connection):(this.socket&&(this.socket.removeAllListeners(),this.socket.destroy(),this.socket=void 0),new Promise((t,e)=>{this.socket=(0,oi.connect)({host:this.host,port:this.port,keepAlive:this.keepAlive}),this.connectTimeout>0&&(this.socket.setTimeout(this.connectTimeout),this.socket.on("timeout",()=>{let r=new Error(`Connection timeout after ${this.connectTimeout}ms`);this.socket&&(this.socket.destroy(),this.socket=void 0),e(r)})),this.socket.on("connect",()=>{if(!this.socket)return;let r;this.connection=r=new ii(this.socket,this.encoding),this.socket.setTimeout(0),r.addEventListener("close",()=>{this.socket=void 0,this.dispatchEvent(new si)}),r.addEventListener("error",o=>{this.dispatchEvent(new Nt(o.error))}),t(this.connection)}),this.socket.on("error",r=>{this.socket&&(this.socket.destroy(),this.socket=void 0),e(r)})}))}async send(t){return(await this.connect()).send(t)}async sendAndWait(t){return(await this.connect()).sendAndWait(t)}close(){this.socket&&(this.socket.removeAllListeners(),this.socket.destroy(),this.socket=void 0),this.connection&&(this.connection.close(),delete this.connection)}},ui=class{constructor(t){this.handler=t}start(t,e,r=!1){let o=li.default.createServer(s=>{let i=new ii(s,e,r);this.handler(i)}),n=async s=>{s?.code==="EADDRINUSE"&&(await(0,ci.sleep)(50),o.close(),o.listen(t))};o.on("error",n),o.once("listening",()=>{o.off("error",n)}),o.listen(t),this.server=o}async stop(){return new Promise((t,e)=>{if(!this.server){e(new Error("Stop was called but there is no server running"));return}this.server.close(r=>{if(r){e(r);return}t()}),this.server=void 0})}};var pi=require("node:fs");var Vu=new g("send").description("Send an HL7 v2 message via MLLP").argument("<host>","The destination host name or IP address").argument("<port>","The destination port number").argument("[body]","Optional HL7 message body").option("--generate-example","Generate a sample HL7 message").option("--file <file>","Read the HL7 message from a file").option("--encoding <encoding>","The encoding to use").action(async(t,e,r,o)=>{if(o.generateExample?r=Xu():o.file&&(r=(0,pi.readFileSync)(o.file,"utf8")),!r)throw new Error("Missing HL7 message body");let n=new ai({host:t,port:Number.parseInt(e,10),encoding:o.encoding});try{let s=await n.sendAndWait(Lt.Hl7Message.parse(r));console.log(s.toString().replaceAll("\r",`
|
|
14
|
+
`)}`,{cause:n})}br.description("Saves the bot").argument("<botName>").action(async(t,e)=>{let r=await R(e);await Ot(r,t)});Pr.description("Deploy the bot to AWS").argument("<botName>").action(async(t,e)=>{let r=await R(e);await Ot(r,t,!0)});Cr.arguments("<botName> <projectId> <sourceFile> <distFile>").description("Creates and saves the bot").action(async(t,e,r,o,n)=>{let s=await R(n);await zt(s,t,e,r,o)});var xt=require("node:fs"),Tr=require("node:path"),Qs=require("node:readline");var ei=new g("export"),ti=new g("import"),$t=new g("bulk");y($t,ei);y($t,ti);ei.option("-e, --export-level <exportLevel>",'Optional export level. Defaults to system level export. "Group/:id" - Group of Patients, "Patient" - All Patients.').option("-t, --types <types>","optional resource types to export").option("-s, --since <since>","optional Resources will be included in the response if their state has changed after the supplied time (e.g. if Resource.meta.lastUpdated is later than the supplied _since time).").option("-d, --target-directory <targetDirectory>","optional target directory to save files from the bulk export operations.").action(async t=>{let{exportLevel:e,types:r,since:o,targetDirectory:n}=t,s=await R(t);(await s.bulkExport(e,r,o,{pollStatusOnAccepted:!0})).output?.forEach(async({type:c,url:l})=>{let u=new URL(l),h=await s.download(l),f=`${c}_${u.pathname}`.replace(/[^a-zA-Z0-9]+/g,"_")+".ndjson",S=(0,Tr.resolve)(n??"",f);(0,xt.writeFile)(`${S}`,await h.text(),()=>{console.log(`${S} is created`)})})});ti.argument("<filename>","File Name").option("--num-resources-per-request <numResourcesPerRequest>","optional number of resources to import per batch request. Defaults to 25.","25").option("--add-extensions-for-missing-values","optional flag to add extensions for missing values in a resource",!1).option("-d, --target-directory <targetDirectory>","optional target directory of file to be imported").action(async(t,e)=>{let{numResourcesPerRequest:r,addExtensionsForMissingValues:o,targetDirectory:n}=e,s=(0,Tr.resolve)(n??process.cwd(),t),i=await R(e);await Wu(s,Number.parseInt(r,10),i,o)});async function Wu(t,e,r,o){let n=[],s=(0,xt.createReadStream)(t),i=(0,Qs.createInterface)({input:s});for await(let c of i){let l=Ku(c,o);n.push({resource:l,request:{method:"POST",url:l.resourceType}}),n.length%e===0&&(await Zs(n,r),n=[])}n.length>0&&await Zs(n,r)}async function Zs(t,e){(await e.executeBatch({resourceType:"Bundle",type:"transaction",entry:t})).entry?.forEach(o=>{J(o.response)})}function Ku(t,e){let r=JSON.parse(t);return e?qu(r):r}function qu(t){return t.resourceType==="ExplanationOfBenefit"?Hu(t):t}function Hu(t){return t.provider||(t.provider=Yt()),t.item?.forEach(e=>{e?.productOrService||(e.productOrService=Yt())}),t}var Lt=require("@medplum/core");var oi=require("node:net"),ni=require("@medplum/core"),Or=$(require("iconv-lite"),1),ci=require("@medplum/core"),li=$(require("node:net"),1),ri=class extends EventTarget{addEventListener(t,e,r){super.addEventListener(t,e,r)}removeEventListener(t,e,r){super.removeEventListener(t,e,r)}};var Gu=class extends Event{constructor(t,e){super("message"),this.connection=t,this.message=e}},Nt=class extends Event{constructor(t){super("error"),this.error=t}},si=class extends Event{constructor(){super("close")}},ii=class extends ri{constructor(t,e="utf-8",r=!1){super(),this.chunks=[],this.messageQueue=[],this.socket=t,this.encoding=e,this.enhancedMode=r,t.on("data",o=>{try{if(this.appendData(o),o.at(-2)===28&&o.at(-1)===13){let n=Buffer.concat(this.chunks),s=n.subarray(1,n.length-2),i=Or.default.decode(s,this.encoding),c=ni.Hl7Message.parse(i);this.dispatchEvent(new Gu(this,c)),this.resetBuffer()}}catch(n){this.dispatchEvent(new Nt(n))}}),t.on("error",o=>{this.resetBuffer(),this.dispatchEvent(new Nt(o))}),t.on("end",()=>{this.close()}),this.addEventListener("message",o=>{r&&this.send(o.message.buildAck({ackCode:"CA"}));let n=this.messageQueue.shift();if(!n){this.dispatchEvent(new Nt(new Error(`Received a message when no pending messages were in the queue. Message: ${o.message}`)));return}n.resolve?.(o.message)})}sendImpl(t,e){this.messageQueue.push(e);let r=t.toString(),o=Or.default.encode(r,this.encoding),n=Buffer.alloc(o.length+3);n.writeInt8(11,0),o.copy(n,1),n.writeInt8(28,o.length+1),n.writeInt8(13,o.length+2),this.socket.write(n)}send(t){this.sendImpl(t,{message:t})}async sendAndWait(t){return new Promise((e,r)=>{let o={message:t,resolve:e,reject:r};this.sendImpl(t,o)})}close(){this.socket.end(),this.socket.destroy(),this.dispatchEvent(new si)}appendData(t){this.chunks.push(t)}resetBuffer(){this.chunks=[]}},ai=class extends ri{constructor(t){super(),this.options=t,this.host=this.options.host,this.port=this.options.port,this.encoding=this.options.encoding,this.keepAlive=this.options.keepAlive??!1,this.connectTimeout=this.options.connectTimeout??3e4}connect(){return this.connection?Promise.resolve(this.connection):(this.socket&&(this.socket.removeAllListeners(),this.socket.destroy(),this.socket=void 0),new Promise((t,e)=>{this.socket=(0,oi.connect)({host:this.host,port:this.port,keepAlive:this.keepAlive}),this.connectTimeout>0&&(this.socket.setTimeout(this.connectTimeout),this.socket.on("timeout",()=>{let r=new Error(`Connection timeout after ${this.connectTimeout}ms`);this.socket&&(this.socket.destroy(),this.socket=void 0),e(r)})),this.socket.on("connect",()=>{if(!this.socket)return;let r;this.connection=r=new ii(this.socket,this.encoding),this.socket.setTimeout(0),r.addEventListener("close",()=>{this.socket=void 0,this.connection=void 0,this.dispatchEvent(new si)}),r.addEventListener("error",o=>{this.dispatchEvent(new Nt(o.error))}),t(this.connection)}),this.socket.on("error",r=>{this.socket&&(this.socket.destroy(),this.socket=void 0),e(r)})}))}async send(t){return(await this.connect()).send(t)}async sendAndWait(t){return(await this.connect()).sendAndWait(t)}close(){this.socket&&(this.socket.removeAllListeners(),this.socket.destroy(),this.socket=void 0),this.connection&&(this.connection.close(),delete this.connection)}},ui=class{constructor(t){this.handler=t}start(t,e,r=!1){let o=li.default.createServer(s=>{let i=new ii(s,e,r);this.handler(i)}),n=async s=>{s?.code==="EADDRINUSE"&&(await(0,ci.sleep)(50),o.close(),o.listen(t))};o.on("error",n),o.once("listening",()=>{o.off("error",n)}),o.listen(t),this.server=o}async stop(){return new Promise((t,e)=>{if(!this.server){e(new Error("Stop was called but there is no server running"));return}this.server.close(r=>{if(r){e(r);return}t()}),this.server=void 0})}};var pi=require("node:fs");var Vu=new g("send").description("Send an HL7 v2 message via MLLP").argument("<host>","The destination host name or IP address").argument("<port>","The destination port number").argument("[body]","Optional HL7 message body").option("--generate-example","Generate a sample HL7 message").option("--file <file>","Read the HL7 message from a file").option("--encoding <encoding>","The encoding to use").action(async(t,e,r,o)=>{if(o.generateExample?r=Xu():o.file&&(r=(0,pi.readFileSync)(o.file,"utf8")),!r)throw new Error("Missing HL7 message body");let n=new ai({host:t,port:Number.parseInt(e,10),encoding:o.encoding});try{let s=await n.sendAndWait(Lt.Hl7Message.parse(r));console.log(s.toString().replaceAll("\r",`
|
|
15
15
|
`))}finally{n.close()}}),Ju=new g("listen").description("Starts an HL7 v2 MLLP server").argument("<port>").option("--encoding <encoding>","The encoding to use").action(async(t,e)=>{new ui(o=>{o.addEventListener("message",({message:n})=>{console.log(n.toString().replaceAll("\r",`
|
|
16
16
|
`)),o.send(n.buildAck())})}).start(Number.parseInt(t,10),e.encoding),console.log("Listening on port "+t)}),kt=new g("hl7");y(kt,Vu);y(kt,Ju);function Xu(){let t=(0,Lt.formatHl7DateTime)(new Date),e=Date.now().toString();return`MSH|^~\\&|ADTSYS|HOSPITAL|RECEIVER|DEST|${t}||ADT^A01|${e}|P|2.5|
|
|
17
17
|
EVN|A01|${t}||
|