@medplum/core 2.0.5 → 2.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +872 -27
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.min.cjs +1 -1
- package/dist/esm/client.mjs +7 -6
- package/dist/esm/client.mjs.map +1 -1
- package/dist/esm/fhirlexer/tokenize.mjs +13 -4
- package/dist/esm/fhirlexer/tokenize.mjs.map +1 -1
- package/dist/esm/fhirmapper/parse.mjs +317 -0
- package/dist/esm/fhirmapper/parse.mjs.map +1 -0
- package/dist/esm/fhirmapper/tokenize.mjs +15 -0
- package/dist/esm/fhirmapper/tokenize.mjs.map +1 -0
- package/dist/esm/fhirpath/atoms.mjs +2 -2
- package/dist/esm/fhirpath/atoms.mjs.map +1 -1
- package/dist/esm/fhirpath/functions.mjs +2 -2
- package/dist/esm/fhirpath/functions.mjs.map +1 -1
- package/dist/esm/fhirpath/utils.mjs +4 -4
- package/dist/esm/fhirpath/utils.mjs.map +1 -1
- package/dist/esm/filter/parse.mjs +51 -0
- package/dist/esm/filter/parse.mjs.map +1 -0
- package/dist/esm/filter/tokenize.mjs +18 -0
- package/dist/esm/filter/tokenize.mjs.map +1 -0
- package/dist/esm/filter/types.mjs +34 -0
- package/dist/esm/filter/types.mjs.map +1 -0
- package/dist/esm/index.min.mjs +1 -1
- package/dist/esm/index.mjs +8 -2
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/node_modules/tslib/tslib.es6.mjs.map +1 -1
- package/dist/esm/outcomes.mjs +15 -1
- package/dist/esm/outcomes.mjs.map +1 -1
- package/dist/esm/schema.mjs +397 -0
- package/dist/esm/schema.mjs.map +1 -0
- package/dist/esm/search/details.mjs +1 -1
- package/dist/esm/search/details.mjs.map +1 -1
- package/dist/esm/types.mjs +34 -8
- package/dist/esm/types.mjs.map +1 -1
- package/dist/types/client.d.ts +20 -8
- package/dist/types/fhirlexer/tokenize.d.ts +5 -1
- package/dist/types/fhirmapper/index.d.ts +1 -0
- package/dist/types/filter/index.d.ts +2 -0
- package/dist/types/filter/parse.d.ts +7 -0
- package/dist/types/filter/tokenize.d.ts +2 -0
- package/dist/types/filter/types.d.ts +31 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/outcomes.d.ts +1 -0
- package/dist/types/schema.d.ts +120 -0
- package/dist/types/types.d.ts +19 -5
- package/package.json +1 -1
- package/tsconfig.build.json +0 -9
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.mjs","sources":["../../src/schema.ts"],"sourcesContent":["import { ElementDefinition, OperationOutcomeIssue, Resource } from '@medplum/fhirtypes';\nimport { getTypedPropertyValue, toTypedValue } from './fhirpath';\nimport { OperationOutcomeError, validationError } from './outcomes';\nimport { globalSchema, PropertyType, TypedValue } from './types';\nimport { capitalize, getExtensionValue, isEmpty, isLowerCase } from './utils';\n\n/*\n * This file provides schema validation utilities for FHIR JSON objects.\n *\n * See: [JSON Representation of Resources](https://hl7.org/fhir/json.html)\n * See: [FHIR Data Types](https://www.hl7.org/fhir/datatypes.html)\n */\n\nconst fhirTypeToJsType: Record<string, string> = {\n base64Binary: 'string',\n boolean: 'boolean',\n canonical: 'string',\n code: 'string',\n date: 'string',\n dateTime: 'string',\n decimal: 'number',\n id: 'string',\n instant: 'string',\n integer: 'number',\n markdown: 'string',\n oid: 'string',\n positiveInt: 'number',\n string: 'string',\n time: 'string',\n unsignedInt: 'number',\n uri: 'string',\n url: 'string',\n uuid: 'string',\n xhtml: 'string',\n 'http://hl7.org/fhirpath/System.String': 'string',\n};\n\nconst baseResourceProperties = new Set<string>([\n // Resource\n 'resourceType',\n 'id',\n 'meta',\n 'implicitRules',\n 'language',\n\n // DomainResource\n 'text',\n 'contained',\n 'extension',\n 'modifierExtension',\n]);\n\n/**\n * Returns true if the given string is a valid FHIR resource type.\n *\n * ```ts\n * isResourceType('Patient'); // true\n * isResourceType('XYZ'); // false\n * ```\n *\n * Note that this depends on globalSchema, which is populated by the StructureDefinition loader.\n *\n * In a server context, you can load all schema definitions:\n *\n * ```ts\n * import { indexStructureDefinitionBundle } from '@medplum/core';\n * import { readJson } from '@medplum/definitions';\n * import { Bundle } from '@medplum/fhirtypes';\n *\n * indexStructureDefinitionBundle(readJson('fhir/r4/profiles-resources.json') as Bundle);\n * ```\n *\n * In a client context, you can load the schema definitions using MedplumClient:\n *\n * ```ts\n * import { MedplumClient } from '@medplum/core';\n *\n * const medplum = new MedplumClient();\n * await medplum.requestSchema('Patient');\n * ```\n *\n * @param resourceType The candidate resource type string.\n * @returns True if the resource type is a valid FHIR resource type.\n */\nexport function isResourceType(resourceType: string): boolean {\n const typeSchema = globalSchema.types[resourceType];\n return (\n typeSchema &&\n typeSchema.structureDefinition.id === resourceType &&\n typeSchema.structureDefinition.kind === 'resource'\n );\n}\n\n/**\n * Validates that the given string is a valid FHIR resource type.\n * On success, silently returns void.\n * On failure, throws an OperationOutcomeError.\n *\n * ```ts\n * validateResourceType('Patient'); // nothing\n * validateResourceType('XYZ'); // throws OperationOutcomeError\n * ```\n *\n * Note that this depends on globalSchema, which is populated by the StructureDefinition loader.\n *\n * In a server context, you can load all schema definitions:\n *\n * ```ts\n * import { indexStructureDefinitionBundle } from '@medplum/core';\n * import { readJson } from '@medplum/definitions';\n * import { Bundle } from '@medplum/fhirtypes';\n *\n * indexStructureDefinitionBundle(readJson('fhir/r4/profiles-resources.json') as Bundle);\n * ```\n *\n * In a client context, you can load the schema definitions using MedplumClient:\n *\n * ```ts\n * import { MedplumClient } from '@medplum/core';\n *\n * const medplum = new MedplumClient();\n * await medplum.requestSchema('Patient');\n * ```\n *\n * @param resourceType The candidate resource type string.\n * @returns True if the resource type is a valid FHIR resource type.\n */\nexport function validateResourceType(resourceType: string): void {\n if (!resourceType) {\n throw new OperationOutcomeError(validationError('Resource type is null'));\n }\n if (!isResourceType(resourceType)) {\n throw new OperationOutcomeError(validationError('Unknown resource type'));\n }\n}\n\n/**\n * Validates a candidate FHIR resource object.\n * On success, silently returns void.\n * On failure, throws an OperationOutcomeError with issues for each violation.\n *\n * ```ts\n * validateResource({ resourceType: 'Patient' }); // nothing\n * validateResource({ resourceType: 'XYZ' }); // throws OperationOutcomeError\n * ```\n *\n * Note that this depends on globalSchema, which is populated by the StructureDefinition loader.\n *\n * In a server context, you can load all schema definitions:\n *\n * ```ts\n * import { indexStructureDefinitionBundle } from '@medplum/core';\n * import { readJson } from '@medplum/definitions';\n * import { Bundle } from '@medplum/fhirtypes';\n *\n * indexStructureDefinitionBundle(readJson('fhir/r4/profiles-resources.json') as Bundle);\n * ```\n *\n * In a client context, you can load the schema definitions using MedplumClient:\n *\n * ```ts\n * import { MedplumClient } from '@medplum/core';\n *\n * const medplum = new MedplumClient();\n * await medplum.requestSchema('Patient');\n * ```\n *\n * @param resourceType The candidate resource type string.\n * @returns True if the resource type is a valid FHIR resource type.\n */\nexport function validateResource<T extends Resource>(resource: T): void {\n new FhirSchemaValidator(resource).validate();\n}\n\nexport class FhirSchemaValidator<T extends Resource> {\n readonly #issues: OperationOutcomeIssue[];\n readonly #root: T;\n\n constructor(root: T) {\n this.#issues = [];\n this.#root = root;\n }\n\n validate(): void {\n const resource = this.#root;\n if (!resource) {\n throw new OperationOutcomeError(validationError('Resource is null'));\n }\n\n const resourceType = resource.resourceType;\n if (!resourceType) {\n throw new OperationOutcomeError(validationError('Missing resource type'));\n }\n\n // Check for \"null\" once for the entire object hierarchy\n checkForNull(resource, '', this.#issues);\n\n this.#validateObject(toTypedValue(resource), resourceType);\n\n if (this.#issues.length > 0) {\n throw new OperationOutcomeError({\n resourceType: 'OperationOutcome',\n issue: this.#issues,\n });\n }\n }\n\n #validateObject(typedValue: TypedValue, path: string): void {\n const definition = globalSchema.types[typedValue.type];\n if (!definition) {\n throw new OperationOutcomeError(validationError('Unknown type: ' + typedValue.type));\n }\n\n const propertyDefinitions = definition.properties;\n this.#checkProperties(path, propertyDefinitions, typedValue);\n this.#checkAdditionalProperties(path, typedValue, propertyDefinitions);\n }\n\n #checkProperties(path: string, propertyDefinitions: Record<string, ElementDefinition>, typedValue: TypedValue): void {\n for (const [key, elementDefinition] of Object.entries(propertyDefinitions)) {\n this.#checkProperty(path + '.' + key, elementDefinition, typedValue);\n }\n }\n\n #checkProperty(path: string, elementDefinition: ElementDefinition, typedValue: TypedValue): void {\n const propertyName = path.split('.').pop() as string;\n const value = getTypedPropertyValue(typedValue, propertyName);\n\n if (isEmpty(value)) {\n if (elementDefinition.min !== undefined && elementDefinition.min > 0) {\n this.#issues.push(createStructureIssue(path, 'Missing required property'));\n }\n return;\n }\n\n if (elementDefinition.max === '*') {\n if (!Array.isArray(value)) {\n this.#issues.push(createStructureIssue(path, 'Expected array for property'));\n return;\n }\n for (const item of value) {\n this.#checkPropertyValue(path, elementDefinition, item);\n }\n } else {\n this.#checkPropertyValue(path, elementDefinition, value as TypedValue);\n }\n }\n\n #checkPropertyValue(path: string, elementDefinition: ElementDefinition, typedValue: TypedValue): void {\n if (typedValue.value === null) {\n // Null handled separately\n return;\n }\n\n if (isLowerCase(typedValue.type.charAt(0))) {\n this.#validatePrimitiveType(elementDefinition, typedValue);\n } else {\n this.#validateObject(typedValue, path);\n }\n }\n\n #validatePrimitiveType(elementDefinition: ElementDefinition, typedValue: TypedValue): void {\n const { type, value } = typedValue;\n\n if (value === null) {\n // Null handled separately, so this code should never be reached\n // Leaving this check in place for now, in case we change the null handling\n return;\n }\n\n // First, make sure the value is the correct JS type\n const expectedType = fhirTypeToJsType[typedValue.type];\n if (typeof value !== expectedType) {\n this.#createIssue(elementDefinition, 'Invalid type for ' + type);\n return;\n }\n\n // Then, perform additional checks for specialty types\n if (expectedType === 'string') {\n this.#validateString(elementDefinition, type as PropertyType, value as string);\n } else if (expectedType === 'number') {\n this.#validateNumber(elementDefinition, type as PropertyType, value as number);\n }\n }\n\n #validateString(elementDefinition: ElementDefinition, type: PropertyType, value: string): void {\n if (!value.trim()) {\n this.#createIssue(elementDefinition, 'Invalid empty string');\n return;\n }\n\n // Try to get the regex\n const valueDefinition = globalSchema.types[type]?.properties?.['value'];\n if (valueDefinition?.type) {\n const regex = getExtensionValue(valueDefinition.type[0], 'http://hl7.org/fhir/StructureDefinition/regex');\n if (regex) {\n if (!value.match(new RegExp(regex))) {\n this.#createIssue(elementDefinition, 'Invalid ' + type + ' format');\n }\n }\n }\n }\n\n #validateNumber(elementDefinition: ElementDefinition, type: PropertyType, value: number): void {\n if (isNaN(value) || !isFinite(value)) {\n this.#createIssue(elementDefinition, 'Invalid ' + type + ' value');\n return;\n }\n\n if (isIntegerType(type) && !Number.isInteger(value)) {\n this.#createIssue(elementDefinition, 'Number is not an integer');\n }\n\n if (type === PropertyType.positiveInt && value <= 0) {\n this.#createIssue(elementDefinition, 'Number is less than or equal to zero');\n }\n\n if (type === PropertyType.unsignedInt && value < 0) {\n this.#createIssue(elementDefinition, 'Number is negative');\n }\n }\n\n #checkAdditionalProperties(\n path: string,\n typedValue: TypedValue,\n propertyDefinitions: Record<string, ElementDefinition>\n ): void {\n const object = typedValue.value as Record<string, unknown>;\n for (const key of Object.keys(object)) {\n this.#checkAdditionalProperty(path, key, typedValue, propertyDefinitions);\n }\n }\n\n /**\n * Checks if the given property is allowed on the given object.\n * @param path The path of the current object.\n * @param key The key of a property to check.\n * @param typedValue The current object.\n * @param propertyDefinitions The property definitions of the current object.\n */\n #checkAdditionalProperty(\n path: string,\n key: string,\n typedValue: TypedValue,\n propertyDefinitions: Record<string, ElementDefinition>\n ): void {\n if (\n !baseResourceProperties.has(key) &&\n !(key in propertyDefinitions) &&\n !isChoiceOfType(key, typedValue, propertyDefinitions) &&\n !this.#checkPrimitiveElement(path, key, typedValue)\n ) {\n const expression = `${path}.${key}`;\n this.#issues.push(createStructureIssue(expression, `Invalid additional property \"${expression}\"`));\n }\n }\n\n /**\n * Checks the element for a primitive.\n *\n * FHIR elements with primitive data types are represented in two parts:\n * 1) A JSON property with the name of the element, which has a JSON type of number, boolean, or string\n * 2) a JSON property with _ prepended to the name of the element, which, if present, contains the value's id and/or extensions\n *\n * See: https://hl7.org/fhir/json.html#primitive\n *\n * @param path The path to the property\n * @param key\n * @param typedValue\n */\n #checkPrimitiveElement(path: string, key: string, typedValue: TypedValue): boolean {\n // Primitive element starts with underscore\n if (!key.startsWith('_')) {\n return false;\n }\n\n // Validate the non-underscore property exists\n const primitiveKey = key.slice(1);\n if (!(primitiveKey in typedValue.value)) {\n return false;\n }\n\n // Then validate the element\n this.#validateObject({ type: 'Element', value: typedValue.value[key] }, path);\n return true;\n }\n\n #createIssue(elementDefinition: ElementDefinition, message: string): void {\n this.#issues.push(createStructureIssue(elementDefinition.path as string, message));\n }\n}\n\nfunction isIntegerType(propertyType: PropertyType): boolean {\n return (\n propertyType === PropertyType.integer ||\n propertyType === PropertyType.positiveInt ||\n propertyType === PropertyType.unsignedInt\n );\n}\n\nfunction isChoiceOfType(\n key: string,\n typedValue: TypedValue,\n propertyDefinitions: Record<string, ElementDefinition>\n): boolean {\n for (const propertyName of Object.keys(propertyDefinitions)) {\n if (!propertyName.endsWith('[x]')) {\n continue;\n }\n const basePropertyName = propertyName.replace('[x]', '');\n if (!key.startsWith(basePropertyName)) {\n continue;\n }\n let typedPropertyValue = getTypedPropertyValue(typedValue, propertyName);\n if (!typedPropertyValue) {\n continue;\n }\n if (Array.isArray(typedPropertyValue)) {\n // At present, there are no choice types that are arrays in the FHIR spec\n // Leaving this here to make TypeScript happy, and in case that changes\n typedPropertyValue = typedPropertyValue[0];\n }\n if (typedPropertyValue && key === basePropertyName + capitalize(typedPropertyValue.type)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Recursively checks for null values in an object.\n *\n * Note that \"null\" is a special value in JSON that is not allowed in FHIR.\n *\n * @param value Input value of any type.\n * @param path Path string to the value for OperationOutcome.\n * @param issues Output list of issues.\n */\nexport function checkForNull(value: unknown, path: string, issues: OperationOutcomeIssue[]): void {\n if (value === null) {\n issues.push(createStructureIssue(path, 'Invalid null value'));\n } else if (Array.isArray(value)) {\n checkArrayForNull(value, path, issues);\n } else if (typeof value === 'object') {\n checkObjectForNull(value as Record<string, unknown>, path, issues);\n }\n}\n\nfunction checkArrayForNull(array: unknown[], path: string, issues: OperationOutcomeIssue[]): void {\n for (let i = 0; i < array.length; i++) {\n if (array[i] === undefined) {\n issues.push(createStructureIssue(`${path}[${i}]`, 'Invalid undefined value'));\n } else {\n checkForNull(array[i], `${path}[${i}]`, issues);\n }\n }\n}\n\nfunction checkObjectForNull(obj: Record<string, unknown>, path: string, issues: OperationOutcomeIssue[]): void {\n for (const [key, value] of Object.entries(obj)) {\n checkForNull(value, `${path}${path ? '.' : ''}${key}`, issues);\n }\n}\n\nexport function createStructureIssue(expression: string, details: string): OperationOutcomeIssue {\n return {\n severity: 'error',\n code: 'structure',\n details: {\n text: details,\n },\n expression: [expression],\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -146,7 +146,7 @@ function simplifyExpression(input) {
|
|
|
146
146
|
if (result.includes('[0]')) {
|
|
147
147
|
result = result.replaceAll('[0]', '');
|
|
148
148
|
}
|
|
149
|
-
const stopStrings = [' != ', ' as ', '.as(', '.exists(', '.where('];
|
|
149
|
+
const stopStrings = [' != ', ' as ', '.as(', '.exists(', '.resolve(', '.where('];
|
|
150
150
|
for (const stopString of stopStrings) {
|
|
151
151
|
if (result.includes(stopString)) {
|
|
152
152
|
result = result.substring(0, result.indexOf(stopString));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"details.mjs","sources":["../../../src/search/details.ts"],"sourcesContent":["import { ElementDefinition, SearchParameter } from '@medplum/fhirtypes';\nimport { buildTypeName, getElementDefinition, globalSchema, PropertyType } from '../types';\nimport { capitalize } from '../utils';\n\nexport enum SearchParameterType {\n BOOLEAN = 'BOOLEAN',\n NUMBER = 'NUMBER',\n QUANTITY = 'QUANTITY',\n TEXT = 'TEXT',\n REFERENCE = 'REFERENCE',\n DATE = 'DATE',\n DATETIME = 'DATETIME',\n PERIOD = 'PERIOD',\n}\n\nexport interface SearchParameterDetails {\n readonly columnName: string;\n readonly type: SearchParameterType;\n readonly elementDefinition?: ElementDefinition;\n readonly array?: boolean;\n}\n\n/**\n * Returns the type details of a SearchParameter.\n *\n * The SearchParameter resource has a \"type\" parameter, but that is missing some critical information.\n *\n * For example:\n * 1) The \"date\" type includes \"date\", \"datetime\", and \"period\".\n * 2) The \"token\" type includes enums and booleans.\n * 3) Arrays/multiple values are not reflected at all.\n *\n * @param resourceType The root resource type.\n * @param searchParam The search parameter.\n * @returns The search parameter type details.\n */\nexport function getSearchParameterDetails(resourceType: string, searchParam: SearchParameter): SearchParameterDetails {\n let result: SearchParameterDetails | undefined =\n globalSchema.types[resourceType]?.searchParamsDetails?.[searchParam.code as string];\n if (!result) {\n result = buildSearchParamterDetails(resourceType, searchParam);\n }\n return result;\n}\n\nfunction setSearchParamterDetails(resourceType: string, code: string, details: SearchParameterDetails): void {\n const typeSchema = globalSchema.types[resourceType];\n if (!typeSchema.searchParamsDetails) {\n typeSchema.searchParamsDetails = {};\n }\n typeSchema.searchParamsDetails[code] = details;\n}\n\nfunction buildSearchParamterDetails(resourceType: string, searchParam: SearchParameter): SearchParameterDetails {\n const code = searchParam.code as string;\n const columnName = convertCodeToColumnName(code);\n const expression = getExpressionForResourceType(resourceType, searchParam.expression as string)?.split('.');\n if (!expression) {\n // This happens on compound types\n // In the future, explore returning multiple column definitions\n return { columnName, type: SearchParameterType.TEXT };\n }\n\n const defaultType = getSearchParameterType(searchParam);\n let baseType = resourceType;\n let elementDefinition = undefined;\n let propertyType = undefined;\n let array = false;\n\n for (let i = 1; i < expression.length; i++) {\n const propertyName = expression[i];\n elementDefinition = getElementDefinition(baseType, propertyName);\n if (!elementDefinition) {\n throw new Error(`Element definition not found for ${resourceType} ${searchParam.code}`);\n }\n\n if (elementDefinition.max === '*') {\n array = true;\n }\n\n propertyType = elementDefinition.type?.[0].code;\n if (!propertyType) {\n // This happens when one of parent properties uses contentReference\n // In the future, explore following the reference\n return { columnName, type: defaultType, array };\n }\n\n if (i < expression.length - 1) {\n if (isBackboneElement(propertyType)) {\n baseType = buildTypeName(elementDefinition.path?.split('.') as string[]);\n } else {\n baseType = propertyType;\n }\n }\n }\n\n const type = getSearchParameterType(searchParam, propertyType as PropertyType);\n const result = { columnName, type, elementDefinition, array };\n setSearchParamterDetails(resourceType, code, result);\n return result;\n}\n\nfunction isBackboneElement(propertyType: string): boolean {\n return propertyType === 'Element' || propertyType === 'BackboneElement';\n}\n\n/**\n * Converts a hyphen-delimited code to camelCase string.\n * @param code The search parameter code.\n * @returns The SQL column name.\n */\nfunction convertCodeToColumnName(code: string): string {\n return code.split('-').reduce((result, word, index) => result + (index ? capitalize(word) : word), '');\n}\n\nfunction getSearchParameterType(searchParam: SearchParameter, propertyType?: PropertyType): SearchParameterType {\n let type = SearchParameterType.TEXT;\n switch (searchParam.type) {\n case 'date':\n if (propertyType === PropertyType.dateTime || propertyType === PropertyType.instant) {\n type = SearchParameterType.DATETIME;\n } else {\n type = SearchParameterType.DATE;\n }\n break;\n case 'number':\n type = SearchParameterType.NUMBER;\n break;\n case 'quantity':\n type = SearchParameterType.QUANTITY;\n break;\n case 'reference':\n type = SearchParameterType.REFERENCE;\n break;\n case 'token':\n if (propertyType === 'boolean') {\n type = SearchParameterType.BOOLEAN;\n }\n break;\n }\n return type;\n}\n\nexport function getExpressionForResourceType(resourceType: string, expression: string): string | undefined {\n const expressions = expression.split(' | ');\n for (const e of expressions) {\n if (isIgnoredExpression(e)) {\n continue;\n }\n const simplified = simplifyExpression(e);\n if (simplified.startsWith(resourceType + '.')) {\n return simplified;\n }\n }\n return undefined;\n}\n\nfunction isIgnoredExpression(input: string): boolean {\n return input.includes(' as Period') || input.includes(' as SampledDate');\n}\n\nfunction simplifyExpression(input: string): string {\n let result = input.trim();\n\n if (result.startsWith('(') && result.endsWith(')')) {\n result = result.substring(1, result.length - 1);\n }\n\n if (result.includes('[0]')) {\n result = result.replaceAll('[0]', '');\n }\n\n const stopStrings = [' != ', ' as ', '.as(', '.exists(', '.where('];\n for (const stopString of stopStrings) {\n if (result.includes(stopString)) {\n result = result.substring(0, result.indexOf(stopString));\n }\n }\n\n return result;\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"details.mjs","sources":["../../../src/search/details.ts"],"sourcesContent":["import { ElementDefinition, SearchParameter } from '@medplum/fhirtypes';\nimport { buildTypeName, getElementDefinition, globalSchema, PropertyType } from '../types';\nimport { capitalize } from '../utils';\n\nexport enum SearchParameterType {\n BOOLEAN = 'BOOLEAN',\n NUMBER = 'NUMBER',\n QUANTITY = 'QUANTITY',\n TEXT = 'TEXT',\n REFERENCE = 'REFERENCE',\n DATE = 'DATE',\n DATETIME = 'DATETIME',\n PERIOD = 'PERIOD',\n}\n\nexport interface SearchParameterDetails {\n readonly columnName: string;\n readonly type: SearchParameterType;\n readonly elementDefinition?: ElementDefinition;\n readonly array?: boolean;\n}\n\n/**\n * Returns the type details of a SearchParameter.\n *\n * The SearchParameter resource has a \"type\" parameter, but that is missing some critical information.\n *\n * For example:\n * 1) The \"date\" type includes \"date\", \"datetime\", and \"period\".\n * 2) The \"token\" type includes enums and booleans.\n * 3) Arrays/multiple values are not reflected at all.\n *\n * @param resourceType The root resource type.\n * @param searchParam The search parameter.\n * @returns The search parameter type details.\n */\nexport function getSearchParameterDetails(resourceType: string, searchParam: SearchParameter): SearchParameterDetails {\n let result: SearchParameterDetails | undefined =\n globalSchema.types[resourceType]?.searchParamsDetails?.[searchParam.code as string];\n if (!result) {\n result = buildSearchParamterDetails(resourceType, searchParam);\n }\n return result;\n}\n\nfunction setSearchParamterDetails(resourceType: string, code: string, details: SearchParameterDetails): void {\n const typeSchema = globalSchema.types[resourceType];\n if (!typeSchema.searchParamsDetails) {\n typeSchema.searchParamsDetails = {};\n }\n typeSchema.searchParamsDetails[code] = details;\n}\n\nfunction buildSearchParamterDetails(resourceType: string, searchParam: SearchParameter): SearchParameterDetails {\n const code = searchParam.code as string;\n const columnName = convertCodeToColumnName(code);\n const expression = getExpressionForResourceType(resourceType, searchParam.expression as string)?.split('.');\n if (!expression) {\n // This happens on compound types\n // In the future, explore returning multiple column definitions\n return { columnName, type: SearchParameterType.TEXT };\n }\n\n const defaultType = getSearchParameterType(searchParam);\n let baseType = resourceType;\n let elementDefinition = undefined;\n let propertyType = undefined;\n let array = false;\n\n for (let i = 1; i < expression.length; i++) {\n const propertyName = expression[i];\n elementDefinition = getElementDefinition(baseType, propertyName);\n if (!elementDefinition) {\n throw new Error(`Element definition not found for ${resourceType} ${searchParam.code}`);\n }\n\n if (elementDefinition.max === '*') {\n array = true;\n }\n\n propertyType = elementDefinition.type?.[0].code;\n if (!propertyType) {\n // This happens when one of parent properties uses contentReference\n // In the future, explore following the reference\n return { columnName, type: defaultType, array };\n }\n\n if (i < expression.length - 1) {\n if (isBackboneElement(propertyType)) {\n baseType = buildTypeName(elementDefinition.path?.split('.') as string[]);\n } else {\n baseType = propertyType;\n }\n }\n }\n\n const type = getSearchParameterType(searchParam, propertyType as PropertyType);\n const result = { columnName, type, elementDefinition, array };\n setSearchParamterDetails(resourceType, code, result);\n return result;\n}\n\nfunction isBackboneElement(propertyType: string): boolean {\n return propertyType === 'Element' || propertyType === 'BackboneElement';\n}\n\n/**\n * Converts a hyphen-delimited code to camelCase string.\n * @param code The search parameter code.\n * @returns The SQL column name.\n */\nfunction convertCodeToColumnName(code: string): string {\n return code.split('-').reduce((result, word, index) => result + (index ? capitalize(word) : word), '');\n}\n\nfunction getSearchParameterType(searchParam: SearchParameter, propertyType?: PropertyType): SearchParameterType {\n let type = SearchParameterType.TEXT;\n switch (searchParam.type) {\n case 'date':\n if (propertyType === PropertyType.dateTime || propertyType === PropertyType.instant) {\n type = SearchParameterType.DATETIME;\n } else {\n type = SearchParameterType.DATE;\n }\n break;\n case 'number':\n type = SearchParameterType.NUMBER;\n break;\n case 'quantity':\n type = SearchParameterType.QUANTITY;\n break;\n case 'reference':\n type = SearchParameterType.REFERENCE;\n break;\n case 'token':\n if (propertyType === 'boolean') {\n type = SearchParameterType.BOOLEAN;\n }\n break;\n }\n return type;\n}\n\nexport function getExpressionForResourceType(resourceType: string, expression: string): string | undefined {\n const expressions = expression.split(' | ');\n for (const e of expressions) {\n if (isIgnoredExpression(e)) {\n continue;\n }\n const simplified = simplifyExpression(e);\n if (simplified.startsWith(resourceType + '.')) {\n return simplified;\n }\n }\n return undefined;\n}\n\nfunction isIgnoredExpression(input: string): boolean {\n return input.includes(' as Period') || input.includes(' as SampledDate');\n}\n\nfunction simplifyExpression(input: string): string {\n let result = input.trim();\n\n if (result.startsWith('(') && result.endsWith(')')) {\n result = result.substring(1, result.length - 1);\n }\n\n if (result.includes('[0]')) {\n result = result.replaceAll('[0]', '');\n }\n\n const stopStrings = [' != ', ' as ', '.as(', '.exists(', '.resolve(', '.where('];\n for (const stopString of stopStrings) {\n if (result.includes(stopString)) {\n result = result.substring(0, result.indexOf(stopString));\n }\n }\n\n return result;\n}\n"],"names":[],"mappings":";;;IAIY,oBASX;AATD,CAAA,UAAY,mBAAmB,EAAA;AAC7B,IAAA,mBAAA,CAAA,SAAA,CAAA,GAAA,SAAmB,CAAA;AACnB,IAAA,mBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB,CAAA;AACjB,IAAA,mBAAA,CAAA,UAAA,CAAA,GAAA,UAAqB,CAAA;AACrB,IAAA,mBAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACb,IAAA,mBAAA,CAAA,WAAA,CAAA,GAAA,WAAuB,CAAA;AACvB,IAAA,mBAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACb,IAAA,mBAAA,CAAA,UAAA,CAAA,GAAA,UAAqB,CAAA;AACrB,IAAA,mBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB,CAAA;AACnB,CAAC,EATW,mBAAmB,KAAnB,mBAAmB,GAS9B,EAAA,CAAA,CAAA,CAAA;AASD;;;;;;;;;;;;;AAaG;AACa,SAAA,yBAAyB,CAAC,YAAoB,EAAE,WAA4B,EAAA;AAC1F,IAAA,IAAI,MAAM,GACR,YAAY,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,mBAAmB,GAAG,WAAW,CAAC,IAAc,CAAC,CAAC;IACtF,IAAI,CAAC,MAAM,EAAE;AACX,QAAA,MAAM,GAAG,0BAA0B,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;AAChE,KAAA;AACD,IAAA,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,wBAAwB,CAAC,YAAoB,EAAE,IAAY,EAAE,OAA+B,EAAA;IACnG,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;AACpD,IAAA,IAAI,CAAC,UAAU,CAAC,mBAAmB,EAAE;AACnC,QAAA,UAAU,CAAC,mBAAmB,GAAG,EAAE,CAAC;AACrC,KAAA;AACD,IAAA,UAAU,CAAC,mBAAmB,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;AACjD,CAAC;AAED,SAAS,0BAA0B,CAAC,YAAoB,EAAE,WAA4B,EAAA;AACpF,IAAA,MAAM,IAAI,GAAG,WAAW,CAAC,IAAc,CAAC;AACxC,IAAA,MAAM,UAAU,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;AACjD,IAAA,MAAM,UAAU,GAAG,4BAA4B,CAAC,YAAY,EAAE,WAAW,CAAC,UAAoB,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAC5G,IAAI,CAAC,UAAU,EAAE;;;QAGf,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,mBAAmB,CAAC,IAAI,EAAE,CAAC;AACvD,KAAA;AAED,IAAA,MAAM,WAAW,GAAG,sBAAsB,CAAC,WAAW,CAAC,CAAC;IACxD,IAAI,QAAQ,GAAG,YAAY,CAAC;IAC5B,IAAI,iBAAiB,GAAG,SAAS,CAAC;IAClC,IAAI,YAAY,GAAG,SAAS,CAAC;IAC7B,IAAI,KAAK,GAAG,KAAK,CAAC;AAElB,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AAC1C,QAAA,MAAM,YAAY,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;AACnC,QAAA,iBAAiB,GAAG,oBAAoB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QACjE,IAAI,CAAC,iBAAiB,EAAE;YACtB,MAAM,IAAI,KAAK,CAAC,CAAoC,iCAAA,EAAA,YAAY,CAAI,CAAA,EAAA,WAAW,CAAC,IAAI,CAAE,CAAA,CAAC,CAAC;AACzF,SAAA;AAED,QAAA,IAAI,iBAAiB,CAAC,GAAG,KAAK,GAAG,EAAE;YACjC,KAAK,GAAG,IAAI,CAAC;AACd,SAAA;QAED,YAAY,GAAG,iBAAiB,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;QAChD,IAAI,CAAC,YAAY,EAAE;;;YAGjB,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;AACjD,SAAA;AAED,QAAA,IAAI,CAAC,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;AAC7B,YAAA,IAAI,iBAAiB,CAAC,YAAY,CAAC,EAAE;AACnC,gBAAA,QAAQ,GAAG,aAAa,CAAC,iBAAiB,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAa,CAAC,CAAC;AAC1E,aAAA;AAAM,iBAAA;gBACL,QAAQ,GAAG,YAAY,CAAC;AACzB,aAAA;AACF,SAAA;AACF,KAAA;IAED,MAAM,IAAI,GAAG,sBAAsB,CAAC,WAAW,EAAE,YAA4B,CAAC,CAAC;IAC/E,MAAM,MAAM,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC;AAC9D,IAAA,wBAAwB,CAAC,YAAY,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AACrD,IAAA,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,iBAAiB,CAAC,YAAoB,EAAA;AAC7C,IAAA,OAAO,YAAY,KAAK,SAAS,IAAI,YAAY,KAAK,iBAAiB,CAAC;AAC1E,CAAC;AAED;;;;AAIG;AACH,SAAS,uBAAuB,CAAC,IAAY,EAAA;AAC3C,IAAA,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,KAAK,MAAM,IAAI,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;AACzG,CAAC;AAED,SAAS,sBAAsB,CAAC,WAA4B,EAAE,YAA2B,EAAA;AACvF,IAAA,IAAI,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC;IACpC,QAAQ,WAAW,CAAC,IAAI;AACtB,QAAA,KAAK,MAAM;YACT,IAAI,YAAY,KAAK,YAAY,CAAC,QAAQ,IAAI,YAAY,KAAK,YAAY,CAAC,OAAO,EAAE;AACnF,gBAAA,IAAI,GAAG,mBAAmB,CAAC,QAAQ,CAAC;AACrC,aAAA;AAAM,iBAAA;AACL,gBAAA,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC;AACjC,aAAA;YACD,MAAM;AACR,QAAA,KAAK,QAAQ;AACX,YAAA,IAAI,GAAG,mBAAmB,CAAC,MAAM,CAAC;YAClC,MAAM;AACR,QAAA,KAAK,UAAU;AACb,YAAA,IAAI,GAAG,mBAAmB,CAAC,QAAQ,CAAC;YACpC,MAAM;AACR,QAAA,KAAK,WAAW;AACd,YAAA,IAAI,GAAG,mBAAmB,CAAC,SAAS,CAAC;YACrC,MAAM;AACR,QAAA,KAAK,OAAO;YACV,IAAI,YAAY,KAAK,SAAS,EAAE;AAC9B,gBAAA,IAAI,GAAG,mBAAmB,CAAC,OAAO,CAAC;AACpC,aAAA;YACD,MAAM;AACT,KAAA;AACD,IAAA,OAAO,IAAI,CAAC;AACd,CAAC;AAEe,SAAA,4BAA4B,CAAC,YAAoB,EAAE,UAAkB,EAAA;IACnF,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAC5C,IAAA,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE;AAC3B,QAAA,IAAI,mBAAmB,CAAC,CAAC,CAAC,EAAE;YAC1B,SAAS;AACV,SAAA;AACD,QAAA,MAAM,UAAU,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;QACzC,IAAI,UAAU,CAAC,UAAU,CAAC,YAAY,GAAG,GAAG,CAAC,EAAE;AAC7C,YAAA,OAAO,UAAU,CAAC;AACnB,SAAA;AACF,KAAA;AACD,IAAA,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAa,EAAA;AACxC,IAAA,OAAO,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC;AAC3E,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAa,EAAA;AACvC,IAAA,IAAI,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;AAE1B,IAAA,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AAClD,QAAA,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACjD,KAAA;AAED,IAAA,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;QAC1B,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACvC,KAAA;AAED,IAAA,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;AACjF,IAAA,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE;AACpC,QAAA,IAAI,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE;AAC/B,YAAA,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;AAC1D,SAAA;AACF,KAAA;AAED,IAAA,OAAO,MAAM,CAAC;AAChB;;;;"}
|
package/dist/esm/types.mjs
CHANGED
|
@@ -96,7 +96,7 @@ function indexStructureDefinition(structureDefinition) {
|
|
|
96
96
|
// First pass, build types
|
|
97
97
|
elements.forEach((element) => indexType(structureDefinition, element));
|
|
98
98
|
// Second pass, build properties
|
|
99
|
-
elements.forEach((element) => indexProperty(element));
|
|
99
|
+
elements.forEach((element) => indexProperty(structureDefinition, element));
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
/**
|
|
@@ -114,6 +114,9 @@ function indexType(structureDefinition, elementDefinition) {
|
|
|
114
114
|
return;
|
|
115
115
|
}
|
|
116
116
|
const parts = path.split('.');
|
|
117
|
+
// Force the first part to be the type name
|
|
118
|
+
// This is necessary for "SimpleQuantity" and "MoneyQuantity"
|
|
119
|
+
parts[0] = structureDefinition.name;
|
|
117
120
|
const typeName = buildTypeName(parts);
|
|
118
121
|
let typeSchema = globalSchema.types[typeName];
|
|
119
122
|
if (!typeSchema) {
|
|
@@ -131,12 +134,15 @@ function indexType(structureDefinition, elementDefinition) {
|
|
|
131
134
|
* @param element The input ElementDefinition.
|
|
132
135
|
* @see {@link IndexedStructureDefinition} for more details on indexed StructureDefinitions.
|
|
133
136
|
*/
|
|
134
|
-
function indexProperty(element) {
|
|
137
|
+
function indexProperty(structureDefinition, element) {
|
|
135
138
|
const path = element.path;
|
|
136
139
|
const parts = path.split('.');
|
|
137
140
|
if (parts.length === 1) {
|
|
138
141
|
return;
|
|
139
142
|
}
|
|
143
|
+
// Force the first part to be the type name
|
|
144
|
+
// This is necessary for "SimpleQuantity" and "MoneyQuantity"
|
|
145
|
+
parts[0] = structureDefinition.name;
|
|
140
146
|
const typeName = buildTypeName(parts.slice(0, parts.length - 1));
|
|
141
147
|
const typeSchema = globalSchema.types[typeName];
|
|
142
148
|
if (!typeSchema) {
|
|
@@ -240,12 +246,16 @@ function buildTypeName(components) {
|
|
|
240
246
|
return components.map(capitalize).join('');
|
|
241
247
|
}
|
|
242
248
|
/**
|
|
243
|
-
* Returns true if the type schema is a
|
|
249
|
+
* Returns true if the type schema is a non-abstract FHIR resource.
|
|
244
250
|
* @param typeSchema The type schema to check.
|
|
245
|
-
* @returns True if the type schema is a
|
|
251
|
+
* @returns True if the type schema is a non-abstract FHIR resource.
|
|
246
252
|
*/
|
|
247
|
-
function
|
|
248
|
-
|
|
253
|
+
function isResourceTypeSchema(typeSchema) {
|
|
254
|
+
const structureDefinition = typeSchema.structureDefinition;
|
|
255
|
+
return (structureDefinition &&
|
|
256
|
+
structureDefinition.name === typeSchema.elementDefinition?.path &&
|
|
257
|
+
structureDefinition.kind === 'resource' &&
|
|
258
|
+
!structureDefinition.abstract);
|
|
249
259
|
}
|
|
250
260
|
/**
|
|
251
261
|
* Returns an array of all resource types.
|
|
@@ -255,7 +265,7 @@ function isResourceType(typeSchema) {
|
|
|
255
265
|
function getResourceTypes() {
|
|
256
266
|
const result = [];
|
|
257
267
|
for (const [resourceType, typeSchema] of Object.entries(globalSchema.types)) {
|
|
258
|
-
if (
|
|
268
|
+
if (isResourceTypeSchema(typeSchema)) {
|
|
259
269
|
result.push(resourceType);
|
|
260
270
|
}
|
|
261
271
|
}
|
|
@@ -334,10 +344,26 @@ function getElementDefinition(typeName, propertyName) {
|
|
|
334
344
|
}
|
|
335
345
|
return property;
|
|
336
346
|
}
|
|
347
|
+
/**
|
|
348
|
+
* Typeguard to validate that an object is a FHIR resource
|
|
349
|
+
* @param value The object to check
|
|
350
|
+
* @returns True if the input is of type 'object' and contains property 'resourceType'
|
|
351
|
+
*/
|
|
352
|
+
function isResource(value) {
|
|
353
|
+
return !!(value && typeof value === 'object' && 'resourceType' in value);
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Typeguard to validate that an object is a FHIR resource
|
|
357
|
+
* @param value The object to check
|
|
358
|
+
* @returns True if the input is of type 'object' and contains property 'reference'
|
|
359
|
+
*/
|
|
360
|
+
function isReference(value) {
|
|
361
|
+
return !!(value && typeof value === 'object' && 'reference' in value);
|
|
362
|
+
}
|
|
337
363
|
/**
|
|
338
364
|
* Global schema singleton.
|
|
339
365
|
*/
|
|
340
366
|
const globalSchema = baseSchema;
|
|
341
367
|
|
|
342
|
-
export { PropertyType, buildTypeName, getElementDefinition, getElementDefinitionTypeName, getPropertyDisplayName, getResourceTypeSchema, getResourceTypes, getSearchParameters, globalSchema, indexSearchParameter, indexSearchParameterBundle, indexStructureDefinition, indexStructureDefinitionBundle,
|
|
368
|
+
export { PropertyType, buildTypeName, getElementDefinition, getElementDefinitionTypeName, getPropertyDisplayName, getResourceTypeSchema, getResourceTypes, getSearchParameters, globalSchema, indexSearchParameter, indexSearchParameterBundle, indexStructureDefinition, indexStructureDefinitionBundle, isReference, isResource, isResourceTypeSchema };
|
|
343
369
|
//# sourceMappingURL=types.mjs.map
|
package/dist/esm/types.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.mjs","sources":["../../src/types.ts"],"sourcesContent":["import {\n Bundle,\n BundleEntry,\n ElementDefinition,\n Resource,\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(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 const parts = path.split('.');\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 element The input ElementDefinition.\n * @see {@link IndexedStructureDefinition} for more details on indexed StructureDefinitions.\n */\nfunction indexProperty(element: ElementDefinition): void {\n const path = element.path as string;\n const parts = path.split('.');\n if (parts.length === 1) {\n return;\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 DomainResource.\n * @param typeSchema The type schema to check.\n * @returns True if the type schema is a DomainResource.\n */\nexport function isResourceType(typeSchema: TypeSchema): boolean {\n return typeSchema.structureDefinition?.baseDefinition === 'http://hl7.org/fhir/StructureDefinition/DomainResource';\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(): string[] {\n const result: string[] = [];\n for (const [resourceType, typeSchema] of Object.entries(globalSchema.types)) {\n if (isResourceType(typeSchema)) {\n result.push(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', '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 * 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 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', '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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"}
|
package/dist/types/client.d.ts
CHANGED
|
@@ -139,6 +139,17 @@ export interface MedplumClientOptions {
|
|
|
139
139
|
export interface FetchLike {
|
|
140
140
|
(url: string, options?: any): Promise<any>;
|
|
141
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* QueryTypes defines the different ways to specify FHIR search parameters.
|
|
144
|
+
*
|
|
145
|
+
* Can be any valid input to the URLSearchParams() constructor.
|
|
146
|
+
*
|
|
147
|
+
* TypeScript definitions for URLSearchParams do not match runtime behavior.
|
|
148
|
+
* The official spec only accepts string values.
|
|
149
|
+
* Web browsers and Node.js automatically coerce values to strings.
|
|
150
|
+
* See: https://github.com/microsoft/TypeScript/issues/32951
|
|
151
|
+
*/
|
|
152
|
+
export type QueryTypes = URLSearchParams | string[][] | Record<string, any> | string | undefined;
|
|
142
153
|
export interface CreatePdfFunction {
|
|
143
154
|
(docDefinition: TDocumentDefinitions, tableLayouts?: {
|
|
144
155
|
[name: string]: CustomTableLayout;
|
|
@@ -542,10 +553,11 @@ export declare class MedplumClient extends EventTarget {
|
|
|
542
553
|
* Builds a FHIR search URL from a search query or structured query object.
|
|
543
554
|
* @category HTTP
|
|
544
555
|
* @category Search
|
|
545
|
-
* @param
|
|
556
|
+
* @param resourceType The FHIR resource type.
|
|
557
|
+
* @param query The FHIR search query or structured query object. Can be any valid input to the URLSearchParams() constructor.
|
|
546
558
|
* @returns The well-formed FHIR URL.
|
|
547
559
|
*/
|
|
548
|
-
fhirSearchUrl(resourceType: ResourceType, query:
|
|
560
|
+
fhirSearchUrl(resourceType: ResourceType, query: QueryTypes): URL;
|
|
549
561
|
/**
|
|
550
562
|
* Sends a FHIR search request.
|
|
551
563
|
*
|
|
@@ -590,11 +602,11 @@ export declare class MedplumClient extends EventTarget {
|
|
|
590
602
|
*
|
|
591
603
|
* @category Search
|
|
592
604
|
* @param resourceType The FHIR resource type.
|
|
593
|
-
* @param query
|
|
605
|
+
* @param query Optional FHIR search query or structured query object. Can be any valid input to the URLSearchParams() constructor.
|
|
594
606
|
* @param options Optional fetch options.
|
|
595
607
|
* @returns Promise to the search result bundle.
|
|
596
608
|
*/
|
|
597
|
-
search<K extends ResourceType>(resourceType: K, query?:
|
|
609
|
+
search<K extends ResourceType>(resourceType: K, query?: QueryTypes, options?: RequestInit): ReadablePromise<Bundle<ExtractResource<K>>>;
|
|
598
610
|
/**
|
|
599
611
|
* Sends a FHIR search request for a single resource.
|
|
600
612
|
*
|
|
@@ -613,11 +625,11 @@ export declare class MedplumClient extends EventTarget {
|
|
|
613
625
|
*
|
|
614
626
|
* @category Search
|
|
615
627
|
* @param resourceType The FHIR resource type.
|
|
616
|
-
* @param query
|
|
628
|
+
* @param query Optional FHIR search query or structured query object. Can be any valid input to the URLSearchParams() constructor.
|
|
617
629
|
* @param options Optional fetch options.
|
|
618
630
|
* @returns Promise to the search result bundle.
|
|
619
631
|
*/
|
|
620
|
-
searchOne<K extends ResourceType>(resourceType: K, query?:
|
|
632
|
+
searchOne<K extends ResourceType>(resourceType: K, query?: QueryTypes, options?: RequestInit): ReadablePromise<ExtractResource<K> | undefined>;
|
|
621
633
|
/**
|
|
622
634
|
* Sends a FHIR search request for an array of resources.
|
|
623
635
|
*
|
|
@@ -636,11 +648,11 @@ export declare class MedplumClient extends EventTarget {
|
|
|
636
648
|
*
|
|
637
649
|
* @category Search
|
|
638
650
|
* @param resourceType The FHIR resource type.
|
|
639
|
-
* @param query
|
|
651
|
+
* @param query Optional FHIR search query or structured query object. Can be any valid input to the URLSearchParams() constructor.
|
|
640
652
|
* @param options Optional fetch options.
|
|
641
653
|
* @returns Promise to the search result bundle.
|
|
642
654
|
*/
|
|
643
|
-
searchResources<K extends ResourceType>(resourceType: K, query?:
|
|
655
|
+
searchResources<K extends ResourceType>(resourceType: K, query?: QueryTypes, options?: RequestInit): ReadablePromise<ExtractResource<K>[]>;
|
|
644
656
|
/**
|
|
645
657
|
* Searches a ValueSet resource using the "expand" operation.
|
|
646
658
|
* See: https://www.hl7.org/fhir/operation-valueset-expand.html
|
|
@@ -7,8 +7,12 @@ export interface Token extends Marker {
|
|
|
7
7
|
id: string;
|
|
8
8
|
value: string;
|
|
9
9
|
}
|
|
10
|
+
export interface TokenizerOptions {
|
|
11
|
+
dateTimeLiterals?: boolean;
|
|
12
|
+
symbolRegex?: RegExp;
|
|
13
|
+
}
|
|
10
14
|
export declare class Tokenizer {
|
|
11
15
|
#private;
|
|
12
|
-
constructor(str: string, keywords: string[], operators: string[]);
|
|
16
|
+
constructor(str: string, keywords: string[], operators: string[], options?: TokenizerOptions);
|
|
13
17
|
tokenize(): Token[];
|
|
14
18
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './parse';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { FhirFilterExpression } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Parses a FHIR _filter parameter expression into an AST.
|
|
4
|
+
* @param input The FHIR _filter parameter expression.
|
|
5
|
+
* @returns The AST representing the filters.
|
|
6
|
+
*/
|
|
7
|
+
export declare function parseFilterParameter(input: string): FhirFilterExpression;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The FhirFilterExpression type is the base type of all filter expressions.
|
|
3
|
+
*/
|
|
4
|
+
export type FhirFilterExpression = FhirFilterComparison | FhirFilterNegation | FhirFilterConnective;
|
|
5
|
+
/**
|
|
6
|
+
* The FhirFilterComparison class represents a comparison expression.
|
|
7
|
+
*/
|
|
8
|
+
export declare class FhirFilterComparison {
|
|
9
|
+
readonly path: string;
|
|
10
|
+
readonly operator: string;
|
|
11
|
+
readonly value: string;
|
|
12
|
+
constructor(path: string, operator: string, value: string);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The FhirFilterNegation class represents a negation expression.
|
|
16
|
+
* It contains a single child expression.
|
|
17
|
+
*/
|
|
18
|
+
export declare class FhirFilterNegation {
|
|
19
|
+
readonly child: FhirFilterExpression;
|
|
20
|
+
constructor(child: FhirFilterExpression);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The FhirFilterConnective class represents a connective expression.
|
|
24
|
+
* It contains a list of child expressions.
|
|
25
|
+
*/
|
|
26
|
+
export declare class FhirFilterConnective {
|
|
27
|
+
readonly keyword: 'and' | 'or';
|
|
28
|
+
readonly left: FhirFilterExpression;
|
|
29
|
+
readonly right: FhirFilterExpression;
|
|
30
|
+
constructor(keyword: 'and' | 'or', left: FhirFilterExpression, right: FhirFilterExpression);
|
|
31
|
+
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
export * from './cache';
|
|
2
2
|
export * from './client';
|
|
3
|
+
export * from './fhirlexer';
|
|
4
|
+
export * from './fhirmapper';
|
|
3
5
|
export * from './fhirpath';
|
|
6
|
+
export * from './filter';
|
|
4
7
|
export * from './format';
|
|
5
8
|
export * from './hl7';
|
|
6
9
|
export * from './jwt';
|
|
7
10
|
export * from './outcomes';
|
|
8
11
|
export * from './readablepromise';
|
|
12
|
+
export * from './schema';
|
|
9
13
|
export * from './search/details';
|
|
10
14
|
export * from './search/match';
|
|
11
15
|
export * from './search/parse';
|
package/dist/types/outcomes.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export declare const forbidden: OperationOutcome;
|
|
|
8
8
|
export declare const gone: OperationOutcome;
|
|
9
9
|
export declare const tooManyRequests: OperationOutcome;
|
|
10
10
|
export declare function badRequest(details: string, expression?: string): OperationOutcome;
|
|
11
|
+
export declare function validationError(details: string): OperationOutcome;
|
|
11
12
|
export declare function isOperationOutcome(value: unknown): value is OperationOutcome;
|
|
12
13
|
export declare function isOk(outcome: OperationOutcome): boolean;
|
|
13
14
|
export declare function isNotFound(outcome: OperationOutcome): boolean;
|