@medplum/cli 2.0.7 → 2.0.10
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 +153 -17
- package/dist/cjs/index.cjs +217 -11
- package/dist/cjs/index.cjs.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -4,13 +4,161 @@ The Medplum CLI (Command Line Interface) is a set of command line tools to quick
|
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
|
-
Add
|
|
7
|
+
Add globally:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install --global @medplum/cli
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Or add as a package dependency:
|
|
8
14
|
|
|
9
15
|
```bash
|
|
10
16
|
npm install @medplum/cli
|
|
11
17
|
```
|
|
12
18
|
|
|
13
|
-
##
|
|
19
|
+
## Authentication
|
|
20
|
+
|
|
21
|
+
Use one of these authentication options:
|
|
22
|
+
|
|
23
|
+
1. Stored credentials in `~/.medplum/credentials`. You can use the `medplum login` command (see below) to automatically create this file.
|
|
24
|
+
2. Client credentials in environment variables `MEDPLUM_CLIENT_ID` and `MEDPLUM_CLIENT_SECRET`. `dotenv` is enabled, so you can store them in a `.env` file.
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
If installed globally, you can use the `medplum` command directly:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
medplum <command> <args>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
If installed as a package dependency, you can use the `medplum` command via `npx`:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npx medplum <command> <args>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
By default, the `medplum` command uses the Medplum hosted API at "https://api.medplum.com". If you want to use the `medplum` command against your own self-hosted server, you can use the `MEDPLUM_BASE_URL` environment variable. `dotenv` is enabled, so you can store this value in a `.env` file.
|
|
41
|
+
|
|
42
|
+
### Auth
|
|
43
|
+
|
|
44
|
+
#### `login`
|
|
45
|
+
|
|
46
|
+
The `login` command opens a web browser to a Medplum authentication page.
|
|
47
|
+
|
|
48
|
+
On successful login, the command writes credentials to disk at `~/.medplum/credentials`.
|
|
49
|
+
|
|
50
|
+
The `medplum` command will then load those credentials on all future runs.
|
|
51
|
+
|
|
52
|
+
Example:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
medplum login
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
#### `whoami`
|
|
59
|
+
|
|
60
|
+
The `whoami` command displays whether the client is authenticated, and, if so, the name of the current user and current Medplum project.
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
medplum whoami
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### RESTful Operations
|
|
67
|
+
|
|
68
|
+
The `medplum` command can be used as a convenient tool for basic Medplum CRUD and RESTful operations.
|
|
69
|
+
|
|
70
|
+
While all API endpoints are available to any command line HTTP client such as `curl` or `wget`, there are a few advantages to using the `medplum` command:
|
|
71
|
+
|
|
72
|
+
1. Authentication and credentials - login once using the `login` command, and the `Authorization` header will be set automatically.
|
|
73
|
+
2. URL prefixes - adds the base URL (i.e., "https://api.medplum.com") and FHIR path prefix (i.e., "fhir/R4/").
|
|
74
|
+
3. Pretty print - formats the JSON with spaces and newlines.
|
|
75
|
+
4. Medplum extended mode - adds the `X-Medplum` HTTP header for private Medplum fields.
|
|
76
|
+
|
|
77
|
+
#### `get`
|
|
78
|
+
|
|
79
|
+
Makes an HTTP `GET` request.
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
medplum get <url>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Example: Search for patients:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
medplum get 'Patient?name=homer'
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Example: Read patient by ID:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
medplum get Patient/$id
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
#### `post`
|
|
98
|
+
|
|
99
|
+
Makes an HTTP `POST` request.
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
medplum post <url> <body>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Example: Create a patient:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
medplum post Patient '{"resourceType":"Patient","name":[{"family":"Simpson"}]}'
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Example: Invoke a FHIR operation:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
medplum post 'Patient/$validate' '{"resourceType":"Patient","name":[{"family":"Simpson"}]}'
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
#### `put`
|
|
118
|
+
|
|
119
|
+
Makes an HTTP `PUT` request.
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
medplum put <url> <body>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Example: Update a patient:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
medplum put Patient/$id '{"resourceType":"Patient","name":[{"family":"Simpson"}]}'
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
#### `patch`
|
|
132
|
+
|
|
133
|
+
Makes an HTTP `PATCH` request.
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
medplum patch <url> <body>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Example: Update a patient with [JSONPatch](https://jsonpatch.com/):
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
medplum patch Patient/$id '[{"op":"add","path":"/active","value":[true]}]'
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
#### `delete`
|
|
146
|
+
|
|
147
|
+
Makes an HTTP `DELETE` request.
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
medplum delete <url>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Example: Delete patient by ID:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
medplum delete Patient/$id
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Bots
|
|
160
|
+
|
|
161
|
+
#### Bots Config file
|
|
14
162
|
|
|
15
163
|
Create a Medplum config file called `medplum.config.json`:
|
|
16
164
|
|
|
@@ -35,15 +183,7 @@ The `source` property is the file path to the original source. When you "save" t
|
|
|
35
183
|
|
|
36
184
|
The `dist` property is the optional file path to the compiled source. If omitted, the command falls back to using the `source` property. When you "deploy" the Bot, the contents of this file will be deployed to the Bot runtime. This file must be JavaScript.
|
|
37
185
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
Syntax:
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
npx medplum <command> <args>
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### save-bot
|
|
186
|
+
#### save-bot
|
|
47
187
|
|
|
48
188
|
Updates the `code` value on a `Bot` resource
|
|
49
189
|
|
|
@@ -59,7 +199,7 @@ Example:
|
|
|
59
199
|
npx medplum save-bot hello-world
|
|
60
200
|
```
|
|
61
201
|
|
|
62
|
-
|
|
202
|
+
#### deploy-bot
|
|
63
203
|
|
|
64
204
|
Deploys the Bot code
|
|
65
205
|
|
|
@@ -75,11 +215,7 @@ Example:
|
|
|
75
215
|
npx medplum-deploy-bot <bot name>
|
|
76
216
|
```
|
|
77
217
|
|
|
78
|
-
##
|
|
79
|
-
|
|
80
|
-
Authentication requires client credentials in environment variables `MEDPLUM_CLIENT_ID` and `MEDPLUM_CLIENT_SECRET`. This supports most use cases, including secrets from CI/CD. `dotenv` is enabled, so you can store them in a `.env` file.
|
|
81
|
-
|
|
82
|
-
## Example
|
|
218
|
+
## Bots Example
|
|
83
219
|
|
|
84
220
|
Create a Medplum config file `medplum.config.json`:
|
|
85
221
|
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -2,26 +2,235 @@
|
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var core = require('@medplum/core');
|
|
5
|
+
var child_process = require('child_process');
|
|
5
6
|
var dotenv = require('dotenv');
|
|
6
7
|
var fs = require('fs');
|
|
8
|
+
var http = require('http');
|
|
7
9
|
var fetch = require('node-fetch');
|
|
10
|
+
var os = require('os');
|
|
8
11
|
var path = require('path');
|
|
9
12
|
|
|
13
|
+
/******************************************************************************
|
|
14
|
+
Copyright (c) Microsoft Corporation.
|
|
15
|
+
|
|
16
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
17
|
+
purpose with or without fee is hereby granted.
|
|
18
|
+
|
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
20
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
21
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
22
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
23
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
24
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
25
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
26
|
+
***************************************************************************** */
|
|
27
|
+
|
|
28
|
+
function __classPrivateFieldGet(receiver, state, kind, f) {
|
|
29
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
30
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
31
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function __classPrivateFieldSet(receiver, state, value, kind, f) {
|
|
35
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
36
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
37
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
38
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
var _FileSystemStorage_instances, _FileSystemStorage_dirName, _FileSystemStorage_fileName, _FileSystemStorage_readFile, _FileSystemStorage_writeFile;
|
|
42
|
+
class FileSystemStorage extends core.ClientStorage {
|
|
43
|
+
constructor() {
|
|
44
|
+
super();
|
|
45
|
+
_FileSystemStorage_instances.add(this);
|
|
46
|
+
_FileSystemStorage_dirName.set(this, void 0);
|
|
47
|
+
_FileSystemStorage_fileName.set(this, void 0);
|
|
48
|
+
__classPrivateFieldSet(this, _FileSystemStorage_dirName, path.resolve(os.homedir(), '.medplum'), "f");
|
|
49
|
+
__classPrivateFieldSet(this, _FileSystemStorage_fileName, path.resolve(__classPrivateFieldGet(this, _FileSystemStorage_dirName, "f"), 'credentials'), "f");
|
|
50
|
+
}
|
|
51
|
+
clear() {
|
|
52
|
+
__classPrivateFieldGet(this, _FileSystemStorage_instances, "m", _FileSystemStorage_writeFile).call(this, {});
|
|
53
|
+
}
|
|
54
|
+
getString(key) {
|
|
55
|
+
return __classPrivateFieldGet(this, _FileSystemStorage_instances, "m", _FileSystemStorage_readFile).call(this)?.[key];
|
|
56
|
+
}
|
|
57
|
+
setString(key, value) {
|
|
58
|
+
const data = __classPrivateFieldGet(this, _FileSystemStorage_instances, "m", _FileSystemStorage_readFile).call(this) || {};
|
|
59
|
+
if (value) {
|
|
60
|
+
data[key] = value;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
delete data[key];
|
|
64
|
+
}
|
|
65
|
+
__classPrivateFieldGet(this, _FileSystemStorage_instances, "m", _FileSystemStorage_writeFile).call(this, data);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
_FileSystemStorage_dirName = new WeakMap(), _FileSystemStorage_fileName = new WeakMap(), _FileSystemStorage_instances = new WeakSet(), _FileSystemStorage_readFile = function _FileSystemStorage_readFile() {
|
|
69
|
+
if (fs.existsSync(__classPrivateFieldGet(this, _FileSystemStorage_fileName, "f"))) {
|
|
70
|
+
return JSON.parse(fs.readFileSync(__classPrivateFieldGet(this, _FileSystemStorage_fileName, "f"), 'utf8'));
|
|
71
|
+
}
|
|
72
|
+
return undefined;
|
|
73
|
+
}, _FileSystemStorage_writeFile = function _FileSystemStorage_writeFile(data) {
|
|
74
|
+
if (!fs.existsSync(__classPrivateFieldGet(this, _FileSystemStorage_dirName, "f"))) {
|
|
75
|
+
fs.mkdirSync(__classPrivateFieldGet(this, _FileSystemStorage_dirName, "f"));
|
|
76
|
+
}
|
|
77
|
+
fs.writeFileSync(__classPrivateFieldGet(this, _FileSystemStorage_fileName, "f"), JSON.stringify(data, null, 2), 'utf8');
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const baseUrl = process.env['MEDPLUM_BASE_URL'] || 'https://api.medplum.com/';
|
|
81
|
+
const clientId = 'medplum-cli';
|
|
82
|
+
const redirectUri = 'http://localhost:9615';
|
|
10
83
|
async function main(medplum, argv) {
|
|
11
84
|
if (argv.length < 3) {
|
|
12
85
|
console.log('Usage: medplum <command>');
|
|
13
86
|
return;
|
|
14
87
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
88
|
+
// Legacy support for MEDPLUM_CLIENT_ID and MEDPLUM_CLIENT_SECRET environment variables
|
|
89
|
+
const clientId = process.env['MEDPLUM_CLIENT_ID'];
|
|
90
|
+
const clientSecret = process.env['MEDPLUM_CLIENT_SECRET'];
|
|
91
|
+
if (clientId && clientSecret) {
|
|
92
|
+
await medplum.startClientLogin(clientId, clientSecret);
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
const command = argv[2].toLowerCase();
|
|
96
|
+
switch (command) {
|
|
97
|
+
//
|
|
98
|
+
// Auth commands
|
|
99
|
+
//
|
|
100
|
+
case 'login':
|
|
101
|
+
await startLogin(medplum);
|
|
102
|
+
break;
|
|
103
|
+
case 'whoami':
|
|
104
|
+
printMe(medplum);
|
|
105
|
+
break;
|
|
106
|
+
//
|
|
107
|
+
// REST commands
|
|
108
|
+
//
|
|
109
|
+
case 'delete':
|
|
110
|
+
prettyPrint(await medplum.delete(cleanUrl(argv[3])));
|
|
111
|
+
break;
|
|
112
|
+
case 'get':
|
|
113
|
+
prettyPrint(await medplum.get(cleanUrl(argv[3])));
|
|
114
|
+
break;
|
|
115
|
+
case 'patch':
|
|
116
|
+
prettyPrint(await medplum.patch(cleanUrl(argv[3]), parseBody(argv[4])));
|
|
117
|
+
break;
|
|
118
|
+
case 'post':
|
|
119
|
+
prettyPrint(await medplum.post(cleanUrl(argv[3]), parseBody(argv[4])));
|
|
120
|
+
break;
|
|
121
|
+
case 'put':
|
|
122
|
+
prettyPrint(await medplum.put(cleanUrl(argv[3]), parseBody(argv[4])));
|
|
123
|
+
break;
|
|
124
|
+
//
|
|
125
|
+
// Bot commands
|
|
126
|
+
//
|
|
127
|
+
case 'save-bot':
|
|
128
|
+
await runBotCommands(medplum, argv, ['save']);
|
|
129
|
+
break;
|
|
130
|
+
case 'deploy-bot':
|
|
131
|
+
await runBotCommands(medplum, argv, ['save', 'deploy']);
|
|
132
|
+
break;
|
|
133
|
+
default:
|
|
134
|
+
console.log(`Unknown command: ${command}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
console.error('Error: ' + core.normalizeErrorString(err));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
async function startLogin(medplum) {
|
|
142
|
+
await startWebServer(medplum);
|
|
143
|
+
const loginUrl = new URL('/oauth2/authorize', baseUrl);
|
|
144
|
+
loginUrl.searchParams.set('client_id', clientId);
|
|
145
|
+
loginUrl.searchParams.set('redirect_uri', redirectUri);
|
|
146
|
+
loginUrl.searchParams.set('scope', 'openid');
|
|
147
|
+
loginUrl.searchParams.set('response_type', 'code');
|
|
148
|
+
await openBrowser(loginUrl.toString());
|
|
149
|
+
}
|
|
150
|
+
async function startWebServer(medplum) {
|
|
151
|
+
const server = http.createServer(async (req, res) => {
|
|
152
|
+
const url = new URL(req.url, 'http://localhost:9615');
|
|
153
|
+
const code = url.searchParams.get('code');
|
|
154
|
+
if (url.pathname === '/' && code) {
|
|
155
|
+
try {
|
|
156
|
+
const profile = await medplum.processCode(code, { clientId, redirectUri });
|
|
157
|
+
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
|
158
|
+
res.end(`Signed in as ${core.getDisplayString(profile)}. You may close this window.`);
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
res.writeHead(400, { 'Content-Type': 'text/plain' });
|
|
162
|
+
res.end(`Error: ${core.normalizeErrorString(err)}`);
|
|
163
|
+
}
|
|
164
|
+
finally {
|
|
165
|
+
server.close();
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
170
|
+
res.end('Not found');
|
|
171
|
+
}
|
|
172
|
+
}).listen(9615);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Opens a web browser to the specified URL.
|
|
176
|
+
* See: https://hasinthaindrajee.medium.com/browser-sso-for-cli-applications-b0be743fa656
|
|
177
|
+
* @param url The URL to open.
|
|
178
|
+
*/
|
|
179
|
+
async function openBrowser(url) {
|
|
180
|
+
const os$1 = os.platform();
|
|
181
|
+
let cmd = undefined;
|
|
182
|
+
switch (os$1) {
|
|
183
|
+
case 'openbsd':
|
|
184
|
+
case 'linux':
|
|
185
|
+
cmd = `xdg-open '${url}'`;
|
|
186
|
+
break;
|
|
187
|
+
case 'darwin':
|
|
188
|
+
cmd = `open '${url}'`;
|
|
189
|
+
break;
|
|
190
|
+
case 'win32':
|
|
191
|
+
cmd = `cmd /c start "" "${url}"`;
|
|
192
|
+
break;
|
|
193
|
+
default:
|
|
194
|
+
throw new Error('Unsupported platform: ' + os$1);
|
|
18
195
|
}
|
|
19
|
-
|
|
20
|
-
|
|
196
|
+
child_process.exec(cmd);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Prints the current user and project.
|
|
200
|
+
* @param medplum The Medplum client.
|
|
201
|
+
*/
|
|
202
|
+
function printMe(medplum) {
|
|
203
|
+
const loginState = medplum.getActiveLogin();
|
|
204
|
+
if (loginState) {
|
|
205
|
+
console.log(`Profile: ${loginState.profile?.display} (${loginState.profile?.reference})`);
|
|
206
|
+
console.log(`Project: ${loginState.project?.display} (${loginState.project?.reference})`);
|
|
21
207
|
}
|
|
22
208
|
else {
|
|
23
|
-
console.log(
|
|
209
|
+
console.log('Not logged in');
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
function cleanUrl(input) {
|
|
213
|
+
const knownPrefixes = ['admin/', 'auth/', 'fhir/R4'];
|
|
214
|
+
if (knownPrefixes.some((p) => input.startsWith(p))) {
|
|
215
|
+
// If the URL starts with a known prefix, return it as-is
|
|
216
|
+
return input;
|
|
24
217
|
}
|
|
218
|
+
// Otherwise, default to FHIR
|
|
219
|
+
return 'fhir/R4/' + input;
|
|
220
|
+
}
|
|
221
|
+
function parseBody(input) {
|
|
222
|
+
if (!input) {
|
|
223
|
+
return undefined;
|
|
224
|
+
}
|
|
225
|
+
try {
|
|
226
|
+
return JSON.parse(input);
|
|
227
|
+
}
|
|
228
|
+
catch (err) {
|
|
229
|
+
return input;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
function prettyPrint(input) {
|
|
233
|
+
console.log(JSON.stringify(input, null, 2));
|
|
25
234
|
}
|
|
26
235
|
async function runBotCommands(medplum, argv, commands) {
|
|
27
236
|
if (argv.length < 4) {
|
|
@@ -107,11 +316,8 @@ function readFileContents(fileName) {
|
|
|
107
316
|
}
|
|
108
317
|
if (require.main === module) {
|
|
109
318
|
dotenv.config();
|
|
110
|
-
const medplum = new core.MedplumClient({ fetch, baseUrl:
|
|
111
|
-
medplum
|
|
112
|
-
.startClientLogin(process.env['MEDPLUM_CLIENT_ID'], process.env['MEDPLUM_CLIENT_SECRET'])
|
|
113
|
-
.then(() => main(medplum, process.argv))
|
|
114
|
-
.catch((err) => console.error('Unhandled error:', err));
|
|
319
|
+
const medplum = new core.MedplumClient({ fetch, baseUrl, storage: new FileSystemStorage() });
|
|
320
|
+
main(medplum, process.argv).catch((err) => console.error('Unhandled error:', err));
|
|
115
321
|
}
|
|
116
322
|
|
|
117
323
|
exports.main = main;
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../src/index.ts"],"sourcesContent":["import { MedplumClient, normalizeErrorString } from '@medplum/core';\nimport { Bot, OperationOutcome } from '@medplum/fhirtypes';\nimport dotenv from 'dotenv';\nimport { existsSync, readFileSync } from 'fs';\nimport fetch from 'node-fetch';\nimport { resolve } from 'path';\n\ninterface MedplumConfig {\n readonly bots?: MedplumBotConfig[];\n}\n\ninterface MedplumBotConfig {\n readonly name: string;\n readonly id: string;\n readonly source: string;\n readonly dist?: string;\n}\n\nexport async function main(medplum: MedplumClient, argv: string[]): Promise<void> {\n if (argv.length < 3) {\n console.log('Usage: medplum <command>');\n return;\n }\n\n const command = argv[2];\n if (command === 'save-bot') {\n await runBotCommands(medplum, argv, ['save']);\n } else if (command === 'deploy-bot') {\n await runBotCommands(medplum, argv, ['save', 'deploy']);\n } else {\n console.log(`Unknown command: ${command}`);\n }\n}\n\nasync function runBotCommands(medplum: MedplumClient, argv: string[], commands: string[]): Promise<void> {\n if (argv.length < 4) {\n console.log(`Usage: medplum ${argv[2]} <bot-name>`);\n return;\n }\n\n const botName = argv[3];\n const botConfig = readBotConfig(botName);\n if (!botConfig) {\n console.log(`Error: ${botName} not found`);\n return;\n }\n\n let bot;\n try {\n bot = await medplum.readResource('Bot', botConfig.id);\n } catch (err) {\n console.log('Error: ' + normalizeErrorString(err));\n return;\n }\n\n if (commands.includes('save')) {\n await saveBot(medplum, botConfig, bot);\n }\n\n if (commands.includes('deploy')) {\n await deployBot(medplum, botConfig, bot);\n }\n}\n\nasync function saveBot(medplum: MedplumClient, botConfig: MedplumBotConfig, bot: Bot): Promise<void> {\n const code = readFileContents(botConfig.source);\n if (!code) {\n return;\n }\n\n try {\n console.log('Update bot code.....');\n const updateResult = await medplum.updateResource({\n ...bot,\n code,\n });\n if (!updateResult) {\n console.log('Bot not modified');\n } else {\n console.log('Success! New bot version: ' + updateResult.meta?.versionId);\n }\n } catch (err) {\n console.log('Update error: ', err);\n }\n}\n\nasync function deployBot(medplum: MedplumClient, botConfig: MedplumBotConfig, bot: Bot): Promise<void> {\n const code = readFileContents(botConfig.dist ?? botConfig.source);\n if (!code) {\n return;\n }\n\n try {\n console.log('Deploying bot...');\n const deployResult = (await medplum.post(medplum.fhirUrl('Bot', bot.id as string, '$deploy'), {\n code,\n })) as OperationOutcome;\n console.log('Deploy result: ' + deployResult.issue?.[0]?.details?.text);\n } catch (err) {\n console.log('Deploy error: ', err);\n }\n}\n\nfunction readBotConfig(botName: string): MedplumBotConfig | undefined {\n return readConfig()?.bots?.find((b) => b.name === botName);\n}\n\nfunction readConfig(): MedplumConfig | undefined {\n const content = readFileContents('medplum.config.json');\n if (!content) {\n return undefined;\n }\n return JSON.parse(content);\n}\n\nfunction readFileContents(fileName: string): string | undefined {\n const path = resolve(process.cwd(), fileName);\n if (!existsSync(path)) {\n console.log('Error: File does not exist: ' + path);\n return '';\n }\n return readFileSync(path, 'utf8');\n}\n\nif (require.main === module) {\n dotenv.config();\n const medplum = new MedplumClient({ fetch, baseUrl: process.env['MEDPLUM_BASE_URL'] });\n medplum\n .startClientLogin(process.env['MEDPLUM_CLIENT_ID'] as string, process.env['MEDPLUM_CLIENT_SECRET'] as string)\n .then(() => main(medplum, process.argv))\n .catch((err) => console.error('Unhandled error:', err));\n}\n"],"names":["normalizeErrorString","path","resolve","existsSync","readFileSync","MedplumClient"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../../node_modules/tslib/tslib.es6.js","../../../src/storage.ts","../../../src/index.ts"],"sourcesContent":["/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\r\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\r\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\r\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\r\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\r\n var _, done = false;\r\n for (var i = decorators.length - 1; i >= 0; i--) {\r\n var context = {};\r\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\r\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\r\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\r\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\r\n if (kind === \"accessor\") {\r\n if (result === void 0) continue;\r\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\r\n if (_ = accept(result.get)) descriptor.get = _;\r\n if (_ = accept(result.set)) descriptor.set = _;\r\n if (_ = accept(result.init)) initializers.push(_);\r\n }\r\n else if (_ = accept(result)) {\r\n if (kind === \"field\") initializers.push(_);\r\n else descriptor[key] = _;\r\n }\r\n }\r\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\r\n done = true;\r\n};\r\n\r\nexport function __runInitializers(thisArg, initializers, value) {\r\n var useValue = arguments.length > 2;\r\n for (var i = 0; i < initializers.length; i++) {\r\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\r\n }\r\n return useValue ? value : void 0;\r\n};\r\n\r\nexport function __propKey(x) {\r\n return typeof x === \"symbol\" ? x : \"\".concat(x);\r\n};\r\n\r\nexport function __setFunctionName(f, name, prefix) {\r\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\r\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\r\n};\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nexport function __classPrivateFieldIn(state, receiver) {\r\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\r\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\r\n}\r\n","import { ClientStorage } from '@medplum/core';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';\nimport { homedir } from 'os';\nimport { resolve } from 'path';\n\nexport class FileSystemStorage extends ClientStorage {\n readonly #dirName: string;\n readonly #fileName: string;\n\n constructor() {\n super();\n this.#dirName = resolve(homedir(), '.medplum');\n this.#fileName = resolve(this.#dirName, 'credentials');\n }\n\n clear(): void {\n this.#writeFile({});\n }\n\n getString(key: string): string | undefined {\n return this.#readFile()?.[key];\n }\n\n setString(key: string, value: string | undefined): void {\n const data = this.#readFile() || {};\n if (value) {\n data[key] = value;\n } else {\n delete data[key];\n }\n this.#writeFile(data);\n }\n\n #readFile(): Record<string, string> | undefined {\n if (existsSync(this.#fileName)) {\n return JSON.parse(readFileSync(this.#fileName, 'utf8'));\n }\n return undefined;\n }\n\n #writeFile(data: Record<string, string>): void {\n if (!existsSync(this.#dirName)) {\n mkdirSync(this.#dirName);\n }\n writeFileSync(this.#fileName, JSON.stringify(data, null, 2), 'utf8');\n }\n}\n","import { getDisplayString, MedplumClient, normalizeErrorString } from '@medplum/core';\nimport { Bot, OperationOutcome } from '@medplum/fhirtypes';\nimport { exec } from 'child_process';\nimport dotenv from 'dotenv';\nimport { existsSync, readFileSync } from 'fs';\nimport { createServer } from 'http';\nimport fetch from 'node-fetch';\nimport { platform } from 'os';\nimport { resolve } from 'path';\nimport { FileSystemStorage } from './storage';\n\ninterface MedplumConfig {\n readonly bots?: MedplumBotConfig[];\n}\n\ninterface MedplumBotConfig {\n readonly name: string;\n readonly id: string;\n readonly source: string;\n readonly dist?: string;\n}\n\nconst baseUrl = process.env['MEDPLUM_BASE_URL'] || 'https://api.medplum.com/';\nconst clientId = 'medplum-cli';\nconst redirectUri = 'http://localhost:9615';\n\nexport async function main(medplum: MedplumClient, argv: string[]): Promise<void> {\n if (argv.length < 3) {\n console.log('Usage: medplum <command>');\n return;\n }\n\n // Legacy support for MEDPLUM_CLIENT_ID and MEDPLUM_CLIENT_SECRET environment variables\n const clientId = process.env['MEDPLUM_CLIENT_ID'];\n const clientSecret = process.env['MEDPLUM_CLIENT_SECRET'];\n if (clientId && clientSecret) {\n await medplum.startClientLogin(clientId, clientSecret);\n }\n\n try {\n const command = argv[2].toLowerCase();\n switch (command) {\n //\n // Auth commands\n //\n case 'login':\n await startLogin(medplum);\n break;\n case 'whoami':\n printMe(medplum);\n break;\n //\n // REST commands\n //\n case 'delete':\n prettyPrint(await medplum.delete(cleanUrl(argv[3])));\n break;\n case 'get':\n prettyPrint(await medplum.get(cleanUrl(argv[3])));\n break;\n case 'patch':\n prettyPrint(await medplum.patch(cleanUrl(argv[3]), parseBody(argv[4])));\n break;\n case 'post':\n prettyPrint(await medplum.post(cleanUrl(argv[3]), parseBody(argv[4])));\n break;\n case 'put':\n prettyPrint(await medplum.put(cleanUrl(argv[3]), parseBody(argv[4])));\n break;\n //\n // Bot commands\n //\n case 'save-bot':\n await runBotCommands(medplum, argv, ['save']);\n break;\n case 'deploy-bot':\n await runBotCommands(medplum, argv, ['save', 'deploy']);\n break;\n default:\n console.log(`Unknown command: ${command}`);\n }\n } catch (err) {\n console.error('Error: ' + normalizeErrorString(err));\n }\n}\n\nasync function startLogin(medplum: MedplumClient): Promise<void> {\n await startWebServer(medplum);\n\n const loginUrl = new URL('/oauth2/authorize', baseUrl);\n loginUrl.searchParams.set('client_id', clientId);\n loginUrl.searchParams.set('redirect_uri', redirectUri);\n loginUrl.searchParams.set('scope', 'openid');\n loginUrl.searchParams.set('response_type', 'code');\n await openBrowser(loginUrl.toString());\n}\n\nasync function startWebServer(medplum: MedplumClient): Promise<void> {\n const server = createServer(async (req, res) => {\n const url = new URL(req.url as string, 'http://localhost:9615');\n const code = url.searchParams.get('code');\n if (url.pathname === '/' && code) {\n try {\n const profile = await medplum.processCode(code, { clientId, redirectUri });\n res.writeHead(200, { 'Content-Type': 'text/plain' });\n res.end(`Signed in as ${getDisplayString(profile)}. You may close this window.`);\n } catch (err) {\n res.writeHead(400, { 'Content-Type': 'text/plain' });\n res.end(`Error: ${normalizeErrorString(err)}`);\n } finally {\n server.close();\n }\n } else {\n res.writeHead(404, { 'Content-Type': 'text/plain' });\n res.end('Not found');\n }\n }).listen(9615);\n}\n\n/**\n * Opens a web browser to the specified URL.\n * See: https://hasinthaindrajee.medium.com/browser-sso-for-cli-applications-b0be743fa656\n * @param url The URL to open.\n */\nasync function openBrowser(url: string): Promise<void> {\n const os = platform();\n let cmd = undefined;\n switch (os) {\n case 'openbsd':\n case 'linux':\n cmd = `xdg-open '${url}'`;\n break;\n case 'darwin':\n cmd = `open '${url}'`;\n break;\n case 'win32':\n cmd = `cmd /c start \"\" \"${url}\"`;\n break;\n default:\n throw new Error('Unsupported platform: ' + os);\n }\n exec(cmd);\n}\n\n/**\n * Prints the current user and project.\n * @param medplum The Medplum client.\n */\nfunction printMe(medplum: MedplumClient): void {\n const loginState = medplum.getActiveLogin();\n if (loginState) {\n console.log(`Profile: ${loginState.profile?.display} (${loginState.profile?.reference})`);\n console.log(`Project: ${loginState.project?.display} (${loginState.project?.reference})`);\n } else {\n console.log('Not logged in');\n }\n}\n\nfunction cleanUrl(input: string): string {\n const knownPrefixes = ['admin/', 'auth/', 'fhir/R4'];\n if (knownPrefixes.some((p) => input.startsWith(p))) {\n // If the URL starts with a known prefix, return it as-is\n return input;\n }\n // Otherwise, default to FHIR\n return 'fhir/R4/' + input;\n}\n\nfunction parseBody(input: string | undefined): any {\n if (!input) {\n return undefined;\n }\n try {\n return JSON.parse(input);\n } catch (err) {\n return input;\n }\n}\n\nfunction prettyPrint(input: unknown): void {\n console.log(JSON.stringify(input, null, 2));\n}\n\nasync function runBotCommands(medplum: MedplumClient, argv: string[], commands: string[]): Promise<void> {\n if (argv.length < 4) {\n console.log(`Usage: medplum ${argv[2]} <bot-name>`);\n return;\n }\n\n const botName = argv[3];\n const botConfig = readBotConfig(botName);\n if (!botConfig) {\n console.log(`Error: ${botName} not found`);\n return;\n }\n\n let bot;\n try {\n bot = await medplum.readResource('Bot', botConfig.id);\n } catch (err) {\n console.log('Error: ' + normalizeErrorString(err));\n return;\n }\n\n if (commands.includes('save')) {\n await saveBot(medplum, botConfig, bot);\n }\n\n if (commands.includes('deploy')) {\n await deployBot(medplum, botConfig, bot);\n }\n}\n\nasync function saveBot(medplum: MedplumClient, botConfig: MedplumBotConfig, bot: Bot): Promise<void> {\n const code = readFileContents(botConfig.source);\n if (!code) {\n return;\n }\n\n try {\n console.log('Update bot code.....');\n const updateResult = await medplum.updateResource({\n ...bot,\n code,\n });\n if (!updateResult) {\n console.log('Bot not modified');\n } else {\n console.log('Success! New bot version: ' + updateResult.meta?.versionId);\n }\n } catch (err) {\n console.log('Update error: ', err);\n }\n}\n\nasync function deployBot(medplum: MedplumClient, botConfig: MedplumBotConfig, bot: Bot): Promise<void> {\n const code = readFileContents(botConfig.dist ?? botConfig.source);\n if (!code) {\n return;\n }\n\n try {\n console.log('Deploying bot...');\n const deployResult = (await medplum.post(medplum.fhirUrl('Bot', bot.id as string, '$deploy'), {\n code,\n })) as OperationOutcome;\n console.log('Deploy result: ' + deployResult.issue?.[0]?.details?.text);\n } catch (err) {\n console.log('Deploy error: ', err);\n }\n}\n\nfunction readBotConfig(botName: string): MedplumBotConfig | undefined {\n return readConfig()?.bots?.find((b) => b.name === botName);\n}\n\nfunction readConfig(): MedplumConfig | undefined {\n const content = readFileContents('medplum.config.json');\n if (!content) {\n return undefined;\n }\n return JSON.parse(content);\n}\n\nfunction readFileContents(fileName: string): string | undefined {\n const path = resolve(process.cwd(), fileName);\n if (!existsSync(path)) {\n console.log('Error: File does not exist: ' + path);\n return '';\n }\n return readFileSync(path, 'utf8');\n}\n\nif (require.main === module) {\n dotenv.config();\n const medplum = new MedplumClient({ fetch, baseUrl, storage: new FileSystemStorage() });\n main(medplum, process.argv).catch((err) => console.error('Unhandled error:', err));\n}\n"],"names":["ClientStorage","resolve","homedir","existsSync","readFileSync","mkdirSync","writeFileSync","normalizeErrorString","createServer","getDisplayString","os","platform","exec","path","MedplumClient"],"mappings":";;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAsQA;AACO,SAAS,sBAAsB,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE;AACjE,IAAI,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,CAAC,EAAE,MAAM,IAAI,SAAS,CAAC,+CAA+C,CAAC,CAAC;AACjG,IAAI,IAAI,OAAO,KAAK,KAAK,UAAU,GAAG,QAAQ,KAAK,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,SAAS,CAAC,0EAA0E,CAAC,CAAC;AACvL,IAAI,OAAO,IAAI,KAAK,GAAG,GAAG,CAAC,GAAG,IAAI,KAAK,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAClG,CAAC;AACD;AACO,SAAS,sBAAsB,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE;AACxE,IAAI,IAAI,IAAI,KAAK,GAAG,EAAE,MAAM,IAAI,SAAS,CAAC,gCAAgC,CAAC,CAAC;AAC5E,IAAI,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,CAAC,EAAE,MAAM,IAAI,SAAS,CAAC,+CAA+C,CAAC,CAAC;AACjG,IAAI,IAAI,OAAO,KAAK,KAAK,UAAU,GAAG,QAAQ,KAAK,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,SAAS,CAAC,yEAAyE,CAAC,CAAC;AACtL,IAAI,OAAO,CAAC,IAAI,KAAK,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC;AAC9G;;;AC1RM,MAAO,iBAAkB,SAAQA,kBAAa,CAAA;AAIlD,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE,CAAC;;QAJV,0BAA0B,CAAA,GAAA,CAAA,IAAA,EAAA,KAAA,CAAA,CAAA,CAAA;QAC1B,2BAA2B,CAAA,GAAA,CAAA,IAAA,EAAA,KAAA,CAAA,CAAA,CAAA;QAIzB,sBAAA,CAAA,IAAI,EAAY,0BAAA,EAAAC,YAAO,CAACC,UAAO,EAAE,EAAE,UAAU,CAAC,EAAA,GAAA,CAAA,CAAC;QAC/C,sBAAA,CAAA,IAAI,EAAa,2BAAA,EAAAD,YAAO,CAAC,sBAAA,CAAA,IAAI,EAAA,0BAAA,EAAA,GAAA,CAAS,EAAE,aAAa,CAAC,EAAA,GAAA,CAAA,CAAC;KACxD;IAED,KAAK,GAAA;AACH,QAAA,sBAAA,CAAA,IAAI,EAAW,4BAAA,EAAA,GAAA,EAAA,4BAAA,CAAA,CAAA,IAAA,CAAf,IAAI,EAAY,EAAE,CAAC,CAAC;KACrB;AAED,IAAA,SAAS,CAAC,GAAW,EAAA;QACnB,OAAO,sBAAA,CAAA,IAAI,EAAA,4BAAA,EAAA,GAAA,EAAA,2BAAA,CAAU,CAAd,IAAA,CAAA,IAAI,CAAY,GAAG,GAAG,CAAC,CAAC;KAChC;IAED,SAAS,CAAC,GAAW,EAAE,KAAyB,EAAA;QAC9C,MAAM,IAAI,GAAG,sBAAA,CAAA,IAAI,EAAA,4BAAA,EAAA,GAAA,EAAA,2BAAA,CAAU,MAAd,IAAI,CAAY,IAAI,EAAE,CAAC;AACpC,QAAA,IAAI,KAAK,EAAE;AACT,YAAA,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AACnB,SAAA;AAAM,aAAA;AACL,YAAA,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;AAClB,SAAA;AACD,QAAA,sBAAA,CAAA,IAAI,EAAW,4BAAA,EAAA,GAAA,EAAA,4BAAA,CAAA,CAAA,IAAA,CAAf,IAAI,EAAY,IAAI,CAAC,CAAC;KACvB;AAeF,CAAA;;AAZG,IAAA,IAAIE,aAAU,CAAC,sBAAA,CAAA,IAAI,EAAA,2BAAA,EAAA,GAAA,CAAU,CAAC,EAAE;AAC9B,QAAA,OAAO,IAAI,CAAC,KAAK,CAACC,eAAY,CAAC,sBAAA,CAAA,IAAI,EAAU,2BAAA,EAAA,GAAA,CAAA,EAAE,MAAM,CAAC,CAAC,CAAC;AACzD,KAAA;AACD,IAAA,OAAO,SAAS,CAAC;AACnB,CAAC,uEAEU,IAA4B,EAAA;AACrC,IAAA,IAAI,CAACD,aAAU,CAAC,uBAAA,IAAI,EAAA,0BAAA,EAAA,GAAA,CAAS,CAAC,EAAE;AAC9B,QAAAE,YAAS,CAAC,sBAAA,CAAA,IAAI,EAAA,0BAAA,EAAA,GAAA,CAAS,CAAC,CAAC;AAC1B,KAAA;AACD,IAAAC,gBAAa,CAAC,sBAAA,CAAA,IAAI,mCAAU,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AACvE,CAAC;;ACvBH,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,0BAA0B,CAAC;AAC9E,MAAM,QAAQ,GAAG,aAAa,CAAC;AAC/B,MAAM,WAAW,GAAG,uBAAuB,CAAC;AAErC,eAAe,IAAI,CAAC,OAAsB,EAAE,IAAc,EAAA;AAC/D,IAAA,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;AACnB,QAAA,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;QACxC,OAAO;AACR,KAAA;;IAGD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IAClD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;IAC1D,IAAI,QAAQ,IAAI,YAAY,EAAE;QAC5B,MAAM,OAAO,CAAC,gBAAgB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;AACxD,KAAA;IAED,IAAI;QACF,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;AACtC,QAAA,QAAQ,OAAO;;;;AAIb,YAAA,KAAK,OAAO;AACV,gBAAA,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;gBAC1B,MAAM;AACR,YAAA,KAAK,QAAQ;gBACX,OAAO,CAAC,OAAO,CAAC,CAAC;gBACjB,MAAM;;;;AAIR,YAAA,KAAK,QAAQ;AACX,gBAAA,WAAW,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACrD,MAAM;AACR,YAAA,KAAK,KAAK;AACR,gBAAA,WAAW,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAClD,MAAM;AACR,YAAA,KAAK,OAAO;gBACV,WAAW,CAAC,MAAM,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACxE,MAAM;AACR,YAAA,KAAK,MAAM;gBACT,WAAW,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACvE,MAAM;AACR,YAAA,KAAK,KAAK;gBACR,WAAW,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACtE,MAAM;;;;AAIR,YAAA,KAAK,UAAU;gBACb,MAAM,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC9C,MAAM;AACR,YAAA,KAAK,YAAY;AACf,gBAAA,MAAM,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;gBACxD,MAAM;AACR,YAAA;AACE,gBAAA,OAAO,CAAC,GAAG,CAAC,oBAAoB,OAAO,CAAA,CAAE,CAAC,CAAC;AAC9C,SAAA;AACF,KAAA;AAAC,IAAA,OAAO,GAAG,EAAE;QACZ,OAAO,CAAC,KAAK,CAAC,SAAS,GAAGC,yBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC;AACtD,KAAA;AACH,CAAC;AAED,eAAe,UAAU,CAAC,OAAsB,EAAA;AAC9C,IAAA,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;IAE9B,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;IACvD,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IACjD,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;IACvD,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC7C,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;AACnD,IAAA,MAAM,WAAW,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;AACzC,CAAC;AAED,eAAe,cAAc,CAAC,OAAsB,EAAA;IAClD,MAAM,MAAM,GAAGC,iBAAY,CAAC,OAAO,GAAG,EAAE,GAAG,KAAI;QAC7C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAa,EAAE,uBAAuB,CAAC,CAAC;QAChE,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC1C,QAAA,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,IAAI,IAAI,EAAE;YAChC,IAAI;AACF,gBAAA,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC;gBAC3E,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;gBACrD,GAAG,CAAC,GAAG,CAAC,CAAgB,aAAA,EAAAC,qBAAgB,CAAC,OAAO,CAAC,CAA8B,4BAAA,CAAA,CAAC,CAAC;AAClF,aAAA;AAAC,YAAA,OAAO,GAAG,EAAE;gBACZ,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;gBACrD,GAAG,CAAC,GAAG,CAAC,CAAU,OAAA,EAAAF,yBAAoB,CAAC,GAAG,CAAC,CAAE,CAAA,CAAC,CAAC;AAChD,aAAA;AAAS,oBAAA;gBACR,MAAM,CAAC,KAAK,EAAE,CAAC;AAChB,aAAA;AACF,SAAA;AAAM,aAAA;YACL,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;AACrD,YAAA,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AACtB,SAAA;AACH,KAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAClB,CAAC;AAED;;;;AAIG;AACH,eAAe,WAAW,CAAC,GAAW,EAAA;AACpC,IAAA,MAAMG,IAAE,GAAGC,WAAQ,EAAE,CAAC;IACtB,IAAI,GAAG,GAAG,SAAS,CAAC;AACpB,IAAA,QAAQD,IAAE;AACR,QAAA,KAAK,SAAS,CAAC;AACf,QAAA,KAAK,OAAO;AACV,YAAA,GAAG,GAAG,CAAA,UAAA,EAAa,GAAG,CAAA,CAAA,CAAG,CAAC;YAC1B,MAAM;AACR,QAAA,KAAK,QAAQ;AACX,YAAA,GAAG,GAAG,CAAA,MAAA,EAAS,GAAG,CAAA,CAAA,CAAG,CAAC;YACtB,MAAM;AACR,QAAA,KAAK,OAAO;AACV,YAAA,GAAG,GAAG,CAAA,iBAAA,EAAoB,GAAG,CAAA,CAAA,CAAG,CAAC;YACjC,MAAM;AACR,QAAA;AACE,YAAA,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAGA,IAAE,CAAC,CAAC;AAClD,KAAA;IACDE,kBAAI,CAAC,GAAG,CAAC,CAAC;AACZ,CAAC;AAED;;;AAGG;AACH,SAAS,OAAO,CAAC,OAAsB,EAAA;AACrC,IAAA,MAAM,UAAU,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;AAC5C,IAAA,IAAI,UAAU,EAAE;AACd,QAAA,OAAO,CAAC,GAAG,CAAC,CAAY,SAAA,EAAA,UAAU,CAAC,OAAO,EAAE,OAAO,CAAA,EAAA,EAAK,UAAU,CAAC,OAAO,EAAE,SAAS,CAAA,CAAA,CAAG,CAAC,CAAC;AAC1F,QAAA,OAAO,CAAC,GAAG,CAAC,CAAY,SAAA,EAAA,UAAU,CAAC,OAAO,EAAE,OAAO,CAAA,EAAA,EAAK,UAAU,CAAC,OAAO,EAAE,SAAS,CAAA,CAAA,CAAG,CAAC,CAAC;AAC3F,KAAA;AAAM,SAAA;AACL,QAAA,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;AAC9B,KAAA;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa,EAAA;IAC7B,MAAM,aAAa,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;AACrD,IAAA,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE;;AAElD,QAAA,OAAO,KAAK,CAAC;AACd,KAAA;;IAED,OAAO,UAAU,GAAG,KAAK,CAAC;AAC5B,CAAC;AAED,SAAS,SAAS,CAAC,KAAyB,EAAA;IAC1C,IAAI,CAAC,KAAK,EAAE;AACV,QAAA,OAAO,SAAS,CAAC;AAClB,KAAA;IACD,IAAI;AACF,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAC1B,KAAA;AAAC,IAAA,OAAO,GAAG,EAAE;AACZ,QAAA,OAAO,KAAK,CAAC;AACd,KAAA;AACH,CAAC;AAED,SAAS,WAAW,CAAC,KAAc,EAAA;AACjC,IAAA,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED,eAAe,cAAc,CAAC,OAAsB,EAAE,IAAc,EAAE,QAAkB,EAAA;AACtF,IAAA,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;QACnB,OAAO,CAAC,GAAG,CAAC,CAAkB,eAAA,EAAA,IAAI,CAAC,CAAC,CAAC,CAAa,WAAA,CAAA,CAAC,CAAC;QACpD,OAAO;AACR,KAAA;AAED,IAAA,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AACxB,IAAA,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACzC,IAAI,CAAC,SAAS,EAAE;AACd,QAAA,OAAO,CAAC,GAAG,CAAC,UAAU,OAAO,CAAA,UAAA,CAAY,CAAC,CAAC;QAC3C,OAAO;AACR,KAAA;AAED,IAAA,IAAI,GAAG,CAAC;IACR,IAAI;AACF,QAAA,GAAG,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC;AACvD,KAAA;AAAC,IAAA,OAAO,GAAG,EAAE;QACZ,OAAO,CAAC,GAAG,CAAC,SAAS,GAAGL,yBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC;QACnD,OAAO;AACR,KAAA;AAED,IAAA,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;QAC7B,MAAM,OAAO,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;AACxC,KAAA;AAED,IAAA,IAAI,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAC/B,MAAM,SAAS,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;AAC1C,KAAA;AACH,CAAC;AAED,eAAe,OAAO,CAAC,OAAsB,EAAE,SAA2B,EAAE,GAAQ,EAAA;IAClF,MAAM,IAAI,GAAG,gBAAgB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAChD,IAAI,CAAC,IAAI,EAAE;QACT,OAAO;AACR,KAAA;IAED,IAAI;AACF,QAAA,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;AACpC,QAAA,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC;AAChD,YAAA,GAAG,GAAG;YACN,IAAI;AACL,SAAA,CAAC,CAAC;QACH,IAAI,CAAC,YAAY,EAAE;AACjB,YAAA,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;AACjC,SAAA;AAAM,aAAA;YACL,OAAO,CAAC,GAAG,CAAC,4BAA4B,GAAG,YAAY,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;AAC1E,SAAA;AACF,KAAA;AAAC,IAAA,OAAO,GAAG,EAAE;AACZ,QAAA,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;AACpC,KAAA;AACH,CAAC;AAED,eAAe,SAAS,CAAC,OAAsB,EAAE,SAA2B,EAAE,GAAQ,EAAA;AACpF,IAAA,MAAM,IAAI,GAAG,gBAAgB,CAAC,SAAS,CAAC,IAAI,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;IAClE,IAAI,CAAC,IAAI,EAAE;QACT,OAAO;AACR,KAAA;IAED,IAAI;AACF,QAAA,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAChC,MAAM,YAAY,IAAI,MAAM,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,EAAY,EAAE,SAAS,CAAC,EAAE;YAC5F,IAAI;AACL,SAAA,CAAC,CAAqB,CAAC;AACxB,QAAA,OAAO,CAAC,GAAG,CAAC,iBAAiB,GAAG,YAAY,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;AACzE,KAAA;AAAC,IAAA,OAAO,GAAG,EAAE;AACZ,QAAA,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;AACpC,KAAA;AACH,CAAC;AAED,SAAS,aAAa,CAAC,OAAe,EAAA;AACpC,IAAA,OAAO,UAAU,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;AAC7D,CAAC;AAED,SAAS,UAAU,GAAA;AACjB,IAAA,MAAM,OAAO,GAAG,gBAAgB,CAAC,qBAAqB,CAAC,CAAC;IACxD,IAAI,CAAC,OAAO,EAAE;AACZ,QAAA,OAAO,SAAS,CAAC;AAClB,KAAA;AACD,IAAA,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAgB,EAAA;IACxC,MAAMM,MAAI,GAAGZ,YAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;AAC9C,IAAA,IAAI,CAACE,aAAU,CAACU,MAAI,CAAC,EAAE;AACrB,QAAA,OAAO,CAAC,GAAG,CAAC,8BAA8B,GAAGA,MAAI,CAAC,CAAC;AACnD,QAAA,OAAO,EAAE,CAAC;AACX,KAAA;AACD,IAAA,OAAOT,eAAY,CAACS,MAAI,EAAE,MAAM,CAAC,CAAC;AACpC,CAAC;AAED,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE;IAC3B,MAAM,CAAC,MAAM,EAAE,CAAC;AAChB,IAAA,MAAM,OAAO,GAAG,IAAIC,kBAAa,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,iBAAiB,EAAE,EAAE,CAAC,CAAC;IACxF,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC,CAAC;AACpF;;;;","x_google_ignoreList":[0]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@medplum/cli",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.10",
|
|
4
4
|
"description": "Medplum Command Line Interface",
|
|
5
5
|
"author": "Medplum <hello@medplum.com>",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"directory": "packages/cli"
|
|
12
12
|
},
|
|
13
13
|
"scripts": {
|
|
14
|
+
"medplum": "ts-node src/index.ts",
|
|
14
15
|
"clean": "rimraf dist",
|
|
15
16
|
"build": "npm run clean && tsc && rollup --config rollup.config.mjs",
|
|
16
17
|
"test": "jest"
|