@medplum/core 2.0.23 → 2.0.24

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.
Files changed (55) hide show
  1. package/dist/cjs/index.cjs +14080 -13352
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/cjs/index.min.cjs +1 -1
  4. package/dist/esm/access.mjs +142 -0
  5. package/dist/esm/access.mjs.map +1 -0
  6. package/dist/esm/bundle.mjs +3 -3
  7. package/dist/esm/bundle.mjs.map +1 -1
  8. package/dist/esm/client.mjs +49 -25
  9. package/dist/esm/client.mjs.map +1 -1
  10. package/dist/esm/fhirlexer/parse.mjs.map +1 -1
  11. package/dist/esm/fhirmapper/parse.mjs +1 -1
  12. package/dist/esm/fhirmapper/parse.mjs.map +1 -1
  13. package/dist/esm/fhirpath/functions.mjs +2 -2
  14. package/dist/esm/fhirpath/functions.mjs.map +1 -1
  15. package/dist/esm/fhirpath/parse.mjs +2 -1
  16. package/dist/esm/fhirpath/parse.mjs.map +1 -1
  17. package/dist/esm/fhirpath/utils.mjs +4 -5
  18. package/dist/esm/fhirpath/utils.mjs.map +1 -1
  19. package/dist/esm/format.mjs +1 -1
  20. package/dist/esm/format.mjs.map +1 -1
  21. package/dist/esm/hl7.mjs +6 -6
  22. package/dist/esm/hl7.mjs.map +1 -1
  23. package/dist/esm/index.min.mjs +1 -1
  24. package/dist/esm/index.mjs +5 -2
  25. package/dist/esm/index.mjs.map +1 -1
  26. package/dist/esm/outcomes.mjs +38 -14
  27. package/dist/esm/outcomes.mjs.map +1 -1
  28. package/dist/esm/readablepromise.mjs +1 -1
  29. package/dist/esm/readablepromise.mjs.map +1 -1
  30. package/dist/esm/schema.mjs +1 -1
  31. package/dist/esm/schema.mjs.map +1 -1
  32. package/dist/esm/search/details.mjs +14 -16
  33. package/dist/esm/search/details.mjs.map +1 -1
  34. package/dist/esm/search/match.mjs +7 -5
  35. package/dist/esm/search/match.mjs.map +1 -1
  36. package/dist/esm/search/search.mjs +14 -5
  37. package/dist/esm/search/search.mjs.map +1 -1
  38. package/dist/esm/types.mjs +1 -1
  39. package/dist/esm/types.mjs.map +1 -1
  40. package/dist/esm/typeschema/types.mjs +278 -0
  41. package/dist/esm/typeschema/types.mjs.map +1 -0
  42. package/dist/esm/typeschema/validation.mjs +262 -0
  43. package/dist/esm/typeschema/validation.mjs.map +1 -0
  44. package/dist/esm/utils.mjs +3 -3
  45. package/dist/esm/utils.mjs.map +1 -1
  46. package/dist/types/access.d.ts +48 -0
  47. package/dist/types/client.d.ts +15 -20
  48. package/dist/types/fhirlexer/parse.d.ts +5 -4
  49. package/dist/types/fhirpath/functions.d.ts +1 -3
  50. package/dist/types/index.d.ts +3 -0
  51. package/dist/types/outcomes.d.ts +3 -1
  52. package/dist/types/search/search.d.ts +7 -0
  53. package/dist/types/typeschema/types.d.ts +5 -2
  54. package/dist/types/typeschema/validation.d.ts +2 -0
  55. package/package.json +1 -1
