@medplum/core 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.
@@ -1368,7 +1368,7 @@
1368
1368
  }
1369
1369
  class OperationOutcomeError extends Error {
1370
1370
  constructor(outcome, cause) {
1371
- super(outcome?.issue?.[0].details?.text);
1371
+ super(operationOutcomeToString(outcome));
1372
1372
  this.outcome = outcome;
1373
1373
  this.cause = cause;
1374
1374
  }
@@ -1403,10 +1403,28 @@
1403
1403
  return error.message;
1404
1404
  }
1405
1405
  if (isOperationOutcome(error)) {
1406
- return error.issue?.[0]?.details?.text ?? 'Unknown error';
1406
+ return operationOutcomeToString(error);
1407
1407
  }
1408
1408
  return JSON.stringify(error);
1409
1409
  }
1410
+ /**
1411
+ * Returns a string represenation of the operation outcome.
1412
+ * @param outcome The operation outcome.
1413
+ * @returns The string representation of the operation outcome.
1414
+ */
1415
+ function operationOutcomeToString(outcome) {
1416
+ const strs = [];
1417
+ if (outcome.issue) {
1418
+ for (const issue of outcome.issue) {
1419
+ let issueStr = issue.details?.text || 'Unknown error';
1420
+ if (issue.expression?.length) {
1421
+ issueStr += ` (${issue.expression.join(', ')})`;
1422
+ }
1423
+ strs.push(issueStr);
1424
+ }
1425
+ }
1426
+ return strs.length > 0 ? strs.join('; ') : 'Unknown error';
1427
+ }
1410
1428
 
1411
1429
  var _ReadablePromise_suspender, _ReadablePromise_status, _ReadablePromise_response, _ReadablePromise_error, _a;
1412
1430
  /**
@@ -6352,7 +6370,7 @@
6352
6370
  // PKCE auth based on:
6353
6371
  // https://aws.amazon.com/blogs/security/how-to-add-authentication-single-page-web-application-with-amazon-cognito-oauth2-implementation/
6354
6372
  var _MedplumClient_instances, _MedplumClient_fetch, _MedplumClient_createPdf, _MedplumClient_storage, _MedplumClient_requestCache, _MedplumClient_cacheTime, _MedplumClient_baseUrl, _MedplumClient_fhirBaseUrl, _MedplumClient_authorizeUrl, _MedplumClient_tokenUrl, _MedplumClient_logoutUrl, _MedplumClient_onUnauthenticated, _MedplumClient_autoBatchTime, _MedplumClient_autoBatchQueue, _MedplumClient_clientId, _MedplumClient_clientSecret, _MedplumClient_autoBatchTimerId, _MedplumClient_accessToken, _MedplumClient_refreshToken, _MedplumClient_refreshPromise, _MedplumClient_profilePromise, _MedplumClient_profile, _MedplumClient_config, _MedplumClient_addLogin, _MedplumClient_refreshProfile, _MedplumClient_getCacheEntry, _MedplumClient_setCacheEntry, _MedplumClient_cacheResource, _MedplumClient_deleteCacheEntry, _MedplumClient_request, _MedplumClient_fetchWithRetry, _MedplumClient_executeAutoBatch, _MedplumClient_addFetchOptionsDefaults, _MedplumClient_setRequestContentType, _MedplumClient_setRequestBody, _MedplumClient_handleUnauthenticated, _MedplumClient_requestAuthorization, _MedplumClient_refresh, _MedplumClient_fetchTokens, _MedplumClient_verifyTokens, _MedplumClient_setupStorageListener;
6355
- const MEDPLUM_VERSION = "2.0.7-c59953c5";
6373
+ const MEDPLUM_VERSION = "2.0.10-20b3fb40";
6356
6374
  const DEFAULT_BASE_URL = 'https://api.medplum.com/';
6357
6375
  const DEFAULT_RESOURCE_CACHE_SIZE = 1000;
6358
6376
  const DEFAULT_CACHE_TIME = 60000; // 60 seconds
@@ -6444,8 +6462,8 @@
6444
6462
  }
6445
6463
  }
6446
6464
  __classPrivateFieldSet(this, _MedplumClient_fetch, options?.fetch || getDefaultFetch(), "f");
6465
+ __classPrivateFieldSet(this, _MedplumClient_storage, options?.storage || new ClientStorage(), "f");
6447
6466
  __classPrivateFieldSet(this, _MedplumClient_createPdf, options?.createPdf, "f");
6448
- __classPrivateFieldSet(this, _MedplumClient_storage, new ClientStorage(), "f");
6449
6467
  __classPrivateFieldSet(this, _MedplumClient_requestCache, new LRUCache(options?.resourceCacheSize ?? DEFAULT_RESOURCE_CACHE_SIZE), "f");
6450
6468
  __classPrivateFieldSet(this, _MedplumClient_cacheTime, options?.cacheTime ?? DEFAULT_CACHE_TIME, "f");
6451
6469
  __classPrivateFieldSet(this, _MedplumClient_baseUrl, ensureTrailingSlash(options?.baseUrl) || DEFAULT_BASE_URL, "f");
@@ -7680,12 +7698,14 @@
7680
7698
  await __classPrivateFieldGet(this, _MedplumClient_instances, "m", _MedplumClient_refreshProfile).call(this);
7681
7699
  }
7682
7700
  /**
7701
+ * Returns the current access token.
7683
7702
  * @category Authentication
7684
7703
  */
