@medplum/core 2.0.17 → 2.0.18

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.
@@ -1555,7 +1555,7 @@
1555
1555
  *
1556
1556
  * When using MedplumClient in the browser, it will be backed by browser localStorage.
1557
1557
  *
1558
- * When Using MedplumClient in the server, it will be backed by the MemoryStorage class.
1558
+ * When Using MedplumClient in the server, it will be backed by the MemoryStorage class. For example, the Medplum CLI uses `FileSystemStorage`.
1559
1559
  */
1560
1560
  class ClientStorage {
1561
1561
  constructor() {
@@ -6404,7 +6404,7 @@
6404
6404
  const globalSchema = baseSchema;
6405
6405
 
6406
6406
  // PKCE auth based on:
6407
- const MEDPLUM_VERSION = "2.0.17-5c5ebbda";
6407
+ const MEDPLUM_VERSION = "2.0.18-e7b9bd9c" ;
6408
6408
  const DEFAULT_BASE_URL = 'https://api.medplum.com/';
6409
6409
  const DEFAULT_RESOURCE_CACHE_SIZE = 1000;
6410
6410
  const DEFAULT_CACHE_TIME = 60000; // 60 seconds
@@ -7980,6 +7980,9 @@
7980
7980
  // No content or change
7981
7981
  return undefined;
7982
7982
  }
7983
+ if (response.status === 404) {
7984
+ throw new OperationOutcomeError(normalizeOperationOutcome(notFound));
7985
+ }
7983
7986
  let obj = undefined;
7984
7987
  try {
7985
7988
  obj = await response.json();
@@ -8204,6 +8207,14 @@
8204
8207
  }
8205
8208
  /**
8206
8209
  * Starts a new OAuth2 client credentials flow.
8210
+ *
8211
+ * ```typescript
8212
+ * await medplum.startClientLogin(process.env.MEDPLUM_CLIENT_ID, process.env.MEDPLUM_CLIENT_SECRET)
8213
+ * // Example Search
8214
+ * await medplum.searchResources('Patient')
8215
+ * ```
8216
+ *
8217
+ *
8207
8218
  * See: https://datatracker.ietf.org/doc/html/rfc6749#section-4.4
8208
8219
  * @category Authentication
8209
8220
  * @param clientId The client ID.
@@ -8221,6 +8232,13 @@
8221
8232
  }
8222
8233
  /**
8223
8234
  * Sets the client ID and secret for basic auth.
8235
+ *
8236
+ * ```typescript
8237
+ * medplum.setBasicAuth(process.env.MEDPLUM_CLIENT_ID, process.env.MEDPLUM_CLIENT_SECRET)
8238
+ * // Example Search
8239
+ * await medplum.searchResources('Patient')
8240
+ * ```
8241
+ *
8224
8242
  * @category Authentication
8225
8243
  * @param clientId The client ID.
8226
8244
  * @param clientSecret The client secret.
@@ -12276,6 +12294,8 @@
12276
12294
  Operator["MISSING"] = "missing";
12277
12295
  // Reference
12278
12296
  Operator["IDENTIFIER"] = "identifier";
12297
+ // _include and _revinclude
12298
+ Operator["ITERATE"] = "iterate";
12279
12299
  })(exports.Operator || (exports.Operator = {}));
12280
12300
  /**
12281
12301
  * Parameter names may specify a modifier as a suffix.
@@ -12294,6 +12314,7 @@
12294
12314
  'of-type': exports.Operator.OF_TYPE,
12295
12315
  missing: exports.Operator.MISSING,
12296
12316
  identifier: exports.Operator.IDENTIFIER,
12317
+ iterate: exports.Operator.ITERATE,
12297
12318
  };
12298
12319
  /**
12299
12320
  * For the ordered parameter types of number, date, and quantity,
@@ -12387,12 +12408,32 @@
12387
12408
  searchRequest.total = 'estimate';
12388
12409
  searchRequest.count = 0;
12389
12410
  break;
12390
- case '_include':
12391
- searchRequest.include = value;
12411
+ case '_include': {
12412
+ const target = parseIncludeTarget(value);
12413
+ if (modifier === 'iterate') {
12414
+ target.modifier = exports.Operator.ITERATE;
12415
+ }
12416
+ if (searchRequest.include) {
12417
+ searchRequest.include.push(target);
12418
+ }
12419
+ else {
12420
+ searchRequest.include = [target];
12421
+ }
12392
12422
  break;
12393
- case '_revinclude':
12394
- searchRequest.revInclude = value;
12423
+ }
12424
+ case '_revinclude': {
12425
+ const target = parseIncludeTarget(value);
12426
+ if (modifier === 'iterate') {
12427
+ target.modifier = exports.Operator.ITERATE;
12428
+ }
12429
+ if (searchRequest.revInclude) {
12430
+ searchRequest.revInclude.push(target);
12431
+ }
12432
+ else {
12433
+ searchRequest.revInclude = [target];
12434
+ }
12395
12435
  break;
12436
+ }
12396
12437
  case '_fields':
12397
12438
  searchRequest.fields = value.split(',');
12398
12439
  break;
@@ -12506,6 +12547,34 @@
12506
12547
  function parseModifier(modifier) {
12507
12548
  return MODIFIER_OPERATORS[modifier] || exports.Operator.EQUALS;
12508
12549
  }
12550
+ function parseIncludeTarget(input) {
12551
+ const parts = input.split(':');
12552
+ parts.forEach((p) => {
12553
+ if (p === '*') {
12554
+ throw new OperationOutcomeError(badRequest(`'*' is not supported as a value for search inclusion parameters`));
12555
+ }
12556
+ });
12557
+ if (parts.length === 1) {
12558
+ // Full wildcard, not currently supported
12559
+ throw new OperationOutcomeError(badRequest(`Invalid include value '${input}': must be of the form ResourceType:search-parameter`));
12560
+ }
12561
+ else if (parts.length === 2) {
12562
+ return {
12563
+ resourceType: parts[0],
12564
+ searchParam: parts[1],
12565
+ };
12566
+ }
12567
+ else if (parts.length === 3) {
12568
+ return {
12569
+ resourceType: parts[0],
12570
+ searchParam: parts[1],
12571
+ targetType: parts[2],
12572
+ };
12573
+ }
12574
+ else {
12575
+ throw new OperationOutcomeError(badRequest(`Invalid include value '${input}'`));
12576
+ }
12577
+ }
12509
12578
  function addFilter(searchRequest, filter) {
12510
12579
  if (searchRequest.filters) {
12511
12580
  searchRequest.filters.push(filter);