@@ -84,8 +84,8 @@ function parseSearchRequest(resourceType, query) {
84
84
  const queryArray = [];
85
85
  for (const [key, value] of Object.entries(query)) {
86
86
  if (Array.isArray(value)) {
87
- for (let i = 0; i < value.length; i++) {
88
- queryArray.push([key, value[i]]);
87
+ for (const v of value) {
88
+ queryArray.push([key, v]);
89
89
  }
90
90
  }
91
91
  else {
@@ -111,6 +111,15 @@ function parseSearchUrl(url) {
111
111
  function parseSearchDefinition(url) {
112
112
  return parseSearchUrl(new URL(url, 'https://example.com/'));
113
113
  }
114
+ /**
115
+ * Parses a FHIR criteria string into a SearchRequest.
116
+ * FHIR criteria strings are found on resources such as Subscription.
117
+ * @param criteria The FHIR criteria string.
118
+ * @returns Parsed search definition.
119
+ */
120
+ function parseCriteriaAsSearchRequest(criteria) {
121
+ return parseSearchUrl(new URL(criteria, 'https://api.medplum.com/'));
122
+ }
114
123
  function parseSearchImpl(resourceType, query) {
115
124
  const searchRequest = {
116
125
  resourceType,
@@ -137,10 +146,10 @@ function parseKeyValue(searchRequest, key, value) {
137
146
  parseSortRule(searchRequest, value);
138
147
  break;
139
148
  case '_count':
140
- searchRequest.count = parseInt(value);
149
+ searchRequest.count = parseInt(value, 10);
141
150
  break;
142
151
  case '_offset':
143
- searchRequest.offset = parseInt(value);
152
+ searchRequest.offset = parseInt(value, 10);
144
153
  break;
145
154
  case '_total':
146
155
  searchRequest.total = value;
@@ -365,5 +374,5 @@ function formatSortRules(sortRules) {
365
374
  return '_sort=' + sortRules.map((sr) => (sr.descending ? '-' + sr.code : sr.code)).join(',');
366
375
  }
367
376
 
368
- export { DEFAULT_SEARCH_COUNT, Operator, formatSearchQuery, parseSearchDefinition, parseSearchRequest, parseSearchUrl };
377
+ export { DEFAULT_SEARCH_COUNT, Operator, formatSearchQuery, parseCriteriaAsSearchRequest, parseSearchDefinition, parseSearchRequest, parseSearchUrl };
369
378
  //# sourceMappingURL=search.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"search.mjs","sources":["../../../src/search/search.ts"],"sourcesContent":["import { Resource, ResourceType, SearchParameter } from '@medplum/fhirtypes';\nimport { globalSchema } from '../types';\nimport { OperationOutcomeError, badRequest } from '../outcomes';\n\nexport const DEFAULT_SEARCH_COUNT = 20;\n\nexport interface SearchRequest<T extends Resource = Resource> {\n readonly resourceType: T['resourceType'];\n filters?: Filter[];\n sortRules?: SortRule[];\n offset?: number;\n count?: number;\n fields?: string[];\n name?: string;\n total?: 'none' | 'estimate' | 'accurate';\n include?: IncludeTarget[];\n revInclude?: IncludeTarget[];\n}\n\nexport interface Filter {\n code: string;\n operator: Operator;\n value: string;\n unitSystem?: string;\n unitCode?: string;\n}\n\nexport interface SortRule {\n code: string;\n descending?: boolean;\n}\n\nexport interface IncludeTarget {\n resourceType: string;\n searchParam: string;\n targetType?: string;\n modifier?: string;\n}\n\n/**\n * Search operators.\n * These operators represent \"modifiers\" and \"prefixes\" in FHIR search.\n * See: https://www.hl7.org/fhir/search.html\n */\nexport enum Operator {\n EQUALS = 'eq',\n NOT_EQUALS = 'ne',\n\n // Numbers\n GREATER_THAN = 'gt',\n LESS_THAN = 'lt',\n GREATER_THAN_OR_EQUALS = 'ge',\n LESS_THAN_OR_EQUALS = 'le',\n\n // Dates\n STARTS_AFTER = 'sa',\n ENDS_BEFORE = 'eb',\n APPROXIMATELY = 'ap',\n\n // String\n CONTAINS = 'contains',\n EXACT = 'exact',\n\n // Token\n TEXT = 'text',\n NOT = 'not',\n ABOVE = 'above',\n BELOW = 'below',\n IN = 'in',\n NOT_IN = 'not-in',\n OF_TYPE = 'of-type',\n\n // All\n MISSING = 'missing',\n\n // Reference\n IDENTIFIER = 'identifier',\n\n // _include and _revinclude\n ITERATE = 'iterate',\n}\n\n/**\n * Parameter names may specify a modifier as a suffix.\n * The modifiers are separated from the parameter name by a colon.\n * See: https://www.hl7.org/fhir/search.html#modifiers\n */\nconst MODIFIER_OPERATORS: Record<string, Operator> = {\n contains: Operator.CONTAINS,\n exact: Operator.EXACT,\n above: Operator.ABOVE,\n below: Operator.BELOW,\n text: Operator.TEXT,\n not: Operator.NOT,\n in: Operator.IN,\n 'not-in': Operator.NOT_IN,\n 'of-type': Operator.OF_TYPE,\n missing: Operator.MISSING,\n identifier: Operator.IDENTIFIER,\n iterate: Operator.ITERATE,\n};\n\n/**\n * For the ordered parameter types of number, date, and quantity,\n * a prefix to the parameter value may be used to control the nature\n * of the matching.\n * See: https://www.hl7.org/fhir/search.html#prefix\n */\nconst PREFIX_OPERATORS: Record<string, Operator> = {\n eq: Operator.EQUALS,\n ne: Operator.NOT_EQUALS,\n lt: Operator.LESS_THAN,\n le: Operator.LESS_THAN_OR_EQUALS,\n gt: Operator.GREATER_THAN,\n ge: Operator.GREATER_THAN_OR_EQUALS,\n sa: Operator.STARTS_AFTER,\n eb: Operator.ENDS_BEFORE,\n ap: Operator.APPROXIMATELY,\n};\n\n/**\n * Parses a search URL into a search request.\n * @param resourceType The FHIR resource type.\n * @param query The collection of query string parameters.\n * @returns A parsed SearchRequest.\n */\nexport function parseSearchRequest<T extends Resource = Resource>(\n resourceType: T['resourceType'],\n query: Record<string, string[] | string | undefined>\n): SearchRequest<T> {\n const queryArray: [string, string][] = [];\n for (const [key, value] of Object.entries(query)) {\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n queryArray.push([key, value[i]]);\n }\n } else {\n queryArray.push([key, value || '']);\n }\n }\n return parseSearchImpl(resourceType, queryArray);\n}\n\n/**\n * Parses a search URL into a search request.\n * @param url The search URL.\n * @returns A parsed SearchRequest.\n */\nexport function parseSearchUrl<T extends Resource = Resource>(url: URL): SearchRequest<T> {\n const resourceType = url.pathname.split('/').filter(Boolean).pop() as ResourceType;\n return parseSearchImpl<T>(resourceType, url.searchParams.entries());\n}\n\n/**\n * Parses a URL string into a SearchRequest.\n * @param url The URL to parse.\n * @returns Parsed search definition.\n */\nexport function parseSearchDefinition<T extends Resource = Resource>(url: string): SearchRequest<T> {\n return parseSearchUrl<T>(new URL(url, 'https://example.com/'));\n}\n\nfunction parseSearchImpl<T extends Resource = Resource>(\n resourceType: T['resourceType'],\n query: [string, string][] | IterableIterator<[string, string]>\n): SearchRequest<T> {\n const searchRequest: SearchRequest<T> = {\n resourceType,\n };\n\n for (const [key, value] of query) {\n parseKeyValue(searchRequest, key, value);\n }\n\n return searchRequest;\n}\n\nfunction parseKeyValue(searchRequest: SearchRequest, key: string, value: string): void {\n let code;\n let modifier;\n\n const colonIndex = key.indexOf(':');\n if (colonIndex >= 0) {\n code = key.substring(0, colonIndex);\n modifier = key.substring(colonIndex + 1);\n } else {\n code = key;\n modifier = '';\n }\n\n switch (code) {\n case '_sort':\n parseSortRule(searchRequest, value);\n break;\n\n case '_count':\n searchRequest.count = parseInt(value);\n break;\n\n case '_offset':\n searchRequest.offset = parseInt(value);\n break;\n\n case '_total':\n searchRequest.total = value as 'none' | 'estimate' | 'accurate';\n break;\n\n case '_summary':\n searchRequest.total = 'accurate';\n searchRequest.count = 0;\n break;\n\n case '_include': {\n const target = parseIncludeTarget(value);\n if (modifier === 'iterate') {\n target.modifier = Operator.ITERATE;\n }\n if (searchRequest.include) {\n searchRequest.include.push(target);\n } else {\n searchRequest.include = [target];\n }\n break;\n }\n\n case '_revinclude': {\n const target = parseIncludeTarget(value);\n if (modifier === 'iterate') {\n target.modifier = Operator.ITERATE;\n }\n if (searchRequest.revInclude) {\n searchRequest.revInclude.push(target);\n } else {\n searchRequest.revInclude = [target];\n }\n break;\n }\n\n case '_fields':\n searchRequest.fields = value.split(',');\n break;\n\n default: {\n const param = globalSchema.types[searchRequest.resourceType]?.searchParams?.[code];\n if (param) {\n parseParameter(searchRequest, param, modifier, value);\n } else {\n parseUnknownParameter(searchRequest, code, modifier, value);\n }\n }\n }\n}\n\nfunction parseSortRule(searchRequest: SearchRequest, value: string): void {\n for (const field of value.split(',')) {\n let code;\n let descending = false;\n if (field.startsWith('-')) {\n code = field.substring(1);\n descending = true;\n } else {\n code = field;\n }\n if (!searchRequest.sortRules) {\n searchRequest.sortRules = [];\n }\n searchRequest.sortRules.push({ code, descending });\n }\n}\n\nfunction parseParameter(\n searchRequest: SearchRequest,\n searchParam: SearchParameter,\n modifier: string,\n value: string\n): void {\n if (modifier === 'missing') {\n addFilter(searchRequest, {\n code: searchParam.code as string,\n operator: Operator.MISSING,\n value,\n });\n return;\n }\n switch (searchParam.type) {\n case 'number':\n case 'date':\n parsePrefixType(searchRequest, searchParam, value);\n break;\n case 'reference':\n case 'string':\n case 'token':\n case 'uri':\n parseModifierType(searchRequest, searchParam, modifier, value);\n break;\n case 'quantity':\n parseQuantity(searchRequest, searchParam, value);\n break;\n }\n}\n\nfunction parsePrefixType(searchRequest: SearchRequest, param: SearchParameter, input: string): void {\n const { operator, value } = parsePrefix(input);\n addFilter(searchRequest, {\n code: param.code as string,\n operator,\n value,\n });\n}\n\nfunction parseModifierType(\n searchRequest: SearchRequest,\n param: SearchParameter,\n modifier: string,\n value: string\n): void {\n addFilter(searchRequest, {\n code: param.code as string,\n operator: parseModifier(modifier),\n value,\n });\n}\n\nfunction parseQuantity(searchRequest: SearchRequest, param: SearchParameter, input: string): void {\n const [prefixNumber, unitSystem, unitCode] = input.split('|');\n const { operator, value } = parsePrefix(prefixNumber);\n addFilter(searchRequest, {\n code: param.code as string,\n operator,\n value,\n unitSystem,\n unitCode,\n });\n}\n\nfunction parseUnknownParameter(searchRequest: SearchRequest, code: string, modifier: string, value: string): void {\n let operator = Operator.EQUALS;\n if (modifier) {\n operator = modifier as Operator;\n } else if (value.length >= 2) {\n const prefix = value.substring(0, 2);\n if (prefix in PREFIX_OPERATORS) {\n if (value.length === 2 || value.at(2)?.match(/\\d/)) {\n operator = prefix as Operator;\n value = value.substring(prefix.length);\n }\n }\n }\n\n addFilter(searchRequest, {\n code,\n operator,\n value,\n });\n}\n\nfunction parsePrefix(input: string): { operator: Operator; value: string } {\n const prefix = input.substring(0, 2);\n const prefixOperator = PREFIX_OPERATORS[prefix];\n if (prefixOperator) {\n return { operator: prefixOperator, value: input.substring(2) };\n }\n return { operator: Operator.EQUALS, value: input };\n}\n\nfunction parseModifier(modifier: string): Operator {\n return MODIFIER_OPERATORS[modifier] || Operator.EQUALS;\n}\n\nfunction parseIncludeTarget(input: string): IncludeTarget {\n const parts = input.split(':');\n\n parts.forEach((p) => {\n if (p === '*') {\n throw new OperationOutcomeError(badRequest(`'*' is not supported as a value for search inclusion parameters`));\n }\n });\n\n if (parts.length === 1) {\n // Full wildcard, not currently supported\n throw new OperationOutcomeError(\n badRequest(`Invalid include value '${input}': must be of the form ResourceType:search-parameter`)\n );\n } else if (parts.length === 2) {\n return {\n resourceType: parts[0],\n searchParam: parts[1],\n };\n } else if (parts.length === 3) {\n return {\n resourceType: parts[0],\n searchParam: parts[1],\n targetType: parts[2],\n };\n } else {\n throw new OperationOutcomeError(badRequest(`Invalid include value '${input}'`));\n }\n}\n\nfunction addFilter(searchRequest: SearchRequest, filter: Filter): void {\n if (searchRequest.filters) {\n searchRequest.filters.push(filter);\n } else {\n searchRequest.filters = [filter];\n }\n}\n\n/**\n * Formats a search definition object into a query string.\n * Note: The return value does not include the resource type.\n * @param definition The search definition.\n * @returns Formatted URL.\n */\nexport function formatSearchQuery(definition: SearchRequest): string {\n const params: string[] = [];\n\n if (definition.fields) {\n params.push('_fields=' + definition.fields.join(','));\n }\n\n if (definition.filters) {\n definition.filters.forEach((filter) => params.push(formatFilter(filter)));\n }\n\n if (definition.sortRules && definition.sortRules.length > 0) {\n params.push(formatSortRules(definition.sortRules));\n }\n\n if (definition.offset !== undefined) {\n params.push('_offset=' + definition.offset);\n }\n\n if (definition.count !== undefined) {\n params.push('_count=' + definition.count);\n }\n\n if (definition.total !== undefined) {\n params.push('_total=' + definition.total);\n }\n\n if (params.length === 0) {\n return '';\n }\n\n params.sort();\n return '?' + params.join('&');\n}\n\nfunction formatFilter(filter: Filter): string {\n const modifier = filter.operator in MODIFIER_OPERATORS ? ':' + filter.operator : '';\n const prefix = filter.operator !== Operator.EQUALS && filter.operator in PREFIX_OPERATORS ? filter.operator : '';\n return `${filter.code}${modifier}=${prefix}${encodeURIComponent(filter.value)}`;\n}\n\nfunction formatSortRules(sortRules: SortRule[]): string {\n return '_sort=' + sortRules.map((sr) => (sr.descending ? '-' + sr.code : sr.code)).join(',');\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search.mjs","sources":["../../../src/search/search.ts"],"sourcesContent":["import { Resource, ResourceType, SearchParameter } from '@medplum/fhirtypes';\nimport { globalSchema } from '../types';\nimport { OperationOutcomeError, badRequest } from '../outcomes';\n\nexport const DEFAULT_SEARCH_COUNT = 20;\n\nexport interface SearchRequest<T extends Resource = Resource> {\n readonly resourceType: T['resourceType'];\n filters?: Filter[];\n sortRules?: SortRule[];\n offset?: number;\n count?: number;\n fields?: string[];\n name?: string;\n total?: 'none' | 'estimate' | 'accurate';\n include?: IncludeTarget[];\n revInclude?: IncludeTarget[];\n}\n\nexport interface Filter {\n code: string;\n operator: Operator;\n value: string;\n unitSystem?: string;\n unitCode?: string;\n}\n\nexport interface SortRule {\n code: string;\n descending?: boolean;\n}\n\nexport interface IncludeTarget {\n resourceType: string;\n searchParam: string;\n targetType?: string;\n modifier?: string;\n}\n\n/**\n * Search operators.\n * These operators represent \"modifiers\" and \"prefixes\" in FHIR search.\n * See: https://www.hl7.org/fhir/search.html\n */\nexport enum Operator {\n EQUALS = 'eq',\n NOT_EQUALS = 'ne',\n\n // Numbers\n GREATER_THAN = 'gt',\n LESS_THAN = 'lt',\n GREATER_THAN_OR_EQUALS = 'ge',\n LESS_THAN_OR_EQUALS = 'le',\n\n // Dates\n STARTS_AFTER = 'sa',\n ENDS_BEFORE = 'eb',\n APPROXIMATELY = 'ap',\n\n // String\n CONTAINS = 'contains',\n EXACT = 'exact',\n\n // Token\n TEXT = 'text',\n NOT = 'not',\n ABOVE = 'above',\n BELOW = 'below',\n IN = 'in',\n NOT_IN = 'not-in',\n OF_TYPE = 'of-type',\n\n // All\n MISSING = 'missing',\n\n // Reference\n IDENTIFIER = 'identifier',\n\n // _include and _revinclude\n ITERATE = 'iterate',\n}\n\n/**\n * Parameter names may specify a modifier as a suffix.\n * The modifiers are separated from the parameter name by a colon.\n * See: https://www.hl7.org/fhir/search.html#modifiers\n */\nconst MODIFIER_OPERATORS: Record<string, Operator> = {\n contains: Operator.CONTAINS,\n exact: Operator.EXACT,\n above: Operator.ABOVE,\n below: Operator.BELOW,\n text: Operator.TEXT,\n not: Operator.NOT,\n in: Operator.IN,\n 'not-in': Operator.NOT_IN,\n 'of-type': Operator.OF_TYPE,\n missing: Operator.MISSING,\n identifier: Operator.IDENTIFIER,\n iterate: Operator.ITERATE,\n};\n\n/**\n * For the ordered parameter types of number, date, and quantity,\n * a prefix to the parameter value may be used to control the nature\n * of the matching.\n * See: https://www.hl7.org/fhir/search.html#prefix\n */\nconst PREFIX_OPERATORS: Record<string, Operator> = {\n eq: Operator.EQUALS,\n ne: Operator.NOT_EQUALS,\n lt: Operator.LESS_THAN,\n le: Operator.LESS_THAN_OR_EQUALS,\n gt: Operator.GREATER_THAN,\n ge: Operator.GREATER_THAN_OR_EQUALS,\n sa: Operator.STARTS_AFTER,\n eb: Operator.ENDS_BEFORE,\n ap: Operator.APPROXIMATELY,\n};\n\n/**\n * Parses a search URL into a search request.\n * @param resourceType The FHIR resource type.\n * @param query The collection of query string parameters.\n * @returns A parsed SearchRequest.\n */\nexport function parseSearchRequest<T extends Resource = Resource>(\n resourceType: T['resourceType'],\n query: Record<string, string[] | string | undefined>\n): SearchRequest<T> {\n const queryArray: [string, string][] = [];\n for (const [key, value] of Object.entries(query)) {\n if (Array.isArray(value)) {\n for (const v of value) {\n queryArray.push([key, v]);\n }\n } else {\n queryArray.push([key, value || '']);\n }\n }\n return parseSearchImpl(resourceType, queryArray);\n}\n\n/**\n * Parses a search URL into a search request.\n * @param url The search URL.\n * @returns A parsed SearchRequest.\n */\nexport function parseSearchUrl<T extends Resource = Resource>(url: URL): SearchRequest<T> {\n const resourceType = url.pathname.split('/').filter(Boolean).pop() as ResourceType;\n return parseSearchImpl<T>(resourceType, url.searchParams.entries());\n}\n\n/**\n * Parses a URL string into a SearchRequest.\n * @param url The URL to parse.\n * @returns Parsed search definition.\n */\nexport function parseSearchDefinition<T extends Resource = Resource>(url: string): SearchRequest<T> {\n return parseSearchUrl<T>(new URL(url, 'https://example.com/'));\n}\n\n/**\n * Parses a FHIR criteria string into a SearchRequest.\n * FHIR criteria strings are found on resources such as Subscription.\n * @param criteria The FHIR criteria string.\n * @returns Parsed search definition.\n */\nexport function parseCriteriaAsSearchRequest(criteria: string): SearchRequest {\n return parseSearchUrl(new URL(criteria, 'https://api.medplum.com/'));\n}\n\nfunction parseSearchImpl<T extends Resource = Resource>(\n resourceType: T['resourceType'],\n query: [string, string][] | IterableIterator<[string, string]>\n): SearchRequest<T> {\n const searchRequest: SearchRequest<T> = {\n resourceType,\n };\n\n for (const [key, value] of query) {\n parseKeyValue(searchRequest, key, value);\n }\n\n return searchRequest;\n}\n\nfunction parseKeyValue(searchRequest: SearchRequest, key: string, value: string): void {\n let code;\n let modifier;\n\n const colonIndex = key.indexOf(':');\n if (colonIndex >= 0) {\n code = key.substring(0, colonIndex);\n modifier = key.substring(colonIndex + 1);\n } else {\n code = key;\n modifier = '';\n }\n\n switch (code) {\n case '_sort':\n parseSortRule(searchRequest, value);\n break;\n\n case '_count':\n searchRequest.count = parseInt(value, 10);\n break;\n\n case '_offset':\n searchRequest.offset = parseInt(value, 10);\n break;\n\n case '_total':\n searchRequest.total = value as 'none' | 'estimate' | 'accurate';\n break;\n\n case '_summary':\n searchRequest.total = 'accurate';\n searchRequest.count = 0;\n break;\n\n case '_include': {\n const target = parseIncludeTarget(value);\n if (modifier === 'iterate') {\n target.modifier = Operator.ITERATE;\n }\n if (searchRequest.include) {\n searchRequest.include.push(target);\n } else {\n searchRequest.include = [target];\n }\n break;\n }\n\n case '_revinclude': {\n const target = parseIncludeTarget(value);\n if (modifier === 'iterate') {\n target.modifier = Operator.ITERATE;\n }\n if (searchRequest.revInclude) {\n searchRequest.revInclude.push(target);\n } else {\n searchRequest.revInclude = [target];\n }\n break;\n }\n\n case '_fields':\n searchRequest.fields = value.split(',');\n break;\n\n default: {\n const param = globalSchema.types[searchRequest.resourceType]?.searchParams?.[code];\n if (param) {\n parseParameter(searchRequest, param, modifier, value);\n } else {\n parseUnknownParameter(searchRequest, code, modifier, value);\n }\n }\n }\n}\n\nfunction parseSortRule(searchRequest: SearchRequest, value: string): void {\n for (const field of value.split(',')) {\n let code;\n let descending = false;\n if (field.startsWith('-')) {\n code = field.substring(1);\n descending = true;\n } else {\n code = field;\n }\n if (!searchRequest.sortRules) {\n searchRequest.sortRules = [];\n }\n searchRequest.sortRules.push({ code, descending });\n }\n}\n\nfunction parseParameter(\n searchRequest: SearchRequest,\n searchParam: SearchParameter,\n modifier: string,\n value: string\n): void {\n if (modifier === 'missing') {\n addFilter(searchRequest, {\n code: searchParam.code as string,\n operator: Operator.MISSING,\n value,\n });\n return;\n }\n switch (searchParam.type) {\n case 'number':\n case 'date':\n parsePrefixType(searchRequest, searchParam, value);\n break;\n case 'reference':\n case 'string':\n case 'token':\n case 'uri':\n parseModifierType(searchRequest, searchParam, modifier, value);\n break;\n case 'quantity':\n parseQuantity(searchRequest, searchParam, value);\n break;\n default:\n break;\n }\n}\n\nfunction parsePrefixType(searchRequest: SearchRequest, param: SearchParameter, input: string): void {\n const { operator, value } = parsePrefix(input);\n addFilter(searchRequest, {\n code: param.code as string,\n operator,\n value,\n });\n}\n\nfunction parseModifierType(\n searchRequest: SearchRequest,\n param: SearchParameter,\n modifier: string,\n value: string\n): void {\n addFilter(searchRequest, {\n code: param.code as string,\n operator: parseModifier(modifier),\n value,\n });\n}\n\nfunction parseQuantity(searchRequest: SearchRequest, param: SearchParameter, input: string): void {\n const [prefixNumber, unitSystem, unitCode] = input.split('|');\n const { operator, value } = parsePrefix(prefixNumber);\n addFilter(searchRequest, {\n code: param.code as string,\n operator,\n value,\n unitSystem,\n unitCode,\n });\n}\n\nfunction parseUnknownParameter(searchRequest: SearchRequest, code: string, modifier: string, value: string): void {\n let operator = Operator.EQUALS;\n if (modifier) {\n operator = modifier as Operator;\n } else if (value.length >= 2) {\n const prefix = value.substring(0, 2);\n if (prefix in PREFIX_OPERATORS) {\n if (value.length === 2 || value.at(2)?.match(/\\d/)) {\n operator = prefix as Operator;\n value = value.substring(prefix.length);\n }\n }\n }\n\n addFilter(searchRequest, {\n code,\n operator,\n value,\n });\n}\n\nfunction parsePrefix(input: string): { operator: Operator; value: string } {\n const prefix = input.substring(0, 2);\n const prefixOperator = PREFIX_OPERATORS[prefix];\n if (prefixOperator) {\n return { operator: prefixOperator, value: input.substring(2) };\n }\n return { operator: Operator.EQUALS, value: input };\n}\n\nfunction parseModifier(modifier: string): Operator {\n return MODIFIER_OPERATORS[modifier] || Operator.EQUALS;\n}\n\nfunction parseIncludeTarget(input: string): IncludeTarget {\n const parts = input.split(':');\n\n parts.forEach((p) => {\n if (p === '*') {\n throw new OperationOutcomeError(badRequest(`'*' is not supported as a value for search inclusion parameters`));\n }\n });\n\n if (parts.length === 1) {\n // Full wildcard, not currently supported\n throw new OperationOutcomeError(\n badRequest(`Invalid include value '${input}': must be of the form ResourceType:search-parameter`)\n );\n } else if (parts.length === 2) {\n return {\n resourceType: parts[0],\n searchParam: parts[1],\n };\n } else if (parts.length === 3) {\n return {\n resourceType: parts[0],\n searchParam: parts[1],\n targetType: parts[2],\n };\n } else {\n throw new OperationOutcomeError(badRequest(`Invalid include value '${input}'`));\n }\n}\n\nfunction addFilter(searchRequest: SearchRequest, filter: Filter): void {\n if (searchRequest.filters) {\n searchRequest.filters.push(filter);\n } else {\n searchRequest.filters = [filter];\n }\n}\n\n/**\n * Formats a search definition object into a query string.\n * Note: The return value does not include the resource type.\n * @param definition The search definition.\n * @returns Formatted URL.\n */\nexport function formatSearchQuery(definition: SearchRequest): string {\n const params: string[] = [];\n\n if (definition.fields) {\n params.push('_fields=' + definition.fields.join(','));\n }\n\n if (definition.filters) {\n definition.filters.forEach((filter) => params.push(formatFilter(filter)));\n }\n\n if (definition.sortRules && definition.sortRules.length > 0) {\n params.push(formatSortRules(definition.sortRules));\n }\n\n if (definition.offset !== undefined) {\n params.push('_offset=' + definition.offset);\n }\n\n if (definition.count !== undefined) {\n params.push('_count=' + definition.count);\n }\n\n if (definition.total !== undefined) {\n params.push('_total=' + definition.total);\n }\n\n if (params.length === 0) {\n return '';\n }\n\n params.sort();\n return '?' + params.join('&');\n}\n\nfunction formatFilter(filter: Filter): string {\n const modifier = filter.operator in MODIFIER_OPERATORS ? ':' + filter.operator : '';\n const prefix = filter.operator !== Operator.EQUALS && filter.operator in PREFIX_OPERATORS ? filter.operator : '';\n return `${filter.code}${modifier}=${prefix}${encodeURIComponent(filter.value)}`;\n}\n\nfunction formatSortRules(sortRules: SortRule[]): string {\n return '_sort=' + sortRules.map((sr) => (sr.descending ? '-' + sr.code : sr.code)).join(',');\n}\n"],"names":[],"mappings":"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"}
@@ -254,7 +254,7 @@ function buildTypeName(components) {
254
254
  function isResourceTypeSchema(typeSchema) {
255
255
  const structureDefinition = typeSchema.structureDefinition;
256
256
  return (structureDefinition &&
257
- structureDefinition.name === typeSchema.elementDefinition?.path &&
257
+ structureDefinition.name === typeSchema.elementDefinition.path &&
258
258
  structureDefinition.kind === 'resource' &&
259
259
  !structureDefinition.abstract);
260
260
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.mjs","sources":["../../src/types.ts"],"sourcesContent":["import {\n Bundle,\n BundleEntry,\n ElementDefinition,\n Reference,\n Resource,\n ResourceType,\n SearchParameter,\n StructureDefinition,\n} from '@medplum/fhirtypes';\nimport baseSchema from './base-schema.json';\nimport { SearchParameterDetails } from './search/details';\nimport { capitalize } from './utils';\n\nexport interface TypedValue {\n readonly type: string;\n readonly value: any;\n}\n\n/**\n * List of property types.\n * http://www.hl7.org/fhir/valueset-defined-types.html\n * The list here includes additions found from StructureDefinition resources.\n */\nexport enum PropertyType {\n Address = 'Address',\n Age = 'Age',\n Annotation = 'Annotation',\n Attachment = 'Attachment',\n BackboneElement = 'BackboneElement',\n CodeableConcept = 'CodeableConcept',\n Coding = 'Coding',\n ContactDetail = 'ContactDetail',\n ContactPoint = 'ContactPoint',\n Contributor = 'Contributor',\n Count = 'Count',\n DataRequirement = 'DataRequirement',\n Distance = 'Distance',\n Dosage = 'Dosage',\n Duration = 'Duration',\n Expression = 'Expression',\n Extension = 'Extension',\n HumanName = 'HumanName',\n Identifier = 'Identifier',\n MarketingStatus = 'MarketingStatus',\n Meta = 'Meta',\n Money = 'Money',\n Narrative = 'Narrative',\n ParameterDefinition = 'ParameterDefinition',\n Period = 'Period',\n Population = 'Population',\n ProdCharacteristic = 'ProdCharacteristic',\n ProductShelfLife = 'ProductShelfLife',\n Quantity = 'Quantity',\n Range = 'Range',\n Ratio = 'Ratio',\n Reference = 'Reference',\n RelatedArtifact = 'RelatedArtifact',\n SampledData = 'SampledData',\n Signature = 'Signature',\n SubstanceAmount = 'SubstanceAmount',\n SystemString = 'http://hl7.org/fhirpath/System.String',\n Timing = 'Timing',\n TriggerDefinition = 'TriggerDefinition',\n UsageContext = 'UsageContext',\n base64Binary = 'base64Binary',\n boolean = 'boolean',\n canonical = 'canonical',\n code = 'code',\n date = 'date',\n dateTime = 'dateTime',\n decimal = 'decimal',\n id = 'id',\n instant = 'instant',\n integer = 'integer',\n markdown = 'markdown',\n oid = 'oid',\n positiveInt = 'positiveInt',\n string = 'string',\n time = 'time',\n unsignedInt = 'unsignedInt',\n uri = 'uri',\n url = 'url',\n uuid = 'uuid',\n}\n\n/**\n * An IndexedStructureDefinition is a lookup-optimized version of a StructureDefinition.\n *\n * StructureDefinition resources contain schema information for other resource types.\n * These schemas can be used to automatically generate user interface elements for\n * resources.\n *\n * However, a StructureDefinition resource is not optimized for realtime lookups. All\n * resource types, sub types, and property definitions are stored in a flat array of\n * ElementDefinition objects. Therefore, to lookup the schema for a property (i.e., \"Patient.name\")\n * requires a linear scan of all ElementDefinition objects\n *\n * A StructureDefinition resource contains information about one or more types.\n * For example, the \"Patient\" StructureDefinition includes \"Patient\", \"Patient_Contact\",\n * \"Patient_Communication\", and \"Patient_Link\". This is inefficient.\n *\n * Instead, we create an indexed version of the StructureDefinition, called IndexedStructureDefinition.\n * In an IndexedStructureDefinition, retrieving a property definition is a hashtable lookup.\n *\n * The hierarchy is:\n * IndexedStructureDefinition - top level for one resource type\n * TypeSchema - one per resource type and all contained BackboneElements\n * PropertySchema - one per property/field\n */\nexport interface IndexedStructureDefinition {\n types: { [resourceType: string]: TypeSchema };\n}\n\n/**\n * An indexed TypeSchema.\n *\n * Example: The IndexedStructureDefinition for \"Patient\" would include the following TypeSchemas:\n * 1) Patient\n * 2) Patient_Contact\n * 3) Patient_Communication\n * 4) Patient_Link\n */\nexport interface TypeSchema {\n structureDefinition: StructureDefinition;\n elementDefinition: ElementDefinition;\n display: string;\n properties: { [name: string]: ElementDefinition };\n searchParams?: { [code: string]: SearchParameter };\n searchParamsDetails?: { [code: string]: SearchParameterDetails };\n description?: string;\n parentType?: string;\n}\n\n/**\n * Indexes a bundle of StructureDefinitions for faster lookup.\n * @param bundle A FHIR bundle StructureDefinition resources.\n * @see {@link IndexedStructureDefinition} for more details on indexed StructureDefinitions.\n */\nexport function indexStructureDefinitionBundle(bundle: Bundle): void {\n for (const entry of bundle.entry as BundleEntry[]) {\n const resource = entry.resource as Resource;\n if (resource.resourceType === 'StructureDefinition') {\n indexStructureDefinition(resource);\n }\n }\n}\n\n/**\n * Indexes a StructureDefinition for fast lookup.\n * @param structureDefinition The original StructureDefinition.\n * @see {@link IndexedStructureDefinition} for more details on indexed StructureDefinitions.\n */\nexport function indexStructureDefinition(structureDefinition: StructureDefinition): void {\n const typeName = structureDefinition.name;\n if (!typeName) {\n return;\n }\n\n const elements = structureDefinition.snapshot?.element;\n if (elements) {\n // First pass, build types\n elements.forEach((element) => indexType(structureDefinition, element));\n\n // Second pass, build properties\n elements.forEach((element) => indexProperty(structureDefinition, element));\n }\n}\n\n/**\n * Indexes TypeSchema from an ElementDefinition.\n * In the common case, there will be many ElementDefinition instances per TypeSchema.\n * Only the first occurrence is saved.\n * @param structureDefinition The parent type structure definition.\n * @param elementDefinition The element definition.\n * @see {@link IndexedStructureDefinition} for more details on indexed StructureDefinitions.\n */\nfunction indexType(structureDefinition: StructureDefinition, elementDefinition: ElementDefinition): void {\n const path = elementDefinition.path as string;\n const typeCode = elementDefinition.type?.[0]?.code;\n if (typeCode !== undefined && typeCode !== 'Element' && typeCode !== 'BackboneElement') {\n return;\n }\n\n const parts = path.split('.');\n\n // Force the first part to be the type name\n // This is necessary for \"SimpleQuantity\" and \"MoneyQuantity\"\n parts[0] = structureDefinition.name as string;\n\n const typeName = buildTypeName(parts);\n let typeSchema = globalSchema.types[typeName];\n\n if (!typeSchema) {\n globalSchema.types[typeName] = typeSchema = {} as TypeSchema;\n }\n\n typeSchema.parentType = typeSchema.parentType || buildTypeName(parts.slice(0, parts.length - 1));\n typeSchema.display = typeSchema.display || typeName;\n typeSchema.structureDefinition = typeSchema.structureDefinition || structureDefinition;\n typeSchema.elementDefinition = typeSchema.elementDefinition || elementDefinition;\n typeSchema.description = typeSchema.description || elementDefinition.definition;\n typeSchema.properties = typeSchema.properties || {};\n}\n\n/**\n * Indexes PropertySchema from an ElementDefinition.\n * @param structureDefinition The input StructureDefinition.\n * @param element The input ElementDefinition.\n * @see {@link IndexedStructureDefinition} for more details on indexed StructureDefinitions.\n */\nfunction indexProperty(structureDefinition: StructureDefinition, element: ElementDefinition): void {\n const path = element.path as string;\n const parts = path.split('.');\n if (parts.length === 1) {\n return;\n }\n\n // Force the first part to be the type name\n // This is necessary for \"SimpleQuantity\" and \"MoneyQuantity\"\n parts[0] = structureDefinition.name as string;\n\n const typeName = buildTypeName(parts.slice(0, parts.length - 1));\n const typeSchema = globalSchema.types[typeName];\n if (!typeSchema) {\n return;\n }\n const key = parts[parts.length - 1];\n typeSchema.properties[key] = element;\n}\n\n/**\n * Indexes a bundle of SearchParameter resources for faster lookup.\n * @param bundle A FHIR bundle SearchParameter resources.\n * @see {@link IndexedStructureDefinition} for more details on indexed StructureDefinitions.\n */\nexport function indexSearchParameterBundle(bundle: Bundle<SearchParameter>): void {\n for (const entry of bundle.entry as BundleEntry[]) {\n const resource = entry.resource as SearchParameter;\n if (resource.resourceType === 'SearchParameter') {\n indexSearchParameter(resource);\n }\n }\n}\n\n/**\n * Indexes a SearchParameter resource for fast lookup.\n * Indexes by SearchParameter.code, which is the query string parameter name.\n * @param searchParam The SearchParameter resource.\n * @see {@link IndexedStructureDefinition} for more details on indexed StructureDefinitions.\n */\nexport function indexSearchParameter(searchParam: SearchParameter): void {\n if (!searchParam.base) {\n return;\n }\n\n for (const resourceType of searchParam.base) {\n const typeSchema = globalSchema.types[resourceType];\n if (!typeSchema) {\n continue;\n }\n\n if (!typeSchema.searchParams) {\n typeSchema.searchParams = {\n _id: {\n base: [resourceType],\n code: '_id',\n type: 'token',\n expression: resourceType + '.id',\n } as SearchParameter,\n _lastUpdated: {\n base: [resourceType],\n code: '_lastUpdated',\n type: 'date',\n expression: resourceType + '.meta.lastUpdated',\n } as SearchParameter,\n _compartment: {\n base: [resourceType],\n code: '_compartment',\n type: 'reference',\n expression: resourceType + '.meta.compartment',\n } as SearchParameter,\n _profile: {\n base: [resourceType],\n code: '_profile',\n type: 'uri',\n expression: resourceType + '.meta.profile',\n } as SearchParameter,\n _security: {\n base: [resourceType],\n code: '_security',\n type: 'token',\n expression: resourceType + '.meta.security',\n } as SearchParameter,\n _source: {\n base: [resourceType],\n code: '_source',\n type: 'uri',\n expression: resourceType + '.meta.source',\n } as SearchParameter,\n _tag: {\n base: [resourceType],\n code: '_tag',\n type: 'token',\n expression: resourceType + '.meta.tag',\n } as SearchParameter,\n };\n }\n\n typeSchema.searchParams[searchParam.code as string] = searchParam;\n }\n}\n\n/**\n * Returns the type name for an ElementDefinition.\n * @param elementDefinition The element definition.\n * @returns The Medplum type name.\n */\nexport function getElementDefinitionTypeName(elementDefinition: ElementDefinition): string {\n const code = elementDefinition.type?.[0]?.code as string;\n return code === 'BackboneElement' || code === 'Element'\n ? buildTypeName(elementDefinition.path?.split('.') as string[])\n : code;\n}\n\nexport function buildTypeName(components: string[]): string {\n if (components.length === 1) {\n return components[0];\n }\n return components.map(capitalize).join('');\n}\n\n/**\n * Returns true if the type schema is a non-abstract FHIR resource.\n * @param typeSchema The type schema to check.\n * @returns True if the type schema is a non-abstract FHIR resource.\n */\nexport function isResourceTypeSchema(typeSchema: TypeSchema): boolean {\n const structureDefinition = typeSchema.structureDefinition;\n return (\n structureDefinition &&\n structureDefinition.name === typeSchema.elementDefinition?.path &&\n structureDefinition.kind === 'resource' &&\n !structureDefinition.abstract\n );\n}\n\n/**\n * Returns an array of all resource types.\n * Note that this is based on globalSchema, and will only return resource types that are currently in memory.\n * @returns An array of all resource types.\n */\nexport function getResourceTypes(): ResourceType[] {\n const result: ResourceType[] = [];\n for (const [resourceType, typeSchema] of Object.entries(globalSchema.types)) {\n if (isResourceTypeSchema(typeSchema)) {\n result.push(resourceType as ResourceType);\n }\n }\n return result;\n}\n\n/**\n * Returns the type schema for the resource type.\n * @param resourceType The resource type.\n * @returns The type schema for the resource type.\n */\nexport function getResourceTypeSchema(resourceType: string): TypeSchema {\n return globalSchema.types[resourceType];\n}\n\n/**\n * Returns the search parameters for the resource type indexed by search code.\n * @param resourceType The resource type.\n * @returns The search parameters for the resource type indexed by search code.\n */\nexport function getSearchParameters(resourceType: string): Record<string, SearchParameter> | undefined {\n return globalSchema.types[resourceType].searchParams;\n}\n\n/**\n * Returns a human friendly display name for a FHIR element definition path.\n * @param path The FHIR element definition path.\n * @returns The best guess of the display name.\n */\nexport function getPropertyDisplayName(path: string): string {\n // Get the property name, which is the remainder after the last period\n // For example, for path \"Patient.birthDate\"\n // the property name is \"birthDate\"\n const propertyName = path.replaceAll('[x]', '').split('.').pop() as string;\n\n // Split by capital letters\n // Capitalize the first letter of each word\n // Join together with spaces in between\n // Then normalize whitespace to single space character\n // For example, for property name \"birthDate\",\n // the display name is \"Birth Date\".\n return propertyName\n .split(/(?=[A-Z])/)\n .map(capitalizeDisplayWord)\n .join(' ')\n .replace('_', ' ')\n .replace(/\\s+/g, ' ');\n}\n\nconst capitalizedWords = new Set(['ID', 'IP', 'PKCE', 'JWKS', 'URI', 'URL']);\n\nfunction capitalizeDisplayWord(word: string): string {\n const upper = word.toUpperCase();\n if (capitalizedWords.has(upper)) {\n return upper;\n }\n return upper.charAt(0) + word.slice(1);\n}\n\n/**\n * Returns an element definition by type and property name.\n * Handles content references.\n * @param typeName The type name.\n * @param propertyName The property name.\n * @returns The element definition if found.\n */\nexport function getElementDefinition(typeName: string, propertyName: string): ElementDefinition | undefined {\n const typeSchema = globalSchema.types[typeName];\n if (!typeSchema) {\n return undefined;\n }\n\n const property = typeSchema.properties[propertyName] ?? typeSchema.properties[propertyName + '[x]'];\n if (!property) {\n return undefined;\n }\n\n if (property.contentReference) {\n // Content references start with a \"#\"\n // Remove the \"#\" character\n const contentReference = property.contentReference.substring(1).split('.');\n const referencePropertyName = contentReference.pop() as string;\n const referenceTypeName = buildTypeName(contentReference);\n return getElementDefinition(referenceTypeName, referencePropertyName);\n }\n\n return property;\n}\n\n/**\n * Typeguard to validate that an object is a FHIR resource\n * @param value The object to check\n * @returns True if the input is of type 'object' and contains property 'resourceType'\n */\nexport function isResource<T extends Resource = Resource>(\n value: T | Reference<T> | string | undefined | null\n): value is T {\n return !!(value && typeof value === 'object' && 'resourceType' in value);\n}\n\n/**\n * Typeguard to validate that an object is a FHIR resource\n * @param value The object to check\n * @returns True if the input is of type 'object' and contains property 'reference'\n */\nexport function isReference<T extends Resource>(\n value: T | Reference<T> | string | undefined | null\n): value is Reference<T> & { reference: string } {\n return !!(value && typeof value === 'object' && 'reference' in value);\n}\n\n/**\n * Global schema singleton.\n */\nexport const globalSchema = baseSchema as unknown as IndexedStructureDefinition;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.mjs","sources":["../../src/types.ts"],"sourcesContent":["import {\n Bundle,\n BundleEntry,\n ElementDefinition,\n Reference,\n Resource,\n ResourceType,\n SearchParameter,\n StructureDefinition,\n} from '@medplum/fhirtypes';\nimport baseSchema from './base-schema.json';\nimport { SearchParameterDetails } from './search/details';\nimport { capitalize } from './utils';\n\nexport interface TypedValue {\n readonly type: string;\n readonly value: any;\n}\n\n/**\n * List of property types.\n * http://www.hl7.org/fhir/valueset-defined-types.html\n * The list here includes additions found from StructureDefinition resources.\n */\nexport enum PropertyType {\n Address = 'Address',\n Age = 'Age',\n Annotation = 'Annotation',\n Attachment = 'Attachment',\n BackboneElement = 'BackboneElement',\n CodeableConcept = 'CodeableConcept',\n Coding = 'Coding',\n ContactDetail = 'ContactDetail',\n ContactPoint = 'ContactPoint',\n Contributor = 'Contributor',\n Count = 'Count',\n DataRequirement = 'DataRequirement',\n Distance = 'Distance',\n Dosage = 'Dosage',\n Duration = 'Duration',\n Expression = 'Expression',\n Extension = 'Extension',\n HumanName = 'HumanName',\n Identifier = 'Identifier',\n MarketingStatus = 'MarketingStatus',\n Meta = 'Meta',\n Money = 'Money',\n Narrative = 'Narrative',\n ParameterDefinition = 'ParameterDefinition',\n Period = 'Period',\n Population = 'Population',\n ProdCharacteristic = 'ProdCharacteristic',\n ProductShelfLife = 'ProductShelfLife',\n Quantity = 'Quantity',\n Range = 'Range',\n Ratio = 'Ratio',\n Reference = 'Reference',\n RelatedArtifact = 'RelatedArtifact',\n SampledData = 'SampledData',\n Signature = 'Signature',\n SubstanceAmount = 'SubstanceAmount',\n SystemString = 'http://hl7.org/fhirpath/System.String',\n Timing = 'Timing',\n TriggerDefinition = 'TriggerDefinition',\n UsageContext = 'UsageContext',\n base64Binary = 'base64Binary',\n boolean = 'boolean',\n canonical = 'canonical',\n code = 'code',\n date = 'date',\n dateTime = 'dateTime',\n decimal = 'decimal',\n id = 'id',\n instant = 'instant',\n integer = 'integer',\n markdown = 'markdown',\n oid = 'oid',\n positiveInt = 'positiveInt',\n string = 'string',\n time = 'time',\n unsignedInt = 'unsignedInt',\n uri = 'uri',\n url = 'url',\n uuid = 'uuid',\n}\n\n/**\n * An IndexedStructureDefinition is a lookup-optimized version of a StructureDefinition.\n *\n * StructureDefinition resources contain schema information for other resource types.\n * These schemas can be used to automatically generate user interface elements for\n * resources.\n *\n * However, a StructureDefinition resource is not optimized for realtime lookups. All\n * resource types, sub types, and property definitions are stored in a flat array of\n * ElementDefinition objects. Therefore, to lookup the schema for a property (i.e., \"Patient.name\")\n * requires a linear scan of all ElementDefinition objects\n *\n * A StructureDefinition resource contains information about one or more types.\n * For example, the \"Patient\" StructureDefinition includes \"Patient\", \"Patient_Contact\",\n * \"Patient_Communication\", and \"Patient_Link\". This is inefficient.\n *\n * Instead, we create an indexed version of the StructureDefinition, called IndexedStructureDefinition.\n * In an IndexedStructureDefinition, retrieving a property definition is a hashtable lookup.\n *\n * The hierarchy is:\n * IndexedStructureDefinition - top level for one resource type\n * TypeSchema - one per resource type and all contained BackboneElements\n * PropertySchema - one per property/field\n */\nexport interface IndexedStructureDefinition {\n types: { [resourceType: string]: TypeSchema };\n}\n\n/**\n * An indexed TypeSchema.\n *\n * Example: The IndexedStructureDefinition for \"Patient\" would include the following TypeSchemas:\n * 1) Patient\n * 2) Patient_Contact\n * 3) Patient_Communication\n * 4) Patient_Link\n */\nexport interface TypeSchema {\n structureDefinition: StructureDefinition;\n elementDefinition: ElementDefinition;\n display: string;\n properties: { [name: string]: ElementDefinition };\n searchParams?: { [code: string]: SearchParameter };\n searchParamsDetails?: { [code: string]: SearchParameterDetails };\n description?: string;\n parentType?: string;\n}\n\n/**\n * Indexes a bundle of StructureDefinitions for faster lookup.\n * @param bundle A FHIR bundle StructureDefinition resources.\n * @see {@link IndexedStructureDefinition} for more details on indexed StructureDefinitions.\n */\nexport function indexStructureDefinitionBundle(bundle: Bundle): void {\n for (const entry of bundle.entry as BundleEntry[]) {\n const resource = entry.resource as Resource;\n if (resource.resourceType === 'StructureDefinition') {\n indexStructureDefinition(resource);\n }\n }\n}\n\n/**\n * Indexes a StructureDefinition for fast lookup.\n * @param structureDefinition The original StructureDefinition.\n * @see {@link IndexedStructureDefinition} for more details on indexed StructureDefinitions.\n */\nexport function indexStructureDefinition(structureDefinition: StructureDefinition): void {\n const typeName = structureDefinition.name;\n if (!typeName) {\n return;\n }\n\n const elements = structureDefinition.snapshot?.element;\n if (elements) {\n // First pass, build types\n elements.forEach((element) => indexType(structureDefinition, element));\n\n // Second pass, build properties\n elements.forEach((element) => indexProperty(structureDefinition, element));\n }\n}\n\n/**\n * Indexes TypeSchema from an ElementDefinition.\n * In the common case, there will be many ElementDefinition instances per TypeSchema.\n * Only the first occurrence is saved.\n * @param structureDefinition The parent type structure definition.\n * @param elementDefinition The element definition.\n * @see {@link IndexedStructureDefinition} for more details on indexed StructureDefinitions.\n */\nfunction indexType(structureDefinition: StructureDefinition, elementDefinition: ElementDefinition): void {\n const path = elementDefinition.path as string;\n const typeCode = elementDefinition.type?.[0]?.code;\n if (typeCode !== undefined && typeCode !== 'Element' && typeCode !== 'BackboneElement') {\n return;\n }\n\n const parts = path.split('.');\n\n // Force the first part to be the type name\n // This is necessary for \"SimpleQuantity\" and \"MoneyQuantity\"\n parts[0] = structureDefinition.name as string;\n\n const typeName = buildTypeName(parts);\n let typeSchema = globalSchema.types[typeName];\n\n if (!typeSchema) {\n globalSchema.types[typeName] = typeSchema = {} as TypeSchema;\n }\n\n typeSchema.parentType = typeSchema.parentType || buildTypeName(parts.slice(0, parts.length - 1));\n typeSchema.display = typeSchema.display || typeName;\n typeSchema.structureDefinition = typeSchema.structureDefinition || structureDefinition;\n typeSchema.elementDefinition = typeSchema.elementDefinition || elementDefinition;\n typeSchema.description = typeSchema.description || elementDefinition.definition;\n typeSchema.properties = typeSchema.properties || {};\n}\n\n/**\n * Indexes PropertySchema from an ElementDefinition.\n * @param structureDefinition The input StructureDefinition.\n * @param element The input ElementDefinition.\n * @see {@link IndexedStructureDefinition} for more details on indexed StructureDefinitions.\n */\nfunction indexProperty(structureDefinition: StructureDefinition, element: ElementDefinition): void {\n const path = element.path as string;\n const parts = path.split('.');\n if (parts.length === 1) {\n return;\n }\n\n // Force the first part to be the type name\n // This is necessary for \"SimpleQuantity\" and \"MoneyQuantity\"\n parts[0] = structureDefinition.name as string;\n\n const typeName = buildTypeName(parts.slice(0, parts.length - 1));\n const typeSchema = globalSchema.types[typeName];\n if (!typeSchema) {\n return;\n }\n const key = parts[parts.length - 1];\n typeSchema.properties[key] = element;\n}\n\n/**\n * Indexes a bundle of SearchParameter resources for faster lookup.\n * @param bundle A FHIR bundle SearchParameter resources.\n * @see {@link IndexedStructureDefinition} for more details on indexed StructureDefinitions.\n */\nexport function indexSearchParameterBundle(bundle: Bundle<SearchParameter>): void {\n for (const entry of bundle.entry as BundleEntry[]) {\n const resource = entry.resource as SearchParameter;\n if (resource.resourceType === 'SearchParameter') {\n indexSearchParameter(resource);\n }\n }\n}\n\n/**\n * Indexes a SearchParameter resource for fast lookup.\n * Indexes by SearchParameter.code, which is the query string parameter name.\n * @param searchParam The SearchParameter resource.\n * @see {@link IndexedStructureDefinition} for more details on indexed StructureDefinitions.\n */\nexport function indexSearchParameter(searchParam: SearchParameter): void {\n if (!searchParam.base) {\n return;\n }\n\n for (const resourceType of searchParam.base) {\n const typeSchema = globalSchema.types[resourceType];\n if (!typeSchema) {\n continue;\n }\n\n if (!typeSchema.searchParams) {\n typeSchema.searchParams = {\n _id: {\n base: [resourceType],\n code: '_id',\n type: 'token',\n expression: resourceType + '.id',\n } as SearchParameter,\n _lastUpdated: {\n base: [resourceType],\n code: '_lastUpdated',\n type: 'date',\n expression: resourceType + '.meta.lastUpdated',\n } as SearchParameter,\n _compartment: {\n base: [resourceType],\n code: '_compartment',\n type: 'reference',\n expression: resourceType + '.meta.compartment',\n } as SearchParameter,\n _profile: {\n base: [resourceType],\n code: '_profile',\n type: 'uri',\n expression: resourceType + '.meta.profile',\n } as SearchParameter,\n _security: {\n base: [resourceType],\n code: '_security',\n type: 'token',\n expression: resourceType + '.meta.security',\n } as SearchParameter,\n _source: {\n base: [resourceType],\n code: '_source',\n type: 'uri',\n expression: resourceType + '.meta.source',\n } as SearchParameter,\n _tag: {\n base: [resourceType],\n code: '_tag',\n type: 'token',\n expression: resourceType + '.meta.tag',\n } as SearchParameter,\n };\n }\n\n typeSchema.searchParams[searchParam.code as string] = searchParam;\n }\n}\n\n/**\n * Returns the type name for an ElementDefinition.\n * @param elementDefinition The element definition.\n * @returns The Medplum type name.\n */\nexport function getElementDefinitionTypeName(elementDefinition: ElementDefinition): string {\n const code = elementDefinition.type?.[0]?.code as string;\n return code === 'BackboneElement' || code === 'Element'\n ? buildTypeName(elementDefinition.path?.split('.') as string[])\n : code;\n}\n\nexport function buildTypeName(components: string[]): string {\n if (components.length === 1) {\n return components[0];\n }\n return components.map(capitalize).join('');\n}\n\n/**\n * Returns true if the type schema is a non-abstract FHIR resource.\n * @param typeSchema The type schema to check.\n * @returns True if the type schema is a non-abstract FHIR resource.\n */\nexport function isResourceTypeSchema(typeSchema: TypeSchema): boolean {\n const structureDefinition = typeSchema.structureDefinition;\n return (\n structureDefinition &&\n structureDefinition.name === typeSchema.elementDefinition.path &&\n structureDefinition.kind === 'resource' &&\n !structureDefinition.abstract\n );\n}\n\n/**\n * Returns an array of all resource types.\n * Note that this is based on globalSchema, and will only return resource types that are currently in memory.\n * @returns An array of all resource types.\n */\nexport function getResourceTypes(): ResourceType[] {\n const result: ResourceType[] = [];\n for (const [resourceType, typeSchema] of Object.entries(globalSchema.types)) {\n if (isResourceTypeSchema(typeSchema)) {\n result.push(resourceType as ResourceType);\n }\n }\n return result;\n}\n\n/**\n * Returns the type schema for the resource type.\n * @param resourceType The resource type.\n * @returns The type schema for the resource type.\n */\nexport function getResourceTypeSchema(resourceType: string): TypeSchema {\n return globalSchema.types[resourceType];\n}\n\n/**\n * Returns the search parameters for the resource type indexed by search code.\n * @param resourceType The resource type.\n * @returns The search parameters for the resource type indexed by search code.\n */\nexport function getSearchParameters(resourceType: string): Record<string, SearchParameter> | undefined {\n return globalSchema.types[resourceType].searchParams;\n}\n\n/**\n * Returns a human friendly display name for a FHIR element definition path.\n * @param path The FHIR element definition path.\n * @returns The best guess of the display name.\n */\nexport function getPropertyDisplayName(path: string): string {\n // Get the property name, which is the remainder after the last period\n // For example, for path \"Patient.birthDate\"\n // the property name is \"birthDate\"\n const propertyName = path.replaceAll('[x]', '').split('.').pop() as string;\n\n // Split by capital letters\n // Capitalize the first letter of each word\n // Join together with spaces in between\n // Then normalize whitespace to single space character\n // For example, for property name \"birthDate\",\n // the display name is \"Birth Date\".\n return propertyName\n .split(/(?=[A-Z])/)\n .map(capitalizeDisplayWord)\n .join(' ')\n .replace('_', ' ')\n .replace(/\\s+/g, ' ');\n}\n\nconst capitalizedWords = new Set(['ID', 'IP', 'PKCE', 'JWKS', 'URI', 'URL']);\n\nfunction capitalizeDisplayWord(word: string): string {\n const upper = word.toUpperCase();\n if (capitalizedWords.has(upper)) {\n return upper;\n }\n return upper.charAt(0) + word.slice(1);\n}\n\n/**\n * Returns an element definition by type and property name.\n * Handles content references.\n * @param typeName The type name.\n * @param propertyName The property name.\n * @returns The element definition if found.\n */\nexport function getElementDefinition(typeName: string, propertyName: string): ElementDefinition | undefined {\n const typeSchema = globalSchema.types[typeName];\n if (!typeSchema) {\n return undefined;\n }\n\n const property = typeSchema.properties[propertyName] ?? typeSchema.properties[propertyName + '[x]'];\n if (!property) {\n return undefined;\n }\n\n if (property.contentReference) {\n // Content references start with a \"#\"\n // Remove the \"#\" character\n const contentReference = property.contentReference.substring(1).split('.');\n const referencePropertyName = contentReference.pop() as string;\n const referenceTypeName = buildTypeName(contentReference);\n return getElementDefinition(referenceTypeName, referencePropertyName);\n }\n\n return property;\n}\n\n/**\n * Typeguard to validate that an object is a FHIR resource\n * @param value The object to check\n * @returns True if the input is of type 'object' and contains property 'resourceType'\n */\nexport function isResource<T extends Resource = Resource>(\n value: T | Reference<T> | string | undefined | null\n): value is T {\n return !!(value && typeof value === 'object' && 'resourceType' in value);\n}\n\n/**\n * Typeguard to validate that an object is a FHIR resource\n * @param value The object to check\n * @returns True if the input is of type 'object' and contains property 'reference'\n */\nexport function isReference<T extends Resource>(\n value: T | Reference<T> | string | undefined | null\n): value is Reference<T> & { reference: string } {\n return !!(value && typeof value === 'object' && 'reference' in value);\n}\n\n/**\n * Global schema singleton.\n */\nexport const globalSchema = baseSchema as unknown as IndexedStructureDefinition;\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,278 @@
1
+ import '../types.mjs';
2
+ import { capitalize, isEmpty } from '../utils.mjs';
3
+ import { getTypedPropertyValue } from '../fhirpath/utils.mjs';
4
+ import '../fhirpath/parse.mjs';
5
+ import { OperationOutcomeError, serverError } from '../outcomes.mjs';
6
+
7
+ /**
8
+ * Parses a StructureDefinition resource into an internal schema better suited for
9
+ * programmatic validation and usage in internal systems
10
+ * @param sd The StructureDefinition resource to parse
11
+ * @returns The parsed schema for the given resource type
12
+ * @experimental
13
+ */
14
+ function parseStructureDefinition(sd) {
15
+ return new StructureDefinitionParser(sd).parse();
16
+ }
17
+ const DATA_TYPES = Object.create(null);
18
+ function loadDataTypes(bundle) {
19
+ for (const { resource: sd } of bundle.entry ?? []) {
20
+ if (!sd?.name) {
21
+ throw new Error(`Failed loading StructureDefinition from bundle`);
22
+ }
23
+ if (sd.resourceType !== 'StructureDefinition') {
24
+ continue;
25
+ }
26
+ const schema = parseStructureDefinition(sd);
27
+ DATA_TYPES[sd.name] = schema;
28
+ for (const inner of schema.innerTypes) {
29
+ DATA_TYPES[inner.name] = inner;
30
+ }
31
+ }
32
+ }
33
+ function getDataType(type) {
34
+ const schema = DATA_TYPES[type];
35
+ if (!schema) {
36
+ throw new OperationOutcomeError(serverError(Error('Unknown data type: ' + type)));
37
+ }
38
+ return schema;
39
+ }
40
+ /**
41
+ * @experimental
42
+ */
43
+ class StructureDefinitionParser {
44
+ /**
45
+ * @param sd The StructureDefinition to parse
46
+ * @throws Throws when the StructureDefinition does not have a populated `snapshot` field
47
+ */
48
+ constructor(sd) {
49
+ if (!sd.snapshot?.element || sd.snapshot.element.length === 0) {
50
+ throw new Error(`No snapshot defined for StructureDefinition '${sd.name}'`);
51
+ }
52
+ const root = sd.snapshot.element[0];
53
+ this.elements = sd.snapshot.element.slice(1);
54
+ this.elementIndex = Object.create(null);
55
+ this.index = 0;
56
+ this.resourceSchema = {
57
+ name: sd.type,
58
+ fields: {},
59
+ constraints: this.parseFieldDefinition(root).constraints,
60
+ innerTypes: [],
61
+ };
62
+ this.innerTypes = [];
63
+ }
64
+ parse() {
65
+ let element = this.next();
66
+ while (element) {
67
+ if (element.sliceName) {
68
+ // Start of slice: this ElementDefinition defines the top-level element of a slice value
69
+ this.parseSliceStart(element);
70
+ }
71
+ else if (element.id?.includes(':')) {
72
+ // Slice element, part of some slice definition
73
+ if (this.slicingContext?.current) {
74
+ const path = elementPath(element, this.slicingContext.path);
75
+ this.slicingContext.current.fields[path] = this.parseFieldDefinition(element);
76
+ }
77
+ }
78
+ else {
79
+ // Normal field definition
80
+ const field = this.parseFieldDefinition(element);
81
+ this.checkFieldEnter(element, field);
82
+ // Record field in schema
83
+ if (this.backboneContext && element.path?.startsWith(this.backboneContext.path + '.')) {
84
+ this.backboneContext.type.fields[elementPath(element, this.backboneContext.path)] = field;
85
+ }
86
+ else if (this.backboneContext?.parent && element.path?.startsWith(this.backboneContext.parent.path + '.')) {
87
+ this.backboneContext.parent.type.fields[elementPath(element, this.backboneContext.parent.path)] = field;
88
+ }
89
+ else {
90
+ this.resourceSchema.fields[elementPath(element, this.resourceSchema.name)] = field;
91
+ }
92
+ // Clean up contextual book-keeping
93
+ this.checkFieldExit(element);
94
+ }
95
+ element = this.next();
96
+ }
97
+ // Wrap up if the StructureDefinition ends on a slice or backbone element
98
+ this.checkFieldExit();
99
+ if (this.innerTypes.length > 0) {
100
+ this.resourceSchema.innerTypes = this.innerTypes;
101
+ }
102
+ return this.resourceSchema;
103
+ }
104
+ checkFieldEnter(element, field) {
105
+ if (this.isInnerType(element)) {
106
+ while (this.backboneContext && !pathsCompatible(this.backboneContext?.path, element.path)) {
107
+ // Starting new inner type, unwind type stack to this property's parent
108
+ this.innerTypes.push(this.backboneContext.type);
109
+ this.backboneContext = this.backboneContext.parent;
110
+ }
111
+ this.backboneContext = {
112
+ type: {
113
+ name: buildTypeName(element.path?.split('.') ?? []),
114
+ fields: {},
115
+ constraints: this.parseFieldDefinition(element).constraints,
116
+ innerTypes: [],
117
+ },
118
+ path: element.path ?? '',
119
+ parent: pathsCompatible(this.backboneContext?.path, element.path)
120
+ ? this.backboneContext
121
+ : this.backboneContext?.parent,
122
+ };
123
+ }
124
+ if (element.slicing && !this.slicingContext) {
125
+ field.slicing = {
126
+ discriminator: (element.slicing?.discriminator ?? []).map((d) => ({
127
+ path: d.path,
128
+ type: d.type,
129
+ })),
130
+ slices: [],
131
+ ordered: element.slicing?.ordered ?? false,
132
+ rule: element.slicing?.rules,
133
+ };
134
+ this.slicingContext = { field: field.slicing, path: element.path ?? '' };
135
+ }
136
+ }
137
+ checkFieldExit(element = undefined) {
138
+ if (this.backboneContext && !pathsCompatible(this.backboneContext.path, element?.path)) {
139
+ // Leaving BackboneElement child fields
140
+ if (this.backboneContext.parent) {
141
+ do {
142
+ this.innerTypes.push(this.backboneContext.type);
143
+ this.backboneContext = this.backboneContext.parent;
144
+ } while (this.backboneContext && !pathsCompatible(this.backboneContext.path, element?.path));
145
+ }
146
+ else {
147
+ this.innerTypes.push(this.backboneContext.type);
148
+ delete this.backboneContext;
149
+ }
150
+ }
151
+ if (this.slicingContext && !pathsCompatible(this.slicingContext.path, element?.path)) {
152
+ // Path must be compatible with the sliced field path (i.e. have it as a prefix) to be a part of the
153
+ // same slice group; otherwise, that group is finished and this is the start of a new field
154
+ if (this.slicingContext?.current) {
155
+ this.slicingContext.field.slices.push(this.slicingContext.current);
156
+ }
157
+ delete this.slicingContext;
158
+ }
159
+ }
160
+ next() {
161
+ const element = this.peek();
162
+ if (element) {
163
+ this.index++;
164
+ return element;
165
+ }
166
+ return undefined;
167
+ }
168
+ peek() {
169
+ const element = this.elements[this.index];
170
+ if (element) {
171
+ this.elementIndex[element.path ?? ''] = element;
172
+ if (element.contentReference) {
173
+ const ref = this.elementIndex[element.contentReference.slice(element.contentReference.indexOf('#') + 1)];
174
+ if (!ref) {
175
+ return undefined;
176
+ }
177
+ return {
178
+ ...ref,
179
+ id: element.id,
180
+ path: element.path,
181
+ };
182
+ }
183
+ return element;
184
+ }
185
+ return undefined;
186
+ }
187
+ isInnerType(current) {
188
+ const next = this.peek();
189
+ return !!(pathsCompatible(current?.path, next?.path) &&
190
+ current.type?.some((t) => ['BackboneElement', 'Element'].includes(t.code)));
191
+ }
192
+ parseSliceStart(element) {
193
+ if (!this.slicingContext) {
194
+ throw new Error('Invalid slice start before discriminator');
195
+ }
196
+ if (this.slicingContext.current) {
197
+ this.slicingContext.field.slices.push(this.slicingContext.current);
198
+ }
199
+ this.slicingContext.current = {
200
+ name: element.sliceName ?? '',
201
+ fields: {},
202
+ min: element.min ?? 0,
203
+ max: element.max === '*' ? Number.POSITIVE_INFINITY : Number.parseInt(element.max, 10),
204
+ };
205
+ }
206
+ parseFieldDefinition(ed) {
207
+ const max = parseCardinality(ed.max);
208
+ const baseMax = ed.base?.max ? parseCardinality(ed.base.max) : max;
209
+ const typedElementDef = { type: 'ElementDefinition', value: ed };
210
+ return {
211
+ min: ed.min ?? 0,
212
+ max: max,
213
+ isArray: baseMax > 1,
214
+ constraints: (ed.constraint ?? []).map((c) => ({
215
+ key: c.key ?? '',
216
+ severity: c.severity ?? 'error',
217
+ expression: c.expression ?? '',
218
+ description: c.human ?? '',
219
+ })),
220
+ type: (ed.type ?? []).map((t) => ({
221
+ code: ['BackboneElement', 'Element'].includes(t.code)
222
+ ? buildTypeName(ed.base?.path?.split('.') ?? [])
223
+ : t.code ?? '',
224
+ targetProfile: t.targetProfile ?? [],
225
+ })),
226
+ fixed: firstValue(getTypedPropertyValue(typedElementDef, 'fixed')),
227
+ pattern: firstValue(getTypedPropertyValue(typedElementDef, 'pattern')),
228
+ binding: ed.binding?.strength === 'required' ? ed.binding.valueSet : undefined,
229
+ };
230
+ }
231
+ }
232
+ function parseCardinality(c) {
233
+ return c === '*' ? Number.POSITIVE_INFINITY : Number.parseInt(c, 10);
234
+ }
235
+ function elementPath(element, prefix = '') {
236
+ return trimPrefix(element.path, prefix);
237
+ }
238
+ function trimPrefix(str, prefix) {
239
+ if (!str) {
240
+ return '';
241
+ }
242
+ if (prefix && str.startsWith(prefix)) {
243
+ return str.substring(prefix.length + 1);
244
+ }
245
+ return str;
246
+ }
247
+ /**
248
+ * Tests whether two element paths are compatible, i.e. whether the child path is nested under the parent.
249
+ * @param parent The expected parent path, which should be a prefix of the child path.
250
+ * @param child The child path to test for compatibility with the parent path.
251
+ * @returns True if the given path is a child of the parent.
252
+ */
253
+ function pathsCompatible(parent, child) {
254
+ if (!parent || !child) {
255
+ return false;
256
+ }
257
+ return child.startsWith(parent + '.') || child === parent;
258
+ }
259
+ function buildTypeName(components) {
260
+ if (components.length === 1) {
261
+ return components[0];
262
+ }
263
+ return components.map(capitalize).join('');
264
+ }
265
+ function firstValue(obj) {
266
+ if (Array.isArray(obj) && obj.length > 0) {
267
+ return obj[0];
268
+ }
269
+ else if (!isEmpty(obj)) {
270
+ return obj;
271
+ }
272
+ else {
273
+ return undefined;
274
+ }
275
+ }
276
+
277
+ export { getDataType, loadDataTypes, parseStructureDefinition };
278
+ //# sourceMappingURL=types.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.mjs","sources":["../../../src/typeschema/types.ts"],"sourcesContent":["import { Bundle, ElementDefinition, ResourceType, StructureDefinition } from '@medplum/fhirtypes';\nimport { getTypedPropertyValue } from '../fhirpath';\nimport { OperationOutcomeError, serverError } from '../outcomes';\nimport { TypedValue } from '../types';\nimport { capitalize, isEmpty } from '../utils';\n\n/**\n * Internal representation of a non-primitive FHIR type, suitable for use in resource validation\n */\nexport interface InternalTypeSchema {\n name: string;\n fields: Record<string, ElementValidator>;\n constraints: Constraint[];\n innerTypes: InternalTypeSchema[];\n}\n\nexport interface ElementValidator {\n min: number;\n max: number;\n isArray: boolean;\n constraints: Constraint[];\n type: ElementType[];\n slicing?: SlicingRules;\n fixed?: TypedValue;\n pattern?: TypedValue;\n binding?: string;\n}\n\nexport interface ElementType {\n code: string;\n targetProfile: string[];\n}\n\nexport interface Constraint {\n key: string;\n severity: 'error' | 'warning';\n expression: string;\n description: string;\n}\n\nexport interface SlicingRules {\n discriminator: SliceDiscriminator[];\n ordered: boolean;\n rule?: 'open' | 'closed' | 'openAtEnd';\n slices: SliceDefinition[];\n}\n\nexport interface SliceDefinition {\n name: string;\n fields: Record<string, ElementValidator>;\n min: number;\n max: number;\n}\n\nexport interface SliceDiscriminator {\n path: string;\n type: string;\n}\n\n/**\n * Parses a StructureDefinition resource into an internal schema better suited for\n * programmatic validation and usage in internal systems\n * @param sd The StructureDefinition resource to parse\n * @returns The parsed schema for the given resource type\n * @experimental\n */\nexport function parseStructureDefinition(sd: StructureDefinition): InternalTypeSchema {\n return new StructureDefinitionParser(sd).parse();\n}\n\nconst DATA_TYPES: Record<string, InternalTypeSchema> = Object.create(null);\n\nexport function loadDataTypes(bundle: Bundle<StructureDefinition>): void {\n for (const { resource: sd } of bundle.entry ?? []) {\n if (!sd?.name) {\n throw new Error(`Failed loading StructureDefinition from bundle`);\n }\n if (sd.resourceType !== 'StructureDefinition') {\n continue;\n }\n const schema = parseStructureDefinition(sd);\n DATA_TYPES[sd.name] = schema;\n for (const inner of schema.innerTypes) {\n DATA_TYPES[inner.name] = inner;\n }\n }\n}\n\nexport function getDataType(type: string): InternalTypeSchema {\n const schema = DATA_TYPES[type];\n if (!schema) {\n throw new OperationOutcomeError(serverError(Error('Unknown data type: ' + type)));\n }\n return schema;\n}\n\ninterface BackboneContext {\n type: InternalTypeSchema;\n path: string;\n parent?: BackboneContext;\n}\n\n/**\n * @experimental\n */\nclass StructureDefinitionParser {\n private readonly elements: ElementDefinition[];\n private readonly elementIndex: Record<string, ElementDefinition>;\n private index: number;\n private readonly resourceSchema: InternalTypeSchema;\n private slicingContext: { field: SlicingRules; current?: SliceDefinition; path: string } | undefined;\n private innerTypes: InternalTypeSchema[];\n private backboneContext: BackboneContext | undefined;\n\n /**\n * @param sd The StructureDefinition to parse\n * @throws Throws when the StructureDefinition does not have a populated `snapshot` field\n */\n constructor(sd: StructureDefinition) {\n if (!sd.snapshot?.element || sd.snapshot.element.length === 0) {\n throw new Error(`No snapshot defined for StructureDefinition '${sd.name}'`);\n }\n const root = sd.snapshot.element[0];\n\n this.elements = sd.snapshot.element.slice(1);\n this.elementIndex = Object.create(null);\n this.index = 0;\n this.resourceSchema = {\n name: sd.type as ResourceType,\n fields: {},\n constraints: this.parseFieldDefinition(root).constraints,\n innerTypes: [],\n };\n this.innerTypes = [];\n }\n\n parse(): InternalTypeSchema {\n let element = this.next();\n while (element) {\n if (element.sliceName) {\n // Start of slice: this ElementDefinition defines the top-level element of a slice value\n this.parseSliceStart(element);\n } else if (element.id?.includes(':')) {\n // Slice element, part of some slice definition\n if (this.slicingContext?.current) {\n const path = elementPath(element, this.slicingContext.path);\n this.slicingContext.current.fields[path] = this.parseFieldDefinition(element);\n }\n } else {\n // Normal field definition\n const field = this.parseFieldDefinition(element);\n this.checkFieldEnter(element, field);\n\n // Record field in schema\n if (this.backboneContext && element.path?.startsWith(this.backboneContext.path + '.')) {\n this.backboneContext.type.fields[elementPath(element, this.backboneContext.path)] = field;\n } else if (this.backboneContext?.parent && element.path?.startsWith(this.backboneContext.parent.path + '.')) {\n this.backboneContext.parent.type.fields[elementPath(element, this.backboneContext.parent.path)] = field;\n } else {\n this.resourceSchema.fields[elementPath(element, this.resourceSchema.name)] = field;\n }\n\n // Clean up contextual book-keeping\n this.checkFieldExit(element);\n }\n\n element = this.next();\n }\n\n // Wrap up if the StructureDefinition ends on a slice or backbone element\n this.checkFieldExit();\n if (this.innerTypes.length > 0) {\n this.resourceSchema.innerTypes = this.innerTypes;\n }\n\n return this.resourceSchema;\n }\n\n private checkFieldEnter(element: ElementDefinition, field: ElementValidator): void {\n if (this.isInnerType(element)) {\n while (this.backboneContext && !pathsCompatible(this.backboneContext?.path, element.path)) {\n // Starting new inner type, unwind type stack to this property's parent\n this.innerTypes.push(this.backboneContext.type);\n this.backboneContext = this.backboneContext.parent;\n }\n this.backboneContext = {\n type: {\n name: buildTypeName(element.path?.split('.') ?? []) as ResourceType,\n fields: {},\n constraints: this.parseFieldDefinition(element).constraints,\n innerTypes: [],\n },\n path: element.path ?? '',\n parent: pathsCompatible(this.backboneContext?.path, element.path)\n ? this.backboneContext\n : this.backboneContext?.parent,\n };\n }\n if (element.slicing && !this.slicingContext) {\n field.slicing = {\n discriminator: (element.slicing?.discriminator ?? []).map((d) => ({\n path: d.path as string,\n type: d.type as string,\n })),\n slices: [],\n ordered: element.slicing?.ordered ?? false,\n rule: element.slicing?.rules,\n };\n this.slicingContext = { field: field.slicing, path: element.path ?? '' };\n }\n }\n\n private checkFieldExit(element: ElementDefinition | undefined = undefined): void {\n if (this.backboneContext && !pathsCompatible(this.backboneContext.path, element?.path)) {\n // Leaving BackboneElement child fields\n if (this.backboneContext.parent) {\n do {\n this.innerTypes.push(this.backboneContext.type);\n this.backboneContext = this.backboneContext.parent;\n } while (this.backboneContext && !pathsCompatible(this.backboneContext.path, element?.path));\n } else {\n this.innerTypes.push(this.backboneContext.type);\n delete this.backboneContext;\n }\n }\n if (this.slicingContext && !pathsCompatible(this.slicingContext.path, element?.path as string)) {\n // Path must be compatible with the sliced field path (i.e. have it as a prefix) to be a part of the\n // same slice group; otherwise, that group is finished and this is the start of a new field\n if (this.slicingContext?.current) {\n this.slicingContext.field.slices.push(this.slicingContext.current);\n }\n delete this.slicingContext;\n }\n }\n\n private next(): ElementDefinition | undefined {\n const element = this.peek();\n if (element) {\n this.index++;\n return element;\n }\n return undefined;\n }\n\n private peek(): ElementDefinition | undefined {\n const element = this.elements[this.index];\n if (element) {\n this.elementIndex[element.path ?? ''] = element;\n if (element.contentReference) {\n const ref = this.elementIndex[element.contentReference.slice(element.contentReference.indexOf('#') + 1)];\n if (!ref) {\n return undefined;\n }\n return {\n ...ref,\n id: element.id,\n path: element.path,\n };\n }\n return element;\n }\n return undefined;\n }\n\n private isInnerType(current: ElementDefinition): boolean {\n const next = this.peek();\n return !!(\n pathsCompatible(current?.path, next?.path) &&\n current.type?.some((t) => ['BackboneElement', 'Element'].includes(t.code as string))\n );\n }\n\n private parseSliceStart(element: ElementDefinition): void {\n if (!this.slicingContext) {\n throw new Error('Invalid slice start before discriminator');\n }\n if (this.slicingContext.current) {\n this.slicingContext.field.slices.push(this.slicingContext.current);\n }\n this.slicingContext.current = {\n name: element.sliceName ?? '',\n fields: {},\n min: element.min ?? 0,\n max: element.max === '*' ? Number.POSITIVE_INFINITY : Number.parseInt(element.max as string, 10),\n };\n }\n\n private parseFieldDefinition(ed: ElementDefinition): ElementValidator {\n const max = parseCardinality(ed.max as string);\n const baseMax = ed.base?.max ? parseCardinality(ed.base.max) : max;\n const typedElementDef = { type: 'ElementDefinition', value: ed };\n return {\n min: ed.min ?? 0,\n max: max,\n isArray: baseMax > 1,\n constraints: (ed.constraint ?? []).map((c) => ({\n key: c.key ?? '',\n severity: c.severity ?? 'error',\n expression: c.expression ?? '',\n description: c.human ?? '',\n })),\n type: (ed.type ?? []).map((t) => ({\n code: ['BackboneElement', 'Element'].includes(t.code as string)\n ? buildTypeName(ed.base?.path?.split('.') ?? [])\n : t.code ?? '',\n targetProfile: t.targetProfile ?? [],\n })),\n fixed: firstValue(getTypedPropertyValue(typedElementDef, 'fixed')),\n pattern: firstValue(getTypedPropertyValue(typedElementDef, 'pattern')),\n binding: ed.binding?.strength === 'required' ? ed.binding.valueSet : undefined,\n };\n }\n}\n\nfunction parseCardinality(c: string): number {\n return c === '*' ? Number.POSITIVE_INFINITY : Number.parseInt(c, 10);\n}\n\nfunction elementPath(element: ElementDefinition, prefix = ''): string {\n return trimPrefix(element.path, prefix);\n}\n\nfunction trimPrefix(str: string | undefined, prefix: string): string {\n if (!str) {\n return '';\n }\n if (prefix && str.startsWith(prefix)) {\n return str.substring(prefix.length + 1);\n }\n return str;\n}\n\n/**\n * Tests whether two element paths are compatible, i.e. whether the child path is nested under the parent.\n * @param parent The expected parent path, which should be a prefix of the child path.\n * @param child The child path to test for compatibility with the parent path.\n * @returns True if the given path is a child of the parent.\n */\nfunction pathsCompatible(parent: string | undefined, child: string | undefined): boolean {\n if (!parent || !child) {\n return false;\n }\n return child.startsWith(parent + '.') || child === parent;\n}\n\nfunction buildTypeName(components: string[]): string {\n if (components.length === 1) {\n return components[0];\n }\n return components.map(capitalize).join('');\n}\n\nfunction firstValue(obj: TypedValue | TypedValue[] | undefined): TypedValue | undefined {\n if (Array.isArray(obj) && obj.length > 0) {\n return obj[0];\n } else if (!isEmpty(obj)) {\n return obj as TypedValue;\n } else {\n return undefined;\n }\n}\n"],"names":[],"mappings":"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"}