@medplum/cli 2.0.15 → 2.0.16
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 +280 -194
- package/dist/cjs/index.cjs.map +1 -1
- package/package.json +2 -1
package/dist/cjs/index.cjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
+
var commander = require('commander');
|
|
4
5
|
var core = require('@medplum/core');
|
|
5
|
-
var child_process = require('child_process');
|
|
6
|
-
var dotenv = require('dotenv');
|
|
7
6
|
var fs = require('fs');
|
|
8
|
-
var http = require('http');
|
|
9
|
-
var fetch = require('node-fetch');
|
|
10
7
|
var os = require('os');
|
|
11
8
|
var path = require('path');
|
|
9
|
+
var dotenv = require('dotenv');
|
|
10
|
+
var child_process = require('child_process');
|
|
11
|
+
var http = require('http');
|
|
12
12
|
|
|
13
13
|
class FileSystemStorage extends core.ClientStorage {
|
|
14
14
|
constructor() {
|
|
@@ -46,69 +46,178 @@ class FileSystemStorage extends core.ClientStorage {
|
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
function prettyPrint(input) {
|
|
50
|
+
console.log(JSON.stringify(input, null, 2));
|
|
51
|
+
}
|
|
52
|
+
async function saveBot(medplum, botConfig, bot) {
|
|
53
|
+
const code = readFileContents(botConfig.source);
|
|
54
|
+
if (!code) {
|
|
54
55
|
return;
|
|
55
56
|
}
|
|
56
|
-
// Legacy support for MEDPLUM_CLIENT_ID and MEDPLUM_CLIENT_SECRET environment variables
|
|
57
|
-
const clientId = process.env['MEDPLUM_CLIENT_ID'];
|
|
58
|
-
const clientSecret = process.env['MEDPLUM_CLIENT_SECRET'];
|
|
59
|
-
if (clientId && clientSecret) {
|
|
60
|
-
await medplum.startClientLogin(clientId, clientSecret);
|
|
61
|
-
}
|
|
62
57
|
try {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
break;
|
|
74
|
-
//
|
|
75
|
-
// REST commands
|
|
76
|
-
//
|
|
77
|
-
case 'delete':
|
|
78
|
-
prettyPrint(await medplum.delete(cleanUrl(argv[3])));
|
|
79
|
-
break;
|
|
80
|
-
case 'get':
|
|
81
|
-
prettyPrint(await medplum.get(cleanUrl(argv[3])));
|
|
82
|
-
break;
|
|
83
|
-
case 'patch':
|
|
84
|
-
prettyPrint(await medplum.patch(cleanUrl(argv[3]), parseBody(argv[4])));
|
|
85
|
-
break;
|
|
86
|
-
case 'post':
|
|
87
|
-
prettyPrint(await medplum.post(cleanUrl(argv[3]), parseBody(argv[4])));
|
|
88
|
-
break;
|
|
89
|
-
case 'put':
|
|
90
|
-
prettyPrint(await medplum.put(cleanUrl(argv[3]), parseBody(argv[4])));
|
|
91
|
-
break;
|
|
92
|
-
//
|
|
93
|
-
// Bot commands
|
|
94
|
-
//
|
|
95
|
-
case 'save-bot':
|
|
96
|
-
await runBotCommands(medplum, argv, ['save']);
|
|
97
|
-
break;
|
|
98
|
-
case 'deploy-bot':
|
|
99
|
-
await runBotCommands(medplum, argv, ['save', 'deploy']);
|
|
100
|
-
break;
|
|
101
|
-
case 'create-bot':
|
|
102
|
-
await createBot(medplum, argv);
|
|
103
|
-
break;
|
|
104
|
-
default:
|
|
105
|
-
console.log(`Unknown command: ${command}`);
|
|
58
|
+
console.log('Update bot code.....');
|
|
59
|
+
const updateResult = await medplum.updateResource({
|
|
60
|
+
...bot,
|
|
61
|
+
code,
|
|
62
|
+
});
|
|
63
|
+
if (!updateResult) {
|
|
64
|
+
console.log('Bot not modified');
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
console.log('Success! New bot version: ' + updateResult.meta?.versionId);
|
|
106
68
|
}
|
|
107
69
|
}
|
|
108
70
|
catch (err) {
|
|
109
|
-
console.
|
|
71
|
+
console.log('Update error: ', err);
|
|
110
72
|
}
|
|
111
73
|
}
|
|
74
|
+
async function deployBot(medplum, botConfig, bot) {
|
|
75
|
+
const code = readFileContents(botConfig.dist ?? botConfig.source);
|
|
76
|
+
if (!code) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
console.log('Deploying bot...');
|
|
81
|
+
const deployResult = (await medplum.post(medplum.fhirUrl('Bot', bot.id, '$deploy'), {
|
|
82
|
+
code,
|
|
83
|
+
}));
|
|
84
|
+
console.log('Deploy result: ' + deployResult.issue?.[0]?.details?.text);
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
console.log('Deploy error: ', err);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async function createBot(medplum, argv) {
|
|
91
|
+
if (argv.length < 4) {
|
|
92
|
+
console.log(`Error: command needs to be npx medplum <new-bot-name> <project-id> <source-file> <dist-file>`);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const botName = argv[0];
|
|
96
|
+
const projectId = argv[1];
|
|
97
|
+
const sourceFile = argv[2];
|
|
98
|
+
const distFile = argv[3];
|
|
99
|
+
try {
|
|
100
|
+
const body = {
|
|
101
|
+
name: botName,
|
|
102
|
+
description: '',
|
|
103
|
+
};
|
|
104
|
+
const newBot = await medplum.post('admin/projects/' + projectId + '/bot', body);
|
|
105
|
+
const bot = await medplum.readResource('Bot', newBot.id);
|
|
106
|
+
const botConfig = {
|
|
107
|
+
name: botName,
|
|
108
|
+
id: newBot.id,
|
|
109
|
+
source: sourceFile,
|
|
110
|
+
dist: distFile,
|
|
111
|
+
};
|
|
112
|
+
await saveBot(medplum, botConfig, bot);
|
|
113
|
+
console.log(`Success! Bot created: ${bot.id}`);
|
|
114
|
+
addBotToConfig(botConfig);
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
console.log('Error while creating new bot: ' + err);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function readBotConfigs(botName) {
|
|
121
|
+
const regExBotName = new RegExp('^' + escapeRegex(botName).replace(/\\\*/g, '.*') + '$');
|
|
122
|
+
const botConfigs = readConfig()?.bots?.filter((b) => regExBotName.test(b.name));
|
|
123
|
+
if (!botConfigs) {
|
|
124
|
+
return [];
|
|
125
|
+
}
|
|
126
|
+
return botConfigs;
|
|
127
|
+
}
|
|
128
|
+
function readConfig() {
|
|
129
|
+
const content = readFileContents('medplum.config.json');
|
|
130
|
+
if (!content) {
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
return JSON.parse(content);
|
|
134
|
+
}
|
|
135
|
+
function readFileContents(fileName) {
|
|
136
|
+
const path$1 = path.resolve(process.cwd(), fileName);
|
|
137
|
+
if (!fs.existsSync(path$1)) {
|
|
138
|
+
console.log('Error: File does not exist: ' + path$1);
|
|
139
|
+
return '';
|
|
140
|
+
}
|
|
141
|
+
return fs.readFileSync(path$1, 'utf8');
|
|
142
|
+
}
|
|
143
|
+
function addBotToConfig(botConfig) {
|
|
144
|
+
const config = readConfig();
|
|
145
|
+
config?.bots?.push(botConfig);
|
|
146
|
+
fs.writeFile('medplum.config.json', JSON.stringify(config), () => {
|
|
147
|
+
console.log(`Bot added to config: ${botConfig.id}`);
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
function escapeRegex(str) {
|
|
151
|
+
return str.replace(/[/\-\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const bot = new commander.Command('bot');
|
|
155
|
+
// Commands to deprecate
|
|
156
|
+
const saveBotDeprecate = new commander.Command('save-bot');
|
|
157
|
+
const deployBotDeprecate = new commander.Command('deploy-bot');
|
|
158
|
+
const createBotDeprecate = new commander.Command('create-bot');
|
|
159
|
+
bot
|
|
160
|
+
.command('save')
|
|
161
|
+
.description('Saving the bot')
|
|
162
|
+
.argument('<botName>')
|
|
163
|
+
.action(async (botName) => {
|
|
164
|
+
await botWrapper(exports.medplum, botName);
|
|
165
|
+
});
|
|
166
|
+
bot
|
|
167
|
+
.command('deploy')
|
|
168
|
+
.description('Deploy the app to AWS')
|
|
169
|
+
.argument('<botName>')
|
|
170
|
+
.action(async (botName) => {
|
|
171
|
+
await botWrapper(exports.medplum, botName, true);
|
|
172
|
+
});
|
|
173
|
+
bot
|
|
174
|
+
.command('create')
|
|
175
|
+
.arguments('<botName> <projectId> <sourceFile> <distFile>')
|
|
176
|
+
.description('Creating a bot')
|
|
177
|
+
.action(async (botName, projectId, sourceFile, distFile) => {
|
|
178
|
+
await createBot(exports.medplum, [botName, projectId, sourceFile, distFile]);
|
|
179
|
+
});
|
|
180
|
+
async function botWrapper(medplum, botName, deploy = false) {
|
|
181
|
+
const botConfigs = readBotConfigs(botName);
|
|
182
|
+
for (const botConfig of botConfigs) {
|
|
183
|
+
const bot = await medplum.readResource('Bot', botConfig.id);
|
|
184
|
+
await saveBot(medplum, botConfig, bot);
|
|
185
|
+
if (deploy) {
|
|
186
|
+
await deployBot(medplum, botConfig, bot);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
console.log(`Number of bots deployed: ${botConfigs.length}`);
|
|
190
|
+
}
|
|
191
|
+
// Deprecate bot commands
|
|
192
|
+
saveBotDeprecate
|
|
193
|
+
.description('Saves the bot')
|
|
194
|
+
.argument('<botName>')
|
|
195
|
+
.action(async (botName) => {
|
|
196
|
+
await botWrapper(exports.medplum, botName);
|
|
197
|
+
});
|
|
198
|
+
deployBotDeprecate
|
|
199
|
+
.description('Deploy the bot to AWS')
|
|
200
|
+
.argument('<botName>')
|
|
201
|
+
.action(async (botName) => {
|
|
202
|
+
await botWrapper(exports.medplum, botName, true);
|
|
203
|
+
});
|
|
204
|
+
createBotDeprecate
|
|
205
|
+
.arguments('<botName> <projectId> <sourceFile> <distFile>')
|
|
206
|
+
.description('Creates and saves the bot')
|
|
207
|
+
.action(async (botName, projectId, sourceFile, distFile) => {
|
|
208
|
+
await createBot(exports.medplum, [botName, projectId, sourceFile, distFile]);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
const clientId = 'medplum-cli';
|
|
212
|
+
const redirectUri = 'http://localhost:9615';
|
|
213
|
+
const login = new commander.Command('login');
|
|
214
|
+
const whoami = new commander.Command('whoami');
|
|
215
|
+
login.action(async () => {
|
|
216
|
+
await startLogin(exports.medplum);
|
|
217
|
+
});
|
|
218
|
+
whoami.action(() => {
|
|
219
|
+
printMe(exports.medplum);
|
|
220
|
+
});
|
|
112
221
|
async function startLogin(medplum) {
|
|
113
222
|
await startWebServer(medplum);
|
|
114
223
|
const loginUrl = new URL('/oauth2/authorize', medplum.getBaseUrl());
|
|
@@ -181,15 +290,41 @@ function printMe(medplum) {
|
|
|
181
290
|
console.log('Not logged in');
|
|
182
291
|
}
|
|
183
292
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
293
|
+
|
|
294
|
+
const deleteObject = new commander.Command('delete');
|
|
295
|
+
const get = new commander.Command('get');
|
|
296
|
+
const patch = new commander.Command('patch');
|
|
297
|
+
const post = new commander.Command('post');
|
|
298
|
+
const put = new commander.Command('put');
|
|
299
|
+
deleteObject.argument('<url>', 'Resource/$id').action(async (url) => {
|
|
300
|
+
prettyPrint(await exports.medplum.delete(cleanUrl(url)));
|
|
301
|
+
});
|
|
302
|
+
get
|
|
303
|
+
.argument('<url>', 'Resource/$id')
|
|
304
|
+
.option('--as-transaction', 'Print out the bundle as a transaction type')
|
|
305
|
+
.action(async (url, options) => {
|
|
306
|
+
try {
|
|
307
|
+
const response = await exports.medplum.get(cleanUrl(url));
|
|
308
|
+
if (options.asTransaction) {
|
|
309
|
+
prettyPrint(core.convertToTransactionBundle(response));
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
prettyPrint(response);
|
|
313
|
+
}
|
|
189
314
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
}
|
|
315
|
+
catch (err) {
|
|
316
|
+
console.log(err);
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
patch.arguments('<url> <body>').action(async (url, body) => {
|
|
320
|
+
prettyPrint(await exports.medplum.patch(cleanUrl(url), parseBody(body)));
|
|
321
|
+
});
|
|
322
|
+
post.arguments('<url> <body>').action(async (url, body) => {
|
|
323
|
+
prettyPrint(await exports.medplum.post(cleanUrl(url), parseBody(body)));
|
|
324
|
+
});
|
|
325
|
+
put.arguments('<url> <body>').action(async (url, body) => {
|
|
326
|
+
prettyPrint(await exports.medplum.put(cleanUrl(url), parseBody(body)));
|
|
327
|
+
});
|
|
193
328
|
function parseBody(input) {
|
|
194
329
|
if (!input) {
|
|
195
330
|
return undefined;
|
|
@@ -201,148 +336,99 @@ function parseBody(input) {
|
|
|
201
336
|
return input;
|
|
202
337
|
}
|
|
203
338
|
}
|
|
204
|
-
function
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
console.log(`Usage: medplum ${argv[2]} <bot-name>`);
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
const botName = argv[3];
|
|
213
|
-
const botConfigs = readBotConfigs(botName);
|
|
214
|
-
if (botConfigs.length === 0) {
|
|
215
|
-
console.log(`Error: ${botName} not found`);
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
for (const botConfig of botConfigs) {
|
|
219
|
-
await runBotConfig(botConfig, medplum, argv, commands);
|
|
220
|
-
}
|
|
221
|
-
console.log(`Number of bots deployed: ${botConfigs.length}`);
|
|
222
|
-
}
|
|
223
|
-
async function runBotConfig(botConfig, medplum, argv, commands) {
|
|
224
|
-
let bot;
|
|
225
|
-
try {
|
|
226
|
-
bot = await medplum.readResource('Bot', botConfig.id);
|
|
227
|
-
console.log(`Initialized Bot -> ${bot.name}...`);
|
|
228
|
-
}
|
|
229
|
-
catch (err) {
|
|
230
|
-
console.log('Error: ' + core.normalizeErrorString(err));
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
if (commands.includes('save')) {
|
|
234
|
-
await saveBot(medplum, botConfig, bot);
|
|
235
|
-
}
|
|
236
|
-
if (commands.includes('deploy')) {
|
|
237
|
-
await deployBot(medplum, botConfig, bot);
|
|
339
|
+
function cleanUrl(input) {
|
|
340
|
+
const knownPrefixes = ['admin/', 'auth/', 'fhir/R4'];
|
|
341
|
+
if (knownPrefixes.some((p) => input.startsWith(p))) {
|
|
342
|
+
// If the URL starts with a known prefix, return it as-is
|
|
343
|
+
return input;
|
|
238
344
|
}
|
|
345
|
+
// Otherwise, default to FHIR
|
|
346
|
+
return 'fhir/R4/' + input;
|
|
239
347
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
const newBot = await medplum.post('admin/projects/' + projectId + '/bot', body);
|
|
255
|
-
const bot = await medplum.readResource('Bot', newBot.id);
|
|
256
|
-
const botConfig = {
|
|
257
|
-
name: botName,
|
|
258
|
-
id: newBot.id,
|
|
259
|
-
source: sourceFile,
|
|
260
|
-
dist: distFile,
|
|
261
|
-
};
|
|
262
|
-
await saveBot(medplum, botConfig, bot);
|
|
263
|
-
console.log(`Success! Bot created: ${bot.id}`);
|
|
264
|
-
addBotToConfig(botConfig);
|
|
265
|
-
}
|
|
266
|
-
catch (err) {
|
|
267
|
-
console.log('Error while creating new bot ', err);
|
|
268
|
-
}
|
|
348
|
+
|
|
349
|
+
const project = new commander.Command('project');
|
|
350
|
+
project
|
|
351
|
+
.command('list')
|
|
352
|
+
.description('List of current projects')
|
|
353
|
+
.action(async () => {
|
|
354
|
+
projectList(exports.medplum);
|
|
355
|
+
});
|
|
356
|
+
function projectList(medplum) {
|
|
357
|
+
const logins = medplum.getLogins();
|
|
358
|
+
const projects = logins
|
|
359
|
+
.map((login) => `${login.project.display} (${login.project.reference})`)
|
|
360
|
+
.join('\n\n');
|
|
361
|
+
console.log(projects);
|
|
269
362
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
363
|
+
project
|
|
364
|
+
.command('current')
|
|
365
|
+
.description('Project you are currently on')
|
|
366
|
+
.action(() => {
|
|
367
|
+
const login = exports.medplum.getActiveLogin();
|
|
368
|
+
if (!login) {
|
|
369
|
+
throw new Error('Unauthenticated: run `npx medplum login` to login');
|
|
370
|
+
}
|
|
371
|
+
console.log(`${login.project.display} (${login.project.reference})`);
|
|
372
|
+
});
|
|
373
|
+
project
|
|
374
|
+
.command('switch')
|
|
375
|
+
.description('Switching to another project from the current one')
|
|
376
|
+
.argument('<projectId>')
|
|
377
|
+
.action(async (projectId) => {
|
|
378
|
+
await switchProject(exports.medplum, projectId);
|
|
379
|
+
});
|
|
380
|
+
async function switchProject(medplum, projectId) {
|
|
381
|
+
const logins = medplum.getLogins();
|
|
382
|
+
const login = logins.find((login) => login.project?.reference?.includes(projectId));
|
|
383
|
+
if (!login) {
|
|
384
|
+
console.log(`Error: project ${projectId} not found. Make sure you are added as a user to this project`);
|
|
274
385
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
...bot,
|
|
279
|
-
code,
|
|
280
|
-
});
|
|
281
|
-
if (!updateResult) {
|
|
282
|
-
console.log('Bot not modified');
|
|
283
|
-
}
|
|
284
|
-
else {
|
|
285
|
-
console.log('Success! New bot version: ' + updateResult.meta?.versionId);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
catch (err) {
|
|
289
|
-
console.log('Update error: ', err);
|
|
386
|
+
else {
|
|
387
|
+
await medplum.setActiveLogin(login);
|
|
388
|
+
console.log(`Switched to project ${projectId}\n`);
|
|
290
389
|
}
|
|
291
390
|
}
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
391
|
+
|
|
392
|
+
exports.medplum = void 0;
|
|
393
|
+
async function main(medplumClient, argv) {
|
|
394
|
+
exports.medplum = medplumClient;
|
|
395
|
+
// Legacy support for MEDPLUM_CLIENT_ID and MEDPLUM_CLIENT_SECRET environment variables
|
|
396
|
+
const clientId = process.env['MEDPLUM_CLIENT_ID'];
|
|
397
|
+
const clientSecret = process.env['MEDPLUM_CLIENT_SECRET'];
|
|
398
|
+
if (clientId && clientSecret) {
|
|
399
|
+
await exports.medplum.startClientLogin(clientId, clientSecret);
|
|
296
400
|
}
|
|
297
401
|
try {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
402
|
+
const index = new commander.Command('medplum').description('Command to access Medplum CLI');
|
|
403
|
+
index.version('0.1.0');
|
|
404
|
+
// Auth commands
|
|
405
|
+
index.addCommand(login);
|
|
406
|
+
index.addCommand(whoami);
|
|
407
|
+
// REST commands
|
|
408
|
+
index.addCommand(get);
|
|
409
|
+
index.addCommand(post);
|
|
410
|
+
index.addCommand(patch);
|
|
411
|
+
index.addCommand(put);
|
|
412
|
+
index.addCommand(deleteObject);
|
|
413
|
+
// Project
|
|
414
|
+
index.addCommand(project);
|
|
415
|
+
// Bot Commands
|
|
416
|
+
index.addCommand(bot);
|
|
417
|
+
// Deprecated Bot Commands
|
|
418
|
+
index.addCommand(saveBotDeprecate);
|
|
419
|
+
index.addCommand(deployBotDeprecate);
|
|
420
|
+
index.addCommand(createBotDeprecate);
|
|
421
|
+
await index.parseAsync(argv);
|
|
303
422
|
}
|
|
304
423
|
catch (err) {
|
|
305
|
-
console.
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
function escapeRegex(str) {
|
|
309
|
-
return str.replace(/[/\-\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
310
|
-
}
|
|
311
|
-
function readBotConfigs(botName) {
|
|
312
|
-
const regExBotName = new RegExp('^' + escapeRegex(botName).replace(/\\\*/g, '.*') + '$');
|
|
313
|
-
const botConfigs = readConfig()?.bots?.filter((b) => regExBotName.test(b.name));
|
|
314
|
-
if (!botConfigs) {
|
|
315
|
-
return [];
|
|
316
|
-
}
|
|
317
|
-
return botConfigs;
|
|
318
|
-
}
|
|
319
|
-
function readConfig() {
|
|
320
|
-
const content = readFileContents('medplum.config.json');
|
|
321
|
-
if (!content) {
|
|
322
|
-
return undefined;
|
|
323
|
-
}
|
|
324
|
-
return JSON.parse(content);
|
|
325
|
-
}
|
|
326
|
-
function readFileContents(fileName) {
|
|
327
|
-
const path$1 = path.resolve(process.cwd(), fileName);
|
|
328
|
-
if (!fs.existsSync(path$1)) {
|
|
329
|
-
console.log('Error: File does not exist: ' + path$1);
|
|
330
|
-
return '';
|
|
424
|
+
console.error('Error: ' + core.normalizeErrorString(err));
|
|
331
425
|
}
|
|
332
|
-
return fs.readFileSync(path$1, 'utf8');
|
|
333
|
-
}
|
|
334
|
-
function addBotToConfig(botConfig) {
|
|
335
|
-
const config = readConfig();
|
|
336
|
-
config?.bots?.push(botConfig);
|
|
337
|
-
fs.writeFile('medplum.config.json', JSON.stringify(config), () => {
|
|
338
|
-
console.log(`Bot added to config: ${botConfig.id}`);
|
|
339
|
-
});
|
|
340
426
|
}
|
|
341
427
|
if (require.main === module) {
|
|
342
428
|
dotenv.config();
|
|
343
429
|
const baseUrl = process.env['MEDPLUM_BASE_URL'] || 'https://api.medplum.com/';
|
|
344
|
-
const
|
|
345
|
-
main(
|
|
430
|
+
const medplumClient = new core.MedplumClient({ fetch, baseUrl, storage: new FileSystemStorage() });
|
|
431
|
+
main(medplumClient, process.argv).catch((err) => console.error('Unhandled error:', err));
|
|
346
432
|
}
|
|
347
433
|
|
|
348
434
|
exports.main = main;
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../src/storage.ts","../../../src/index.ts"],"sourcesContent":["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 private readonly dirName: string;\n private 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 private 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 private 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, writeFile } 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 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 case 'create-bot':\n await createBot(medplum, argv);\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', medplum.getBaseUrl());\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(`Server: ${medplum.getBaseUrl()}`);\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\n const botConfigs = readBotConfigs(botName);\n if (botConfigs.length === 0) {\n console.log(`Error: ${botName} not found`);\n return;\n }\n\n for (const botConfig of botConfigs) {\n await runBotConfig(botConfig, medplum, argv, commands);\n }\n\n console.log(`Number of bots deployed: ${botConfigs.length}`);\n}\n\nasync function runBotConfig(\n botConfig: MedplumBotConfig,\n medplum: MedplumClient,\n argv: string[],\n commands: string[]\n): Promise<void> {\n let bot;\n try {\n bot = await medplum.readResource('Bot', botConfig.id);\n console.log(`Initialized Bot -> ${bot.name}...`);\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 createBot(medplum: MedplumClient, argv: string[]): Promise<void> {\n if (argv.length < 7) {\n console.log(`Error: command needs to be npx medplum <new-bot-name> <project-id> <source-file> <dist-file>`);\n return;\n }\n const botName = argv[3];\n const projectId = argv[4];\n const sourceFile = argv[5];\n const distFile = argv[6];\n\n try {\n const body = {\n name: botName,\n description: '',\n };\n const newBot = await medplum.post('admin/projects/' + projectId + '/bot', body);\n const bot = await medplum.readResource('Bot', newBot.id);\n\n const botConfig = {\n name: botName,\n id: newBot.id,\n source: sourceFile,\n dist: distFile,\n };\n await saveBot(medplum, botConfig as MedplumBotConfig, bot);\n console.log(`Success! Bot created: ${bot.id}`);\n\n addBotToConfig(botConfig);\n } catch (err) {\n console.log('Error while creating new bot ', err);\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 escapeRegex(str: string): string {\n return str.replace(/[/\\-\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n}\n\nfunction readBotConfigs(botName: string): MedplumBotConfig[] {\n const regExBotName = new RegExp('^' + escapeRegex(botName).replace(/\\\\\\*/g, '.*') + '$');\n const botConfigs = readConfig()?.bots?.filter((b) => regExBotName.test(b.name));\n if (!botConfigs) {\n return [];\n }\n return botConfigs;\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\nfunction addBotToConfig(botConfig: MedplumBotConfig): void {\n const config = readConfig();\n config?.bots?.push(botConfig);\n writeFile('medplum.config.json', JSON.stringify(config), () => {\n console.log(`Bot added to config: ${botConfig.id}`);\n });\n}\n\nif (require.main === module) {\n dotenv.config();\n const baseUrl = process.env['MEDPLUM_BASE_URL'] || 'https://api.medplum.com/';\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","writeFile","MedplumClient"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../src/storage.ts","../../../src/utils.ts","../../../src/bots.ts","../../../src/auth.ts","../../../src/rest.ts","../../../src/projects.ts","../../../src/index.ts"],"sourcesContent":["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 private readonly dirName: string;\n private 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 private 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 private 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 { MedplumClient } from '@medplum/core';\nimport { resolve } from 'path';\nimport { existsSync, readFileSync, writeFile } from 'fs';\nimport { Bot, OperationOutcome } from '@medplum/fhirtypes';\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 function prettyPrint(input: unknown): void {\n console.log(JSON.stringify(input, null, 2));\n}\n\nexport async 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\nexport async 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\nexport async function createBot(medplum: MedplumClient, argv: string[]): Promise<void> {\n if (argv.length < 4) {\n console.log(`Error: command needs to be npx medplum <new-bot-name> <project-id> <source-file> <dist-file>`);\n return;\n }\n const botName = argv[0];\n const projectId = argv[1];\n const sourceFile = argv[2];\n const distFile = argv[3];\n\n try {\n const body = {\n name: botName,\n description: '',\n };\n const newBot = await medplum.post('admin/projects/' + projectId + '/bot', body);\n const bot = await medplum.readResource('Bot', newBot.id);\n\n const botConfig = {\n name: botName,\n id: newBot.id,\n source: sourceFile,\n dist: distFile,\n };\n await saveBot(medplum, botConfig as MedplumBotConfig, bot);\n console.log(`Success! Bot created: ${bot.id}`);\n\n addBotToConfig(botConfig);\n } catch (err) {\n console.log('Error while creating new bot: ' + err);\n }\n}\n\nexport function readBotConfigs(botName: string): MedplumBotConfig[] {\n const regExBotName = new RegExp('^' + escapeRegex(botName).replace(/\\\\\\*/g, '.*') + '$');\n const botConfigs = readConfig()?.bots?.filter((b) => regExBotName.test(b.name));\n if (!botConfigs) {\n return [];\n }\n return botConfigs;\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\nfunction addBotToConfig(botConfig: MedplumBotConfig): void {\n const config = readConfig();\n config?.bots?.push(botConfig);\n writeFile('medplum.config.json', JSON.stringify(config), () => {\n console.log(`Bot added to config: ${botConfig.id}`);\n });\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[/\\-\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n}\n","import { Command } from 'commander';\nimport { medplum } from '.';\nimport { createBot, deployBot, readBotConfigs, saveBot } from './utils';\nimport { MedplumClient } from '@medplum/core';\n\nexport const bot = new Command('bot');\n\n// Commands to deprecate\nexport const saveBotDeprecate = new Command('save-bot');\nexport const deployBotDeprecate = new Command('deploy-bot');\nexport const createBotDeprecate = new Command('create-bot');\n\nbot\n .command('save')\n .description('Saving the bot')\n .argument('<botName>')\n .action(async (botName) => {\n await botWrapper(medplum, botName);\n });\n\nbot\n .command('deploy')\n .description('Deploy the app to AWS')\n .argument('<botName>')\n .action(async (botName) => {\n await botWrapper(medplum, botName, true);\n });\n\nbot\n .command('create')\n .arguments('<botName> <projectId> <sourceFile> <distFile>')\n .description('Creating a bot')\n .action(async (botName, projectId, sourceFile, distFile) => {\n await createBot(medplum, [botName, projectId, sourceFile, distFile]);\n });\n\nexport async function botWrapper(medplum: MedplumClient, botName: string, deploy = false): Promise<void> {\n const botConfigs = readBotConfigs(botName);\n for (const botConfig of botConfigs) {\n const bot = await medplum.readResource('Bot', botConfig.id);\n await saveBot(medplum, botConfig, bot);\n if (deploy) {\n await deployBot(medplum, botConfig, bot);\n }\n }\n console.log(`Number of bots deployed: ${botConfigs.length}`);\n}\n\n// Deprecate bot commands\nsaveBotDeprecate\n .description('Saves the bot')\n .argument('<botName>')\n .action(async (botName) => {\n await botWrapper(medplum, botName);\n });\n\ndeployBotDeprecate\n .description('Deploy the bot to AWS')\n .argument('<botName>')\n .action(async (botName) => {\n await botWrapper(medplum, botName, true);\n });\n\ncreateBotDeprecate\n .arguments('<botName> <projectId> <sourceFile> <distFile>')\n .description('Creates and saves the bot')\n .action(async (botName, projectId, sourceFile, distFile) => {\n await createBot(medplum, [botName, projectId, sourceFile, distFile]);\n });\n","import { Command } from 'commander';\nimport { medplum } from '.';\nimport { MedplumClient, getDisplayString, normalizeErrorString } from '@medplum/core';\nimport { platform } from 'os';\nimport { exec } from 'child_process';\nimport { createServer } from 'http';\n\nconst clientId = 'medplum-cli';\nconst redirectUri = 'http://localhost:9615';\n\nexport const login = new Command('login');\nexport const whoami = new Command('whoami');\n\nlogin.action(async () => {\n await startLogin(medplum);\n});\n\nwhoami.action(() => {\n printMe(medplum);\n});\n\nasync function startLogin(medplum: MedplumClient): Promise<void> {\n await startWebServer(medplum);\n\n const loginUrl = new URL('/oauth2/authorize', medplum.getBaseUrl());\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(`Server: ${medplum.getBaseUrl()}`);\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","import { convertToTransactionBundle } from '@medplum/core';\nimport { Command } from 'commander';\nimport { medplum } from '.';\nimport { prettyPrint } from './utils';\n\nexport const deleteObject = new Command('delete');\nexport const get = new Command('get');\nexport const patch = new Command('patch');\nexport const post = new Command('post');\nexport const put = new Command('put');\n\ndeleteObject.argument('<url>', 'Resource/$id').action(async (url) => {\n prettyPrint(await medplum.delete(cleanUrl(url)));\n});\n\nget\n .argument('<url>', 'Resource/$id')\n .option('--as-transaction', 'Print out the bundle as a transaction type')\n .action(async (url, options) => {\n try {\n const response = await medplum.get(cleanUrl(url));\n if (options.asTransaction) {\n prettyPrint(convertToTransactionBundle(response));\n } else {\n prettyPrint(response);\n }\n } catch (err) {\n console.log(err);\n }\n });\n\npatch.arguments('<url> <body>').action(async (url, body) => {\n prettyPrint(await medplum.patch(cleanUrl(url), parseBody(body)));\n});\n\npost.arguments('<url> <body>').action(async (url, body) => {\n prettyPrint(await medplum.post(cleanUrl(url), parseBody(body)));\n});\n\nput.arguments('<url> <body>').action(async (url, body) => {\n prettyPrint(await medplum.put(cleanUrl(url), parseBody(body)));\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\nexport function 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","import { Command } from 'commander';\nimport { medplum } from '.';\nimport { MedplumClient, LoginState } from '@medplum/core';\n\nexport const project = new Command('project');\n\nproject\n .command('list')\n .description('List of current projects')\n .action(async () => {\n projectList(medplum);\n });\n\nfunction projectList(medplum: MedplumClient): void {\n const logins = medplum.getLogins();\n\n const projects = logins\n .map((login: LoginState) => `${login.project.display} (${login.project.reference})`)\n .join('\\n\\n');\n\n console.log(projects);\n}\n\nproject\n .command('current')\n .description('Project you are currently on')\n .action(() => {\n const login = medplum.getActiveLogin();\n if (!login) {\n throw new Error('Unauthenticated: run `npx medplum login` to login');\n }\n console.log(`${login.project.display} (${login.project.reference})`);\n });\n\nproject\n .command('switch')\n .description('Switching to another project from the current one')\n .argument('<projectId>')\n .action(async (projectId) => {\n await switchProject(medplum, projectId);\n });\n\nasync function switchProject(medplum: MedplumClient, projectId: string): Promise<void> {\n const logins = medplum.getLogins();\n const login = logins.find((login: LoginState) => login.project?.reference?.includes(projectId));\n if (!login) {\n console.log(`Error: project ${projectId} not found. Make sure you are added as a user to this project`);\n } else {\n await medplum.setActiveLogin(login);\n console.log(`Switched to project ${projectId}\\n`);\n }\n}\n","import { Command } from 'commander';\nimport { FileSystemStorage } from './storage';\nimport { MedplumClient, normalizeErrorString } from '@medplum/core';\nimport dotenv from 'dotenv';\nimport { bot, createBotDeprecate, deployBotDeprecate, saveBotDeprecate } from './bots';\nimport { login, whoami } from './auth';\nimport { deleteObject, get, patch, post, put } from './rest';\nimport { project } from './projects';\n\nexport let medplum: MedplumClient;\n\nexport async function main(medplumClient: MedplumClient, argv: string[]): Promise<void> {\n medplum = medplumClient;\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 try {\n const index = new Command('medplum').description('Command to access Medplum CLI');\n index.version('0.1.0');\n\n // Auth commands\n index.addCommand(login);\n index.addCommand(whoami);\n\n // REST commands\n index.addCommand(get);\n index.addCommand(post);\n index.addCommand(patch);\n index.addCommand(put);\n index.addCommand(deleteObject);\n\n // Project\n index.addCommand(project);\n\n // Bot Commands\n index.addCommand(bot);\n\n // Deprecated Bot Commands\n index.addCommand(saveBotDeprecate);\n index.addCommand(deployBotDeprecate);\n index.addCommand(createBotDeprecate);\n\n await index.parseAsync(argv);\n } catch (err) {\n console.error('Error: ' + normalizeErrorString(err));\n }\n}\n\nif (require.main === module) {\n dotenv.config();\n const baseUrl = process.env['MEDPLUM_BASE_URL'] || 'https://api.medplum.com/';\n const medplumClient = new MedplumClient({ fetch, baseUrl, storage: new FileSystemStorage() });\n main(medplumClient, process.argv).catch((err) => console.error('Unhandled error:', err));\n}\n"],"names":["ClientStorage","resolve","homedir","existsSync","readFileSync","mkdirSync","writeFileSync","path","writeFile","Command","medplum","createServer","getDisplayString","normalizeErrorString","os","platform","exec","convertToTransactionBundle","MedplumClient"],"mappings":";;;;;;;;;;;;AAKM,MAAO,iBAAkB,SAAQA,kBAAa,CAAA;AAIlD,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,GAAGC,YAAO,CAACC,UAAO,EAAE,EAAE,UAAU,CAAC,CAAC;QAC9C,IAAI,CAAC,QAAQ,GAAGD,YAAO,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;KACtD;IAED,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;KACpB;AAED,IAAA,SAAS,CAAC,GAAW,EAAA;QACnB,OAAO,IAAI,CAAC,QAAQ,EAAE,GAAG,GAAG,CAAC,CAAC;KAC/B;IAED,SAAS,CAAC,GAAW,EAAE,KAAyB,EAAA;QAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;AACnC,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,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;KACtB;IAEO,QAAQ,GAAA;AACd,QAAA,IAAIE,aAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;AAC7B,YAAA,OAAO,IAAI,CAAC,KAAK,CAACC,eAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AACxD,SAAA;AACD,QAAA,OAAO,SAAS,CAAC;KAClB;AAEO,IAAA,SAAS,CAAC,IAA4B,EAAA;AAC5C,QAAA,IAAI,CAACD,aAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;AAC7B,YAAAE,YAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACzB,SAAA;AACD,QAAAC,gBAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;KACrE;AACF;;AC9BK,SAAU,WAAW,CAAC,KAAc,EAAA;AACxC,IAAA,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC;AAEM,eAAe,OAAO,CAAC,OAAsB,EAAE,SAA2B,EAAE,GAAQ,EAAA;IACzF,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;AAEM,eAAe,SAAS,CAAC,OAAsB,EAAE,SAA2B,EAAE,GAAQ,EAAA;AAC3F,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;AAEM,eAAe,SAAS,CAAC,OAAsB,EAAE,IAAc,EAAA;AACpE,IAAA,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;AACnB,QAAA,OAAO,CAAC,GAAG,CAAC,CAAA,4FAAA,CAA8F,CAAC,CAAC;QAC5G,OAAO;AACR,KAAA;AACD,IAAA,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AACxB,IAAA,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAC1B,IAAA,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAC3B,IAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAEzB,IAAI;AACF,QAAA,MAAM,IAAI,GAAG;AACX,YAAA,IAAI,EAAE,OAAO;AACb,YAAA,WAAW,EAAE,EAAE;SAChB,CAAC;AACF,QAAA,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,iBAAiB,GAAG,SAAS,GAAG,MAAM,EAAE,IAAI,CAAC,CAAC;AAChF,QAAA,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;AAEzD,QAAA,MAAM,SAAS,GAAG;AAChB,YAAA,IAAI,EAAE,OAAO;YACb,EAAE,EAAE,MAAM,CAAC,EAAE;AACb,YAAA,MAAM,EAAE,UAAU;AAClB,YAAA,IAAI,EAAE,QAAQ;SACf,CAAC;QACF,MAAM,OAAO,CAAC,OAAO,EAAE,SAA6B,EAAE,GAAG,CAAC,CAAC;QAC3D,OAAO,CAAC,GAAG,CAAC,CAAA,sBAAA,EAAyB,GAAG,CAAC,EAAE,CAAE,CAAA,CAAC,CAAC;QAE/C,cAAc,CAAC,SAAS,CAAC,CAAC;AAC3B,KAAA;AAAC,IAAA,OAAO,GAAG,EAAE;AACZ,QAAA,OAAO,CAAC,GAAG,CAAC,gCAAgC,GAAG,GAAG,CAAC,CAAC;AACrD,KAAA;AACH,CAAC;AAEK,SAAU,cAAc,CAAC,OAAe,EAAA;IAC5C,MAAM,YAAY,GAAG,IAAI,MAAM,CAAC,GAAG,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;IACzF,MAAM,UAAU,GAAG,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAChF,IAAI,CAAC,UAAU,EAAE;AACf,QAAA,OAAO,EAAE,CAAC;AACX,KAAA;AACD,IAAA,OAAO,UAAU,CAAC;AACpB,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,MAAMC,MAAI,GAAGN,YAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;AAC9C,IAAA,IAAI,CAACE,aAAU,CAACI,MAAI,CAAC,EAAE;AACrB,QAAA,OAAO,CAAC,GAAG,CAAC,8BAA8B,GAAGA,MAAI,CAAC,CAAC;AACnD,QAAA,OAAO,EAAE,CAAC;AACX,KAAA;AACD,IAAA,OAAOH,eAAY,CAACG,MAAI,EAAE,MAAM,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,cAAc,CAAC,SAA2B,EAAA;AACjD,IAAA,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;AAC5B,IAAA,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAC9BC,YAAS,CAAC,qBAAqB,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,MAAK;QAC5D,OAAO,CAAC,GAAG,CAAC,CAAA,qBAAA,EAAwB,SAAS,CAAC,EAAE,CAAE,CAAA,CAAC,CAAC;AACtD,KAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,WAAW,CAAC,GAAW,EAAA;IAC9B,OAAO,GAAG,CAAC,OAAO,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAAC;AACvD;;AC3HO,MAAM,GAAG,GAAG,IAAIC,iBAAO,CAAC,KAAK,CAAC,CAAC;AAEtC;AACO,MAAM,gBAAgB,GAAG,IAAIA,iBAAO,CAAC,UAAU,CAAC,CAAC;AACjD,MAAM,kBAAkB,GAAG,IAAIA,iBAAO,CAAC,YAAY,CAAC,CAAC;AACrD,MAAM,kBAAkB,GAAG,IAAIA,iBAAO,CAAC,YAAY,CAAC,CAAC;AAE5D,GAAG;KACA,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,gBAAgB,CAAC;KAC7B,QAAQ,CAAC,WAAW,CAAC;AACrB,KAAA,MAAM,CAAC,OAAO,OAAO,KAAI;AACxB,IAAA,MAAM,UAAU,CAACC,eAAO,EAAE,OAAO,CAAC,CAAC;AACrC,CAAC,CAAC,CAAC;AAEL,GAAG;KACA,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,uBAAuB,CAAC;KACpC,QAAQ,CAAC,WAAW,CAAC;AACrB,KAAA,MAAM,CAAC,OAAO,OAAO,KAAI;IACxB,MAAM,UAAU,CAACA,eAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC;AAEL,GAAG;KACA,OAAO,CAAC,QAAQ,CAAC;KACjB,SAAS,CAAC,+CAA+C,CAAC;KAC1D,WAAW,CAAC,gBAAgB,CAAC;KAC7B,MAAM,CAAC,OAAO,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,KAAI;AACzD,IAAA,MAAM,SAAS,CAACA,eAAO,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;AACvE,CAAC,CAAC,CAAC;AAEE,eAAe,UAAU,CAAC,OAAsB,EAAE,OAAe,EAAE,MAAM,GAAG,KAAK,EAAA;AACtF,IAAA,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;AAC3C,IAAA,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE;AAClC,QAAA,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC;QAC5D,MAAM,OAAO,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;AACvC,QAAA,IAAI,MAAM,EAAE;YACV,MAAM,SAAS,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;AAC1C,SAAA;AACF,KAAA;IACD,OAAO,CAAC,GAAG,CAAC,CAAA,yBAAA,EAA4B,UAAU,CAAC,MAAM,CAAE,CAAA,CAAC,CAAC;AAC/D,CAAC;AAED;AACA,gBAAgB;KACb,WAAW,CAAC,eAAe,CAAC;KAC5B,QAAQ,CAAC,WAAW,CAAC;AACrB,KAAA,MAAM,CAAC,OAAO,OAAO,KAAI;AACxB,IAAA,MAAM,UAAU,CAACA,eAAO,EAAE,OAAO,CAAC,CAAC;AACrC,CAAC,CAAC,CAAC;AAEL,kBAAkB;KACf,WAAW,CAAC,uBAAuB,CAAC;KACpC,QAAQ,CAAC,WAAW,CAAC;AACrB,KAAA,MAAM,CAAC,OAAO,OAAO,KAAI;IACxB,MAAM,UAAU,CAACA,eAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC;AAEL,kBAAkB;KACf,SAAS,CAAC,+CAA+C,CAAC;KAC1D,WAAW,CAAC,2BAA2B,CAAC;KACxC,MAAM,CAAC,OAAO,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,KAAI;AACzD,IAAA,MAAM,SAAS,CAACA,eAAO,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;AACvE,CAAC,CAAC;;AC7DJ,MAAM,QAAQ,GAAG,aAAa,CAAC;AAC/B,MAAM,WAAW,GAAG,uBAAuB,CAAC;AAErC,MAAM,KAAK,GAAG,IAAID,iBAAO,CAAC,OAAO,CAAC,CAAC;AACnC,MAAM,MAAM,GAAG,IAAIA,iBAAO,CAAC,QAAQ,CAAC,CAAC;AAE5C,KAAK,CAAC,MAAM,CAAC,YAAW;AACtB,IAAA,MAAM,UAAU,CAACC,eAAO,CAAC,CAAC;AAC5B,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,CAAC,MAAK;IACjB,OAAO,CAACA,eAAO,CAAC,CAAC;AACnB,CAAC,CAAC,CAAC;AAEH,eAAe,UAAU,CAAC,OAAsB,EAAA;AAC9C,IAAA,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;AAE9B,IAAA,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,mBAAmB,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IACpE,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,EAAAC,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,MAAMC,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;QACd,OAAO,CAAC,GAAG,CAAC,CAAY,SAAA,EAAA,OAAO,CAAC,UAAU,EAAE,CAAE,CAAA,CAAC,CAAC;AAChD,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;;ACvFO,MAAM,YAAY,GAAG,IAAIP,iBAAO,CAAC,QAAQ,CAAC,CAAC;AAC3C,MAAM,GAAG,GAAG,IAAIA,iBAAO,CAAC,KAAK,CAAC,CAAC;AAC/B,MAAM,KAAK,GAAG,IAAIA,iBAAO,CAAC,OAAO,CAAC,CAAC;AACnC,MAAM,IAAI,GAAG,IAAIA,iBAAO,CAAC,MAAM,CAAC,CAAC;AACjC,MAAM,GAAG,GAAG,IAAIA,iBAAO,CAAC,KAAK,CAAC,CAAC;AAEtC,YAAY,CAAC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,MAAM,CAAC,OAAO,GAAG,KAAI;AAClE,IAAA,WAAW,CAAC,MAAMC,eAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC,CAAC,CAAC;AAEH,GAAG;AACA,KAAA,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;AACjC,KAAA,MAAM,CAAC,kBAAkB,EAAE,4CAA4C,CAAC;AACxE,KAAA,MAAM,CAAC,OAAO,GAAG,EAAE,OAAO,KAAI;IAC7B,IAAI;AACF,QAAA,MAAM,QAAQ,GAAG,MAAMA,eAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;QAClD,IAAI,OAAO,CAAC,aAAa,EAAE;AACzB,YAAA,WAAW,CAACO,+BAA0B,CAAC,QAAQ,CAAC,CAAC,CAAC;AACnD,SAAA;AAAM,aAAA;YACL,WAAW,CAAC,QAAQ,CAAC,CAAC;AACvB,SAAA;AACF,KAAA;AAAC,IAAA,OAAO,GAAG,EAAE;AACZ,QAAA,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAClB,KAAA;AACH,CAAC,CAAC,CAAC;AAEL,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,OAAO,GAAG,EAAE,IAAI,KAAI;AACzD,IAAA,WAAW,CAAC,MAAMP,eAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,OAAO,GAAG,EAAE,IAAI,KAAI;AACxD,IAAA,WAAW,CAAC,MAAMA,eAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC,CAAC,CAAC;AAEH,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,OAAO,GAAG,EAAE,IAAI,KAAI;AACvD,IAAA,WAAW,CAAC,MAAMA,eAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC,CAAC,CAAC;AAEH,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;AAEK,SAAU,QAAQ,CAAC,KAAa,EAAA;IACpC,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;;AC1DO,MAAM,OAAO,GAAG,IAAID,iBAAO,CAAC,SAAS,CAAC,CAAC;AAE9C,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,0BAA0B,CAAC;KACvC,MAAM,CAAC,YAAW;IACjB,WAAW,CAACC,eAAO,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC;AAEL,SAAS,WAAW,CAAC,OAAsB,EAAA;AACzC,IAAA,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAEnC,MAAM,QAAQ,GAAG,MAAM;AACpB,SAAA,GAAG,CAAC,CAAC,KAAiB,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO,CAAC,SAAS,GAAG,CAAC;SACnF,IAAI,CAAC,MAAM,CAAC,CAAC;AAEhB,IAAA,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AACxB,CAAC;AAED,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,8BAA8B,CAAC;KAC3C,MAAM,CAAC,MAAK;AACX,IAAA,MAAM,KAAK,GAAGA,eAAO,CAAC,cAAc,EAAE,CAAC;IACvC,IAAI,CAAC,KAAK,EAAE;AACV,QAAA,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;AACtE,KAAA;AACD,IAAA,OAAO,CAAC,GAAG,CAAC,CAAG,EAAA,KAAK,CAAC,OAAO,CAAC,OAAO,CAAA,EAAA,EAAK,KAAK,CAAC,OAAO,CAAC,SAAS,CAAA,CAAA,CAAG,CAAC,CAAC;AACvE,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,mDAAmD,CAAC;KAChE,QAAQ,CAAC,aAAa,CAAC;AACvB,KAAA,MAAM,CAAC,OAAO,SAAS,KAAI;AAC1B,IAAA,MAAM,aAAa,CAACA,eAAO,EAAE,SAAS,CAAC,CAAC;AAC1C,CAAC,CAAC,CAAC;AAEL,eAAe,aAAa,CAAC,OAAsB,EAAE,SAAiB,EAAA;AACpE,IAAA,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IACnC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,KAAiB,KAAK,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;IAChG,IAAI,CAAC,KAAK,EAAE;AACV,QAAA,OAAO,CAAC,GAAG,CAAC,kBAAkB,SAAS,CAAA,6DAAA,CAA+D,CAAC,CAAC;AACzG,KAAA;AAAM,SAAA;AACL,QAAA,MAAM,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;AACpC,QAAA,OAAO,CAAC,GAAG,CAAC,uBAAuB,SAAS,CAAA,EAAA,CAAI,CAAC,CAAC;AACnD,KAAA;AACH;;AC1CWA,yBAAuB;AAE3B,eAAe,IAAI,CAAC,aAA4B,EAAE,IAAc,EAAA;IACrEA,eAAO,GAAG,aAAa,CAAC;;IAGxB,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,MAAMA,eAAO,CAAC,gBAAgB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;AACxD,KAAA;IACD,IAAI;AACF,QAAA,MAAM,KAAK,GAAG,IAAID,iBAAO,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,+BAA+B,CAAC,CAAC;AAClF,QAAA,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;;AAGvB,QAAA,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;AACxB,QAAA,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;;AAGzB,QAAA,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AACtB,QAAA,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AACvB,QAAA,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;AACxB,QAAA,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AACtB,QAAA,KAAK,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;;AAG/B,QAAA,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;;AAG1B,QAAA,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;;AAGtB,QAAA,KAAK,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;AACnC,QAAA,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;AACrC,QAAA,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;AAErC,QAAA,MAAM,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AAC9B,KAAA;AAAC,IAAA,OAAO,GAAG,EAAE;QACZ,OAAO,CAAC,KAAK,CAAC,SAAS,GAAGI,yBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC;AACtD,KAAA;AACH,CAAC;AAED,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE;IAC3B,MAAM,CAAC,MAAM,EAAE,CAAC;IAChB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,0BAA0B,CAAC;AAC9E,IAAA,MAAM,aAAa,GAAG,IAAIK,kBAAa,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,iBAAiB,EAAE,EAAE,CAAC,CAAC;IAC9F,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC,CAAC;AAC1F;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@medplum/cli",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.16",
|
|
4
4
|
"description": "Medplum Command Line Interface",
|
|
5
5
|
"author": "Medplum <hello@medplum.com>",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@medplum/core": "*",
|
|
21
|
+
"commander": "10.0.1",
|
|
21
22
|
"dotenv": "16.0.3",
|
|
22
23
|
"node-fetch": "2.6.9"
|
|
23
24
|
},
|