dhti-cli 0.5.0 → 0.6.0

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.
@@ -59,6 +59,7 @@ export default class Compose extends Command {
59
59
  const mcpFhir = ['mcp-fhir', 'fhir', 'postgres-db'];
60
60
  const mcpx = ['mcpx'];
61
61
  const docktor = ['mcpx'];
62
+ const medplum = ['medplum-server', 'medplum-app', 'postgres-db', 'redis', 'mpclient'];
62
63
  const _modules = {
63
64
  cqlFhir,
64
65
  fhir,
@@ -73,6 +74,7 @@ export default class Compose extends Command {
73
74
  openmrs,
74
75
  redis,
75
76
  webui,
77
+ medplum,
76
78
  };
77
79
  try {
78
80
  const masterData = yaml.load(fs.readFileSync(path.join(RESOURCES_DIR, 'docker-compose-master.yml'), 'utf8'));
@@ -7,6 +7,7 @@ export default class Mimic extends Command {
7
7
  static examples: string[];
8
8
  static flags: {
9
9
  'dry-run': import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
11
  };
11
12
  run(): Promise<void>;
12
13
  }
@@ -11,9 +11,18 @@ export default class Mimic extends Command {
11
11
  default: false,
12
12
  description: 'Show what changes would be made without actually making them',
13
13
  }),
14
+ token: Flags.string({
15
+ char: 't',
16
+ description: 'Bearer token for authentication (optional)',
17
+ }),
14
18
  };
15
19
  async run() {
16
20
  const { args, flags } = await this.parse(Mimic);
21
+ // Ensure server URL ends with /$import
22
+ let serverUrl = args.server;
23
+ if (!serverUrl.endsWith('/$import')) {
24
+ serverUrl = serverUrl.replace(/\/$/, '') + '/$import';
25
+ }
17
26
  const mimic_request = `{
18
27
 
19
28
  "resourceType": "Parameters",
@@ -148,25 +157,34 @@ export default class Mimic extends Command {
148
157
 
149
158
  }`;
150
159
  if (flags['dry-run']) {
151
- console.log(chalk.yellow(`[DRY RUN] Would send POST request to: ${args.server}`));
160
+ console.log(chalk.yellow(`[DRY RUN] Would send POST request to: ${serverUrl}`));
152
161
  console.log(chalk.cyan('[DRY RUN] Request headers:'));
153
162
  console.log(chalk.green(' Content-Type: application/fhir+json'));
154
163
  console.log(chalk.green(' Prefer: respond-async'));
164
+ if (flags.token) {
165
+ console.log(chalk.green(' Authorization: Bearer <token>'));
166
+ }
155
167
  console.log(chalk.cyan('[DRY RUN] Request body:'));
156
168
  console.log(mimic_request);
157
169
  return;
158
170
  }
171
+ // Build request headers
172
+ const headers = {
173
+ 'Content-Type': 'application/fhir+json',
174
+ Prefer: 'respond-async',
175
+ };
176
+ if (flags.token) {
177
+ headers.Authorization = `Bearer ${flags.token}`;
178
+ }
159
179
  // send a POST request to the server with the mimic_request body
160
- const response = await fetch(args.server, {
180
+ const response = await fetch(serverUrl, {
161
181
  body: mimic_request,
162
- headers: {
163
- 'Content-Type': 'application/fhir+json',
164
- Prefer: 'respond-async',
165
- },
182
+ headers,
166
183
  method: 'POST',
167
184
  });
168
185
  if (!response.ok) {
169
186
  console.error(`Error: ${response.status} ${response.statusText}`);
187
+ this.exit(1);
170
188
  }
171
189
  }
172
190
  }
@@ -173,7 +173,7 @@ services:
173
173
  - LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES=${LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES:-false}
174
174
 
175
175
  postgres-db:
176
- image: postgres
176
+ image: postgres:17
177
177
  restart: "unless-stopped"
178
178
  environment:
179
179
  - POSTGRES_USER=postgres
@@ -183,6 +183,12 @@ services:
183
183
  - 5432:5432
184
184
  volumes:
185
185
  - postgres-db:/var/lib/postgresql/data
186
+ healthcheck:
187
+ test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
188
+ interval: 10s
189
+ timeout: 5s
190
+ retries: 5
191
+ start_period: 10s
186
192
 
187
193
  redis:
188
194
  image: redislabs/redisearch:2.8.8
@@ -191,6 +197,12 @@ services:
191
197
  restart: "unless-stopped"
192
198
  volumes:
193
199
  - redis-db:/data
200
+ healthcheck:
201
+ test: ["CMD", "redis-cli", "ping"]
202
+ interval: 10s
203
+ timeout: 5s
204
+ retries: 3
205
+ start_period: 10s
194
206
 
195
207
  redis-commander:
196
208
  image: rediscommander/redis-commander:latest
@@ -234,14 +246,111 @@ services:
234
246
  - "3000:3000"
235
247
  # environment:
236
248
  # - MCPX_PORT=9000
237
- # - MCPX_SERVER_URL="http://10.0.0.211:9000"
249
+ # - MCPX_SERVER_URL="http://localhost:9000"
238
250
  # - VITE_MCPX_SERVER_PORT=9000
239
- # - VITE_MCPX_SERVER_URL="http://10.0.0.211:9000"
251
+ # - VITE_MCPX_SERVER_URL="http://localhost:9000"
240
252
  restart: unless-stopped
241
253
  volumes:
242
254
  - mcpx-config:/lunar/packages/mcpx-server/config
243
255
  privileged: true
244
256
 
257
+ # Medplum server container
258
+ medplum-server:
259
+ image: medplum/medplum-server:latest
260
+ restart: always
261
+ depends_on:
262
+ postgres-db:
263
+ condition: service_healthy
264
+ redis:
265
+ condition: service_healthy
266
+ ports:
267
+ - '8103:8103'
268
+ volumes:
269
+ # Conditionally define a volume for a `medplum.config.json` if one is specified by the MEDPLUM_CONFIG_PATH env var
270
+ - ${MEDPLUM_CONFIG_PATH:-./medplum.config.json}:/usr/src/medplum/packages/server/medplum.config.json
271
+ entrypoint: >
272
+ sh -c "
273
+ if [ -n '${MEDPLUM_CONFIG_PATH}' ]; then
274
+ echo 'Config file found, running with custom config'
275
+ node --require ./packages/server/dist/otel/instrumentation.js packages/server/dist/index.js file:/usr/src/medplum/packages/server/medplum.config.json
276
+ else
277
+ echo 'No config file found, running with default env settings'
278
+ node --require ./packages/server/dist/otel/instrumentation.js packages/server/dist/index.js env
279
+ fi
280
+ "
281
+ environment:
282
+ MEDPLUM_PORT: 8103
283
+ MEDPLUM_BASE_URL: 'http://localhost:8103/'
284
+ MEDPLUM_APP_BASE_URL: 'http://localhost:3103/'
285
+ MEDPLUM_STORAGE_BASE_URL: 'http://localhost:8103/storage/'
286
+
287
+ MEDPLUM_DATABASE_HOST: 'postgres-db'
288
+ MEDPLUM_DATABASE_PORT: 5432
289
+ MEDPLUM_DATABASE_DBNAME: 'postgres'
290
+ MEDPLUM_DATABASE_USERNAME: 'postgres'
291
+ MEDPLUM_DATABASE_PASSWORD: 'postgres'
292
+
293
+ MEDPLUM_REDIS_HOST: 'redis'
294
+ MEDPLUM_REDIS_PORT: 6379
295
+ # MEDPLUM_REDIS_PASSWORD: 'medplum'
296
+
297
+ MEDPLUM_BINARY_STORAGE: 'file:./binary/'
298
+ MEDPLUM_SUPPORT_EMAIL: '\"Medplum\" <support@medplum.com>'
299
+ MEDPLUM_GOOGLE_CLIENT_ID: '397236612778-c0b5tnjv98frbo1tfuuha5vkme3cmq4s.apps.googleusercontent.com'
300
+ MEDPLUM_GOOGLE_CLIENT_SECRET: ''
301
+ MEDPLUM_RECAPTCHA_SITE_KEY: '6LfHdsYdAAAAAC0uLnnRrDrhcXnziiUwKd8VtLNq'
302
+ MEDPLUM_RECAPTCHA_SECRET_KEY: '6LfHdsYdAAAAAH9dN154jbJ3zpQife3xaiTvPChL'
303
+ MEDPLUM_MAX_JSON_SIZE: '1mb'
304
+ MEDPLUM_MAX_BATCH_SIZE: '50mb'
305
+ MEDPLUM_BOT_LAMBDA_ROLE_ARN: ''
306
+ MEDPLUM_BOT_LAMBDA_LAYER_NAME: 'medplum-bot-layer'
307
+ MEDPLUM_VM_CONTEXT_BOTS_ENABLED: 'true'
308
+ MEDPLUM_DEFAULT_BOT_RUNTIME_VERSION: 'vmcontext'
309
+ MEDPLUM_ALLOWED_ORIGINS: '*'
310
+ MEDPLUM_INTROSPECTION_ENABLED: 'true'
311
+ MEDPLUM_SHUTDOWN_TIMEOUT_MILLISECONDS: 30000
312
+
313
+ healthcheck:
314
+ test:
315
+ # We use Node's fetch for healthcheck because this image doesn't have a curl or wget installed
316
+ [
317
+ 'CMD',
318
+ 'node',
319
+ '-e',
320
+ 'fetch("http://localhost:8103/healthcheck").then(r => r.json()).then(console.log).catch(() => { process.exit(1); })',
321
+ ]
322
+ interval: 30s
323
+ timeout: 10s
324
+ retries: 5
325
+
326
+ # Medplum app container (web UI)
327
+ medplum-app:
328
+ image: medplum/medplum-app:latest
329
+ restart: always
330
+ # depends_on:
331
+ # medplum-server:
332
+ # condition: service_healthy
333
+ ports:
334
+ - '3103:3000'
335
+ healthcheck:
336
+ test: ['CMD', 'curl', '-f', 'http://localhost:3103']
337
+ interval: 10s
338
+ timeout: 5s
339
+ retries: 5
340
+
341
+ mpclient:
342
+ image: beapen/mpclient:15.0
343
+ ports:
344
+ - "8111:8111"
345
+ restart: "unless-stopped"
346
+ environment:
347
+ - PORT=8111
348
+ - MPCLIENT_BASE_URL=http://localhost:8111
349
+ - MEDPLUM_TOKEN_URL=http://medplum-server:8103/oauth2/token
350
+ - MEDPLUM_CLIENT_ID=client-id
351
+ - MEDPLUM_CLIENT_SECRET=secret
352
+ depends_on:
353
+ - medplum-server
245
354
 
246
355
  volumes:
247
356
  openmrs-data: ~
@@ -457,6 +457,14 @@
457
457
  "name": "dry-run",
458
458
  "allowNo": false,
459
459
  "type": "boolean"
460
+ },
461
+ "token": {
462
+ "char": "t",
463
+ "description": "Bearer token for authentication (optional)",
464
+ "name": "token",
465
+ "hasDynamicHelp": false,
466
+ "multiple": false,
467
+ "type": "option"
460
468
  }
461
469
  },
462
470
  "hasDynamicHelp": false,
@@ -566,5 +574,5 @@
566
574
  ]
567
575
  }
568
576
  },
569
- "version": "0.5.0"
577
+ "version": "0.6.0"
570
578
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dhti-cli",
3
3
  "description": "DHTI CLI",
4
- "version": "0.5.0",
4
+ "version": "0.6.0",
5
5
  "author": "Bell Eapen",
6
6
  "bin": {
7
7
  "dhti-cli": "bin/run.js"