7685
7704
  getAccessToken() {
7686
7705
  return __classPrivateFieldGet(this, _MedplumClient_accessToken, "f");
7687
7706
  }
7688
7707
  /**
7708
+ * Sets the current access token.
7689
7709
  * @category Authentication
7690
7710
  */
7691
7711
  setAccessToken(accessToken) {
@@ -7761,14 +7781,15 @@
7761
7781
  * Processes an OAuth authorization code.
7762
7782
  * See: https://openid.net/specs/openid-connect-core-1_0.html#TokenRequest
7763
7783
  * @param code The authorization code received by URL parameter.
7784
+ * @param loginParams Optional login parameters.
7764
7785
  * @category Authentication
7765
7786
  */
7766
- processCode(code) {
7787
+ processCode(code, loginParams) {
7767
7788
  const formBody = new URLSearchParams();
7768
7789
  formBody.set('grant_type', 'authorization_code');
7769
- formBody.set('client_id', __classPrivateFieldGet(this, _MedplumClient_clientId, "f"));
7770
7790
  formBody.set('code', code);
7771
- formBody.set('redirect_uri', getWindowOrigin());
7791
+ formBody.set('client_id', loginParams?.clientId || __classPrivateFieldGet(this, _MedplumClient_clientId, "f"));
7792
+ formBody.set('redirect_uri', loginParams?.redirectUri || getWindowOrigin());
7772
7793
  if (typeof sessionStorage !== 'undefined') {
7773
7794
  const codeVerifier = sessionStorage.getItem('codeVerifier');
7774
7795
  if (codeVerifier) {
@@ -10698,7 +10719,7 @@
10698
10719
  },
10699
10720
  precedence: 0 /* OperatorPrecedence.FunctionCall */,
10700
10721
  };
10701
- function parseQuantity(str) {
10722
+ function parseQuantity$1(str) {
10702
10723
  const parts = str.split(' ');
10703
10724
  const value = parseFloat(parts[0]);
10704
10725
  let unit = parts[1];
@@ -10719,7 +10740,7 @@
10719
10740
  parse: (_, token) => new LiteralAtom({ type: exports.PropertyType.dateTime, value: parseDateString(token.value) }),
10720
10741
  })
10721
10742
  .registerPrefix('Quantity', {
10722
- parse: (_, token) => new LiteralAtom({ type: exports.PropertyType.Quantity, value: parseQuantity(token.value) }),
10743
+ parse: (_, token) => new LiteralAtom({ type: exports.PropertyType.Quantity, value: parseQuantity$1(token.value) }),
10723
10744
  })
10724
10745
  .registerPrefix('Number', {
10725
10746
  parse: (_, token) => new LiteralAtom({ type: exports.PropertyType.decimal, value: parseFloat(token.value) }),
@@ -11976,134 +11997,236 @@
11976
11997
  Operator["OF_TYPE"] = "of-type";
11977
11998
  // All
11978
11999
  Operator["MISSING"] = "missing";
12000
+ // Reference
12001
+ Operator["IDENTIFIER"] = "identifier";
11979
12002
  })(exports.Operator || (exports.Operator = {}));
11980
- const MODIFIER_OPERATORS = [
11981
- exports.Operator.CONTAINS,
11982
- exports.Operator.EXACT,
11983
- exports.Operator.TEXT,
11984
- exports.Operator.NOT,
11985
- exports.Operator.ABOVE,
11986
- exports.Operator.BELOW,
11987
- exports.Operator.IN,
11988
- exports.Operator.NOT_IN,
11989
- exports.Operator.OF_TYPE,
11990
- exports.Operator.MISSING,
11991
- ];
11992
- const PREFIX_OPERATORS = [
11993
- exports.Operator.NOT_EQUALS,
11994
- exports.Operator.GREATER_THAN,
11995
- exports.Operator.LESS_THAN,
11996
- exports.Operator.GREATER_THAN_OR_EQUALS,
11997
- exports.Operator.LESS_THAN_OR_EQUALS,
11998
- exports.Operator.STARTS_AFTER,
11999
- exports.Operator.ENDS_BEFORE,
12000
- exports.Operator.APPROXIMATELY,
12001
- ];
12002
12003
  /**
12003
- * Parses a URL into a SearchRequest.
12004
- *
12005
- * See the FHIR search spec: http://hl7.org/fhir/r4/search.html
12006
- *
12004
+ * Parameter names may specify a modifier as a suffix.
12005
+ * The modifiers are separated from the parameter name by a colon.
12006
+ * See: https://www.hl7.org/fhir/search.html#modifiers
12007
+ */
12008
+ const MODIFIER_OPERATORS = {
12009
+ contains: exports.Operator.CONTAINS,
12010
+ exact: exports.Operator.EXACT,
12011
+ above: exports.Operator.ABOVE,
12012
+ below: exports.Operator.BELOW,
12013
+ text: exports.Operator.TEXT,
12014
+ not: exports.Operator.NOT,
12015
+ in: exports.Operator.IN,
12016
+ 'not-in': exports.Operator.NOT_IN,
12017
+ 'of-type': exports.Operator.OF_TYPE,
12018
+ missing: exports.Operator.MISSING,
12019
+ identifier: exports.Operator.IDENTIFIER,
12020
+ };
12021
+ /**
12022
+ * For the ordered parameter types of number, date, and quantity,
12023
+ * a prefix to the parameter value may be used to control the nature
12024
+ * of the matching.
12025
+ * See: https://www.hl7.org/fhir/search.html#prefix
12026
+ */
12027
+ const PREFIX_OPERATORS = {
12028
+ eq: exports.Operator.EQUALS,
12029
+ ne: exports.Operator.NOT_EQUALS,
12030
+ lt: exports.Operator.LESS_THAN,
12031
+ le: exports.Operator.LESS_THAN_OR_EQUALS,
12032
+ gt: exports.Operator.GREATER_THAN,
12033
+ ge: exports.Operator.GREATER_THAN_OR_EQUALS,
12034
+ sa: exports.Operator.STARTS_AFTER,
12035
+ eb: exports.Operator.ENDS_BEFORE,
12036
+ ap: exports.Operator.APPROXIMATELY,
12037
+ };
12038
+ /**
12039
+ * Parses a search URL into a search request.
12040
+ * @param resourceType The FHIR resource type.
12041
+ * @param query The collection of query string parameters.
12042
+ * @returns A parsed SearchRequest.
12043
+ */
12044
+ function parseSearchRequest(resourceType, query) {
12045
+ return parseSearchImpl(resourceType, query);
12046
+ }
12047
+ /**
12048
+ * Parses a search URL into a search request.
12049
+ * @param url The search URL.
12050
+ * @returns A parsed SearchRequest.
12051
+ */
12052
+ function parseSearchUrl(url) {
12053
+ const resourceType = url.pathname.split('/').filter(Boolean).pop();
12054
+ return parseSearchImpl(resourceType, Object.fromEntries(url.searchParams.entries()));
12055
+ }
12056
+ /**
12057
+ * Parses a URL string into a SearchRequest.
12007
12058
  * @param url The URL to parse.
12008
12059
  * @returns Parsed search definition.
12009
12060
  */
12010
12061
  function parseSearchDefinition(url) {
12011
- const location = new URL(url, 'https://example.com/');
12012
- const resourceType = location.pathname
12013
- .replace(/(^\/)|(\/$)/g, '') // Remove leading and trailing slashes
12014
- .split('/')
12015
- .pop();
12016
- const params = new URLSearchParams(location.search);
12017
- let filters = undefined;
12018
- let sortRules = undefined;
12019
- let fields = undefined;
12020
- let offset = undefined;
12021
- let count = undefined;
12022
- let total = undefined;
12023
- params.forEach((value, key) => {
12024
- if (key === '_fields') {
12025
- fields = value.split(',');
12026
- }
12027
- else if (key === '_offset') {
12028
- offset = parseInt(value);
12029
- }
12030
- else if (key === '_count') {
12031
- count = parseInt(value);
12032
- }
12033
- else if (key === '_total') {
12034
- total = value;
12035
- }
12036
- else if (key === '_sort') {
12037
- sortRules = sortRules || [];
12038
- sortRules.push(parseSortRule(value));
12062
+ return parseSearchUrl(new URL(url, 'https://example.com/'));
12063
+ }
12064
+ function parseSearchImpl(resourceType, query) {
12065
+ const searchRequest = {
12066
+ resourceType,
12067
+ };
12068
+ for (const [key, value] of Object.entries(query)) {
12069
+ if (Array.isArray(value)) {
12070
+ value.forEach((element) => parseKeyValue(searchRequest, key, element));
12039
12071
  }
12040
12072
  else {
12041
- filters = filters || [];
12042
- filters.push(parseSearchFilter(key, value));
12073
+ parseKeyValue(searchRequest, key, value ?? '');
12043
12074
  }
12044
- });
12045
- return {
12046
- resourceType,
12047
- filters,
12048
- fields,
12049
- offset,
12050
- count,
12051
- total,
12052
- sortRules,
12053
- };
12075
+ }
12076
+ return searchRequest;
12054
12077
  }
12055
- /**
12056
- * Parses a URL query parameter into a sort rule.
12057
- *
12058
- * By default, the sort rule is the field name.
12059
- *
12060
- * Sort rules can be reversed into descending order by prefixing the field name with a minus sign.
12061
- *
12062
- * See sorting: http://hl7.org/fhir/r4/search.html#_sort
12063
- *
12064
- * @param value The URL parameter value.
12065
- * @returns The parsed sort rule.
12066
- */
12067
- function parseSortRule(value) {
12068
- if (value.startsWith('-')) {
12069
- return { code: value.substring(1), descending: true };
12078
+ function parseKeyValue(searchRequest, key, value) {
12079
+ let code;
12080
+ let modifier;
12081
+ const colonIndex = key.indexOf(':');
12082
+ if (colonIndex >= 0) {
12083
+ code = key.substring(0, colonIndex);
12084
+ modifier = key.substring(colonIndex + 1);
12070
12085
  }
12071
12086
  else {
12072
- return { code: value };
12087
+ code = key;
12088
+ modifier = '';
12089
+ }
12090
+ switch (code) {
12091
+ case '_sort':
12092
+ parseSortRule(searchRequest, value);
12093
+ break;
12094
+ case '_count':
12095
+ searchRequest.count = parseInt(value);
12096
+ break;
12097
+ case '_offset':
12098
+ searchRequest.offset = parseInt(value);
12099
+ break;
12100
+ case '_total':
12101
+ searchRequest.total = value;
12102
+ break;
12103
+ case '_summary':
12104
+ searchRequest.total = 'estimate';
12105
+ searchRequest.count = 0;
12106
+ break;
12107
+ case '_revinclude':
12108
+ searchRequest.revInclude = value;
12109
+ break;
12110
+ case '_fields':
12111
+ searchRequest.fields = value.split(',');
12112
+ break;
12113
+ default: {
12114
+ const param = globalSchema.types[searchRequest.resourceType]?.searchParams?.[code];
12115
+ if (param) {
12116
+ parseParameter(searchRequest, param, modifier, value);
12117
+ }
12118
+ else {
12119
+ parseUnknownParameter(searchRequest, code, modifier, value);
12120
+ }
12121
+ }
12073
12122
  }
12074
12123
  }
12075
- /**
12076
- * Parses a URL query parameter into a search filter.
12077
- *
12078
- * FHIR search filters can be specified as modifiers or prefixes.
12079
- *
12080
- * For string properties, modifiers are appended to the key, e.g. "name:contains=eve".
12081
- *
12082
- * For date and numeric properties, prefixes are prepended to the value, e.g. "birthdate=gt2000".
12083
- *
12084
- * See the FHIR search spec: http://hl7.org/fhir/r4/search.html
12085
- *
12086
- * @param key The URL parameter key.
12087
- * @param value The URL parameter value.
12088
- * @returns The parsed search filter.
12089
- */
12090
- function parseSearchFilter(key, value) {
12091
- let code = key;
12092
- let operator = exports.Operator.EQUALS;
12093
- for (const modifier of MODIFIER_OPERATORS) {
12094
- const modifierIndex = code.indexOf(':' + modifier);
12095
- if (modifierIndex !== -1) {
12096
- operator = modifier;
12097
- code = code.substring(0, modifierIndex);
12124
+ function parseSortRule(searchRequest, value) {
12125
+ for (const field of value.split(',')) {
12126
+ let code;
12127
+ let descending = false;
12128
+ if (field.startsWith('-')) {
12129
+ code = field.substring(1);
12130
+ descending = true;
12131
+ }
12132
+ else {
12133
+ code = field;
12134
+ }
12135
+ if (!searchRequest.sortRules) {
12136
+ searchRequest.sortRules = [];
12098
12137
  }
12138
+ searchRequest.sortRules.push({ code, descending });
12099
12139
  }
12100
- for (const prefix of PREFIX_OPERATORS) {
12101
- if (value.match(new RegExp('^' + prefix + '\\d'))) {
12102
- operator = prefix;
12103
- value = value.substring(prefix.length);
12140
+ }
12141
+ function parseParameter(searchRequest, searchParam, modifier, value) {
12142
+ if (modifier === 'missing') {
12143
+ addFilter(searchRequest, {
12144
+ code: searchParam.code,
12145
+ operator: exports.Operator.MISSING,
12146
+ value,
12147
+ });
12148
+ return;
12149
+ }
12150
+ switch (searchParam.type) {
12151
+ case 'number':
12152
+ case 'date':
12153
+ parsePrefixType(searchRequest, searchParam, value);
12154
+ break;
12155
+ case 'reference':
12156
+ case 'string':
12157
+ case 'token':
12158
+ case 'uri':
12159
+ parseModifierType(searchRequest, searchParam, modifier, value);
12160
+ break;
12161
+ case 'quantity':
12162
+ parseQuantity(searchRequest, searchParam, value);
12163
+ break;
12164
+ }
12165
+ }
12166
+ function parsePrefixType(searchRequest, param, input) {
12167
+ const { operator, value } = parsePrefix(input);
12168
+ addFilter(searchRequest, {
12169
+ code: param.code,
12170
+ operator,
12171
+ value,
12172
+ });
12173
+ }
12174
+ function parseModifierType(searchRequest, param, modifier, value) {
12175
+ addFilter(searchRequest, {
12176
+ code: param.code,
12177
+ operator: parseModifier(modifier),
12178
+ value,
12179
+ });
12180
+ }
12181
+ function parseQuantity(searchRequest, param, input) {
12182
+ const [prefixNumber, unitSystem, unitCode] = input.split('|');
12183
+ const { operator, value } = parsePrefix(prefixNumber);
12184
+ addFilter(searchRequest, {
12185
+ code: param.code,
12186
+ operator,
12187
+ value,
12188
+ unitSystem,
12189
+ unitCode,
12190
+ });
12191
+ }
12192
+ function parseUnknownParameter(searchRequest, code, modifier, value) {
12193
+ let operator = exports.Operator.EQUALS;
12194
+ if (modifier) {
12195
+ operator = modifier;
12196
+ }
12197
+ else if (value.length >= 2) {
12198
+ const prefix = value.substring(0, 2);
12199
+ if (prefix in PREFIX_OPERATORS) {
12200
+ if (value.length === 2 || value.at(2)?.match(/\d/)) {
12201
+ operator = prefix;
12202
+ value = value.substring(prefix.length);
12203
+ }
12104
12204
  }
12105
12205
  }
12106
- return { code, operator, value };
12206
+ addFilter(searchRequest, {
12207
+ code,
12208
+ operator,
12209
+ value,
12210
+ });
12211
+ }
12212
+ function parsePrefix(input) {
12213
+ const prefix = input.substring(0, 2);
12214
+ const prefixOperator = PREFIX_OPERATORS[prefix];
12215
+ if (prefixOperator) {
12216
+ return { operator: prefixOperator, value: input.substring(2) };
12217
+ }
12218
+ return { operator: exports.Operator.EQUALS, value: input };
12219
+ }
12220
+ function parseModifier(modifier) {
12221
+ return MODIFIER_OPERATORS[modifier] || exports.Operator.EQUALS;
12222
+ }
12223
+ function addFilter(searchRequest, filter) {
12224
+ if (searchRequest.filters) {
12225
+ searchRequest.filters.push(filter);
12226
+ }
12227
+ else {
12228
+ searchRequest.filters = [filter];
12229
+ }
12107
12230
  }
12108
12231
  /**
12109
12232
  * Formats a search definition object into a query string.
@@ -12138,8 +12261,8 @@
12138
12261
  return '?' + params.join('&');
12139
12262
  }
12140
12263
  function formatFilter(filter) {
12141
- const modifier = MODIFIER_OPERATORS.includes(filter.operator) ? ':' + filter.operator : '';
12142
- const prefix = PREFIX_OPERATORS.includes(filter.operator) ? filter.operator : '';
12264
+ const modifier = filter.operator in MODIFIER_OPERATORS ? ':' + filter.operator : '';
12265
+ const prefix = filter.operator != exports.Operator.EQUALS && filter.operator in PREFIX_OPERATORS ? filter.operator : '';
12143
12266
  return `${filter.code}${modifier}=${prefix}${encodeURIComponent(filter.value)}`;
12144
12267
  }
12145
12268
  function formatSortRules(sortRules) {
@@ -12300,221 +12423,10 @@
12300
12423
  return operator === exports.Operator.NOT_EQUALS || operator === exports.Operator.NOT;
12301
12424
  }
12302
12425
 
12303
- var _SearchParser_instances, _SearchParser_parseKeyValue, _SearchParser_parseSortRule, _SearchParser_parseParameter, _SearchParser_parsePrefixType, _SearchParser_parseModifierType, _SearchParser_parseReference, _SearchParser_parseQuantity, _SearchParser_parseUnknownParameter;
12304
- /**
12305
- * Parses a FHIR search query.
12306
- * See: https://www.hl7.org/fhir/search.html
12307
- */
12308
- /**
12309
- * For the ordered parameter types of number, date, and quantity,
12310
- * a prefix to the parameter value may be used to control the nature
12311
- * of the matching.
12312
- * See: https://www.hl7.org/fhir/search.html#prefix
12313
- */
12314
- const prefixMap = {
12315
- eq: exports.Operator.EQUALS,
12316
- ne: exports.Operator.NOT_EQUALS,
12317
- lt: exports.Operator.LESS_THAN,
12318
- le: exports.Operator.LESS_THAN_OR_EQUALS,
12319
- gt: exports.Operator.GREATER_THAN,
12320
- ge: exports.Operator.GREATER_THAN_OR_EQUALS,
12321
- sa: exports.Operator.STARTS_AFTER,
12322
- eb: exports.Operator.ENDS_BEFORE,
12323
- ap: exports.Operator.APPROXIMATELY,
12324
- };
12325
- /**
12326
- * Parameter names may specify a modifier as a suffix.
12327
- * The modifiers are separated from the parameter name by a colon.
12328
- * See: https://www.hl7.org/fhir/search.html#modifiers
12329
- */
12330
- const modifierMap = {
12331
- contains: exports.Operator.CONTAINS,
12332
- exact: exports.Operator.EXACT,
12333
- above: exports.Operator.ABOVE,
12334
- below: exports.Operator.BELOW,
12335
- text: exports.Operator.TEXT,
12336
- not: exports.Operator.NOT,
12337
- in: exports.Operator.IN,
12338
- 'not-in': exports.Operator.NOT_IN,
12339
- 'of-type': exports.Operator.OF_TYPE,
12340
- };
12341
- /**
12342
- * Parses a search URL into a search request.
12343
- * @param resourceType The FHIR resource type.
12344
- * @param query The collection of query string parameters.
12345
- * @returns A parsed SearchRequest.
12346
- */
12347
- function parseSearchRequest(resourceType, query) {
12348
- return new SearchParser(resourceType, query);
12349
- }
12350
- /**
12351
- * Parses a search URL into a search request.
12352
- * @param url The search URL.
12353
- * @returns A parsed SearchRequest.
12354
- */
12355
- function parseSearchUrl(url) {
12356
- const resourceType = url.pathname.split('/').pop();
12357
- return new SearchParser(resourceType, Object.fromEntries(url.searchParams.entries()));
12358
- }
12359
- class SearchParser {
12360
- constructor(resourceType, query) {
12361
- _SearchParser_instances.add(this);
12362
- this.resourceType = resourceType;
12363
- this.filters = [];
12364
- this.sortRules = [];
12365
- for (const [key, value] of Object.entries(query)) {
12366
- if (Array.isArray(value)) {
12367
- value.forEach((element) => __classPrivateFieldGet(this, _SearchParser_instances, "m", _SearchParser_parseKeyValue).call(this, key, element));
12368
- }
12369
- else {
12370
- __classPrivateFieldGet(this, _SearchParser_instances, "m", _SearchParser_parseKeyValue).call(this, key, value ?? '');
12371
- }
12372
- }
12373
- }
12374
- }
12375
- _SearchParser_instances = new WeakSet(), _SearchParser_parseKeyValue = function _SearchParser_parseKeyValue(key, value) {
12376
- let code;
12377
- let modifier;
12378
- const colonIndex = key.indexOf(':');
12379
- if (colonIndex >= 0) {
12380
- code = key.substring(0, colonIndex);
12381
- modifier = key.substring(colonIndex + 1);
12382
- }
12383
- else {
12384
- code = key;
12385
- modifier = '';
12386
- }
12387
- switch (code) {
12388
- case '_sort':
12389
- __classPrivateFieldGet(this, _SearchParser_instances, "m", _SearchParser_parseSortRule).call(this, value);
12390
- break;
12391
- case '_count':
12392
- this.count = parseInt(value);
12393
- break;
12394
- case '_offset':
12395
- this.offset = parseInt(value);
12396
- break;
12397
- case '_total':
12398
- this.total = value;
12399
- break;
12400
- case '_summary':
12401
- this.total = 'estimate';
12402
- this.count = 0;
12403
- break;
12404
- case '_revinclude':
12405
- this.revInclude = value;
12406
- break;
12407
- default: {
12408
- const param = globalSchema.types[this.resourceType]?.searchParams?.[code];
12409
- if (param) {
12410
- __classPrivateFieldGet(this, _SearchParser_instances, "m", _SearchParser_parseParameter).call(this, param, modifier, value);
12411
- }
12412
- else {
12413
- __classPrivateFieldGet(this, _SearchParser_instances, "m", _SearchParser_parseUnknownParameter).call(this, code, modifier, value);
12414
- }
12415
- }
12416
- }
12417
- }, _SearchParser_parseSortRule = function _SearchParser_parseSortRule(value) {
12418
- for (const field of value.split(',')) {
12419
- let code;
12420
- let descending = false;
12421
- if (field.startsWith('-')) {
12422
- code = field.substring(1);
12423
- descending = true;
12424
- }
12425
- else {
12426
- code = field;
12427
- }
12428
- this.sortRules.push({ code, descending });
12429
- }
12430
- }, _SearchParser_parseParameter = function _SearchParser_parseParameter(searchParam, modifier, value) {
12431
- if (modifier === 'missing') {
12432
- this.filters.push({
12433
- code: searchParam.code,
12434
- operator: exports.Operator.MISSING,
12435
- value,
12436
- });
12437
- return;
12438
- }
12439
- switch (searchParam.type) {
12440
- case 'number':
12441
- case 'date':
12442
- __classPrivateFieldGet(this, _SearchParser_instances, "m", _SearchParser_parsePrefixType).call(this, searchParam, value);
12443
- break;
12444
- case 'string':
12445
- case 'token':
12446
- case 'uri':
12447
- __classPrivateFieldGet(this, _SearchParser_instances, "m", _SearchParser_parseModifierType).call(this, searchParam, modifier, value);
12448
- break;
12449
- case 'reference':
12450
- __classPrivateFieldGet(this, _SearchParser_instances, "m", _SearchParser_parseReference).call(this, searchParam, value);
12451
- break;
12452
- case 'quantity':
12453
- __classPrivateFieldGet(this, _SearchParser_instances, "m", _SearchParser_parseQuantity).call(this, searchParam, value);
12454
- break;
12455
- }
12456
- }, _SearchParser_parsePrefixType = function _SearchParser_parsePrefixType(param, input) {
12457
- const { operator, value } = parsePrefix(input);
12458
- this.filters.push({
12459
- code: param.code,
12460
- operator,
12461
- value,
12462
- });
12463
- }, _SearchParser_parseModifierType = function _SearchParser_parseModifierType(param, modifier, value) {
12464
- this.filters.push({
12465
- code: param.code,
12466
- operator: parseModifier(modifier),
12467
- value,
12468
- });
12469
- }, _SearchParser_parseReference = function _SearchParser_parseReference(param, value) {
12470
- this.filters.push({
12471
- code: param.code,
12472
- operator: exports.Operator.EQUALS,
12473
- value: value,
12474
- });
12475
- }, _SearchParser_parseQuantity = function _SearchParser_parseQuantity(param, input) {
12476
- const [prefixNumber, unitSystem, unitCode] = input.split('|');
12477
- const { operator, value } = parsePrefix(prefixNumber);
12478
- this.filters.push({
12479
- code: param.code,
12480
- operator,
12481
- value,
12482
- unitSystem,
12483
- unitCode,
12484
- });
12485
- }, _SearchParser_parseUnknownParameter = function _SearchParser_parseUnknownParameter(code, modifier, value) {
12486
- let operator = exports.Operator.EQUALS;
12487
- if (modifier) {
12488
- operator = modifier;
12489
- }
12490
- else {
12491
- for (const prefix of Object.keys(prefixMap)) {
12492
- if (value.match(new RegExp('^' + prefix + '\\d'))) {
12493
- operator = prefix;
12494
- value = value.substring(prefix.length);
12495
- }
12496
- }
12497
- }
12498
- this.filters.push({
12499
- code,
12500
- operator,
12501
- value,
12502
- });
12503
- };
12504
- function parsePrefix(input) {
12505
- const prefix = input.substring(0, 2);
12506
- if (prefix in prefixMap) {
12507
- return { operator: prefixMap[prefix], value: input.substring(2) };
12508
- }
12509
- return { operator: exports.Operator.EQUALS, value: input };
12510
- }
12511
- function parseModifier(modifier) {
12512
- return modifierMap[modifier] || exports.Operator.EQUALS;
12513
- }
12514
-
12515
12426
  exports.AndAtom = AndAtom;
12516
12427
  exports.ArithemticOperatorAtom = ArithemticOperatorAtom;
12517
12428
  exports.AsAtom = AsAtom;
12429
+ exports.ClientStorage = ClientStorage;
12518
12430
  exports.ConcatAtom = ConcatAtom;
12519
12431
  exports.ContainsAtom = ContainsAtom;
12520
12432
  exports.DEFAULT_SEARCH_COUNT = DEFAULT_SEARCH_COUNT;
@@ -12542,6 +12454,7 @@
12542
12454
  exports.LiteralAtom = LiteralAtom;
12543
12455
  exports.MEDPLUM_VERSION = MEDPLUM_VERSION;
12544
12456
  exports.MedplumClient = MedplumClient;
12457
+ exports.MemoryStorage = MemoryStorage;
12545
12458
  exports.NotEqualsAtom = NotEqualsAtom;
12546
12459
  exports.NotEquivalentAtom = NotEquivalentAtom;
12547
12460
  exports.OperationOutcomeError = OperationOutcomeError;
@@ -12648,6 +12561,7 @@
12648
12561
  exports.normalizeOperationOutcome = normalizeOperationOutcome;
12649
12562
  exports.notFound = notFound;
12650
12563
  exports.notModified = notModified;
12564
+ exports.operationOutcomeToString = operationOutcomeToString;
12651
12565
  exports.parseFhirPath = parseFhirPath;
12652
12566
  exports.parseFilterParameter = parseFilterParameter;
12653
12567
  exports.parseJWTPayload = parseJWTPayload;