fhir-runtime 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +211 -0
- package/LICENSE +21 -0
- package/README.md +261 -0
- package/dist/cjs/index.cjs +7368 -0
- package/dist/cjs/index.cjs.map +7 -0
- package/dist/cjs/index.d.ts +4224 -0
- package/dist/cjs/package.json +5 -0
- package/dist/esm/index.d.ts +4224 -0
- package/dist/esm/index.mjs +7250 -0
- package/dist/esm/index.mjs.map +7 -0
- package/dist/esm/package.json +5 -0
- package/dist/index.d.ts +4224 -0
- package/dist/lib/context/bundle-loader.d.ts +124 -0
- package/dist/lib/context/bundle-loader.d.ts.map +1 -0
- package/dist/lib/context/core-definitions/index.d.ts +72 -0
- package/dist/lib/context/core-definitions/index.d.ts.map +1 -0
- package/dist/lib/context/errors.d.ts +114 -0
- package/dist/lib/context/errors.d.ts.map +1 -0
- package/dist/lib/context/fhir-context.d.ts +72 -0
- package/dist/lib/context/fhir-context.d.ts.map +1 -0
- package/dist/lib/context/index.d.ts +21 -0
- package/dist/lib/context/index.d.ts.map +1 -0
- package/dist/lib/context/inheritance-resolver.d.ts +98 -0
- package/dist/lib/context/inheritance-resolver.d.ts.map +1 -0
- package/dist/lib/context/inner-type-extractor.d.ts +80 -0
- package/dist/lib/context/inner-type-extractor.d.ts.map +1 -0
- package/dist/lib/context/loaders/composite-loader.d.ts +47 -0
- package/dist/lib/context/loaders/composite-loader.d.ts.map +1 -0
- package/dist/lib/context/loaders/file-loader.d.ts +47 -0
- package/dist/lib/context/loaders/file-loader.d.ts.map +1 -0
- package/dist/lib/context/loaders/index.d.ts +11 -0
- package/dist/lib/context/loaders/index.d.ts.map +1 -0
- package/dist/lib/context/loaders/memory-loader.d.ts +42 -0
- package/dist/lib/context/loaders/memory-loader.d.ts.map +1 -0
- package/dist/lib/context/registry.d.ts +116 -0
- package/dist/lib/context/registry.d.ts.map +1 -0
- package/dist/lib/context/types.d.ts +266 -0
- package/dist/lib/context/types.d.ts.map +1 -0
- package/dist/lib/fhirpath/atoms.d.ts +228 -0
- package/dist/lib/fhirpath/atoms.d.ts.map +1 -0
- package/dist/lib/fhirpath/cache.d.ts +79 -0
- package/dist/lib/fhirpath/cache.d.ts.map +1 -0
- package/dist/lib/fhirpath/date.d.ts +17 -0
- package/dist/lib/fhirpath/date.d.ts.map +1 -0
- package/dist/lib/fhirpath/functions.d.ts +28 -0
- package/dist/lib/fhirpath/functions.d.ts.map +1 -0
- package/dist/lib/fhirpath/index.d.ts +20 -0
- package/dist/lib/fhirpath/index.d.ts.map +1 -0
- package/dist/lib/fhirpath/lexer/parse.d.ts +100 -0
- package/dist/lib/fhirpath/lexer/parse.d.ts.map +1 -0
- package/dist/lib/fhirpath/lexer/tokenize.d.ts +80 -0
- package/dist/lib/fhirpath/lexer/tokenize.d.ts.map +1 -0
- package/dist/lib/fhirpath/parse.d.ts +101 -0
- package/dist/lib/fhirpath/parse.d.ts.map +1 -0
- package/dist/lib/fhirpath/tokenize.d.ts +20 -0
- package/dist/lib/fhirpath/tokenize.d.ts.map +1 -0
- package/dist/lib/fhirpath/types.d.ts +111 -0
- package/dist/lib/fhirpath/types.d.ts.map +1 -0
- package/dist/lib/fhirpath/utils.d.ts +81 -0
- package/dist/lib/fhirpath/utils.d.ts.map +1 -0
- package/dist/lib/index.d.ts +24 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/model/canonical-profile.d.ts +381 -0
- package/dist/lib/model/canonical-profile.d.ts.map +1 -0
- package/dist/lib/model/element-definition.d.ts +503 -0
- package/dist/lib/model/element-definition.d.ts.map +1 -0
- package/dist/lib/model/index.d.ts +14 -0
- package/dist/lib/model/index.d.ts.map +1 -0
- package/dist/lib/model/primitives.d.ts +464 -0
- package/dist/lib/model/primitives.d.ts.map +1 -0
- package/dist/lib/model/structure-definition.d.ts +263 -0
- package/dist/lib/model/structure-definition.d.ts.map +1 -0
- package/dist/lib/parser/choice-type-parser.d.ts +182 -0
- package/dist/lib/parser/choice-type-parser.d.ts.map +1 -0
- package/dist/lib/parser/index.d.ts +16 -0
- package/dist/lib/parser/index.d.ts.map +1 -0
- package/dist/lib/parser/json-parser.d.ts +171 -0
- package/dist/lib/parser/json-parser.d.ts.map +1 -0
- package/dist/lib/parser/parse-error.d.ts +146 -0
- package/dist/lib/parser/parse-error.d.ts.map +1 -0
- package/dist/lib/parser/primitive-parser.d.ts +136 -0
- package/dist/lib/parser/primitive-parser.d.ts.map +1 -0
- package/dist/lib/parser/serializer.d.ts +64 -0
- package/dist/lib/parser/serializer.d.ts.map +1 -0
- package/dist/lib/parser/structure-definition-parser.d.ts +63 -0
- package/dist/lib/parser/structure-definition-parser.d.ts.map +1 -0
- package/dist/lib/profile/canonical-builder.d.ts +87 -0
- package/dist/lib/profile/canonical-builder.d.ts.map +1 -0
- package/dist/lib/profile/constraint-merger.d.ts +100 -0
- package/dist/lib/profile/constraint-merger.d.ts.map +1 -0
- package/dist/lib/profile/element-merger.d.ts +80 -0
- package/dist/lib/profile/element-merger.d.ts.map +1 -0
- package/dist/lib/profile/element-sorter.d.ts +81 -0
- package/dist/lib/profile/element-sorter.d.ts.map +1 -0
- package/dist/lib/profile/errors.d.ts +150 -0
- package/dist/lib/profile/errors.d.ts.map +1 -0
- package/dist/lib/profile/index.d.ts +27 -0
- package/dist/lib/profile/index.d.ts.map +1 -0
- package/dist/lib/profile/path-utils.d.ts +180 -0
- package/dist/lib/profile/path-utils.d.ts.map +1 -0
- package/dist/lib/profile/slicing-handler.d.ts +121 -0
- package/dist/lib/profile/slicing-handler.d.ts.map +1 -0
- package/dist/lib/profile/snapshot-generator.d.ts +73 -0
- package/dist/lib/profile/snapshot-generator.d.ts.map +1 -0
- package/dist/lib/profile/types.d.ts +220 -0
- package/dist/lib/profile/types.d.ts.map +1 -0
- package/dist/lib/validator/errors.d.ts +83 -0
- package/dist/lib/validator/errors.d.ts.map +1 -0
- package/dist/lib/validator/index.d.ts +23 -0
- package/dist/lib/validator/index.d.ts.map +1 -0
- package/dist/lib/validator/invariant-validator.d.ts +62 -0
- package/dist/lib/validator/invariant-validator.d.ts.map +1 -0
- package/dist/lib/validator/path-extractor.d.ts +123 -0
- package/dist/lib/validator/path-extractor.d.ts.map +1 -0
- package/dist/lib/validator/slicing-validator.d.ts +119 -0
- package/dist/lib/validator/slicing-validator.d.ts.map +1 -0
- package/dist/lib/validator/structure-validator.d.ts +74 -0
- package/dist/lib/validator/structure-validator.d.ts.map +1 -0
- package/dist/lib/validator/types.d.ts +288 -0
- package/dist/lib/validator/types.d.ts.map +1 -0
- package/dist/lib/validator/validation-rules.d.ts +198 -0
- package/dist/lib/validator/validation-rules.d.ts.map +1 -0
- package/dist/tsdoc-metadata.json +11 -0
- package/package.json +76 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/parser/parse-error.ts", "../../src/parser/choice-type-parser.ts", "../../src/parser/structure-definition-parser.ts", "../../src/parser/primitive-parser.ts", "../../src/parser/json-parser.ts", "../../src/parser/serializer.ts", "../../src/context/types.ts", "../../src/context/errors.ts", "../../src/context/registry.ts", "../../src/context/inheritance-resolver.ts", "../../src/context/loaders/composite-loader.ts", "../../src/context/core-definitions/index.ts", "../../src/context/fhir-context.ts", "../../src/context/loaders/memory-loader.ts", "../../src/context/loaders/file-loader.ts", "../../src/context/bundle-loader.ts", "../../src/profile/canonical-builder.ts", "../../src/context/inner-type-extractor.ts", "../../src/profile/types.ts", "../../src/profile/path-utils.ts", "../../src/profile/constraint-merger.ts", "../../src/profile/element-merger.ts", "../../src/profile/errors.ts", "../../src/profile/snapshot-generator.ts", "../../src/profile/element-sorter.ts", "../../src/profile/slicing-handler.ts", "../../src/validator/types.ts", "../../src/validator/path-extractor.ts", "../../src/validator/validation-rules.ts", "../../src/validator/slicing-validator.ts", "../../src/validator/errors.ts", "../../src/fhirpath/types.ts", "../../src/fhirpath/lexer/parse.ts", "../../src/fhirpath/utils.ts", "../../src/fhirpath/atoms.ts", "../../src/fhirpath/date.ts", "../../src/fhirpath/lexer/tokenize.ts", "../../src/fhirpath/tokenize.ts", "../../src/fhirpath/functions.ts", "../../src/fhirpath/cache.ts", "../../src/fhirpath/parse.ts", "../../src/validator/invariant-validator.ts", "../../src/validator/structure-validator.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * FHIR JSON Parse Error Types\n *\n * Structured error types for the fhir-parser module. Provides precise\n * error localization via JSON path tracking and supports collecting\n * multiple issues (errors + warnings) in a single parse pass.\n *\n * Design decisions:\n * - Result type over exceptions: allows multi-error collection\n * - Path tracking: every issue carries the JSON path for precise localization\n * - Warning support: non-fatal issues (e.g., unknown properties) reported\n * as warnings without blocking the parse\n *\n * @module fhir-parser\n */\n\n// =============================================================================\n// Section 1: Severity & Error Codes\n// =============================================================================\n\n/**\n * Severity level of a parse issue.\n *\n * - `error` \u2014 the issue prevents correct interpretation of the data\n * - `warning` \u2014 the data can still be used, but something unexpected was found\n */\nexport type ParseSeverity = 'error' | 'warning';\n\n/**\n * Machine-readable error codes for parse issues.\n *\n * Each code corresponds to a specific category of parsing problem.\n * Consumers can switch on these codes for programmatic error handling.\n */\nexport type ParseErrorCode =\n /** JSON syntax error (e.g., malformed JSON string) */\n | 'INVALID_JSON'\n /** Missing required `resourceType` property */\n | 'MISSING_RESOURCE_TYPE'\n /** `resourceType` value is not a recognized FHIR resource type */\n | 'UNKNOWN_RESOURCE_TYPE'\n /** Primitive value has wrong JavaScript type (e.g., string where number expected) */\n | 'INVALID_PRIMITIVE'\n /** Object structure does not match expected shape (e.g., array where object expected) */\n | 'INVALID_STRUCTURE'\n /** Choice type `[x]` property name has an unrecognized type suffix */\n | 'INVALID_CHOICE_TYPE'\n /** Multiple variants of the same choice type field are present */\n | 'MULTIPLE_CHOICE_VALUES'\n /** `_element` array length does not match the corresponding value array */\n | 'ARRAY_MISMATCH'\n /** Unexpected `null` value in a non-nullable position */\n | 'UNEXPECTED_NULL'\n /** Property name not recognized for this type (severity: warning) */\n | 'UNEXPECTED_PROPERTY';\n\n// =============================================================================\n// Section 2: Parse Issue\n// =============================================================================\n\n/**\n * A single issue encountered during parsing.\n *\n * Issues are collected throughout the parse process and returned in the\n * {@link ParseResult}. Both errors and warnings use this same structure.\n *\n * @example\n * ```typescript\n * const issue: ParseIssue = {\n * severity: 'error',\n * code: 'MISSING_RESOURCE_TYPE',\n * message: 'Object is missing the required \"resourceType\" property',\n * path: '$',\n * };\n * ```\n */\nexport interface ParseIssue {\n /** Severity level \u2014 `error` blocks successful parsing, `warning` does not */\n readonly severity: ParseSeverity;\n\n /** Machine-readable error code for programmatic handling */\n readonly code: ParseErrorCode;\n\n /** Human-readable description of the issue */\n readonly message: string;\n\n /**\n * JSON path where the issue was detected.\n *\n * Uses dot notation with array indices:\n * - `\"StructureDefinition\"` \u2014 root level\n * - `\"StructureDefinition.snapshot.element[0].type[1].code\"` \u2014 nested\n * - `\"$\"` \u2014 before resourceType is known\n */\n readonly path: string;\n}\n\n// =============================================================================\n// Section 3: Parse Result\n// =============================================================================\n\n/**\n * Result of a parse operation.\n *\n * Uses a discriminated union on `success`:\n * - `success: true` \u2014 parsing succeeded; `data` contains the parsed value,\n * `issues` may contain warnings\n * - `success: false` \u2014 parsing failed; `data` is `undefined`,\n * `issues` contains at least one error\n *\n * @typeParam T - The expected output type (e.g., `StructureDefinition`)\n *\n * @example\n * ```typescript\n * const result = parseFhirJson(jsonString);\n * if (result.success) {\n * console.log(result.data.url); // T is available\n * } else {\n * for (const issue of result.issues) {\n * console.error(`[${issue.path}] ${issue.message}`);\n * }\n * }\n * ```\n */\nexport type ParseResult<T> =\n | { readonly success: true; readonly data: T; readonly issues: readonly ParseIssue[] }\n | { readonly success: false; readonly data: undefined; readonly issues: readonly ParseIssue[] };\n\n// =============================================================================\n// Section 4: Factory Helpers\n// =============================================================================\n\n/**\n * Create a successful parse result.\n *\n * @param data - The parsed value\n * @param issues - Any warnings collected during parsing (default: none)\n */\nexport function parseSuccess<T>(data: T, issues: ParseIssue[] = []): ParseResult<T> {\n return { success: true, data, issues };\n}\n\n/**\n * Create a failed parse result.\n *\n * @param issues - The error(s) that caused the failure (must contain at least one error)\n */\nexport function parseFailure<T>(issues: ParseIssue[]): ParseResult<T> {\n if (!hasErrors(issues)) {\n throw new Error('parseFailure requires at least one error in issues array');\n }\n return { success: false, data: undefined, issues };\n}\n\n/**\n * Create a single parse issue.\n *\n * Convenience factory to reduce boilerplate when constructing issues.\n *\n * @param severity - Error or warning\n * @param code - Machine-readable error code\n * @param message - Human-readable description\n * @param path - JSON path where the issue was detected\n */\nexport function createIssue(\n severity: ParseSeverity,\n code: ParseErrorCode,\n message: string,\n path: string,\n): ParseIssue {\n return { severity, code, message, path };\n}\n\n/**\n * Check whether an issues array contains at least one error (not just warnings).\n *\n * Useful for determining whether to return success or failure after\n * collecting issues from sub-parsers.\n */\nexport function hasErrors(issues: readonly ParseIssue[]): boolean {\n return issues.some((issue) => issue.severity === 'error');\n}\n", "/**\n * FHIR Choice Type [x] Parser\n *\n * Handles FHIR R4 choice type property dispatch. In FHIR JSON, a choice\n * type element like `value[x]` does not appear as a single property.\n * Instead, the property name includes a type suffix:\n *\n * ```json\n * { \"valueString\": \"hello\" }\n * { \"valueQuantity\": { \"value\": 42, \"unit\": \"kg\" } }\n * ```\n *\n * This module:\n * 1. Defines the `ChoiceTypeField` descriptor and `ChoiceValue` result type\n * 2. Provides `extractChoiceValue()` to scan an object for matching properties\n * 3. Detects multiple-value conflicts (e.g., both `valueString` and `valueBoolean`)\n * 4. Consumes `_element` companions for primitive choice type variants\n * 5. Maintains a registry of all known choice type fields in the model\n *\n * @see https://hl7.org/fhir/R4/formats.html#choice\n * @see ADR-003: FHIR R4 Choice Type [x] Representation Strategy\n * @module fhir-parser\n */\n\nimport type { ParseIssue } from './parse-error.js';\nimport { createIssue } from './parse-error.js';\nimport { pathAppend } from './json-parser.js';\n\n// =============================================================================\n// Section 1: Core Types\n// =============================================================================\n\n/**\n * Definition of a choice type [x] field.\n *\n * Each choice type field has a base name and a set of allowed type suffixes.\n * The actual JSON property name is `baseName` + one of `allowedTypes`.\n *\n * @example\n * ```typescript\n * const field: ChoiceTypeField = {\n * baseName: 'value',\n * allowedTypes: ['String', 'Boolean', 'Integer', 'Quantity', ...],\n * };\n * // Matches: valueString, valueBoolean, valueInteger, valueQuantity, ...\n * ```\n */\nexport interface ChoiceTypeField {\n /** Base property name (e.g., \"value\", \"defaultValue\", \"fixed\") */\n readonly baseName: string;\n /** Allowed type suffixes (e.g., [\"String\", \"Boolean\", \"Quantity\"]) */\n readonly allowedTypes: readonly string[];\n}\n\n/**\n * Parsed choice type value.\n *\n * Preserves the original JSON property name for round-trip serialization.\n */\nexport interface ChoiceValue {\n /** Type suffix (e.g., \"String\", \"Quantity\") */\n readonly typeName: string;\n /** The actual value from JSON */\n readonly value: unknown;\n /** Original JSON property name (e.g., \"valueString\") \u2014 for serialization */\n readonly propertyName: string;\n /** _element companion data, if present */\n readonly elementExtension?: unknown;\n}\n\n// =============================================================================\n// Section 2: Extraction Logic\n// =============================================================================\n\n/**\n * Extract a choice type value from a JSON object.\n *\n * Scans all properties of `obj` looking for keys that match\n * `choiceField.baseName` + one of `choiceField.allowedTypes`.\n *\n * Handles:\n * - Single match \u2192 returns `ChoiceValue` with type info\n * - No match \u2192 returns `null` (field not present)\n * - Multiple matches \u2192 returns first match + `MULTIPLE_CHOICE_VALUES` error\n * - Unknown suffix \u2192 `INVALID_CHOICE_TYPE` error\n * - `_element` companion \u2192 consumed and attached to result\n *\n * @param obj - The raw JSON object to scan\n * @param choiceField - The choice type field definition\n * @param path - JSON path for error reporting\n * @returns Extracted value, issues, and list of consumed keys\n *\n * @example\n * ```typescript\n * const field = { baseName: 'value', allowedTypes: ['String', 'Boolean'] };\n * const obj = { valueString: 'hello' };\n * const { result, consumedKeys } = extractChoiceValue(obj, field, 'Extension');\n * // result = { typeName: 'String', value: 'hello', propertyName: 'valueString' }\n * // consumedKeys = ['valueString']\n * ```\n */\nexport function extractChoiceValue(\n obj: Record<string, unknown>,\n choiceField: ChoiceTypeField,\n path: string,\n): { result: ChoiceValue | null; issues: ParseIssue[]; consumedKeys: string[] } {\n const issues: ParseIssue[] = [];\n const consumedKeys: string[] = [];\n const matches: Array<{ typeName: string; propertyName: string; value: unknown }> = [];\n\n const { baseName, allowedTypes } = choiceField;\n const allowedSet = new Set(allowedTypes);\n\n // Scan all object keys for potential matches\n for (const key of Object.keys(obj)) {\n // Skip keys that don't start with the base name\n if (!key.startsWith(baseName)) continue;\n\n const suffix = key.slice(baseName.length);\n\n // Must have a suffix and it must start with uppercase\n if (suffix.length === 0) continue;\n if (suffix[0] !== suffix[0].toUpperCase() || suffix[0] === suffix[0].toLowerCase()) continue;\n\n // This key matches the choice type pattern\n consumedKeys.push(key);\n\n // Also consume the _element companion if present\n const underscoreKey = `_${key}`;\n if (obj[underscoreKey] !== undefined) {\n consumedKeys.push(underscoreKey);\n }\n\n if (allowedSet.has(suffix)) {\n matches.push({ typeName: suffix, propertyName: key, value: obj[key] });\n } else {\n // Unknown type suffix\n issues.push(\n createIssue(\n 'error',\n 'INVALID_CHOICE_TYPE',\n `Unknown type suffix \"${suffix}\" for choice field \"${baseName}[x]\". ` +\n `Allowed types: ${allowedTypes.join(', ')}`,\n pathAppend(path, key),\n ),\n );\n }\n }\n\n // No matches found\n if (matches.length === 0) {\n return { result: null, issues, consumedKeys };\n }\n\n // Multiple matches \u2014 report error but use the first one\n if (matches.length > 1) {\n const names = matches.map((m) => m.propertyName).join(', ');\n issues.push(\n createIssue(\n 'error',\n 'MULTIPLE_CHOICE_VALUES',\n `Choice field \"${baseName}[x]\" has multiple values: ${names}. Only one is allowed.`,\n pathAppend(path, baseName),\n ),\n );\n }\n\n const match = matches[0];\n\n // Attach _element companion if present\n const underscoreKey = `_${match.propertyName}`;\n const elementExtension = obj[underscoreKey];\n\n const result: ChoiceValue = {\n typeName: match.typeName,\n value: match.value,\n propertyName: match.propertyName,\n ...(elementExtension !== undefined && { elementExtension }),\n };\n\n return { result, issues, consumedKeys };\n}\n\n/**\n * Extract all choice type values from a JSON object for a given set of fields.\n *\n * Convenience function that calls `extractChoiceValue` for each field definition\n * and aggregates results.\n *\n * @param obj - The raw JSON object\n * @param choiceFields - Array of choice type field definitions\n * @param path - JSON path for error reporting\n * @returns Map of baseName \u2192 ChoiceValue, all issues, and all consumed keys\n */\nexport function extractAllChoiceValues(\n obj: Record<string, unknown>,\n choiceFields: readonly ChoiceTypeField[],\n path: string,\n): {\n results: ReadonlyMap<string, ChoiceValue>;\n issues: ParseIssue[];\n consumedKeys: string[];\n} {\n const results = new Map<string, ChoiceValue>();\n const allIssues: ParseIssue[] = [];\n const allConsumedKeys: string[] = [];\n\n for (const field of choiceFields) {\n const { result, issues, consumedKeys } = extractChoiceValue(obj, field, path);\n allIssues.push(...issues);\n allConsumedKeys.push(...consumedKeys);\n\n if (result !== null) {\n results.set(field.baseName, result);\n }\n }\n\n return { results, issues: allIssues, consumedKeys: allConsumedKeys };\n}\n\n// =============================================================================\n// Section 3: Allowed Type Suffixes\n// =============================================================================\n\n/**\n * All FHIR R4 data types that can appear as choice type suffixes.\n *\n * This covers all primitive types (capitalized) and common complex types.\n * Used by choice fields that allow \"any FHIR data type\" (~50 types).\n *\n * @see https://hl7.org/fhir/R4/datatypes.html\n */\nexport const ALL_FHIR_TYPE_SUFFIXES: readonly string[] = [\n // Primitive types (capitalized for JSON property names)\n 'Boolean',\n 'Integer',\n 'Decimal',\n 'String',\n 'Uri',\n 'Url',\n 'Canonical',\n 'Base64Binary',\n 'Instant',\n 'Date',\n 'DateTime',\n 'Time',\n 'Code',\n 'Oid',\n 'Id',\n 'Markdown',\n 'UnsignedInt',\n 'PositiveInt',\n 'Uuid',\n\n // Complex types\n 'Address',\n 'Age',\n 'Annotation',\n 'Attachment',\n 'CodeableConcept',\n 'Coding',\n 'ContactPoint',\n 'Count',\n 'Distance',\n 'Duration',\n 'HumanName',\n 'Identifier',\n 'Money',\n 'Period',\n 'Quantity',\n 'Range',\n 'Ratio',\n 'Reference',\n 'SampledData',\n 'Signature',\n 'Timing',\n\n // Special types\n 'ContactDetail',\n 'Contributor',\n 'DataRequirement',\n 'Expression',\n 'ParameterDefinition',\n 'RelatedArtifact',\n 'TriggerDefinition',\n 'UsageContext',\n 'Dosage',\n 'Meta',\n] as const;\n\n/**\n * Type suffixes for minValue[x] and maxValue[x] fields.\n *\n * These are restricted to orderable types only.\n * @see https://hl7.org/fhir/R4/elementdefinition-definitions.html#ElementDefinition.minValue_x_\n */\nexport const MIN_MAX_VALUE_TYPE_SUFFIXES: readonly string[] = [\n 'Date',\n 'DateTime',\n 'Instant',\n 'Time',\n 'Decimal',\n 'Integer',\n 'PositiveInt',\n 'UnsignedInt',\n 'Quantity',\n] as const;\n\n/**\n * Type suffixes for UsageContext.value[x].\n * @see https://hl7.org/fhir/R4/metadatatypes-definitions.html#UsageContext.value_x_\n */\nexport const USAGE_CONTEXT_VALUE_TYPE_SUFFIXES: readonly string[] = [\n 'CodeableConcept',\n 'Quantity',\n 'Range',\n 'Reference',\n] as const;\n\n// =============================================================================\n// Section 4: Choice Type Registry\n// =============================================================================\n\n/**\n * All known choice type fields in the fhir-model, grouped by host type.\n *\n * This registry is used by the parser to know which choice type fields\n * exist on each type, enabling proper extraction and validation.\n *\n * Coverage: 8 choice type fields across 4 host types.\n *\n * | Host Type | Base Name | Allowed Types |\n * |----------------------------|----------------|---------------|\n * | Extension | value | All (~50) |\n * | UsageContext | value | 4 |\n * | ElementDefinition | defaultValue | All (~50) |\n * | ElementDefinition | fixed | All (~50) |\n * | ElementDefinition | pattern | All (~50) |\n * | ElementDefinition | minValue | 9 |\n * | ElementDefinition | maxValue | 9 |\n * | ElementDefinitionExample | value | All (~50) |\n */\nexport const CHOICE_TYPE_FIELDS: ReadonlyMap<string, readonly ChoiceTypeField[]> = new Map<\n string,\n readonly ChoiceTypeField[]\n>([\n [\n 'Extension',\n [\n { baseName: 'value', allowedTypes: ALL_FHIR_TYPE_SUFFIXES },\n ],\n ],\n [\n 'UsageContext',\n [\n { baseName: 'value', allowedTypes: USAGE_CONTEXT_VALUE_TYPE_SUFFIXES },\n ],\n ],\n [\n 'ElementDefinition',\n [\n { baseName: 'defaultValue', allowedTypes: ALL_FHIR_TYPE_SUFFIXES },\n { baseName: 'fixed', allowedTypes: ALL_FHIR_TYPE_SUFFIXES },\n { baseName: 'pattern', allowedTypes: ALL_FHIR_TYPE_SUFFIXES },\n { baseName: 'minValue', allowedTypes: MIN_MAX_VALUE_TYPE_SUFFIXES },\n { baseName: 'maxValue', allowedTypes: MIN_MAX_VALUE_TYPE_SUFFIXES },\n ],\n ],\n [\n 'ElementDefinitionExample',\n [\n { baseName: 'value', allowedTypes: ALL_FHIR_TYPE_SUFFIXES },\n ],\n ],\n]);\n\n/**\n * Get the choice type base names for a given host type.\n *\n * Returns an array of base names (e.g., `['value']` for Extension,\n * `['defaultValue', 'fixed', 'pattern', 'minValue', 'maxValue']` for\n * ElementDefinition).\n *\n * This can be used to pass `choiceFieldBases` to `parseComplexObject`\n * for Pass 3 key matching, or for other custom parsing logic.\n *\n * @param hostType - The FHIR type name (e.g., \"Extension\", \"ElementDefinition\")\n * @returns Array of base names, or empty array if no choice fields\n */\nexport function getChoiceFieldBases(hostType: string): readonly string[] {\n const fields = CHOICE_TYPE_FIELDS.get(hostType);\n if (!fields) return [];\n return fields.map((f) => f.baseName);\n}\n\n/**\n * Get the choice type field definitions for a given host type.\n *\n * @param hostType - The FHIR type name\n * @returns Array of ChoiceTypeField definitions, or empty array\n */\nexport function getChoiceFields(hostType: string): readonly ChoiceTypeField[] {\n return CHOICE_TYPE_FIELDS.get(hostType) ?? [];\n}\n\n/**\n * Check whether a property name matches any choice type field for a host type.\n *\n * @param key - The JSON property name to check\n * @param hostType - The FHIR type name\n * @returns The matching ChoiceTypeField and extracted suffix, or null\n */\nexport function matchChoiceTypeProperty(\n key: string,\n hostType: string,\n): { field: ChoiceTypeField; suffix: string } | null {\n const fields = CHOICE_TYPE_FIELDS.get(hostType);\n if (!fields) return null;\n\n for (const field of fields) {\n if (!key.startsWith(field.baseName)) continue;\n\n const suffix = key.slice(field.baseName.length);\n if (suffix.length === 0) continue;\n if (suffix[0] !== suffix[0].toUpperCase() || suffix[0] === suffix[0].toLowerCase()) continue;\n\n return { field, suffix };\n }\n\n return null;\n}\n", "/**\n * StructureDefinition & ElementDefinition Parser\n *\n * Dedicated parser for the most important resource type in Stage-1.\n * All downstream modules (fhir-context, fhir-profile, fhir-validator)\n * depend on correctly parsed StructureDefinitions.\n *\n * Architecture:\n * ```\n * parseStructureDefinition(obj, path)\n * \u251C\u2500\u2500 top-level fields (url, name, status, kind, type, abstract, ...)\n * \u251C\u2500\u2500 sub-types:\n * \u2502 \u251C\u2500\u2500 mapping[] \u2192 parseSDMapping()\n * \u2502 \u251C\u2500\u2500 context[] \u2192 parseSDContext()\n * \u2502 \u251C\u2500\u2500 snapshot \u2192 parseSnapshot() \u2192 element[] \u2192 parseElementDefinition()\n * \u2502 \u2514\u2500\u2500 differential \u2192 parseDifferential() \u2192 element[] \u2192 parseElementDefinition()\n * \u2514\u2500\u2500 unknown property detection\n *\n * parseElementDefinition(obj, path)\n * \u251C\u2500\u2500 basic fields (path, sliceName, min, max, ...)\n * \u251C\u2500\u2500 sub-types:\n * \u2502 \u251C\u2500\u2500 slicing \u2192 parseSlicing() \u2192 discriminator[] \u2192 parseDiscriminator()\n * \u2502 \u251C\u2500\u2500 base \u2192 parseBase()\n * \u2502 \u251C\u2500\u2500 type[] \u2192 parseEDType()\n * \u2502 \u251C\u2500\u2500 constraint[] \u2192 parseConstraint()\n * \u2502 \u251C\u2500\u2500 binding \u2192 parseBinding()\n * \u2502 \u251C\u2500\u2500 example[] \u2192 parseExample() \u2190 contains choice type\n * \u2502 \u2514\u2500\u2500 mapping[] \u2192 parseEDMapping()\n * \u2514\u2500\u2500 choice type fields:\n * \u251C\u2500\u2500 defaultValue[x] \u2192 extractChoiceValue()\n * \u251C\u2500\u2500 fixed[x] \u2192 extractChoiceValue()\n * \u251C\u2500\u2500 pattern[x] \u2192 extractChoiceValue()\n * \u251C\u2500\u2500 minValue[x] \u2192 extractChoiceValue()\n * \u2514\u2500\u2500 maxValue[x] \u2192 extractChoiceValue()\n * ```\n *\n * @module fhir-parser\n */\n\nimport type { StructureDefinition } from '../model/structure-definition.js';\nimport type {\n StructureDefinitionMapping,\n StructureDefinitionContext,\n StructureDefinitionSnapshot,\n StructureDefinitionDifferential,\n} from '../model/structure-definition.js';\nimport type { ElementDefinition } from '../model/element-definition.js';\nimport type {\n ElementDefinitionSlicing,\n SlicingDiscriminator,\n ElementDefinitionBase,\n ElementDefinitionType,\n ElementDefinitionConstraint,\n ElementDefinitionBinding,\n ElementDefinitionExample,\n ElementDefinitionMapping,\n} from '../model/element-definition.js';\n\nimport type { ParseResult, ParseIssue } from './parse-error.js';\nimport { createIssue, parseSuccess, parseFailure, hasErrors } from './parse-error.js';\nimport { isPlainObject, pathAppend, pathIndex } from './json-parser.js';\nimport { extractAllChoiceValues, getChoiceFields } from './choice-type-parser.js';\n\n// =============================================================================\n// Section 1: Known Property Sets\n// =============================================================================\n\nconst STRUCTURE_DEFINITION_PROPERTIES = new Set([\n 'resourceType',\n 'id',\n 'meta',\n 'implicitRules',\n 'language',\n 'text',\n 'contained',\n 'extension',\n 'modifierExtension',\n 'url',\n 'identifier',\n 'version',\n 'name',\n 'title',\n 'status',\n 'experimental',\n 'date',\n 'publisher',\n 'contact',\n 'description',\n 'useContext',\n 'jurisdiction',\n 'purpose',\n 'copyright',\n 'keyword',\n 'fhirVersion',\n 'mapping',\n 'kind',\n 'abstract',\n 'context',\n 'contextInvariant',\n 'type',\n 'baseDefinition',\n 'derivation',\n 'snapshot',\n 'differential',\n]);\n\nconst ELEMENT_DEFINITION_PROPERTIES = new Set([\n 'id',\n 'extension',\n 'modifierExtension',\n 'path',\n 'representation',\n 'sliceName',\n 'sliceIsConstraining',\n 'label',\n 'code',\n 'slicing',\n 'short',\n 'definition',\n 'comment',\n 'requirements',\n 'alias',\n 'min',\n 'max',\n 'base',\n 'contentReference',\n 'type',\n 'meaningWhenMissing',\n 'orderMeaning',\n 'example',\n 'maxLength',\n 'condition',\n 'constraint',\n 'mustSupport',\n 'isModifier',\n 'isModifierReason',\n 'isSummary',\n 'binding',\n 'mapping',\n // choice type prefixes handled by choice-type-parser\n]);\n\n// =============================================================================\n// Section 2: ElementDefinition Sub-Type Parsers\n// =============================================================================\n\n/**\n * Parse a SlicingDiscriminator object.\n */\nfunction parseDiscriminator(\n obj: Record<string, unknown>,\n path: string,\n): { result: SlicingDiscriminator; issues: ParseIssue[] } {\n const issues: ParseIssue[] = [];\n\n if (typeof obj.type !== 'string') {\n issues.push(createIssue('error', 'INVALID_PRIMITIVE', 'discriminator.type must be a string', pathAppend(path, 'type')));\n }\n if (typeof obj.path !== 'string') {\n issues.push(createIssue('error', 'INVALID_PRIMITIVE', 'discriminator.path must be a string', pathAppend(path, 'path')));\n }\n\n const result: SlicingDiscriminator = {\n type: (obj.type as SlicingDiscriminator['type']) ?? ('value' as SlicingDiscriminator['type']),\n path: (obj.path as SlicingDiscriminator['path']) ?? ('' as SlicingDiscriminator['path']),\n ...(obj.id !== undefined && { id: obj.id as SlicingDiscriminator['id'] }),\n ...(obj.extension !== undefined && { extension: obj.extension as SlicingDiscriminator['extension'] }),\n };\n\n return { result, issues };\n}\n\n/**\n * Parse an ElementDefinitionSlicing object.\n */\nfunction parseSlicing(\n obj: Record<string, unknown>,\n path: string,\n): { result: ElementDefinitionSlicing; issues: ParseIssue[] } {\n const issues: ParseIssue[] = [];\n\n // Parse discriminator array\n let discriminator: SlicingDiscriminator[] | undefined;\n if (obj.discriminator !== undefined) {\n if (!Array.isArray(obj.discriminator)) {\n issues.push(createIssue('error', 'INVALID_STRUCTURE', 'slicing.discriminator must be an array', pathAppend(path, 'discriminator')));\n } else {\n discriminator = [];\n for (let i = 0; i < obj.discriminator.length; i++) {\n const item = obj.discriminator[i];\n if (isPlainObject(item)) {\n const parsed = parseDiscriminator(item, pathIndex(pathAppend(path, 'discriminator'), i));\n discriminator.push(parsed.result);\n issues.push(...parsed.issues);\n } else {\n issues.push(createIssue('error', 'INVALID_STRUCTURE', `discriminator[${i}] must be an object`, pathIndex(pathAppend(path, 'discriminator'), i)));\n }\n }\n }\n }\n\n if (typeof obj.rules !== 'string') {\n issues.push(createIssue('error', 'INVALID_PRIMITIVE', 'slicing.rules must be a string', pathAppend(path, 'rules')));\n }\n\n const result: ElementDefinitionSlicing = {\n rules: (obj.rules as ElementDefinitionSlicing['rules']) ?? ('open' as ElementDefinitionSlicing['rules']),\n ...(obj.id !== undefined && { id: obj.id as ElementDefinitionSlicing['id'] }),\n ...(obj.extension !== undefined && { extension: obj.extension as ElementDefinitionSlicing['extension'] }),\n ...(discriminator !== undefined && { discriminator }),\n ...(obj.description !== undefined && { description: obj.description as ElementDefinitionSlicing['description'] }),\n ...(obj.ordered !== undefined && { ordered: obj.ordered as ElementDefinitionSlicing['ordered'] }),\n };\n\n return { result, issues };\n}\n\n/**\n * Parse an ElementDefinitionBase object.\n */\nfunction parseBase(\n obj: Record<string, unknown>,\n path: string,\n): { result: ElementDefinitionBase; issues: ParseIssue[] } {\n const issues: ParseIssue[] = [];\n\n if (typeof obj.path !== 'string') {\n issues.push(createIssue('error', 'INVALID_PRIMITIVE', 'base.path must be a string', pathAppend(path, 'path')));\n }\n if (typeof obj.min !== 'number') {\n issues.push(createIssue('error', 'INVALID_PRIMITIVE', 'base.min must be a number', pathAppend(path, 'min')));\n }\n if (typeof obj.max !== 'string') {\n issues.push(createIssue('error', 'INVALID_PRIMITIVE', 'base.max must be a string', pathAppend(path, 'max')));\n }\n\n const result: ElementDefinitionBase = {\n path: (obj.path as ElementDefinitionBase['path']) ?? ('' as ElementDefinitionBase['path']),\n min: (obj.min as ElementDefinitionBase['min']) ?? (0 as ElementDefinitionBase['min']),\n max: (obj.max as ElementDefinitionBase['max']) ?? ('*' as ElementDefinitionBase['max']),\n ...(obj.id !== undefined && { id: obj.id as ElementDefinitionBase['id'] }),\n ...(obj.extension !== undefined && { extension: obj.extension as ElementDefinitionBase['extension'] }),\n };\n\n return { result, issues };\n}\n\n/**\n * Parse an ElementDefinitionType object.\n */\nfunction parseEDType(\n obj: Record<string, unknown>,\n path: string,\n): { result: ElementDefinitionType; issues: ParseIssue[] } {\n const issues: ParseIssue[] = [];\n\n if (typeof obj.code !== 'string') {\n issues.push(createIssue('error', 'INVALID_PRIMITIVE', 'type.code must be a string', pathAppend(path, 'code')));\n }\n\n const result: ElementDefinitionType = {\n code: (obj.code as ElementDefinitionType['code']) ?? ('' as ElementDefinitionType['code']),\n ...(obj.id !== undefined && { id: obj.id as ElementDefinitionType['id'] }),\n ...(obj.extension !== undefined && { extension: obj.extension as ElementDefinitionType['extension'] }),\n ...(obj.profile !== undefined && { profile: obj.profile as ElementDefinitionType['profile'] }),\n ...(obj.targetProfile !== undefined && { targetProfile: obj.targetProfile as ElementDefinitionType['targetProfile'] }),\n ...(obj.aggregation !== undefined && { aggregation: obj.aggregation as ElementDefinitionType['aggregation'] }),\n ...(obj.versioning !== undefined && { versioning: obj.versioning as ElementDefinitionType['versioning'] }),\n };\n\n return { result, issues };\n}\n\n/**\n * Parse an ElementDefinitionConstraint object.\n */\nfunction parseConstraint(\n obj: Record<string, unknown>,\n path: string,\n): { result: ElementDefinitionConstraint; issues: ParseIssue[] } {\n const issues: ParseIssue[] = [];\n\n if (typeof obj.key !== 'string') {\n issues.push(createIssue('error', 'INVALID_PRIMITIVE', 'constraint.key must be a string', pathAppend(path, 'key')));\n }\n if (typeof obj.severity !== 'string') {\n issues.push(createIssue('error', 'INVALID_PRIMITIVE', 'constraint.severity must be a string', pathAppend(path, 'severity')));\n }\n if (typeof obj.human !== 'string') {\n issues.push(createIssue('error', 'INVALID_PRIMITIVE', 'constraint.human must be a string', pathAppend(path, 'human')));\n }\n\n const result: ElementDefinitionConstraint = {\n key: (obj.key as ElementDefinitionConstraint['key']) ?? ('' as ElementDefinitionConstraint['key']),\n severity: (obj.severity as ElementDefinitionConstraint['severity']) ?? ('error' as ElementDefinitionConstraint['severity']),\n human: (obj.human as ElementDefinitionConstraint['human']) ?? ('' as ElementDefinitionConstraint['human']),\n ...(obj.id !== undefined && { id: obj.id as ElementDefinitionConstraint['id'] }),\n ...(obj.extension !== undefined && { extension: obj.extension as ElementDefinitionConstraint['extension'] }),\n ...(obj.requirements !== undefined && { requirements: obj.requirements as ElementDefinitionConstraint['requirements'] }),\n ...(obj.expression !== undefined && { expression: obj.expression as ElementDefinitionConstraint['expression'] }),\n ...(obj.xpath !== undefined && { xpath: obj.xpath as ElementDefinitionConstraint['xpath'] }),\n ...(obj.source !== undefined && { source: obj.source as ElementDefinitionConstraint['source'] }),\n };\n\n return { result, issues };\n}\n\n/**\n * Parse an ElementDefinitionBinding object.\n */\nfunction parseBinding(\n obj: Record<string, unknown>,\n path: string,\n): { result: ElementDefinitionBinding; issues: ParseIssue[] } {\n const issues: ParseIssue[] = [];\n\n if (typeof obj.strength !== 'string') {\n issues.push(createIssue('error', 'INVALID_PRIMITIVE', 'binding.strength must be a string', pathAppend(path, 'strength')));\n }\n\n const result: ElementDefinitionBinding = {\n strength: (obj.strength as ElementDefinitionBinding['strength']) ?? ('example' as ElementDefinitionBinding['strength']),\n ...(obj.id !== undefined && { id: obj.id as ElementDefinitionBinding['id'] }),\n ...(obj.extension !== undefined && { extension: obj.extension as ElementDefinitionBinding['extension'] }),\n ...(obj.description !== undefined && { description: obj.description as ElementDefinitionBinding['description'] }),\n ...(obj.valueSet !== undefined && { valueSet: obj.valueSet as ElementDefinitionBinding['valueSet'] }),\n };\n\n return { result, issues };\n}\n\n/**\n * Parse an ElementDefinitionExample object (contains choice type value[x]).\n */\nfunction parseExample(\n obj: Record<string, unknown>,\n path: string,\n): { result: ElementDefinitionExample; issues: ParseIssue[] } {\n const issues: ParseIssue[] = [];\n\n if (typeof obj.label !== 'string') {\n issues.push(createIssue('error', 'INVALID_PRIMITIVE', 'example.label must be a string', pathAppend(path, 'label')));\n }\n\n // Extract choice type value[x] from example\n const exampleChoiceFields = getChoiceFields('ElementDefinitionExample');\n const { results: choiceResults, issues: choiceIssues } = extractAllChoiceValues(obj, exampleChoiceFields, path);\n issues.push(...choiceIssues);\n\n const choiceValue = choiceResults.get('value');\n\n const result: ElementDefinitionExample = {\n label: (obj.label as ElementDefinitionExample['label']) ?? ('' as ElementDefinitionExample['label']),\n value: choiceValue ?? undefined,\n ...(obj.id !== undefined && { id: obj.id as ElementDefinitionExample['id'] }),\n ...(obj.extension !== undefined && { extension: obj.extension as ElementDefinitionExample['extension'] }),\n };\n\n return { result, issues };\n}\n\n/**\n * Parse an ElementDefinitionMapping object.\n */\nfunction parseEDMapping(\n obj: Record<string, unknown>,\n path: string,\n): { result: ElementDefinitionMapping; issues: ParseIssue[] } {\n const issues: ParseIssue[] = [];\n\n if (typeof obj.identity !== 'string') {\n issues.push(createIssue('error', 'INVALID_PRIMITIVE', 'mapping.identity must be a string', pathAppend(path, 'identity')));\n }\n if (typeof obj.map !== 'string') {\n issues.push(createIssue('error', 'INVALID_PRIMITIVE', 'mapping.map must be a string', pathAppend(path, 'map')));\n }\n\n const result: ElementDefinitionMapping = {\n identity: (obj.identity as ElementDefinitionMapping['identity']) ?? ('' as ElementDefinitionMapping['identity']),\n map: (obj.map as ElementDefinitionMapping['map']) ?? ('' as ElementDefinitionMapping['map']),\n ...(obj.id !== undefined && { id: obj.id as ElementDefinitionMapping['id'] }),\n ...(obj.extension !== undefined && { extension: obj.extension as ElementDefinitionMapping['extension'] }),\n ...(obj.language !== undefined && { language: obj.language as ElementDefinitionMapping['language'] }),\n ...(obj.comment !== undefined && { comment: obj.comment as ElementDefinitionMapping['comment'] }),\n };\n\n return { result, issues };\n}\n\n// =============================================================================\n// Section 3: Helper \u2014 parse array of sub-type objects\n// =============================================================================\n\nfunction parseObjectArray<T>(\n arr: unknown,\n path: string,\n propertyName: string,\n parser: (obj: Record<string, unknown>, path: string) => { result: T; issues: ParseIssue[] },\n): { result: T[] | undefined; issues: ParseIssue[] } {\n const issues: ParseIssue[] = [];\n\n if (arr === undefined) return { result: undefined, issues };\n\n const arrayPath = pathAppend(path, propertyName);\n\n if (!Array.isArray(arr)) {\n issues.push(createIssue('error', 'INVALID_STRUCTURE', `\"${propertyName}\" must be an array`, arrayPath));\n return { result: undefined, issues };\n }\n\n const results: T[] = [];\n for (let i = 0; i < arr.length; i++) {\n const item = arr[i];\n const itemPath = pathIndex(arrayPath, i);\n if (isPlainObject(item)) {\n const parsed = parser(item, itemPath);\n results.push(parsed.result);\n issues.push(...parsed.issues);\n } else {\n issues.push(createIssue('error', 'INVALID_STRUCTURE', `${propertyName}[${i}] must be an object`, itemPath));\n }\n }\n\n return { result: results.length > 0 ? results : undefined, issues };\n}\n\n// =============================================================================\n// Section 4: ElementDefinition Parser\n// =============================================================================\n\n/**\n * Parse an ElementDefinition JSON object.\n *\n * ElementDefinition is the most complex data type in FHIR,\n * with ~37 fields and 8 sub-types.\n */\nexport function parseElementDefinition(\n obj: Record<string, unknown>,\n path: string,\n): { result: ElementDefinition; issues: ParseIssue[] } {\n const issues: ParseIssue[] = [];\n\n // --- Required field: path ---\n if (typeof obj.path !== 'string') {\n issues.push(createIssue('error', 'INVALID_PRIMITIVE', 'ElementDefinition.path must be a string', pathAppend(path, 'path')));\n }\n\n // --- Parse sub-types ---\n let slicing: ElementDefinitionSlicing | undefined;\n if (obj.slicing !== undefined) {\n if (isPlainObject(obj.slicing)) {\n const parsed = parseSlicing(obj.slicing, pathAppend(path, 'slicing'));\n slicing = parsed.result;\n issues.push(...parsed.issues);\n } else {\n issues.push(createIssue('error', 'INVALID_STRUCTURE', 'slicing must be an object', pathAppend(path, 'slicing')));\n }\n }\n\n let base: ElementDefinitionBase | undefined;\n if (obj.base !== undefined) {\n if (isPlainObject(obj.base)) {\n const parsed = parseBase(obj.base, pathAppend(path, 'base'));\n base = parsed.result;\n issues.push(...parsed.issues);\n } else {\n issues.push(createIssue('error', 'INVALID_STRUCTURE', 'base must be an object', pathAppend(path, 'base')));\n }\n }\n\n let binding: ElementDefinitionBinding | undefined;\n if (obj.binding !== undefined) {\n if (isPlainObject(obj.binding)) {\n const parsed = parseBinding(obj.binding, pathAppend(path, 'binding'));\n binding = parsed.result;\n issues.push(...parsed.issues);\n } else {\n issues.push(createIssue('error', 'INVALID_STRUCTURE', 'binding must be an object', pathAppend(path, 'binding')));\n }\n }\n\n // --- Parse array sub-types ---\n const { result: typeArr, issues: typeIssues } = parseObjectArray(obj.type, path, 'type', parseEDType);\n issues.push(...typeIssues);\n\n const { result: constraintArr, issues: constraintIssues } = parseObjectArray(obj.constraint, path, 'constraint', parseConstraint);\n issues.push(...constraintIssues);\n\n const { result: exampleArr, issues: exampleIssues } = parseObjectArray(obj.example, path, 'example', parseExample);\n issues.push(...exampleIssues);\n\n const { result: mappingArr, issues: mappingIssues } = parseObjectArray(obj.mapping, path, 'mapping', parseEDMapping);\n issues.push(...mappingIssues);\n\n // --- Extract choice type fields ---\n const edChoiceFields = getChoiceFields('ElementDefinition');\n const { results: choiceResults, issues: choiceIssues, consumedKeys } = extractAllChoiceValues(obj, edChoiceFields, path);\n issues.push(...choiceIssues);\n const consumedKeySet = new Set(consumedKeys);\n\n // --- Detect unknown properties ---\n for (const key of Object.keys(obj)) {\n if (ELEMENT_DEFINITION_PROPERTIES.has(key)) continue;\n if (key.startsWith('_')) continue; // _element companions\n if (consumedKeySet.has(key)) continue;\n issues.push(createIssue('warning', 'UNEXPECTED_PROPERTY', `Unknown property \"${key}\" in ElementDefinition`, pathAppend(path, key)));\n }\n\n // --- Assemble result ---\n const result: ElementDefinition = {\n path: (obj.path as ElementDefinition['path']) ?? ('' as ElementDefinition['path']),\n ...(obj.id !== undefined && { id: obj.id as ElementDefinition['id'] }),\n ...(obj.extension !== undefined && { extension: obj.extension as ElementDefinition['extension'] }),\n ...(obj.modifierExtension !== undefined && { modifierExtension: obj.modifierExtension as ElementDefinition['modifierExtension'] }),\n ...(obj.representation !== undefined && { representation: obj.representation as ElementDefinition['representation'] }),\n ...(obj.sliceName !== undefined && { sliceName: obj.sliceName as ElementDefinition['sliceName'] }),\n ...(obj.sliceIsConstraining !== undefined && { sliceIsConstraining: obj.sliceIsConstraining as ElementDefinition['sliceIsConstraining'] }),\n ...(obj.label !== undefined && { label: obj.label as ElementDefinition['label'] }),\n ...(obj.code !== undefined && { code: obj.code as ElementDefinition['code'] }),\n ...(slicing !== undefined && { slicing }),\n ...(obj.short !== undefined && { short: obj.short as ElementDefinition['short'] }),\n ...(obj.definition !== undefined && { definition: obj.definition as ElementDefinition['definition'] }),\n ...(obj.comment !== undefined && { comment: obj.comment as ElementDefinition['comment'] }),\n ...(obj.requirements !== undefined && { requirements: obj.requirements as ElementDefinition['requirements'] }),\n ...(obj.alias !== undefined && { alias: obj.alias as ElementDefinition['alias'] }),\n ...(obj.min !== undefined && { min: obj.min as ElementDefinition['min'] }),\n ...(obj.max !== undefined && { max: obj.max as ElementDefinition['max'] }),\n ...(base !== undefined && { base }),\n ...(obj.contentReference !== undefined && { contentReference: obj.contentReference as ElementDefinition['contentReference'] }),\n ...(typeArr !== undefined && { type: typeArr }),\n ...(choiceResults.has('defaultValue') && { defaultValue: choiceResults.get('defaultValue') }),\n ...(obj.meaningWhenMissing !== undefined && { meaningWhenMissing: obj.meaningWhenMissing as ElementDefinition['meaningWhenMissing'] }),\n ...(obj.orderMeaning !== undefined && { orderMeaning: obj.orderMeaning as ElementDefinition['orderMeaning'] }),\n ...(choiceResults.has('fixed') && { fixed: choiceResults.get('fixed') }),\n ...(choiceResults.has('pattern') && { pattern: choiceResults.get('pattern') }),\n ...(exampleArr !== undefined && { example: exampleArr }),\n ...(choiceResults.has('minValue') && { minValue: choiceResults.get('minValue') }),\n ...(choiceResults.has('maxValue') && { maxValue: choiceResults.get('maxValue') }),\n ...(obj.maxLength !== undefined && { maxLength: obj.maxLength as ElementDefinition['maxLength'] }),\n ...(obj.condition !== undefined && { condition: obj.condition as ElementDefinition['condition'] }),\n ...(constraintArr !== undefined && { constraint: constraintArr }),\n ...(obj.mustSupport !== undefined && { mustSupport: obj.mustSupport as ElementDefinition['mustSupport'] }),\n ...(obj.isModifier !== undefined && { isModifier: obj.isModifier as ElementDefinition['isModifier'] }),\n ...(obj.isModifierReason !== undefined && { isModifierReason: obj.isModifierReason as ElementDefinition['isModifierReason'] }),\n ...(obj.isSummary !== undefined && { isSummary: obj.isSummary as ElementDefinition['isSummary'] }),\n ...(binding !== undefined && { binding }),\n ...(mappingArr !== undefined && { mapping: mappingArr }),\n };\n\n return { result, issues };\n}\n\n// =============================================================================\n// Section 5: StructureDefinition Sub-Type Parsers\n// =============================================================================\n\n/**\n * Parse a StructureDefinitionMapping object.\n */\nfunction parseSDMapping(\n obj: Record<string, unknown>,\n path: string,\n): { result: StructureDefinitionMapping; issues: ParseIssue[] } {\n const issues: ParseIssue[] = [];\n\n if (typeof obj.identity !== 'string') {\n issues.push(createIssue('error', 'INVALID_PRIMITIVE', 'mapping.identity must be a string', pathAppend(path, 'identity')));\n }\n\n const result: StructureDefinitionMapping = {\n identity: (obj.identity as StructureDefinitionMapping['identity']) ?? ('' as StructureDefinitionMapping['identity']),\n ...(obj.id !== undefined && { id: obj.id as StructureDefinitionMapping['id'] }),\n ...(obj.extension !== undefined && { extension: obj.extension as StructureDefinitionMapping['extension'] }),\n ...(obj.modifierExtension !== undefined && { modifierExtension: obj.modifierExtension as StructureDefinitionMapping['modifierExtension'] }),\n ...(obj.uri !== undefined && { uri: obj.uri as StructureDefinitionMapping['uri'] }),\n ...(obj.name !== undefined && { name: obj.name as StructureDefinitionMapping['name'] }),\n ...(obj.comment !== undefined && { comment: obj.comment as StructureDefinitionMapping['comment'] }),\n };\n\n return { result, issues };\n}\n\n/**\n * Parse a StructureDefinitionContext object.\n */\nfunction parseSDContext(\n obj: Record<string, unknown>,\n path: string,\n): { result: StructureDefinitionContext; issues: ParseIssue[] } {\n const issues: ParseIssue[] = [];\n\n if (typeof obj.type !== 'string') {\n issues.push(createIssue('error', 'INVALID_PRIMITIVE', 'context.type must be a string', pathAppend(path, 'type')));\n }\n if (typeof obj.expression !== 'string') {\n issues.push(createIssue('error', 'INVALID_PRIMITIVE', 'context.expression must be a string', pathAppend(path, 'expression')));\n }\n\n const result: StructureDefinitionContext = {\n type: (obj.type as StructureDefinitionContext['type']) ?? ('element' as StructureDefinitionContext['type']),\n expression: (obj.expression as StructureDefinitionContext['expression']) ?? ('' as StructureDefinitionContext['expression']),\n ...(obj.id !== undefined && { id: obj.id as StructureDefinitionContext['id'] }),\n ...(obj.extension !== undefined && { extension: obj.extension as StructureDefinitionContext['extension'] }),\n ...(obj.modifierExtension !== undefined && { modifierExtension: obj.modifierExtension as StructureDefinitionContext['modifierExtension'] }),\n };\n\n return { result, issues };\n}\n\n/**\n * Parse a snapshot or differential object containing element[].\n */\nfunction parseElementContainer(\n obj: Record<string, unknown>,\n path: string,\n): { result: { element: ElementDefinition[]; id?: string; extension?: unknown[]; modifierExtension?: unknown[] }; issues: ParseIssue[] } {\n const issues: ParseIssue[] = [];\n\n if (!Array.isArray(obj.element)) {\n issues.push(createIssue('error', 'INVALID_STRUCTURE', 'element must be an array', pathAppend(path, 'element')));\n return {\n result: {\n element: [],\n ...(obj.id !== undefined && { id: obj.id as string }),\n },\n issues,\n };\n }\n\n const elements: ElementDefinition[] = [];\n for (let i = 0; i < obj.element.length; i++) {\n const item = obj.element[i];\n const itemPath = pathIndex(pathAppend(path, 'element'), i);\n if (isPlainObject(item)) {\n const parsed = parseElementDefinition(item, itemPath);\n elements.push(parsed.result);\n issues.push(...parsed.issues);\n } else {\n issues.push(createIssue('error', 'INVALID_STRUCTURE', `element[${i}] must be an object`, itemPath));\n }\n }\n\n const result = {\n element: elements,\n ...(obj.id !== undefined && { id: obj.id as string }),\n ...(obj.extension !== undefined && { extension: obj.extension as unknown[] }),\n ...(obj.modifierExtension !== undefined && { modifierExtension: obj.modifierExtension as unknown[] }),\n };\n\n return { result, issues };\n}\n\n// =============================================================================\n// Section 6: StructureDefinition Parser \u2014 Public API\n// =============================================================================\n\n/**\n * Parse a StructureDefinition JSON object.\n *\n * This is the most important parse function in Stage-1. All downstream\n * modules (fhir-context, fhir-profile, fhir-validator) depend on\n * correctly parsed StructureDefinitions.\n *\n * @param obj - A parsed JSON object (already validated as having resourceType = \"StructureDefinition\")\n * @param path - Current JSON path (for error reporting)\n */\nexport function parseStructureDefinition(\n obj: Record<string, unknown>,\n path: string,\n): ParseResult<StructureDefinition> {\n const issues: ParseIssue[] = [];\n\n // --- Validate required fields ---\n if (typeof obj.url !== 'string') {\n issues.push(createIssue('error', 'INVALID_PRIMITIVE', 'StructureDefinition.url is required and must be a string', pathAppend(path, 'url')));\n }\n if (typeof obj.name !== 'string') {\n issues.push(createIssue('error', 'INVALID_PRIMITIVE', 'StructureDefinition.name is required and must be a string', pathAppend(path, 'name')));\n }\n if (typeof obj.status !== 'string') {\n issues.push(createIssue('error', 'INVALID_PRIMITIVE', 'StructureDefinition.status is required and must be a string', pathAppend(path, 'status')));\n }\n if (typeof obj.kind !== 'string') {\n issues.push(createIssue('error', 'INVALID_PRIMITIVE', 'StructureDefinition.kind is required and must be a string', pathAppend(path, 'kind')));\n }\n if (typeof obj.abstract !== 'boolean') {\n issues.push(createIssue('error', 'INVALID_PRIMITIVE', 'StructureDefinition.abstract is required and must be a boolean', pathAppend(path, 'abstract')));\n }\n if (typeof obj.type !== 'string') {\n issues.push(createIssue('error', 'INVALID_PRIMITIVE', 'StructureDefinition.type is required and must be a string', pathAppend(path, 'type')));\n }\n\n // --- Parse sub-types ---\n const { result: mappingArr, issues: mappingIssues } = parseObjectArray(obj.mapping, path, 'mapping', parseSDMapping);\n issues.push(...mappingIssues);\n\n const { result: contextArr, issues: contextIssues } = parseObjectArray(obj.context, path, 'context', parseSDContext);\n issues.push(...contextIssues);\n\n // --- Parse snapshot ---\n let snapshot: StructureDefinitionSnapshot | undefined;\n if (obj.snapshot !== undefined) {\n if (isPlainObject(obj.snapshot)) {\n const parsed = parseElementContainer(obj.snapshot, pathAppend(path, 'snapshot'));\n snapshot = parsed.result as StructureDefinitionSnapshot;\n issues.push(...parsed.issues);\n } else {\n issues.push(createIssue('error', 'INVALID_STRUCTURE', 'snapshot must be an object', pathAppend(path, 'snapshot')));\n }\n }\n\n // --- Parse differential ---\n let differential: StructureDefinitionDifferential | undefined;\n if (obj.differential !== undefined) {\n if (isPlainObject(obj.differential)) {\n const parsed = parseElementContainer(obj.differential, pathAppend(path, 'differential'));\n differential = parsed.result as StructureDefinitionDifferential;\n issues.push(...parsed.issues);\n } else {\n issues.push(createIssue('error', 'INVALID_STRUCTURE', 'differential must be an object', pathAppend(path, 'differential')));\n }\n }\n\n // --- Detect unknown properties ---\n for (const key of Object.keys(obj)) {\n if (STRUCTURE_DEFINITION_PROPERTIES.has(key)) continue;\n if (key.startsWith('_')) continue; // _element companions\n issues.push(createIssue('warning', 'UNEXPECTED_PROPERTY', `Unknown property \"${key}\" in StructureDefinition`, pathAppend(path, key)));\n }\n\n // --- Assemble result ---\n const sd: StructureDefinition = {\n resourceType: 'StructureDefinition',\n url: (obj.url as StructureDefinition['url']) ?? ('' as StructureDefinition['url']),\n name: (obj.name as StructureDefinition['name']) ?? ('' as StructureDefinition['name']),\n status: (obj.status as StructureDefinition['status']) ?? ('unknown' as StructureDefinition['status']),\n kind: (obj.kind as StructureDefinition['kind']) ?? ('resource' as StructureDefinition['kind']),\n abstract: (obj.abstract as StructureDefinition['abstract']) ?? false,\n type: (obj.type as StructureDefinition['type']) ?? ('' as StructureDefinition['type']),\n // Optional Resource fields\n ...(obj.id !== undefined && { id: obj.id as StructureDefinition['id'] }),\n ...(obj.meta !== undefined && { meta: obj.meta as StructureDefinition['meta'] }),\n ...(obj.implicitRules !== undefined && { implicitRules: obj.implicitRules as StructureDefinition['implicitRules'] }),\n ...(obj.language !== undefined && { language: obj.language as StructureDefinition['language'] }),\n ...(obj.text !== undefined && { text: obj.text as StructureDefinition['text'] }),\n ...(obj.contained !== undefined && { contained: obj.contained as StructureDefinition['contained'] }),\n ...(obj.extension !== undefined && { extension: obj.extension as StructureDefinition['extension'] }),\n ...(obj.modifierExtension !== undefined && { modifierExtension: obj.modifierExtension as StructureDefinition['modifierExtension'] }),\n // Optional metadata fields\n ...(obj.identifier !== undefined && { identifier: obj.identifier as StructureDefinition['identifier'] }),\n ...(obj.version !== undefined && { version: obj.version as StructureDefinition['version'] }),\n ...(obj.title !== undefined && { title: obj.title as StructureDefinition['title'] }),\n ...(obj.experimental !== undefined && { experimental: obj.experimental as StructureDefinition['experimental'] }),\n ...(obj.date !== undefined && { date: obj.date as StructureDefinition['date'] }),\n ...(obj.publisher !== undefined && { publisher: obj.publisher as StructureDefinition['publisher'] }),\n ...(obj.contact !== undefined && { contact: obj.contact as StructureDefinition['contact'] }),\n ...(obj.description !== undefined && { description: obj.description as StructureDefinition['description'] }),\n ...(obj.useContext !== undefined && { useContext: obj.useContext as StructureDefinition['useContext'] }),\n ...(obj.jurisdiction !== undefined && { jurisdiction: obj.jurisdiction as StructureDefinition['jurisdiction'] }),\n ...(obj.purpose !== undefined && { purpose: obj.purpose as StructureDefinition['purpose'] }),\n ...(obj.copyright !== undefined && { copyright: obj.copyright as StructureDefinition['copyright'] }),\n ...(obj.keyword !== undefined && { keyword: obj.keyword as StructureDefinition['keyword'] }),\n ...(obj.fhirVersion !== undefined && { fhirVersion: obj.fhirVersion as StructureDefinition['fhirVersion'] }),\n // Sub-types\n ...(mappingArr !== undefined && { mapping: mappingArr }),\n ...(contextArr !== undefined && { context: contextArr }),\n ...(obj.contextInvariant !== undefined && { contextInvariant: obj.contextInvariant as StructureDefinition['contextInvariant'] }),\n ...(obj.baseDefinition !== undefined && { baseDefinition: obj.baseDefinition as StructureDefinition['baseDefinition'] }),\n ...(obj.derivation !== undefined && { derivation: obj.derivation as StructureDefinition['derivation'] }),\n ...(snapshot !== undefined && { snapshot }),\n ...(differential !== undefined && { differential }),\n };\n\n if (hasErrors(issues)) {\n return parseFailure<StructureDefinition>(issues);\n }\n\n return parseSuccess(sd, issues);\n}\n", "/**\n * FHIR Primitive Type Parser\n *\n * Handles the FHIR JSON dual-property representation of primitive types:\n * - `name`: the actual value (string | number | boolean)\n * - `_name`: the Element metadata (id, extension)\n *\n * FHIR R4 JSON Representation Rules (\u00A72.6.2):\n * 1. Primitive values appear as JSON string, number, or boolean\n * 2. Element metadata (id, extension) appears under `_name`\n * 3. Either or both may be present\n * 4. For arrays, `null` is used for positional alignment\n *\n * Stage-1 Strategy:\n * - Values are passed through as branded types (no regex validation)\n * - `_element` id and extension are merged onto the result\n * - Regex validation is deferred to fhir-validator (Phase 5)\n *\n * @see https://hl7.org/fhir/R4/json.html#primitive\n * @module fhir-parser\n */\n\nimport type { ParseIssue } from './parse-error.js';\nimport { createIssue } from './parse-error.js';\nimport { isPlainObject, pathAppend, pathIndex } from './json-parser.js';\n\n// =============================================================================\n// Section 1: FHIR Primitive Type \u2192 JavaScript Type Mapping\n// =============================================================================\n\n/**\n * Expected JavaScript type for a FHIR primitive type name.\n *\n * FHIR R4 JSON type mapping:\n * - `boolean` \u2192 JSON boolean\n * - `integer`, `positiveInt`, `unsignedInt` \u2192 JSON number (integer)\n * - `decimal` \u2192 JSON number\n * - All others \u2192 JSON string\n */\nexport type PrimitiveJsType = 'boolean' | 'number' | 'string';\n\n/**\n * Map from FHIR primitive type name to expected JavaScript type.\n *\n * This covers all 20 FHIR R4 primitive types.\n */\nconst PRIMITIVE_JS_TYPE_MAP: ReadonlyMap<string, PrimitiveJsType> = new Map([\n // Boolean\n ['boolean', 'boolean'],\n\n // Number types\n ['integer', 'number'],\n ['positiveInt', 'number'],\n ['unsignedInt', 'number'],\n ['decimal', 'number'],\n\n // String types (all remaining primitives)\n ['string', 'string'],\n ['uri', 'string'],\n ['url', 'string'],\n ['canonical', 'string'],\n ['base64Binary', 'string'],\n ['instant', 'string'],\n ['date', 'string'],\n ['dateTime', 'string'],\n ['time', 'string'],\n ['code', 'string'],\n ['oid', 'string'],\n ['id', 'string'],\n ['markdown', 'string'],\n ['uuid', 'string'],\n ['xhtml', 'string'],\n]);\n\n/**\n * Get the expected JavaScript type for a FHIR primitive type name.\n *\n * Returns `'string'` for unknown type names (safe default).\n */\nexport function getExpectedJsType(fhirType: string): PrimitiveJsType {\n return PRIMITIVE_JS_TYPE_MAP.get(fhirType) ?? 'string';\n}\n\n/**\n * Check whether a FHIR type name is an integer type (not decimal).\n *\n * Used to validate that number values are whole numbers.\n */\nfunction isIntegerType(fhirType: string): boolean {\n return fhirType === 'integer' || fhirType === 'positiveInt' || fhirType === 'unsignedInt';\n}\n\n// =============================================================================\n// Section 2: Primitive Value Validation\n// =============================================================================\n\n/**\n * Validate that a primitive value has the correct JavaScript type.\n *\n * This performs structural validation only (correct JS type). It does NOT\n * validate the value against FHIR regex patterns \u2014 that is the responsibility\n * of fhir-validator (Phase 5).\n *\n * @param value - The JSON value to validate\n * @param fhirType - The FHIR primitive type name (e.g., \"string\", \"boolean\", \"integer\")\n * @param path - JSON path for error reporting\n * @returns A `ParseIssue` if validation fails, or `null` if valid\n */\nexport function validatePrimitiveValue(\n value: unknown,\n fhirType: string,\n path: string,\n): ParseIssue | null {\n const expectedType = getExpectedJsType(fhirType);\n\n if (typeof value !== expectedType) {\n return createIssue(\n 'error',\n 'INVALID_PRIMITIVE',\n `Expected ${expectedType} for FHIR type \"${fhirType}\", got ${typeof value}`,\n path,\n );\n }\n\n // For integer types, verify the value is actually a whole number\n if (isIntegerType(fhirType) && typeof value === 'number') {\n if (!Number.isInteger(value)) {\n return createIssue(\n 'error',\n 'INVALID_PRIMITIVE',\n `Expected integer for FHIR type \"${fhirType}\", got decimal ${value}`,\n path,\n );\n }\n }\n\n return null;\n}\n\n// =============================================================================\n// Section 3: _element Parsing\n// =============================================================================\n\n/**\n * The result of parsing a `_element` companion object.\n *\n * Contains the `id` and `extension` fields from the Element base type.\n */\nexport interface ElementMetadata {\n /** Element id (0..1) */\n readonly id?: string;\n /** Extensions (0..*) */\n readonly extension?: unknown[];\n}\n\n/**\n * Parse a `_element` companion object into ElementMetadata.\n *\n * The `_element` object may contain:\n * - `id`: a string\n * - `extension`: an array of Extension objects\n *\n * @param elementObj - The raw `_element` JSON value\n * @param path - JSON path for error reporting\n */\nfunction parseElementMetadata(\n elementObj: unknown,\n path: string,\n): { result: ElementMetadata | null; issues: ParseIssue[] } {\n const issues: ParseIssue[] = [];\n\n if (elementObj === null || elementObj === undefined) {\n return { result: null, issues };\n }\n\n if (!isPlainObject(elementObj)) {\n issues.push(\n createIssue(\n 'error',\n 'INVALID_STRUCTURE',\n `_element must be an object, got ${Array.isArray(elementObj) ? 'array' : typeof elementObj}`,\n path,\n ),\n );\n return { result: null, issues };\n }\n\n const metadata: ElementMetadata = {\n ...(elementObj.id !== undefined && { id: elementObj.id as string }),\n ...(elementObj.extension !== undefined && { extension: elementObj.extension as unknown[] }),\n };\n\n // Validate id is a string if present\n if (elementObj.id !== undefined && typeof elementObj.id !== 'string') {\n issues.push(\n createIssue(\n 'error',\n 'INVALID_PRIMITIVE',\n `_element.id must be a string, got ${typeof elementObj.id}`,\n pathAppend(path, 'id'),\n ),\n );\n }\n\n // Validate extension is an array if present\n if (elementObj.extension !== undefined && !Array.isArray(elementObj.extension)) {\n issues.push(\n createIssue(\n 'error',\n 'INVALID_STRUCTURE',\n `_element.extension must be an array, got ${typeof elementObj.extension}`,\n pathAppend(path, 'extension'),\n ),\n );\n }\n\n // Warn about unexpected properties in _element\n for (const key of Object.keys(elementObj)) {\n if (key !== 'id' && key !== 'extension') {\n issues.push(\n createIssue('warning', 'UNEXPECTED_PROPERTY', `Unknown property \"${key}\" in _element`, pathAppend(path, key)),\n );\n }\n }\n\n return { result: metadata, issues };\n}\n\n// =============================================================================\n// Section 4: Merged Primitive Result\n// =============================================================================\n\n/**\n * A merged primitive value combining the JSON value with Element metadata.\n *\n * This is the internal representation produced by the parser for primitive\n * fields that have a `_element` companion.\n *\n * When no `_element` is present, the value is stored directly (not wrapped).\n */\nexport interface PrimitiveWithMetadata {\n /** The primitive value (string | number | boolean), absent when only _element is present */\n readonly value?: unknown;\n /** Element id from _element (0..1) */\n readonly id?: string;\n /** Extensions from _element (0..*) */\n readonly extension?: unknown[];\n}\n\n// =============================================================================\n// Section 5: Single Primitive Merging\n// =============================================================================\n\n/**\n * Merge a primitive value with its `_element` companion.\n *\n * Handles all combinations:\n * - Value only \u2192 returns value directly (no wrapping)\n * - Value + _element \u2192 returns `PrimitiveWithMetadata`\n * - _element only (no value) \u2192 returns `PrimitiveWithMetadata` with undefined value\n * - Neither \u2192 returns `undefined`\n *\n * @param value - The primitive JSON value (string | number | boolean | undefined)\n * @param elementExtension - The `_element` companion object (or undefined)\n * @param fhirType - The FHIR primitive type name (for JS type validation)\n * @param path - JSON path for error reporting\n *\n * @example\n * ```typescript\n * // Value only\n * mergePrimitiveElement(\"1970-03-30\", undefined, \"date\", \"Patient.birthDate\")\n * // \u2192 { result: \"1970-03-30\", issues: [] }\n *\n * // Value + _element\n * mergePrimitiveElement(\"1970-03-30\", { id: \"314159\" }, \"date\", \"Patient.birthDate\")\n * // \u2192 { result: { value: \"1970-03-30\", id: \"314159\" }, issues: [] }\n *\n * // _element only\n * mergePrimitiveElement(undefined, { extension: [...] }, \"date\", \"Patient.birthDate\")\n * // \u2192 { result: { value: undefined, extension: [...] }, issues: [] }\n * ```\n */\nexport function mergePrimitiveElement(\n value: unknown,\n elementExtension: unknown,\n fhirType: string,\n path: string,\n): { result: unknown; issues: ParseIssue[] } {\n const issues: ParseIssue[] = [];\n\n // Validate value type if present\n if (value !== undefined && value !== null) {\n const typeIssue = validatePrimitiveValue(value, fhirType, path);\n if (typeIssue) {\n issues.push(typeIssue);\n }\n }\n\n // Parse _element metadata\n const elementPath = pathAppend(path.substring(0, path.lastIndexOf('.')), `_${path.substring(path.lastIndexOf('.') + 1)}`);\n const { result: metadata, issues: elementIssues } = parseElementMetadata(\n elementExtension,\n elementExtension !== undefined ? elementPath : path,\n );\n issues.push(...elementIssues);\n\n // Merge based on what's present\n if (value === undefined && metadata === null) {\n return { result: undefined, issues };\n }\n\n if (metadata === null) {\n // Value only \u2014 return unwrapped\n return { result: value, issues };\n }\n\n // Value + metadata or metadata only \u2014 return wrapped\n const merged: PrimitiveWithMetadata = {\n ...(value !== undefined && value !== null && { value }),\n ...(metadata.id !== undefined && { id: metadata.id }),\n ...(metadata.extension !== undefined && { extension: metadata.extension }),\n };\n\n return { result: merged, issues };\n}\n\n// =============================================================================\n// Section 6: Array Primitive Merging\n// =============================================================================\n\n/**\n * Merge a repeating primitive array with its `_element` companion array.\n *\n * FHIR JSON uses null-alignment for repeating primitives:\n * ```json\n * \"code\": [\"au\", \"nz\"],\n * \"_code\": [null, { \"extension\": [...] }]\n * ```\n *\n * Rules:\n * - Both arrays must have the same length (or `_element` may be absent)\n * - `null` in the value array means \"no value at this position\" (only _element)\n * - `null` in the `_element` array means \"no metadata at this position\"\n * - If lengths differ, report `ARRAY_MISMATCH` error\n *\n * @param values - The primitive value array\n * @param elementExtensions - The `_element` companion array (or undefined)\n * @param fhirType - The FHIR primitive type name (for JS type validation)\n * @param path - JSON path for error reporting\n */\nexport function mergePrimitiveArray(\n values: unknown[],\n elementExtensions: unknown[] | undefined,\n fhirType: string,\n path: string,\n): { result: unknown[]; issues: ParseIssue[] } {\n const issues: ParseIssue[] = [];\n\n // If no _element array, just validate and return values\n if (elementExtensions === undefined) {\n const result: unknown[] = [];\n for (let i = 0; i < values.length; i++) {\n const v = values[i];\n if (v === null) {\n // null in value array without _element is unexpected\n issues.push(\n createIssue('warning', 'UNEXPECTED_NULL', `Null value at index ${i} without corresponding _element`, pathIndex(path, i)),\n );\n result.push(null);\n continue;\n }\n if (v !== undefined) {\n const typeIssue = validatePrimitiveValue(v, fhirType, pathIndex(path, i));\n if (typeIssue) issues.push(typeIssue);\n }\n result.push(v);\n }\n return { result, issues };\n }\n\n // Validate array lengths match\n if (!Array.isArray(elementExtensions)) {\n issues.push(\n createIssue('error', 'INVALID_STRUCTURE', `_element must be an array, got ${typeof elementExtensions}`, path),\n );\n // Fall back to values only, preserving the INVALID_STRUCTURE issue\n const fallback = mergePrimitiveArray(values, undefined, fhirType, path);\n return { result: fallback.result, issues: [...issues, ...fallback.issues] };\n }\n\n if (values.length !== elementExtensions.length) {\n issues.push(\n createIssue(\n 'error',\n 'ARRAY_MISMATCH',\n `Value array length (${values.length}) does not match _element array length (${elementExtensions.length})`,\n path,\n ),\n );\n }\n\n // Merge element by element, using the longer array's length\n const maxLen = Math.max(values.length, elementExtensions.length);\n const result: unknown[] = [];\n\n for (let i = 0; i < maxLen; i++) {\n const value = i < values.length ? values[i] : undefined;\n const ext = i < elementExtensions.length ? elementExtensions[i] : undefined;\n const elementPath = pathIndex(path, i);\n\n // null in value array = no value at this position\n const actualValue = value === null ? undefined : value;\n\n // null in _element array = no metadata at this position\n const actualExt = ext === null ? undefined : ext;\n\n if (actualValue === undefined && actualExt === undefined) {\n // Both null \u2014 preserve position\n result.push(null);\n continue;\n }\n\n const { result: merged, issues: mergeIssues } = mergePrimitiveElement(\n actualValue,\n actualExt,\n fhirType,\n elementPath,\n );\n issues.push(...mergeIssues);\n result.push(merged);\n }\n\n return { result, issues };\n}\n", "/**\n * Core FHIR JSON Parser Engine\n *\n * Main entry point for parsing FHIR R4 JSON into TypeScript model types.\n * Handles JSON.parse, resourceType dispatch, and provides the generic\n * complex-type parsing infrastructure used by all downstream parsers.\n *\n * Architecture:\n * ```\n * parseFhirJson(string)\n * \u2514\u2500 parseFhirObject(unknown)\n * \u251C\u2500 validateRootObject()\n * \u251C\u2500 extractResourceType()\n * \u2514\u2500 dispatch by resourceType:\n * \u251C\u2500 \"StructureDefinition\" \u2192 parseStructureDefinitionObject() [Task 2.5]\n * \u2514\u2500 other \u2192 parseGenericResource()\n * ```\n *\n * This module also exports lower-level utilities (`parseComplexObject`,\n * `isPlainObject`, path helpers) that Task 2.3\u20132.5 build upon.\n *\n * @module fhir-parser\n */\n\nimport type { Resource } from '../model/primitives.js';\nimport {\n type ParseResult,\n type ParseIssue,\n createIssue,\n parseSuccess,\n parseFailure,\n hasErrors,\n} from './parse-error.js';\nimport { parseStructureDefinition } from './structure-definition-parser.js';\nimport { mergePrimitiveElement, mergePrimitiveArray } from './primitive-parser.js';\n\n// =============================================================================\n// Section 1: Type Guards & Utilities\n// =============================================================================\n\n/**\n * A plain JSON object \u2014 `Record<string, unknown>` that is not null and not an array.\n *\n * This is the fundamental input shape for all FHIR complex type parsers.\n */\nexport type JsonObject = Record<string, unknown>;\n\n/**\n * Check whether a value is a plain JSON object (non-null, non-array, typeof \"object\").\n */\nexport function isPlainObject(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n// =============================================================================\n// Section 2: Path Helpers\n// =============================================================================\n\n/**\n * Append a property name to a JSON path.\n *\n * @example\n * pathAppend(\"Patient\", \"name\") // \"Patient.name\"\n * pathAppend(\"$\", \"resourceType\") // \"$.resourceType\"\n */\nexport function pathAppend(base: string, property: string): string {\n return `${base}.${property}`;\n}\n\n/**\n * Append an array index to a JSON path.\n *\n * @example\n * pathIndex(\"Patient.name\", 0) // \"Patient.name[0]\"\n */\nexport function pathIndex(base: string, index: number): string {\n return `${base}[${index}]`;\n}\n\n// =============================================================================\n// Section 3: Generic Complex Object Parser\n// =============================================================================\n\n/**\n * Metadata describing a single property of a FHIR complex type.\n *\n * Used by {@link parseComplexObject} to know how to interpret each JSON key.\n */\nexport interface PropertyDescriptor {\n /** The property name as it appears in the TypeScript interface */\n readonly name: string;\n\n /**\n * Whether this property holds a primitive FHIR type.\n *\n * When true, the parser will look for a companion `_name` property\n * carrying id/extension metadata (FHIR primitive element split).\n */\n readonly isPrimitive: boolean;\n\n /**\n * The FHIR primitive type name (e.g., `'string'`, `'boolean'`, `'id'`).\n *\n * Required when `isPrimitive` is true. Used by `mergePrimitiveElement`\n * to validate the JavaScript type of the value (string, number, or boolean).\n * Defaults to `'string'` when not specified.\n */\n readonly fhirType?: string;\n\n /**\n * Whether this property is an array (max cardinality > 1).\n *\n * FHIR JSON always uses arrays for repeating elements, even when\n * only one value is present.\n */\n readonly isArray: boolean;\n\n /**\n * Parser function for complex-type values.\n *\n * Called for each value (or array element) to recursively parse\n * nested complex types. If `undefined`, the value is passed through\n * as-is (used for primitives and `unknown` choice-type placeholders).\n */\n readonly parseElement?: (obj: JsonObject, path: string) => { result: unknown; issues: ParseIssue[] };\n}\n\n/**\n * A schema describing all known properties of a FHIR complex type.\n *\n * Maps property names to their descriptors. Properties not in this map\n * are reported as `UNEXPECTED_PROPERTY` warnings.\n *\n * Choice type `[x]` fields are NOT included here \u2014 they are handled\n * separately by the choice-type-parser (Task 2.4).\n */\nexport type PropertySchema = ReadonlyMap<string, PropertyDescriptor>;\n\n/**\n * Result of parsing a complex object \u2014 the assembled result record\n * plus any issues collected during parsing.\n */\nexport interface ComplexParseResult {\n readonly result: JsonObject;\n readonly issues: ParseIssue[];\n}\n\n/**\n * Parse a FHIR complex type JSON object using a property schema.\n *\n * This is the workhorse function that all type-specific parsers delegate to.\n * It uses a 4-pass strategy to process the JSON object's keys:\n *\n * 1. **Pass 1: Known properties** \u2014 maps non-primitive properties into the result,\n * recursing for complex types. Primitive properties are marked as consumed but\n * their values are deferred to Pass 2 for `_element` merging.\n * 2. **Pass 2: Primitive `_element` merging** \u2014 for each primitive property in the\n * schema, calls `mergePrimitiveElement` (or `mergePrimitiveArray`) from\n * primitive-parser to merge the JSON value with its `_name` companion carrying\n * id/extension metadata.\n * 3. **Pass 3: Choice type `[x]`** \u2014 identifies choice type properties by matching\n * `choiceFieldBases` prefixes with uppercase type suffixes, stores values as-is\n * (full extraction delegated to choice-type-parser in Task 2.4)\n * 4. **Pass 4: Unexpected properties** \u2014 emits `UNEXPECTED_PROPERTY` warnings for\n * any remaining unconsumed keys\n *\n * @param obj - The raw JSON object to parse\n * @param path - Current JSON path (for error reporting)\n * @param schema - Property descriptors for this type\n * @param choiceFieldBases - Base names of choice type `[x]` fields (e.g., `[\"value\", \"defaultValue\"]`).\n * Any key starting with one of these bases is treated as a potential choice type\n * property and NOT flagged as unexpected. Actual choice type extraction is\n * deferred to Task 2.4.\n */\nexport function parseComplexObject(\n obj: JsonObject,\n path: string,\n schema: PropertySchema,\n choiceFieldBases: readonly string[] = [],\n): ComplexParseResult {\n const result: Record<string, unknown> = {};\n const issues: ParseIssue[] = [];\n\n // Collect all keys that are accounted for (known, _, or choice-type)\n const consumedKeys = new Set<string>();\n\n // --- Pass 1: Process known NON-primitive properties ---\n // Primitive properties are deferred to Pass 2 for _element merging.\n for (const [key, descriptor] of schema) {\n const value = obj[key];\n\n // Mark key as consumed even if we defer processing\n if (value !== undefined) {\n consumedKeys.add(key);\n }\n\n // Skip primitives \u2014 handled in Pass 2 with _element merging\n if (descriptor.isPrimitive) continue;\n\n if (value === undefined) continue;\n\n if (value === null) {\n // FHIR JSON: null is only valid inside arrays for primitive alignment\n issues.push(createIssue('error', 'UNEXPECTED_NULL', `Property \"${key}\" must not be null`, pathAppend(path, key)));\n continue;\n }\n\n if (descriptor.isArray) {\n result[key] = parseArrayProperty(value, key, path, descriptor, issues);\n } else if (descriptor.parseElement && isPlainObject(value)) {\n const nested = descriptor.parseElement(value, pathAppend(path, key));\n result[key] = nested.result;\n issues.push(...nested.issues);\n } else {\n // Pass-through value (complex type without dedicated parser)\n result[key] = value;\n }\n }\n\n // --- Pass 2: Merge primitive properties with _element companions ---\n for (const [key, descriptor] of schema) {\n if (!descriptor.isPrimitive) continue;\n\n const value = obj[key];\n const underscoreKey = `_${key}`;\n const elementExt = obj[underscoreKey];\n\n // Consume the _element companion key\n if (elementExt !== undefined) {\n consumedKeys.add(underscoreKey);\n }\n\n // Skip if neither value nor _element is present\n if (value === undefined && elementExt === undefined) continue;\n\n // null top-level primitive value is an error (not inside an array)\n if (value === null && elementExt === undefined) {\n issues.push(createIssue('error', 'UNEXPECTED_NULL', `Property \"${key}\" must not be null`, pathAppend(path, key)));\n continue;\n }\n\n const fhirType = descriptor.fhirType ?? 'string';\n const propPath = pathAppend(path, key);\n\n if (descriptor.isArray) {\n // Array primitive \u2014 use mergePrimitiveArray\n if (value !== undefined && !Array.isArray(value)) {\n issues.push(createIssue('error', 'INVALID_STRUCTURE', `Property \"${key}\" must be an array`, propPath));\n continue;\n }\n const valArr = (value as unknown[] | undefined) ?? [];\n const extArr = elementExt as unknown[] | undefined;\n const { result: merged, issues: mergeIssues } = mergePrimitiveArray(valArr, extArr, fhirType, propPath);\n result[key] = merged;\n issues.push(...mergeIssues);\n } else {\n // Single primitive \u2014 use mergePrimitiveElement\n const actualValue = value === null ? undefined : value;\n const { result: merged, issues: mergeIssues } = mergePrimitiveElement(actualValue, elementExt, fhirType, propPath);\n if (merged !== undefined) {\n result[key] = merged;\n }\n issues.push(...mergeIssues);\n }\n }\n\n // --- Pass 3: Identify choice type properties ---\n for (const key of Object.keys(obj)) {\n if (consumedKeys.has(key)) continue;\n\n // Check if this key matches a choice type base name\n const isChoiceKey = choiceFieldBases.some((base) => {\n if (!key.startsWith(base)) return false;\n // The character after the base must be uppercase (type suffix)\n const suffix = key.slice(base.length);\n return suffix.length > 0 && suffix[0] === suffix[0].toUpperCase() && suffix[0] !== suffix[0].toLowerCase();\n });\n\n if (isChoiceKey) {\n consumedKeys.add(key);\n // Store choice type value as-is; full extraction in Task 2.4\n result[key] = obj[key];\n\n // Also consume the companion _element if present\n const underscoreKey = `_${key}`;\n if (obj[underscoreKey] !== undefined) {\n consumedKeys.add(underscoreKey);\n result[underscoreKey] = obj[underscoreKey];\n }\n }\n }\n\n // --- Pass 4: Report unexpected properties ---\n for (const key of Object.keys(obj)) {\n if (consumedKeys.has(key)) continue;\n\n // Skip _-prefixed keys that were already consumed in Pass 2 (primitive _element)\n // or Pass 3 (choice type _element). Do NOT skip based solely on the base name\n // being consumed \u2014 _element is only valid for primitive and choice type properties.\n if (key.startsWith('_') && consumedKeys.has(key)) continue;\n\n issues.push(\n createIssue('warning', 'UNEXPECTED_PROPERTY', `Unknown property \"${key}\"`, pathAppend(path, key)),\n );\n }\n\n return { result, issues };\n}\n\n/**\n * Parse an array property value.\n *\n * Validates that the value is actually an array, then parses each element.\n */\nfunction parseArrayProperty(\n value: unknown,\n key: string,\n parentPath: string,\n descriptor: PropertyDescriptor,\n issues: ParseIssue[],\n): unknown[] {\n const arrayPath = pathAppend(parentPath, key);\n\n if (!Array.isArray(value)) {\n issues.push(\n createIssue('error', 'INVALID_STRUCTURE', `Property \"${key}\" must be an array`, arrayPath),\n );\n // Wrap single value in array as recovery\n return [value];\n }\n\n // FHIR: empty arrays are not valid \u2014 omit the property instead\n if (value.length === 0) {\n issues.push(\n createIssue('warning', 'INVALID_STRUCTURE', `Property \"${key}\" is an empty array (should be omitted)`, arrayPath),\n );\n return [];\n }\n\n const results: unknown[] = [];\n\n for (let i = 0; i < value.length; i++) {\n const element = value[i];\n const elementPath = pathIndex(arrayPath, i);\n\n if (element === null) {\n // null in arrays is valid for primitive alignment; pass through\n results.push(null);\n continue;\n }\n\n if (descriptor.parseElement && isPlainObject(element)) {\n const nested = descriptor.parseElement(element, elementPath);\n results.push(nested.result);\n issues.push(...nested.issues);\n } else {\n results.push(element);\n }\n }\n\n return results;\n}\n\n// =============================================================================\n// Section 4: Resource-Level Parsing\n// =============================================================================\n\n/**\n * Property schema for the base FHIR Resource type.\n *\n * Covers the 5 fields defined on Resource:\n * - resourceType (string, required)\n * - id (primitive, optional)\n * - meta (complex, optional)\n * - implicitRules (primitive, optional)\n * - language (primitive, optional)\n *\n * Used by {@link parseGenericResource} to validate and extract base fields\n * via {@link parseComplexObject}.\n */\nconst RESOURCE_SCHEMA: PropertySchema = new Map<string, PropertyDescriptor>([\n ['resourceType', { name: 'resourceType', isPrimitive: true, isArray: false, fhirType: 'code' }],\n ['id', { name: 'id', isPrimitive: true, isArray: false, fhirType: 'id' }],\n ['meta', { name: 'meta', isPrimitive: false, isArray: false }],\n ['implicitRules', { name: 'implicitRules', isPrimitive: true, isArray: false, fhirType: 'uri' }],\n ['language', { name: 'language', isPrimitive: true, isArray: false, fhirType: 'code' }],\n]);\n\n/**\n * Parse a generic FHIR resource from a JSON object.\n *\n * Uses {@link parseComplexObject} with {@link RESOURCE_SCHEMA} to extract\n * the base `Resource` fields (resourceType, id, meta, implicitRules, language)\n * and report unknown properties as warnings.\n *\n * This is the fallback for resource types that don't have a dedicated parser.\n *\n * @param obj - The raw JSON object (already validated as a plain object with resourceType)\n * @param resourceType - The extracted resourceType value\n * @param path - JSON path for error reporting\n */\nfunction parseGenericResource(\n obj: JsonObject,\n resourceType: string,\n path: string,\n): { result: Resource; issues: ParseIssue[] } {\n const { result: parsed, issues } = parseComplexObject(obj, path, RESOURCE_SCHEMA);\n\n const result: Resource = {\n resourceType,\n ...(parsed.id !== undefined && { id: parsed.id as Resource['id'] }),\n ...(parsed.meta !== undefined && { meta: parsed.meta as Resource['meta'] }),\n ...(parsed.implicitRules !== undefined && { implicitRules: parsed.implicitRules as Resource['implicitRules'] }),\n ...(parsed.language !== undefined && { language: parsed.language as Resource['language'] }),\n };\n\n return { result, issues };\n}\n\n// =============================================================================\n// Section 5: Public API\n// =============================================================================\n\n/**\n * Parse a FHIR JSON string into a Resource object.\n *\n * This is the main entry point for the parser. It:\n * 1. Calls `JSON.parse()` with error capture\n * 2. Delegates to {@link parseFhirObject} for structural parsing\n *\n * Stage-1 supports dedicated parsing for `StructureDefinition` (Task 2.5).\n * All other resource types are parsed generically.\n *\n * @param json - A FHIR JSON string\n * @returns A `ParseResult` containing the parsed `Resource` or error details\n *\n * @example\n * ```typescript\n * const result = parseFhirJson('{\"resourceType\":\"Patient\",\"id\":\"123\"}');\n * if (result.success) {\n * console.log(result.data.resourceType); // \"Patient\"\n * }\n * ```\n */\nexport function parseFhirJson(json: string): ParseResult<Resource> {\n // Step 1: JSON.parse with error capture\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch (e) {\n const message = e instanceof SyntaxError ? e.message : 'Invalid JSON';\n return parseFailure<Resource>([\n createIssue('error', 'INVALID_JSON', message, '$'),\n ]);\n }\n\n // Step 2: Delegate to object parser\n return parseFhirObject(parsed);\n}\n\n/**\n * Parse an already-parsed JSON value into a Resource object.\n *\n * Use this when you already have a JavaScript object (e.g., from a database\n * or from `JSON.parse()` called externally).\n *\n * @param obj - An unknown value (expected to be a plain JSON object with `resourceType`)\n * @returns A `ParseResult` containing the parsed `Resource` or error details\n */\nexport function parseFhirObject(obj: unknown): ParseResult<Resource> {\n const issues: ParseIssue[] = [];\n\n // Step 1: Validate root is a plain object\n if (!isPlainObject(obj)) {\n return parseFailure<Resource>([\n createIssue(\n 'error',\n 'INVALID_STRUCTURE',\n `Expected a JSON object, got ${obj === null ? 'null' : Array.isArray(obj) ? 'array' : typeof obj}`,\n '$',\n ),\n ]);\n }\n\n // Step 2: Extract and validate resourceType\n const resourceType = obj.resourceType;\n\n if (resourceType === undefined || resourceType === null) {\n return parseFailure<Resource>([\n createIssue('error', 'MISSING_RESOURCE_TYPE', 'Missing required property \"resourceType\"', '$'),\n ]);\n }\n\n if (typeof resourceType !== 'string') {\n return parseFailure<Resource>([\n createIssue(\n 'error',\n 'INVALID_PRIMITIVE',\n `\"resourceType\" must be a string, got ${typeof resourceType}`,\n '$.resourceType',\n ),\n ]);\n }\n\n if (resourceType.length === 0) {\n return parseFailure<Resource>([\n createIssue('error', 'INVALID_PRIMITIVE', '\"resourceType\" must not be empty', '$.resourceType'),\n ]);\n }\n\n const path = resourceType;\n\n // Step 3: Dispatch by resourceType\n let result: Resource;\n if (resourceType === 'StructureDefinition') {\n const sdResult = parseStructureDefinition(obj, path);\n issues.push(...sdResult.issues);\n if (!sdResult.success) {\n return parseFailure<Resource>(issues);\n }\n result = sdResult.data;\n } else {\n const generic = parseGenericResource(obj, resourceType, path);\n issues.push(...generic.issues);\n result = generic.result;\n }\n\n if (hasErrors(issues)) {\n return parseFailure<Resource>(issues);\n }\n\n return parseSuccess(result, issues);\n}\n", "/**\n * FHIR JSON Serializer\n *\n * Converts TypeScript model objects back into FHIR R4 JSON.\n * This is the inverse of the parser: it takes a `Resource` (or more\n * specifically a `StructureDefinition`) and produces a FHIR-conformant\n * JSON string or plain object.\n *\n * ## Serialization Rules\n *\n * 1. **resourceType first** \u2014 always the first property in output\n * 2. **Choice type restoration** \u2014 `ChoiceValue.propertyName` restores the\n * original JSON property name (e.g., `fixedString`, `patternCoding`)\n * 3. **Empty value omission** \u2014 `undefined`, empty arrays `[]`, and\n * empty objects `{}` are omitted from output\n * 4. **Property ordering** \u2014 `resourceType` first, then remaining\n * properties in alphabetical order (FHIR canonical JSON convention)\n * 5. **Null alignment** \u2014 preserved in arrays for primitive `_element` alignment\n *\n * ## Scope (Stage-1)\n *\n * Stage-1 focuses on StructureDefinition serialization. The serializer\n * handles:\n * - All StructureDefinition top-level fields\n * - All ElementDefinition fields including sub-types\n * - Choice type fields (defaultValue[x], fixed[x], pattern[x], minValue[x], maxValue[x])\n * - Example value[x] choice types\n * - snapshot/differential element containers\n *\n * @module fhir-parser\n */\n\nimport type { Resource } from '../model/primitives.js';\nimport type {\n StructureDefinition,\n StructureDefinitionMapping,\n StructureDefinitionContext,\n} from '../model/structure-definition.js';\nimport type {\n ElementDefinition,\n ElementDefinitionSlicing,\n SlicingDiscriminator,\n ElementDefinitionBase,\n ElementDefinitionType,\n ElementDefinitionConstraint,\n ElementDefinitionBinding,\n ElementDefinitionExample,\n ElementDefinitionMapping,\n} from '../model/element-definition.js';\nimport type { ChoiceValue } from './choice-type-parser.js';\n\n// =============================================================================\n// Section 1: Public API\n// =============================================================================\n\n/**\n * Serialize a Resource object to a FHIR JSON string.\n *\n * Output conforms to FHIR R4 JSON conventions:\n * - `resourceType` is the first property\n * - Remaining properties are in alphabetical order\n * - Choice type fields use their original JSON property names\n * - Empty values (`undefined`, `[]`, `{}`) are omitted\n *\n * @param resource - The Resource to serialize\n * @returns A FHIR JSON string (pretty-printed with 2-space indent)\n *\n * @example\n * ```typescript\n * const sd: StructureDefinition = { resourceType: 'StructureDefinition', ... };\n * const json = serializeToFhirJson(sd);\n * // '{\\n \"resourceType\": \"StructureDefinition\",\\n ...\\n}'\n * ```\n */\nexport function serializeToFhirJson(resource: Resource): string {\n const obj = serializeToFhirObject(resource);\n return JSON.stringify(obj, null, 2);\n}\n\n/**\n * Serialize a Resource object to a plain JavaScript object suitable\n * for FHIR JSON (without calling `JSON.stringify`).\n *\n * Use this when you need the object form (e.g., for storage or\n * further manipulation) rather than a string.\n *\n * @param resource - The Resource to serialize\n * @returns A plain object conforming to FHIR JSON conventions\n */\nexport function serializeToFhirObject(\n resource: Resource,\n): Record<string, unknown> {\n if (resource.resourceType === 'StructureDefinition') {\n return serializeStructureDefinition(resource as StructureDefinition);\n }\n return serializeGenericResource(resource);\n}\n\n// =============================================================================\n// Section 2: StructureDefinition Serializer\n// =============================================================================\n\n/**\n * Serialize a StructureDefinition to a FHIR JSON object.\n *\n * Handles all top-level fields, sub-types (mapping, context, snapshot,\n * differential), and preserves property ordering conventions.\n */\nfunction serializeStructureDefinition(\n sd: StructureDefinition,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n // resourceType always first\n result.resourceType = sd.resourceType;\n\n // Collect all other properties in alphabetical order\n const props: Record<string, unknown> = {};\n\n // Resource base fields\n assignIfDefined(props, 'id', sd.id);\n assignIfDefined(props, 'meta', sd.meta);\n assignIfDefined(props, 'implicitRules', sd.implicitRules);\n assignIfDefined(props, 'language', sd.language);\n\n // DomainResource fields\n assignIfDefined(props, 'text', sd.text);\n assignIfNotEmptyArray(props, 'contained', sd.contained);\n assignIfNotEmptyArray(props, 'extension', sd.extension);\n assignIfNotEmptyArray(props, 'modifierExtension', sd.modifierExtension);\n\n // StructureDefinition metadata\n props.url = sd.url;\n assignIfNotEmptyArray(props, 'identifier', sd.identifier);\n assignIfDefined(props, 'version', sd.version);\n props.name = sd.name;\n assignIfDefined(props, 'title', sd.title);\n props.status = sd.status;\n assignIfDefined(props, 'experimental', sd.experimental);\n assignIfDefined(props, 'date', sd.date);\n assignIfDefined(props, 'publisher', sd.publisher);\n assignIfNotEmptyArray(props, 'contact', sd.contact);\n assignIfDefined(props, 'description', sd.description);\n assignIfNotEmptyArray(props, 'useContext', sd.useContext);\n assignIfNotEmptyArray(props, 'jurisdiction', sd.jurisdiction);\n assignIfDefined(props, 'purpose', sd.purpose);\n assignIfDefined(props, 'copyright', sd.copyright);\n assignIfNotEmptyArray(props, 'keyword', sd.keyword);\n assignIfDefined(props, 'fhirVersion', sd.fhirVersion);\n\n // Mapping\n if (sd.mapping && sd.mapping.length > 0) {\n props.mapping = sd.mapping.map(serializeSDMapping);\n }\n\n // Core semantic fields\n props.kind = sd.kind;\n props.abstract = sd.abstract;\n\n // Context (extension definitions)\n if (sd.context && sd.context.length > 0) {\n props.context = sd.context.map(serializeSDContext);\n }\n assignIfNotEmptyArray(props, 'contextInvariant', sd.contextInvariant);\n\n props.type = sd.type;\n assignIfDefined(props, 'baseDefinition', sd.baseDefinition);\n assignIfDefined(props, 'derivation', sd.derivation);\n\n // Snapshot & Differential\n if (sd.snapshot) {\n props.snapshot = serializeElementContainer(sd.snapshot);\n }\n if (sd.differential) {\n props.differential = serializeElementContainer(sd.differential);\n }\n\n // Sort remaining properties alphabetically and merge\n const sortedKeys = Object.keys(props).sort();\n for (const key of sortedKeys) {\n result[key] = props[key];\n }\n\n return result;\n}\n\n/**\n * Serialize a generic Resource (non-StructureDefinition).\n * Passes through all properties, with resourceType first and rest sorted.\n */\nfunction serializeGenericResource(resource: Resource): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n result.resourceType = resource.resourceType;\n\n const props: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(resource)) {\n if (key === 'resourceType') continue;\n if (value === undefined) continue;\n props[key] = value;\n }\n\n const sortedKeys = Object.keys(props).sort();\n for (const key of sortedKeys) {\n result[key] = props[key];\n }\n\n return result;\n}\n\n// =============================================================================\n// Section 3: Sub-Type Serializers\n// =============================================================================\n\n/**\n * Serialize a StructureDefinitionMapping.\n */\nfunction serializeSDMapping(\n mapping: StructureDefinitionMapping,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n assignIfDefined(result, 'id', mapping.id);\n assignIfNotEmptyArray(result, 'extension', mapping.extension);\n assignIfNotEmptyArray(result, 'modifierExtension', mapping.modifierExtension);\n result.identity = mapping.identity;\n assignIfDefined(result, 'uri', mapping.uri);\n assignIfDefined(result, 'name', mapping.name);\n assignIfDefined(result, 'comment', mapping.comment);\n return result;\n}\n\n/**\n * Serialize a StructureDefinitionContext.\n */\nfunction serializeSDContext(\n context: StructureDefinitionContext,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n assignIfDefined(result, 'id', context.id);\n assignIfNotEmptyArray(result, 'extension', context.extension);\n assignIfNotEmptyArray(result, 'modifierExtension', context.modifierExtension);\n result.type = context.type;\n result.expression = context.expression;\n return result;\n}\n\n/**\n * Serialize a snapshot or differential element container.\n */\nfunction serializeElementContainer(\n container: { element: ElementDefinition[]; id?: unknown; extension?: unknown[]; modifierExtension?: unknown[] },\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n assignIfDefined(result, 'id', container.id);\n assignIfNotEmptyArray(result, 'extension', container.extension);\n assignIfNotEmptyArray(result, 'modifierExtension', container.modifierExtension);\n result.element = container.element.map(serializeElementDefinition);\n return result;\n}\n\n// =============================================================================\n// Section 4: ElementDefinition Serializer\n// =============================================================================\n\n/**\n * Serialize an ElementDefinition to a FHIR JSON object.\n *\n * Handles all 37+ fields, sub-types, and choice type restoration.\n * Choice type fields (defaultValue, fixed, pattern, minValue, maxValue)\n * are stored as `ChoiceValue` objects in the model; this function\n * restores them to their original JSON property names.\n */\nfunction serializeElementDefinition(ed: ElementDefinition): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n // BackboneElement base\n assignIfDefined(result, 'id', ed.id);\n assignIfNotEmptyArray(result, 'extension', ed.extension);\n assignIfNotEmptyArray(result, 'modifierExtension', ed.modifierExtension);\n\n // Core path & identity\n result.path = ed.path;\n assignIfNotEmptyArray(result, 'representation', ed.representation);\n assignIfDefined(result, 'sliceName', ed.sliceName);\n assignIfDefined(result, 'sliceIsConstraining', ed.sliceIsConstraining);\n assignIfDefined(result, 'label', ed.label);\n assignIfNotEmptyArray(result, 'code', ed.code);\n\n // Slicing\n if (ed.slicing) {\n result.slicing = serializeSlicing(ed.slicing);\n }\n\n // Documentation\n assignIfDefined(result, 'short', ed.short);\n assignIfDefined(result, 'definition', ed.definition);\n assignIfDefined(result, 'comment', ed.comment);\n assignIfDefined(result, 'requirements', ed.requirements);\n assignIfNotEmptyArray(result, 'alias', ed.alias);\n\n // Cardinality\n assignIfDefined(result, 'min', ed.min);\n assignIfDefined(result, 'max', ed.max);\n\n // Base\n if (ed.base) {\n result.base = serializeBase(ed.base);\n }\n\n // Content reference\n assignIfDefined(result, 'contentReference', ed.contentReference);\n\n // Type\n if (ed.type && ed.type.length > 0) {\n result.type = ed.type.map(serializeEDType);\n }\n\n // Choice type fields \u2014 restore to original JSON property names\n serializeChoiceValue(result, ed.defaultValue);\n assignIfDefined(result, 'meaningWhenMissing', ed.meaningWhenMissing);\n assignIfDefined(result, 'orderMeaning', ed.orderMeaning);\n serializeChoiceValue(result, ed.fixed);\n serializeChoiceValue(result, ed.pattern);\n\n // Examples\n if (ed.example && ed.example.length > 0) {\n result.example = ed.example.map(serializeExample);\n }\n\n // Value range (choice types)\n serializeChoiceValue(result, ed.minValue);\n serializeChoiceValue(result, ed.maxValue);\n\n // Max length\n assignIfDefined(result, 'maxLength', ed.maxLength);\n\n // Constraints\n assignIfNotEmptyArray(result, 'condition', ed.condition);\n if (ed.constraint && ed.constraint.length > 0) {\n result.constraint = ed.constraint.map(serializeConstraint);\n }\n\n // Flags\n assignIfDefined(result, 'mustSupport', ed.mustSupport);\n assignIfDefined(result, 'isModifier', ed.isModifier);\n assignIfDefined(result, 'isModifierReason', ed.isModifierReason);\n assignIfDefined(result, 'isSummary', ed.isSummary);\n\n // Binding\n if (ed.binding) {\n result.binding = serializeBinding(ed.binding);\n }\n\n // Mapping\n if (ed.mapping && ed.mapping.length > 0) {\n result.mapping = ed.mapping.map(serializeEDMapping);\n }\n\n return result;\n}\n\n// =============================================================================\n// Section 5: ElementDefinition Sub-Type Serializers\n// =============================================================================\n\n/**\n * Serialize ElementDefinitionSlicing.\n */\nfunction serializeSlicing(\n slicing: ElementDefinitionSlicing,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n assignIfDefined(result, 'id', slicing.id);\n assignIfNotEmptyArray(result, 'extension', slicing.extension);\n\n if (slicing.discriminator && slicing.discriminator.length > 0) {\n result.discriminator = slicing.discriminator.map(serializeDiscriminator);\n }\n\n assignIfDefined(result, 'description', slicing.description);\n assignIfDefined(result, 'ordered', slicing.ordered);\n result.rules = slicing.rules;\n return result;\n}\n\n/**\n * Serialize SlicingDiscriminator.\n */\nfunction serializeDiscriminator(\n disc: SlicingDiscriminator,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n assignIfDefined(result, 'id', disc.id);\n assignIfNotEmptyArray(result, 'extension', disc.extension);\n result.type = disc.type;\n result.path = disc.path;\n return result;\n}\n\n/**\n * Serialize ElementDefinitionBase.\n */\nfunction serializeBase(\n base: ElementDefinitionBase,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n assignIfDefined(result, 'id', base.id);\n assignIfNotEmptyArray(result, 'extension', base.extension);\n result.path = base.path;\n result.min = base.min;\n result.max = base.max;\n return result;\n}\n\n/**\n * Serialize ElementDefinitionType.\n */\nfunction serializeEDType(\n type: ElementDefinitionType,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n assignIfDefined(result, 'id', type.id);\n assignIfNotEmptyArray(result, 'extension', type.extension);\n result.code = type.code;\n assignIfNotEmptyArray(result, 'profile', type.profile);\n assignIfNotEmptyArray(result, 'targetProfile', type.targetProfile);\n assignIfNotEmptyArray(result, 'aggregation', type.aggregation);\n assignIfDefined(result, 'versioning', type.versioning);\n return result;\n}\n\n/**\n * Serialize ElementDefinitionConstraint.\n */\nfunction serializeConstraint(\n constraint: ElementDefinitionConstraint,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n assignIfDefined(result, 'id', constraint.id);\n assignIfNotEmptyArray(result, 'extension', constraint.extension);\n result.key = constraint.key;\n assignIfDefined(result, 'requirements', constraint.requirements);\n result.severity = constraint.severity;\n result.human = constraint.human;\n assignIfDefined(result, 'expression', constraint.expression);\n assignIfDefined(result, 'xpath', constraint.xpath);\n assignIfDefined(result, 'source', constraint.source);\n return result;\n}\n\n/**\n * Serialize ElementDefinitionBinding.\n */\nfunction serializeBinding(\n binding: ElementDefinitionBinding,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n assignIfDefined(result, 'id', binding.id);\n assignIfNotEmptyArray(result, 'extension', binding.extension);\n result.strength = binding.strength;\n assignIfDefined(result, 'description', binding.description);\n assignIfDefined(result, 'valueSet', binding.valueSet);\n return result;\n}\n\n/**\n * Serialize ElementDefinitionExample.\n *\n * The `value` field is a choice type stored as a `ChoiceValue` object.\n * This function restores it to the original JSON property name.\n */\nfunction serializeExample(\n example: ElementDefinitionExample,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n assignIfDefined(result, 'id', example.id);\n assignIfNotEmptyArray(result, 'extension', example.extension);\n result.label = example.label;\n\n // Restore choice type value\n const choiceVal = example.value;\n if (choiceVal !== undefined && choiceVal !== null) {\n if (isChoiceValue(choiceVal)) {\n result[choiceVal.propertyName] = choiceVal.value;\n if (choiceVal.elementExtension !== undefined) {\n result[`_${choiceVal.propertyName}`] = choiceVal.elementExtension;\n }\n } else {\n // Fallback: if not a ChoiceValue, store as-is under a generic key\n result.value = choiceVal;\n }\n }\n\n return result;\n}\n\n/**\n * Serialize ElementDefinitionMapping.\n */\nfunction serializeEDMapping(\n mapping: ElementDefinitionMapping,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n assignIfDefined(result, 'id', mapping.id);\n assignIfNotEmptyArray(result, 'extension', mapping.extension);\n result.identity = mapping.identity;\n assignIfDefined(result, 'language', mapping.language);\n result.map = mapping.map;\n assignIfDefined(result, 'comment', mapping.comment);\n return result;\n}\n\n// =============================================================================\n// Section 6: Choice Type Serialization\n// =============================================================================\n\n/**\n * Check whether a value is a `ChoiceValue` object (duck typing).\n *\n * A ChoiceValue has: `typeName`, `value`, `propertyName`.\n */\nfunction isChoiceValue(val: unknown): val is ChoiceValue {\n if (typeof val !== 'object' || val === null) return false;\n const obj = val as Record<string, unknown>;\n return (\n typeof obj.typeName === 'string' &&\n typeof obj.propertyName === 'string' &&\n 'value' in obj\n );\n}\n\n/**\n * Serialize a choice type value onto the result object.\n *\n * If the value is a `ChoiceValue`, restores the original JSON property name\n * (e.g., `fixedString`, `patternCoding`). Also restores `_element` companion\n * if present.\n *\n * @param result - The target object to write properties onto\n * @param choiceVal - The choice type value (may be undefined, null, or ChoiceValue)\n */\nfunction serializeChoiceValue(\n result: Record<string, unknown>,\n choiceVal: unknown,\n): void {\n if (choiceVal === undefined || choiceVal === null) return;\n\n if (isChoiceValue(choiceVal)) {\n result[choiceVal.propertyName] = choiceVal.value;\n if (choiceVal.elementExtension !== undefined) {\n result[`_${choiceVal.propertyName}`] = choiceVal.elementExtension;\n }\n }\n}\n\n// =============================================================================\n// Section 7: Utility Helpers\n// =============================================================================\n\n/**\n * Assign a value to the result object only if it is defined (not undefined).\n */\nfunction assignIfDefined(\n result: Record<string, unknown>,\n key: string,\n value: unknown,\n): void {\n if (value !== undefined) {\n result[key] = value;\n }\n}\n\n/**\n * Assign an array to the result object only if it is defined and non-empty.\n */\nfunction assignIfNotEmptyArray(\n result: Record<string, unknown>,\n key: string,\n value: unknown[] | undefined,\n): void {\n if (value !== undefined && Array.isArray(value) && value.length > 0) {\n result[key] = value;\n }\n}\n", "/**\n * fhir-context \u2014 Public Interfaces & Types\n *\n * Defines the core abstractions for the FHIR context module:\n * - {@link FhirContext} \u2014 central registry and lifecycle manager\n * - {@link StructureDefinitionLoader} \u2014 pluggable loading strategy\n * - {@link LoaderOptions} \u2014 loader configuration\n * - {@link ContextStatistics} \u2014 runtime metrics\n *\n * This module is conceptually equivalent to HAPI's `FhirContext` +\n * `IValidationSupport` interface, adapted for TypeScript/async patterns.\n *\n * @see https://hapifhir.io/hapi-fhir/docs/\n * @module fhir-context\n */\n\nimport type { StructureDefinition, CanonicalProfile } from '../model/index.js';\n\n// =============================================================================\n// Section 1: FhirContext Interface\n// =============================================================================\n\n/**\n * Central registry and lifecycle manager for FHIR StructureDefinitions.\n *\n * `FhirContext` is the primary entry point for accessing FHIR definitions\n * at runtime. It manages loading, caching, and resolution of\n * StructureDefinitions from one or more sources.\n *\n * Conceptual mapping:\n * - HAPI `FhirContext` \u2192 registry + lifecycle\n * - HAPI `IValidationSupport` \u2192 loader delegation\n *\n * Phase 4 (`fhir-profile`) will use this interface to load base definitions\n * during snapshot generation.\n *\n * @example\n * ```typescript\n * const context = new FhirContextImpl({ loaders: [memoryLoader, fileLoader] });\n * await context.preloadCoreDefinitions();\n *\n * const patient = await context.loadStructureDefinition(\n * 'http://hl7.org/fhir/StructureDefinition/Patient'\n * );\n * const chain = await context.resolveInheritanceChain(patient.url!);\n * // \u2192 ['http://hl7.org/fhir/StructureDefinition/Patient',\n * // 'http://hl7.org/fhir/StructureDefinition/DomainResource',\n * // 'http://hl7.org/fhir/StructureDefinition/Resource']\n * ```\n */\nexport interface FhirContext {\n /**\n * Load a StructureDefinition by canonical URL.\n *\n * Resolution order:\n * 1. Check internal registry (cache hit)\n * 2. Delegate to configured loaders (cache miss)\n * 3. Parse, validate, and register the result\n *\n * Supports versioned URLs in `url|version` format\n * (e.g., `\"http://example.org/Profile|1.0.0\"`).\n *\n * @param url - Canonical URL, optionally with `|version` suffix\n * @returns Resolved StructureDefinition\n * @throws {@link ResourceNotFoundError} if no loader can resolve the URL\n * @throws {@link LoaderError} if a loader fails during loading\n * @throws {@link InvalidStructureDefinitionError} if the loaded resource is malformed\n */\n loadStructureDefinition(url: string): Promise<StructureDefinition>;\n\n /**\n * Synchronously retrieve a StructureDefinition from the registry.\n *\n * Does **not** trigger any loader \u2014 only checks the in-memory registry.\n * Use {@link loadStructureDefinition} if you need on-demand loading.\n *\n * @param url - Canonical URL (with optional `|version`)\n * @returns The cached StructureDefinition, or `undefined` if not loaded\n */\n getStructureDefinition(url: string): StructureDefinition | undefined;\n\n /**\n * Check whether a StructureDefinition is present in the registry.\n *\n * @param url - Canonical URL (with optional `|version`)\n */\n hasStructureDefinition(url: string): boolean;\n\n /**\n * Resolve the full inheritance chain for a profile.\n *\n * Walks the `baseDefinition` links from the given URL up to the root\n * resource type (e.g., `Resource`). Each base is loaded on demand if\n * not already in the registry.\n *\n * @param url - Canonical URL of the starting profile\n * @returns Array of canonical URLs from child to root\n * (e.g., `[ChinesePatient, Patient, DomainResource, Resource]`)\n * @throws {@link CircularDependencyError} if a cycle is detected\n * @throws {@link ResourceNotFoundError} if a base definition cannot be found\n */\n resolveInheritanceChain(url: string): Promise<string[]>;\n\n /**\n * Register a StructureDefinition in the registry.\n *\n * This is used for:\n * - Manually adding definitions (e.g., custom profiles)\n * - Phase 4: caching generated snapshots back into the context\n *\n * If a definition with the same URL (and version) already exists,\n * it will be replaced and any cached inheritance chains invalidated.\n *\n * @param sd - The StructureDefinition to register\n * @throws {@link InvalidStructureDefinitionError} if `sd.url` is missing\n */\n registerStructureDefinition(sd: StructureDefinition): void;\n\n /**\n * Preload FHIR R4 core StructureDefinitions.\n *\n * Loads base resource types (Resource, DomainResource, Patient,\n * Observation, etc.) into the registry so they are available\n * synchronously via {@link getStructureDefinition}.\n *\n * Should be called once during application initialization.\n */\n preloadCoreDefinitions(): Promise<void>;\n\n /**\n * Return runtime statistics for monitoring and diagnostics.\n */\n getStatistics(): ContextStatistics;\n\n /**\n * Register a CanonicalProfile and its extracted InnerTypes.\n *\n * This is the primary method for making InnerTypes available for\n * downstream consumption (UI forms, recursive validation, etc.).\n * Typically called after snapshot generation + `extractInnerTypes()`.\n *\n * @param profile - The CanonicalProfile (with innerTypes populated)\n */\n registerCanonicalProfile(profile: CanonicalProfile): void;\n\n /**\n * Retrieve an InnerType schema by its generated type name.\n *\n * @param typeName - Generated type name (e.g., `'PatientContact'`)\n * @returns The InnerType CanonicalProfile, or `undefined` if not registered\n */\n getInnerType(typeName: string): CanonicalProfile | undefined;\n\n /**\n * Check whether an InnerType is registered.\n *\n * @param typeName - Generated type name (e.g., `'PatientContact'`)\n */\n hasInnerType(typeName: string): boolean;\n\n /**\n * Release all cached data and reset internal state.\n *\n * After calling `dispose()`, the context must be re-initialized\n * (e.g., by calling {@link preloadCoreDefinitions} again).\n */\n dispose(): void;\n}\n\n// =============================================================================\n// Section 2: StructureDefinitionLoader Interface\n// =============================================================================\n\n/**\n * Pluggable strategy for loading StructureDefinitions from an external source.\n *\n * Implementations include:\n * - `MemoryLoader` \u2014 loads from an in-memory map (for testing / preloaded data)\n * - `FileSystemLoader` \u2014 loads from local JSON files\n * - `CompositeLoader` \u2014 chains multiple loaders (fallback pattern)\n *\n * Conceptually equivalent to HAPI's `IValidationSupport` implementations.\n */\nexport interface StructureDefinitionLoader {\n /**\n * Attempt to load a StructureDefinition by canonical URL.\n *\n * @param url - Canonical URL (without `|version` \u2014 version is stripped\n * by the caller before delegation)\n * @returns The loaded StructureDefinition, or `null` if this loader\n * cannot resolve the URL (allows fallback to next loader)\n * @throws {@link LoaderError} on I/O or parse failures\n */\n load(url: string): Promise<StructureDefinition | null>;\n\n /**\n * Quick check whether this loader is likely able to resolve the URL.\n *\n * This is a hint \u2014 returning `true` does not guarantee `load()` will\n * succeed. Returning `false` allows the composite loader to skip this\n * source entirely.\n *\n * @param url - Canonical URL to check\n */\n canLoad(url: string): boolean;\n\n /**\n * Human-readable identifier for the loader source.\n *\n * Used in error messages and diagnostics.\n *\n * @returns Source type label (e.g., `'memory'`, `'filesystem'`, `'http'`)\n */\n getSourceType(): string;\n}\n\n// =============================================================================\n// Section 3: Configuration Types\n// =============================================================================\n\n/**\n * Configuration options for creating a {@link FhirContext}.\n */\nexport interface FhirContextOptions {\n /**\n * One or more loaders to use for resolving StructureDefinitions.\n *\n * When multiple loaders are provided, they are tried in order\n * (first match wins \u2014 chain of responsibility pattern).\n */\n loaders: StructureDefinitionLoader[];\n\n /**\n * Whether to automatically call {@link FhirContext.preloadCoreDefinitions}\n * during initialization.\n *\n * @defaultValue `true`\n */\n preloadCore?: boolean;\n\n /**\n * Path to the FHIR R4 specification directory.\n *\n * Used by the core definition preloader to locate `profiles-resources.json`\n * and `profiles-types.json`.\n *\n * @defaultValue `undefined` (uses bundled definitions)\n */\n specDirectory?: string;\n}\n\n/**\n * Options for individual loader instances.\n */\nexport interface LoaderOptions {\n /**\n * Base directory or URL prefix for resolving relative paths.\n */\n basePath?: string;\n\n /**\n * Request timeout in milliseconds (for future HTTP loaders).\n *\n * @defaultValue `30000`\n */\n timeout?: number;\n\n /**\n * Number of retry attempts on transient failures.\n *\n * @defaultValue `0`\n */\n retryCount?: number;\n}\n\n// =============================================================================\n// Section 4: Statistics Types\n// =============================================================================\n\n/**\n * Runtime metrics for the {@link FhirContext}.\n *\n * Useful for monitoring cache effectiveness and diagnosing\n * performance issues.\n */\nexport interface ContextStatistics {\n /** Total number of StructureDefinitions in the registry */\n totalLoaded: number;\n\n /** Number of `loadStructureDefinition` calls resolved from cache */\n cacheHits: number;\n\n /** Number of `loadStructureDefinition` calls that required loader delegation */\n cacheMisses: number;\n\n /** Total number of loader invocations across all loaders */\n loaderCalls: number;\n\n /** Number of inheritance chains resolved */\n chainsResolved: number;\n\n /** Number of `registerStructureDefinition` calls */\n registrations: number;\n}\n\n/**\n * Create a fresh statistics object with all counters at zero.\n */\nexport function createEmptyStatistics(): ContextStatistics {\n return {\n totalLoaded: 0,\n cacheHits: 0,\n cacheMisses: 0,\n loaderCalls: 0,\n chainsResolved: 0,\n registrations: 0,\n };\n}\n", "/**\n * fhir-context \u2014 Error Types\n *\n * Structured error hierarchy for the FHIR context module.\n * All errors extend {@link ContextError} so consumers can catch\n * context-related failures with a single `catch` clause.\n *\n * Error hierarchy:\n * ```\n * ContextError (base)\n * \u251C\u2500\u2500 ResourceNotFoundError\n * \u251C\u2500\u2500 CircularDependencyError\n * \u251C\u2500\u2500 LoaderError\n * \u2514\u2500\u2500 InvalidStructureDefinitionError\n * ```\n *\n * @module fhir-context\n */\n\n// =============================================================================\n// Section 1: Base Error\n// =============================================================================\n\n/**\n * Base error class for all fhir-context failures.\n *\n * Provides a stable `name` property and preserves the original `cause`\n * when wrapping lower-level errors.\n */\nexport class ContextError extends Error {\n override readonly name: string = 'ContextError';\n\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n // Restore prototype chain (required for `instanceof` after transpilation)\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n// =============================================================================\n// Section 2: ResourceNotFoundError\n// =============================================================================\n\n/**\n * Thrown when a StructureDefinition cannot be resolved by any loader.\n *\n * @example\n * ```typescript\n * throw new ResourceNotFoundError(\n * 'http://hl7.org/fhir/StructureDefinition/UnknownType',\n * ['memory', 'filesystem']\n * );\n * ```\n */\nexport class ResourceNotFoundError extends ContextError {\n override readonly name = 'ResourceNotFoundError';\n\n /** The canonical URL that could not be resolved */\n readonly url: string;\n\n /** Loader source types that were tried */\n readonly triedSources: readonly string[];\n\n constructor(url: string, triedSources: string[] = []) {\n const sourcesMsg =\n triedSources.length > 0\n ? ` (tried: ${triedSources.join(', ')})`\n : '';\n super(`StructureDefinition not found: ${url}${sourcesMsg}`);\n this.url = url;\n this.triedSources = triedSources;\n }\n}\n\n// =============================================================================\n// Section 3: CircularDependencyError\n// =============================================================================\n\n/**\n * Thrown when a circular `baseDefinition` chain is detected during\n * inheritance resolution.\n *\n * @example\n * ```typescript\n * throw new CircularDependencyError([\n * 'http://example.org/A',\n * 'http://example.org/B',\n * 'http://example.org/A', // cycle back to A\n * ]);\n * ```\n */\nexport class CircularDependencyError extends ContextError {\n override readonly name = 'CircularDependencyError';\n\n /** The full chain of URLs that forms the cycle */\n readonly chain: readonly string[];\n\n constructor(chain: string[]) {\n const display = chain.join(' \u2192 ');\n super(`Circular dependency detected: ${display}`);\n this.chain = chain;\n }\n}\n\n// =============================================================================\n// Section 4: LoaderError\n// =============================================================================\n\n/**\n * Thrown when a {@link StructureDefinitionLoader} encounters an I/O\n * or parse failure while loading a definition.\n *\n * The original error is preserved as `cause` for debugging.\n *\n * @example\n * ```typescript\n * throw new LoaderError(\n * 'http://hl7.org/fhir/StructureDefinition/Patient',\n * 'filesystem',\n * originalError\n * );\n * ```\n */\nexport class LoaderError extends ContextError {\n override readonly name = 'LoaderError';\n\n /** The canonical URL being loaded when the error occurred */\n readonly url: string;\n\n /** The loader source type that failed */\n readonly sourceType: string;\n\n constructor(url: string, sourceType: string, cause?: Error) {\n super(\n `Loader '${sourceType}' failed to load ${url}: ${cause?.message ?? 'unknown error'}`,\n cause ? { cause } : undefined,\n );\n this.url = url;\n this.sourceType = sourceType;\n }\n}\n\n// =============================================================================\n// Section 5: InvalidStructureDefinitionError\n// =============================================================================\n\n/**\n * Thrown when a loaded or registered StructureDefinition is missing\n * required fields or has invalid structure.\n *\n * Required fields for a valid StructureDefinition:\n * - `url` \u2014 canonical URL\n * - `name` \u2014 computer-friendly name\n * - `status` \u2014 publication status\n * - `kind` \u2014 resource | complex-type | primitive-type | logical\n *\n * @example\n * ```typescript\n * throw new InvalidStructureDefinitionError(\n * 'Missing required field: url',\n * 'http://example.org/MyProfile'\n * );\n * ```\n */\nexport class InvalidStructureDefinitionError extends ContextError {\n override readonly name = 'InvalidStructureDefinitionError';\n\n /** The URL of the invalid definition (if available) */\n readonly url: string | undefined;\n\n constructor(reason: string, url?: string) {\n const urlMsg = url ? ` (${url})` : '';\n super(`Invalid StructureDefinition${urlMsg}: ${reason}`);\n this.url = url;\n }\n}\n", "/**\n * fhir-context \u2014 StructureDefinition Registry\n *\n * In-memory registry for storing and querying StructureDefinitions.\n * Keyed by canonical URL with optional `|version` support.\n *\n * This is an internal component used by {@link FhirContextImpl}.\n * It is not exported from the public API.\n *\n * @module fhir-context\n */\n\nimport type { StructureDefinition } from '../model/index.js';\nimport { InvalidStructureDefinitionError } from './errors.js';\n\n// =============================================================================\n// Section 1: URL Utilities\n// =============================================================================\n\n/**\n * Parse a canonical URL that may contain a `|version` suffix.\n *\n * @param urlWithVersion - e.g. `\"http://hl7.org/fhir/StructureDefinition/Patient|4.0.1\"`\n * @returns `{ url, version }` where `version` is `undefined` if absent\n */\nexport function parseVersionedUrl(urlWithVersion: string): {\n url: string;\n version: string | undefined;\n} {\n const pipeIndex = urlWithVersion.indexOf('|');\n if (pipeIndex === -1) {\n return { url: urlWithVersion, version: undefined };\n }\n return {\n url: urlWithVersion.substring(0, pipeIndex),\n version: urlWithVersion.substring(pipeIndex + 1),\n };\n}\n\n/**\n * Build a versioned registry key from URL and version.\n *\n * @param url - Canonical URL (without version)\n * @param version - Semantic version string, or `undefined`\n * @returns `\"url|version\"` if version is present, otherwise just `\"url\"`\n */\nexport function buildVersionedKey(\n url: string,\n version: string | undefined,\n): string {\n return version ? `${url}|${version}` : url;\n}\n\n// =============================================================================\n// Section 2: StructureDefinitionRegistry\n// =============================================================================\n\n/**\n * In-memory registry for StructureDefinitions.\n *\n * Storage strategy:\n * - **Primary map**: keyed by `url|version` (exact match)\n * - **Latest map**: keyed by bare `url` \u2192 points to the most recently\n * registered version (for unversioned lookups)\n *\n * When a lookup uses a bare URL (no `|version`), the latest map is consulted.\n * When a lookup uses `url|version`, the primary map is used for exact match.\n */\nexport class StructureDefinitionRegistry {\n /** Primary storage: `url|version` \u2192 StructureDefinition */\n private readonly _entries = new Map<string, StructureDefinition>();\n\n /** Latest-version index: bare `url` \u2192 `url|version` key in _entries */\n private readonly _latestIndex = new Map<string, string>();\n\n /** Statistics counters */\n private _queryCount = 0;\n private _hitCount = 0;\n\n // ---------------------------------------------------------------------------\n // Mutators\n // ---------------------------------------------------------------------------\n\n /**\n * Register a StructureDefinition.\n *\n * Validates that the definition has a `url` field. If a definition with\n * the same URL (and version) already exists, it is silently replaced.\n *\n * @param sd - The StructureDefinition to register\n * @throws {@link InvalidStructureDefinitionError} if `sd.url` is missing\n */\n register(sd: StructureDefinition): void {\n if (!sd.url) {\n throw new InvalidStructureDefinitionError(\n 'Missing required field: url',\n sd.name as string | undefined,\n );\n }\n\n const bareUrl = sd.url as string;\n const version = sd.version as string | undefined;\n const key = buildVersionedKey(bareUrl, version);\n\n this._entries.set(key, sd);\n\n // Update latest index: always point bare URL to the newest registration.\n // If the same bare URL is registered with different versions, the last\n // one registered wins as \"latest\". This is intentional \u2014 callers that\n // need a specific version should use `url|version`.\n this._latestIndex.set(bareUrl, key);\n }\n\n /**\n * Remove a StructureDefinition by canonical URL.\n *\n * @param urlWithVersion - Canonical URL (with optional `|version`)\n * @returns `true` if a definition was removed, `false` if not found\n */\n delete(urlWithVersion: string): boolean {\n const { url, version } = parseVersionedUrl(urlWithVersion);\n\n if (version) {\n // Exact versioned delete\n const key = buildVersionedKey(url, version);\n const deleted = this._entries.delete(key);\n // If the latest index pointed to this key, remove it\n if (deleted && this._latestIndex.get(url) === key) {\n this._latestIndex.delete(url);\n }\n return deleted;\n }\n\n // Unversioned delete: remove the entry pointed to by the latest index\n const latestKey = this._latestIndex.get(url);\n if (latestKey) {\n this._entries.delete(latestKey);\n this._latestIndex.delete(url);\n return true;\n }\n\n return false;\n }\n\n /**\n * Remove all entries and reset statistics.\n */\n clear(): void {\n this._entries.clear();\n this._latestIndex.clear();\n this._queryCount = 0;\n this._hitCount = 0;\n }\n\n // ---------------------------------------------------------------------------\n // Queries\n // ---------------------------------------------------------------------------\n\n /**\n * Retrieve a StructureDefinition by canonical URL.\n *\n * - If `urlWithVersion` contains `|version`, performs exact match.\n * - If no version, returns the latest registered version.\n *\n * @param urlWithVersion - Canonical URL (with optional `|version`)\n * @returns The StructureDefinition, or `undefined` if not found\n */\n get(urlWithVersion: string): StructureDefinition | undefined {\n this._queryCount++;\n\n const { url, version } = parseVersionedUrl(urlWithVersion);\n\n let result: StructureDefinition | undefined;\n\n if (version) {\n // Exact versioned lookup\n result = this._entries.get(buildVersionedKey(url, version));\n } else {\n // Unversioned: use latest index\n const latestKey = this._latestIndex.get(url);\n result = latestKey ? this._entries.get(latestKey) : undefined;\n }\n\n if (result) {\n this._hitCount++;\n }\n\n return result;\n }\n\n /**\n * Check whether a StructureDefinition is registered.\n *\n * @param urlWithVersion - Canonical URL (with optional `|version`)\n */\n has(urlWithVersion: string): boolean {\n const { url, version } = parseVersionedUrl(urlWithVersion);\n\n if (version) {\n return this._entries.has(buildVersionedKey(url, version));\n }\n\n return this._latestIndex.has(url);\n }\n\n /**\n * Total number of registered StructureDefinitions.\n */\n get size(): number {\n return this._entries.size;\n }\n\n /**\n * Return all registered canonical URLs (including version suffixes).\n */\n getAllKeys(): string[] {\n return Array.from(this._entries.keys());\n }\n\n /**\n * Return all registered bare URLs (without version suffixes).\n */\n getAllUrls(): string[] {\n return Array.from(this._latestIndex.keys());\n }\n\n // ---------------------------------------------------------------------------\n // Statistics\n // ---------------------------------------------------------------------------\n\n /**\n * Total number of `get()` calls.\n */\n get queryCount(): number {\n return this._queryCount;\n }\n\n /**\n * Number of `get()` calls that returned a result (cache hits).\n */\n get hitCount(): number {\n return this._hitCount;\n }\n\n /**\n * Number of `get()` calls that returned `undefined` (cache misses).\n */\n get missCount(): number {\n return this._queryCount - this._hitCount;\n }\n\n /**\n * Cache hit ratio (0\u20131). Returns 0 if no queries have been made.\n */\n get hitRate(): number {\n return this._queryCount === 0 ? 0 : this._hitCount / this._queryCount;\n }\n}\n", "/**\n * fhir-context \u2014 Inheritance Chain Resolver\n *\n * Resolves the `baseDefinition` inheritance chain for a FHIR\n * StructureDefinition, walking from a child profile up to the root\n * resource type (e.g., `Resource`).\n *\n * Features:\n * - Recursive resolution with on-demand loading\n * - Circular dependency detection via an \"in-flight\" Set\n * - Resolved chain caching with explicit invalidation\n *\n * @module fhir-context\n */\n\nimport type { StructureDefinition } from '../model/index.js';\nimport { CircularDependencyError, ResourceNotFoundError } from './errors.js';\n\n// =============================================================================\n// Section 1: DefinitionProvider\n// =============================================================================\n\n/**\n * Minimal interface for loading a StructureDefinition by canonical URL.\n *\n * This decouples the resolver from the full {@link FhirContext} interface,\n * making it independently testable. The `FhirContextImpl` class (Task 3.6)\n * will satisfy this interface.\n */\nexport interface DefinitionProvider {\n /**\n * Load a StructureDefinition by canonical URL.\n *\n * Must throw {@link ResourceNotFoundError} if the URL cannot be resolved.\n */\n loadStructureDefinition(url: string): Promise<StructureDefinition>;\n}\n\n// =============================================================================\n// Section 2: InheritanceChainResolver\n// =============================================================================\n\n/**\n * Resolves profile inheritance chains by walking `baseDefinition` links.\n *\n * The resolver loads each StructureDefinition on demand via the provided\n * {@link DefinitionProvider}, detects circular dependencies, and caches\n * resolved chains for repeated lookups.\n *\n * @example\n * ```typescript\n * const resolver = new InheritanceChainResolver(provider);\n * const chain = await resolver.resolve(\n * 'http://hl7.org/fhir/StructureDefinition/Patient'\n * );\n * // \u2192 ['http://hl7.org/fhir/StructureDefinition/Patient',\n * // 'http://hl7.org/fhir/StructureDefinition/DomainResource',\n * // 'http://hl7.org/fhir/StructureDefinition/Resource']\n * ```\n */\nexport class InheritanceChainResolver {\n private readonly _provider: DefinitionProvider;\n\n /** Cache of resolved chains: canonical URL \u2192 chain array */\n private readonly _cache = new Map<string, string[]>();\n\n /** Statistics counter */\n private _resolutionCount = 0;\n\n constructor(provider: DefinitionProvider) {\n this._provider = provider;\n }\n\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n\n /**\n * Resolve the full inheritance chain for a profile.\n *\n * Returns an array of canonical URLs ordered from child to root:\n * `[startUrl, ..., parentUrl, rootUrl]`\n *\n * @param url - Canonical URL of the starting StructureDefinition\n * @returns Inheritance chain from child to root\n * @throws {@link CircularDependencyError} if a cycle is detected\n * @throws {@link ResourceNotFoundError} if a definition cannot be loaded\n */\n async resolve(url: string): Promise<string[]> {\n // Check cache first\n const cached = this._cache.get(url);\n if (cached) {\n return cached;\n }\n\n // Resolve with circular dependency tracking\n const inFlight = new Set<string>();\n const chain = await this._resolveRecursive(url, inFlight);\n\n // Cache the result\n this._cache.set(url, chain);\n this._resolutionCount++;\n\n // Also cache sub-chains for efficiency.\n // If chain is [A, B, C, D], then B\u2192[B,C,D], C\u2192[C,D], D\u2192[D]\n for (let i = 1; i < chain.length; i++) {\n const subChain = chain.slice(i);\n if (!this._cache.has(subChain[0])) {\n this._cache.set(subChain[0], subChain);\n }\n }\n\n return chain;\n }\n\n /**\n * Invalidate the cached chain for a specific URL.\n *\n * Should be called when a StructureDefinition is re-registered,\n * as its `baseDefinition` may have changed.\n *\n * @param url - Canonical URL to invalidate\n */\n invalidate(url: string): void {\n // Remove any cached chain that contains this URL\n for (const [key, chain] of this._cache) {\n if (key === url || chain.includes(url)) {\n this._cache.delete(key);\n }\n }\n }\n\n /**\n * Clear all cached chains.\n */\n clearCache(): void {\n this._cache.clear();\n }\n\n /**\n * Number of chains that have been resolved (not from cache).\n */\n get resolutionCount(): number {\n return this._resolutionCount;\n }\n\n /**\n * Number of chains currently in the cache.\n */\n get cacheSize(): number {\n return this._cache.size;\n }\n\n // ---------------------------------------------------------------------------\n // Internal\n // ---------------------------------------------------------------------------\n\n /**\n * Recursive resolution with circular dependency detection.\n *\n * @param url - Current URL to resolve\n * @param inFlight - Set of URLs currently being resolved (cycle detection)\n * @returns Chain from current URL to root\n */\n private async _resolveRecursive(\n url: string,\n inFlight: Set<string>,\n ): Promise<string[]> {\n // Check for cached sub-chain\n const cached = this._cache.get(url);\n if (cached) {\n return cached;\n }\n\n // Circular dependency check\n if (inFlight.has(url)) {\n // Build the cycle display: existing chain + the repeated URL\n const cycleChain = [...inFlight, url];\n throw new CircularDependencyError(cycleChain);\n }\n\n // Mark as in-flight\n inFlight.add(url);\n\n try {\n // Load the StructureDefinition\n const sd = await this._provider.loadStructureDefinition(url);\n\n // Extract baseDefinition\n const baseUrl = sd.baseDefinition as string | undefined;\n\n if (!baseUrl) {\n // Reached root (e.g., Resource has no baseDefinition)\n return [url];\n }\n\n // Recursively resolve the base chain\n const baseChain = await this._resolveRecursive(baseUrl, inFlight);\n\n // Prepend current URL\n return [url, ...baseChain];\n } finally {\n // Remove from in-flight (important for correct behavior when\n // the same URL appears in multiple independent resolution paths)\n inFlight.delete(url);\n }\n }\n}\n", "/**\n * fhir-context \u2014 CompositeLoader\n *\n * Chains multiple {@link StructureDefinitionLoader} instances using the\n * chain-of-responsibility pattern. Each loader is tried in order until\n * one returns a non-null result.\n *\n * Conceptually equivalent to HAPI's `ValidationSupportChain`.\n *\n * @module fhir-context\n */\n\nimport type { StructureDefinition } from '../../model/index.js';\nimport type { StructureDefinitionLoader } from '../types.js';\nimport { LoaderError } from '../errors.js';\n\n/**\n * A loader that delegates to an ordered list of child loaders.\n *\n * Resolution stops at the first loader that returns a non-null result.\n * If a loader throws an error, the error is collected and the next\n * loader is tried. If all loaders fail or return null, the first\n * collected error (if any) is thrown.\n *\n * This follows the HAPI `ValidationSupportChain` pattern: record\n * errors from individual loaders but continue trying remaining loaders.\n *\n * @example\n * ```typescript\n * const composite = new CompositeLoader([memoryLoader, fileLoader]);\n * const sd = await composite.load(url);\n * // Tries memoryLoader first, then fileLoader\n * ```\n */\nexport class CompositeLoader implements StructureDefinitionLoader {\n private readonly _loaders: readonly StructureDefinitionLoader[];\n\n /**\n * @param loaders - Ordered list of loaders to try. First match wins.\n * @throws Error if loaders array is empty\n */\n constructor(loaders: StructureDefinitionLoader[]) {\n if (loaders.length === 0) {\n throw new Error('CompositeLoader requires at least one child loader');\n }\n this._loaders = loaders;\n }\n\n async load(url: string): Promise<StructureDefinition | null> {\n const errors: Error[] = [];\n\n for (const loader of this._loaders) {\n try {\n const result = await loader.load(url);\n if (result !== null) {\n return result;\n }\n } catch (err) {\n // Collect error and continue to next loader\n if (err instanceof LoaderError) {\n errors.push(err);\n } else {\n errors.push(new LoaderError(url, loader.getSourceType(), err as Error));\n }\n }\n }\n\n // All loaders returned null or threw \u2014 if any errors were collected,\n // throw the first one (it is the most relevant since loaders are ordered)\n if (errors.length > 0) {\n throw errors[0];\n }\n\n return null;\n }\n\n canLoad(url: string): boolean {\n return this._loaders.some((loader) => loader.canLoad(url));\n }\n\n getSourceType(): string {\n const types = this._loaders.map((l) => l.getSourceType());\n return `composite(${types.join(', ')})`;\n }\n\n /**\n * Number of child loaders in the chain.\n */\n get loaderCount(): number {\n return this._loaders.length;\n }\n}\n", "/**\n * fhir-context \u2014 Core Definitions Index\n *\n * Provides the list of core FHIR R4 StructureDefinition filenames\n * and a utility to load them from the `core-definitions/` directory.\n *\n * These definitions are extracted from the official FHIR R4 v4.0.1\n * specification (`profiles-resources.json` and `profiles-types.json`).\n *\n * @module fhir-context\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { readFileSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport type { StructureDefinition } from '../../model/index.js';\nimport { parseFhirJson } from '../../parser/index.js';\nimport { LoaderError } from '../errors.js';\n\n// =============================================================================\n// Section 1: Core Definition Manifest\n// =============================================================================\n\n/**\n * Base resource types \u2014 the foundation of the FHIR type hierarchy.\n * These MUST be loaded first as other definitions depend on them.\n */\nexport const BASE_RESOURCES = [\n 'Resource',\n 'DomainResource',\n 'Element',\n 'BackboneElement',\n 'Extension',\n] as const;\n\n/**\n * Primitive types \u2014 FHIR primitive data types.\n */\nexport const PRIMITIVE_TYPES = [\n 'base64Binary', 'boolean', 'canonical', 'code', 'date', 'dateTime',\n 'decimal', 'id', 'instant', 'integer', 'markdown', 'oid',\n 'positiveInt', 'string', 'time', 'unsignedInt', 'uri', 'url', 'uuid',\n 'xhtml',\n] as const;\n\n/**\n * Complex types \u2014 FHIR complex data types (non-resource).\n */\nexport const COMPLEX_TYPES = [\n 'Address', 'Age', 'Annotation', 'Attachment', 'CodeableConcept', 'Coding',\n 'ContactDetail', 'ContactPoint', 'Count', 'Distance', 'Dosage', 'Duration',\n 'HumanName', 'Identifier', 'Meta', 'Money', 'Narrative', 'Period',\n 'Quantity', 'Range', 'Ratio', 'Reference', 'SampledData', 'Signature',\n 'Timing',\n] as const;\n\n/**\n * Core clinical resources \u2014 commonly used FHIR resource types.\n */\nexport const CORE_RESOURCES = [\n 'AllergyIntolerance', 'Binary', 'Bundle', 'CarePlan', 'Claim',\n 'CodeSystem', 'Condition', 'DiagnosticReport', 'DocumentReference',\n 'Encounter', 'Immunization', 'Location', 'Medication', 'MedicationRequest',\n 'Observation', 'Organization', 'Patient', 'Practitioner', 'Procedure',\n 'Questionnaire', 'ServiceRequest', 'StructureDefinition', 'ValueSet',\n] as const;\n\n/**\n * All core definition filenames in dependency order:\n * base \u2192 primitives \u2192 complex types \u2192 resources.\n */\nexport const ALL_CORE_DEFINITIONS: readonly string[] = [\n ...BASE_RESOURCES,\n ...PRIMITIVE_TYPES,\n ...COMPLEX_TYPES,\n ...CORE_RESOURCES,\n];\n\n// =============================================================================\n// Section 2: Loading Utilities\n// =============================================================================\n\n/**\n * Resolve the absolute path to the `core-definitions/` directory.\n *\n * Works both in ESM (via `import.meta.url`) and when a custom\n * `specDirectory` is provided.\n *\n * @param specDirectory - Optional override directory path\n * @returns Absolute path to the core definitions directory\n */\nexport function getCoreDefinitionsDir(specDirectory?: string): string {\n if (specDirectory) {\n return specDirectory;\n }\n // Default: same directory as this file\n const thisFile = fileURLToPath(import.meta.url);\n return dirname(thisFile);\n}\n\n/**\n * Load a single core StructureDefinition by name (synchronous).\n *\n * @param name - Definition name (e.g., `\"Patient\"`, `\"string\"`)\n * @param baseDir - Directory containing the JSON files\n * @returns Parsed StructureDefinition\n * @throws {@link LoaderError} if the file cannot be read or parsed\n */\nexport function loadCoreDefinitionSync(\n name: string,\n baseDir: string,\n): StructureDefinition {\n const filePath = join(baseDir, `${name}.json`);\n let raw: string;\n try {\n raw = readFileSync(filePath, 'utf-8');\n } catch (err) {\n throw new LoaderError(\n `http://hl7.org/fhir/StructureDefinition/${name}`,\n 'core-definitions',\n err as Error,\n );\n }\n\n const result = parseFhirJson(raw);\n if (!result.success) {\n const messages = result.issues\n .filter((i) => i.severity === 'error')\n .map((i) => i.message)\n .join('; ');\n throw new LoaderError(\n `http://hl7.org/fhir/StructureDefinition/${name}`,\n 'core-definitions',\n new Error(`Parse failed: ${messages}`),\n );\n }\n\n return result.data as StructureDefinition;\n}\n\n/**\n * Load a single core StructureDefinition by name (async).\n *\n * @param name - Definition name (e.g., `\"Patient\"`, `\"string\"`)\n * @param baseDir - Directory containing the JSON files\n * @returns Parsed StructureDefinition\n * @throws {@link LoaderError} if the file cannot be read or parsed\n */\nexport async function loadCoreDefinition(\n name: string,\n baseDir: string,\n): Promise<StructureDefinition> {\n const filePath = join(baseDir, `${name}.json`);\n let raw: string;\n try {\n raw = await readFile(filePath, 'utf-8');\n } catch (err) {\n throw new LoaderError(\n `http://hl7.org/fhir/StructureDefinition/${name}`,\n 'core-definitions',\n err as Error,\n );\n }\n\n const result = parseFhirJson(raw);\n if (!result.success) {\n const messages = result.issues\n .filter((i) => i.severity === 'error')\n .map((i) => i.message)\n .join('; ');\n throw new LoaderError(\n `http://hl7.org/fhir/StructureDefinition/${name}`,\n 'core-definitions',\n new Error(`Parse failed: ${messages}`),\n );\n }\n\n return result.data as StructureDefinition;\n}\n\n/**\n * Load all core definitions and return them as a Map.\n *\n * Loads in dependency order (base \u2192 primitives \u2192 complex \u2192 resources).\n *\n * @param specDirectory - Optional override directory path\n * @returns Map of canonical URL \u2192 StructureDefinition\n */\nexport async function loadAllCoreDefinitions(\n specDirectory?: string,\n): Promise<Map<string, StructureDefinition>> {\n const baseDir = getCoreDefinitionsDir(specDirectory);\n const result = new Map<string, StructureDefinition>();\n\n for (const name of ALL_CORE_DEFINITIONS) {\n const sd = await loadCoreDefinition(name, baseDir);\n result.set(sd.url as string, sd);\n }\n\n return result;\n}\n", "/**\n * fhir-context \u2014 FhirContextImpl\n *\n * Concrete implementation of the {@link FhirContext} interface.\n * Integrates the registry, loaders, and inheritance resolver into\n * a single cohesive entry point.\n *\n * Conceptual mapping:\n * - HAPI `FhirContext` \u2192 this class\n * - HAPI `IValidationSupport` \u2192 loader delegation\n * - HAPI `ValidationSupportChain` \u2192 CompositeLoader\n *\n * @module fhir-context\n */\n\nimport type { StructureDefinition, CanonicalProfile } from '../model/index.js';\nimport type {\n FhirContext,\n FhirContextOptions,\n ContextStatistics,\n StructureDefinitionLoader,\n} from './types.js';\nimport { createEmptyStatistics } from './types.js';\nimport { StructureDefinitionRegistry, parseVersionedUrl } from './registry.js';\nimport { InheritanceChainResolver } from './inheritance-resolver.js';\nimport { CompositeLoader } from './loaders/composite-loader.js';\nimport {\n ResourceNotFoundError,\n InvalidStructureDefinitionError,\n} from './errors.js';\nimport { loadAllCoreDefinitions } from './core-definitions/index.js';\n\n// =============================================================================\n// Section 1: FhirContextImpl\n// =============================================================================\n\n/**\n * Concrete implementation of {@link FhirContext}.\n *\n * @example\n * ```typescript\n * const ctx = new FhirContextImpl({\n * loaders: [memoryLoader, fileLoader],\n * });\n * await ctx.preloadCoreDefinitions();\n *\n * const patient = await ctx.loadStructureDefinition(\n * 'http://hl7.org/fhir/StructureDefinition/Patient'\n * );\n * ```\n */\nexport class FhirContextImpl implements FhirContext {\n private readonly _registry: StructureDefinitionRegistry;\n private readonly _resolver: InheritanceChainResolver;\n private readonly _loader: StructureDefinitionLoader;\n private readonly _options: FhirContextOptions;\n private readonly _stats: ContextStatistics;\n private readonly _innerTypes = new Map<string, CanonicalProfile>();\n private readonly _canonicalProfiles = new Map<string, CanonicalProfile>();\n private _disposed = false;\n\n constructor(options: FhirContextOptions) {\n this._options = options;\n this._registry = new StructureDefinitionRegistry();\n this._stats = createEmptyStatistics();\n\n // Build a single loader (composite if multiple provided)\n if (options.loaders.length === 1) {\n this._loader = options.loaders[0];\n } else {\n this._loader = new CompositeLoader(options.loaders);\n }\n\n // Wire the resolver to use this context's loadStructureDefinition\n this._resolver = new InheritanceChainResolver({\n loadStructureDefinition: (url: string) =>\n this.loadStructureDefinition(url),\n });\n }\n\n // ---------------------------------------------------------------------------\n // FhirContext interface\n // ---------------------------------------------------------------------------\n\n async loadStructureDefinition(url: string): Promise<StructureDefinition> {\n this._ensureNotDisposed();\n\n // 1. Check registry (cache hit)\n const cached = this._registry.get(url);\n if (cached) {\n this._stats.cacheHits++;\n return cached;\n }\n\n // 2. Strip version for loader delegation\n const { url: bareUrl } = parseVersionedUrl(url);\n\n // 3. Delegate to loader (cache miss)\n this._stats.cacheMisses++;\n this._stats.loaderCalls++;\n\n const loaded = await this._loader.load(bareUrl);\n if (!loaded) {\n throw new ResourceNotFoundError(url, [this._loader.getSourceType()]);\n }\n\n // 4. Validate\n this._validateStructureDefinition(loaded);\n\n // 5. Register in registry\n this._registry.register(loaded);\n this._stats.totalLoaded = this._registry.size;\n\n return loaded;\n }\n\n getStructureDefinition(url: string): StructureDefinition | undefined {\n this._ensureNotDisposed();\n return this._registry.get(url);\n }\n\n hasStructureDefinition(url: string): boolean {\n this._ensureNotDisposed();\n return this._registry.has(url);\n }\n\n async resolveInheritanceChain(url: string): Promise<string[]> {\n this._ensureNotDisposed();\n const chain = await this._resolver.resolve(url);\n this._stats.chainsResolved = this._resolver.resolutionCount;\n return chain;\n }\n\n registerStructureDefinition(sd: StructureDefinition): void {\n this._ensureNotDisposed();\n this._validateStructureDefinition(sd);\n this._registry.register(sd);\n this._stats.registrations++;\n this._stats.totalLoaded = this._registry.size;\n\n // Invalidate any cached inheritance chains that include this URL\n this._resolver.invalidate(sd.url as string);\n }\n\n async preloadCoreDefinitions(): Promise<void> {\n this._ensureNotDisposed();\n\n const defs = await loadAllCoreDefinitions(this._options.specDirectory);\n\n defs.forEach((sd) => {\n this._registry.register(sd);\n });\n\n this._stats.totalLoaded = this._registry.size;\n }\n\n getStatistics(): ContextStatistics {\n return { ...this._stats };\n }\n\n registerCanonicalProfile(profile: CanonicalProfile): void {\n this._ensureNotDisposed();\n this._canonicalProfiles.set(profile.type, profile);\n\n // Register all inner types from this profile\n if (profile.innerTypes) {\n for (const [typeName, innerType] of profile.innerTypes) {\n this._innerTypes.set(typeName, innerType);\n }\n }\n }\n\n getInnerType(typeName: string): CanonicalProfile | undefined {\n this._ensureNotDisposed();\n return this._innerTypes.get(typeName);\n }\n\n hasInnerType(typeName: string): boolean {\n this._ensureNotDisposed();\n return this._innerTypes.has(typeName);\n }\n\n dispose(): void {\n this._registry.clear();\n this._resolver.clearCache();\n this._innerTypes.clear();\n this._canonicalProfiles.clear();\n this._stats.totalLoaded = 0;\n this._stats.cacheHits = 0;\n this._stats.cacheMisses = 0;\n this._stats.loaderCalls = 0;\n this._stats.chainsResolved = 0;\n this._stats.registrations = 0;\n this._disposed = true;\n }\n\n // ---------------------------------------------------------------------------\n // Internal helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Validate that a StructureDefinition has the minimum required fields.\n */\n private _validateStructureDefinition(sd: StructureDefinition): void {\n if (!sd.url) {\n throw new InvalidStructureDefinitionError(\n 'Missing required field: url',\n sd.name as string | undefined,\n );\n }\n }\n\n /**\n * Guard against use after dispose.\n */\n private _ensureNotDisposed(): void {\n if (this._disposed) {\n throw new Error(\n 'FhirContext has been disposed. Create a new instance or call preloadCoreDefinitions() again.',\n );\n }\n }\n\n // ---------------------------------------------------------------------------\n // Accessors (for testing / diagnostics)\n // ---------------------------------------------------------------------------\n\n /**\n * Direct access to the internal registry (for diagnostics).\n */\n get registry(): StructureDefinitionRegistry {\n return this._registry;\n }\n\n /**\n * Direct access to the internal resolver (for diagnostics).\n */\n get resolver(): InheritanceChainResolver {\n return this._resolver;\n }\n}\n", "/**\n * fhir-context \u2014 MemoryLoader\n *\n * Loads StructureDefinitions from an in-memory Map.\n * Primary use cases:\n * - Unit testing (inject known definitions)\n * - Preloaded core FHIR R4 definitions\n *\n * @module fhir-context\n */\n\nimport type { StructureDefinition } from '../../model/index.js';\nimport type { StructureDefinitionLoader } from '../types.js';\n\n/**\n * A loader that resolves StructureDefinitions from an in-memory Map.\n *\n * The map is keyed by canonical URL. Lookups are synchronous but the\n * interface returns a Promise for consistency with other loaders.\n *\n * @example\n * ```typescript\n * const definitions = new Map<string, StructureDefinition>();\n * definitions.set('http://hl7.org/fhir/StructureDefinition/Patient', patientSD);\n * const loader = new MemoryLoader(definitions);\n * ```\n */\nexport class MemoryLoader implements StructureDefinitionLoader {\n private readonly _definitions: Map<string, StructureDefinition>;\n\n /**\n * @param definitions - Map of canonical URL \u2192 StructureDefinition.\n * The map is **not** copied; mutations to the\n * original map are visible to the loader.\n */\n constructor(definitions: Map<string, StructureDefinition>) {\n this._definitions = definitions;\n }\n\n async load(url: string): Promise<StructureDefinition | null> {\n return this._definitions.get(url) ?? null;\n }\n\n canLoad(url: string): boolean {\n return this._definitions.has(url);\n }\n\n getSourceType(): string {\n return 'memory';\n }\n\n /**\n * Number of definitions currently held in the map.\n */\n get size(): number {\n return this._definitions.size;\n }\n}\n", "/**\n * fhir-context \u2014 FileSystemLoader\n *\n * Loads StructureDefinitions from local JSON files on disk.\n * Uses the fhir-parser module to parse raw JSON into typed models.\n *\n * URL-to-path mapping strategy:\n * - Extract the resource name from the canonical URL tail\n * (e.g., `http://hl7.org/fhir/StructureDefinition/Patient` \u2192 `Patient`)\n * - Look for `{basePath}/{name}.json`\n *\n * @module fhir-context\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { existsSync } from 'node:fs';\n\nimport type { StructureDefinition } from '../../model/index.js';\nimport type { StructureDefinitionLoader } from '../types.js';\nimport { parseFhirJson } from '../../parser/index.js';\nimport { LoaderError } from '../errors.js';\n\n/**\n * Extract the resource name from a canonical URL.\n *\n * @param url - e.g. `\"http://hl7.org/fhir/StructureDefinition/Patient\"`\n * @returns The last path segment, e.g. `\"Patient\"`\n */\nexport function extractResourceName(url: string): string {\n const lastSlash = url.lastIndexOf('/');\n return lastSlash === -1 ? url : url.substring(lastSlash + 1);\n}\n\n/**\n * A loader that resolves StructureDefinitions from local JSON files.\n *\n * @example\n * ```typescript\n * const loader = new FileSystemLoader('/path/to/definitions');\n * const sd = await loader.load('http://hl7.org/fhir/StructureDefinition/Patient');\n * // Reads /path/to/definitions/Patient.json\n * ```\n */\nexport class FileSystemLoader implements StructureDefinitionLoader {\n private readonly _basePath: string;\n\n /**\n * @param basePath - Directory containing `{ResourceName}.json` files\n */\n constructor(basePath: string) {\n this._basePath = basePath;\n }\n\n async load(url: string): Promise<StructureDefinition | null> {\n const name = extractResourceName(url);\n const filePath = join(this._basePath, `${name}.json`);\n\n let raw: string;\n try {\n raw = await readFile(filePath, 'utf-8');\n } catch (err) {\n // File not found is a normal \"miss\" \u2014 return null to allow fallback\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n return null;\n }\n // Other I/O errors (permission denied, etc.) are hard failures\n throw new LoaderError(url, 'filesystem', err as Error);\n }\n\n // Parse using fhir-parser\n const result = parseFhirJson(raw);\n if (!result.success) {\n const messages = result.issues\n .filter((i) => i.severity === 'error')\n .map((i) => i.message)\n .join('; ');\n throw new LoaderError(\n url,\n 'filesystem',\n new Error(`Parse failed: ${messages}`),\n );\n }\n\n return result.data as StructureDefinition;\n }\n\n canLoad(url: string): boolean {\n const name = extractResourceName(url);\n const filePath = join(this._basePath, `${name}.json`);\n return existsSync(filePath);\n }\n\n getSourceType(): string {\n return 'filesystem';\n }\n\n /**\n * The base directory this loader reads from.\n */\n get basePath(): string {\n return this._basePath;\n }\n}\n", "/**\n * Bundle Loader \u2014 Phase 7\n *\n * Loads FHIR Bundle JSON files containing StructureDefinition entries\n * and converts them to CanonicalProfile[] for downstream consumption\n * by Phase 8's schema generation pipeline.\n *\n * Two data paths exist in MedXAI:\n *\n * ```\n * Path A \u2014 Stage-1 Validation (unchanged):\n * core-definitions/*.json (73 files)\n * \u2192 loadAllCoreDefinitions()\n * \u2192 FhirContextImpl (runtime validation)\n *\n * Path B \u2014 Stage-2 Schema Generation (this module):\n * spec/fhir/r4/profiles-*.json (complete bundles)\n * \u2192 BundleLoader\n * \u2192 StructureDefinitionRegistry (Phase 8)\n * \u2192 TableSchemaBuilder (Phase 8)\n * ```\n *\n * @module fhir-context\n */\n\nimport { readFileSync } from 'node:fs';\n\nimport { parseStructureDefinition } from '../parser/structure-definition-parser.js';\nimport { buildCanonicalProfile } from '../profile/canonical-builder.js';\nimport type { CanonicalProfile } from '../model/canonical-profile.js';\nimport type { StructureDefinitionKind } from '../model/primitives.js';\nimport type { ParseIssue } from '../parser/parse-error.js';\n\n// =============================================================================\n// Section 1: Types\n// =============================================================================\n\n/**\n * Options for filtering which StructureDefinitions to load from a bundle.\n */\nexport interface BundleLoadOptions {\n /** Only include entries where kind matches. Default: all kinds. */\n filterKind?: StructureDefinitionKind | StructureDefinitionKind[];\n\n /** Exclude abstract definitions. Default: false (include abstract). */\n excludeAbstract?: boolean;\n\n /** Only include entries where type matches one of these. */\n filterTypes?: string[];\n}\n\n/**\n * Result of loading one or more bundles.\n */\nexport interface BundleLoadResult {\n /** Successfully loaded CanonicalProfiles. */\n profiles: CanonicalProfile[];\n\n /** Errors encountered during loading (partial failures). */\n errors: BundleLoadError[];\n\n /** Summary statistics. */\n stats: {\n /** Total StructureDefinition entries found in bundle(s). */\n total: number;\n /** Successfully parsed and converted to CanonicalProfile. */\n loaded: number;\n /** Filtered out by options (kind, abstract, type). */\n skipped: number;\n /** Failed to parse or convert. */\n failed: number;\n };\n}\n\n/**\n * Describes a single error encountered while loading a StructureDefinition.\n */\nexport interface BundleLoadError {\n /** The name of the StructureDefinition that failed. */\n name: string;\n /** The canonical URL of the StructureDefinition that failed. */\n url: string;\n /** The error that occurred. */\n error: Error;\n /** Parse issues, if the failure was during parsing. */\n parseIssues?: readonly ParseIssue[];\n}\n\n// =============================================================================\n// Section 2: Internal Helpers\n// =============================================================================\n\n/**\n * Minimal Bundle shape for type-safe access.\n */\ninterface BundleShape {\n resourceType: string;\n entry?: Array<{\n resource?: Record<string, unknown>;\n }>;\n}\n\n/**\n * Check if a StructureDefinition should be included based on filter options.\n */\nfunction shouldInclude(\n sd: Record<string, unknown>,\n options?: BundleLoadOptions,\n): boolean {\n if (!options) return true;\n\n // Filter by kind\n if (options.filterKind !== undefined) {\n const kinds = Array.isArray(options.filterKind) ? options.filterKind : [options.filterKind];\n if (!kinds.includes(sd.kind as StructureDefinitionKind)) {\n return false;\n }\n }\n\n // Filter by abstract\n if (options.excludeAbstract === true && sd.abstract === true) {\n return false;\n }\n\n // Filter by type\n if (options.filterTypes !== undefined && options.filterTypes.length > 0) {\n if (!options.filterTypes.includes(sd.type as string)) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Create an empty BundleLoadResult.\n */\nfunction emptyResult(): BundleLoadResult {\n return {\n profiles: [],\n errors: [],\n stats: { total: 0, loaded: 0, skipped: 0, failed: 0 },\n };\n}\n\n/**\n * Extract StructureDefinition entries from a bundle object.\n */\nfunction extractStructureDefinitions(bundle: BundleShape): Array<Record<string, unknown>> {\n if (bundle.resourceType !== 'Bundle' || !Array.isArray(bundle.entry)) {\n return [];\n }\n\n return bundle.entry\n .filter(\n (e): e is { resource: Record<string, unknown> } =>\n e.resource !== undefined &&\n e.resource !== null &&\n typeof e.resource === 'object' &&\n e.resource.resourceType === 'StructureDefinition',\n )\n .map((e) => e.resource);\n}\n\n// =============================================================================\n// Section 3: Core Loading Functions\n// =============================================================================\n\n/**\n * Load CanonicalProfiles from an already-parsed Bundle object.\n *\n * This is the core loading function. It:\n * 1. Extracts all StructureDefinition entries from the bundle\n * 2. Applies filter options (kind, abstract, type)\n * 3. Parses each SD through `parseStructureDefinition`\n * 4. Converts each parsed SD to `CanonicalProfile` via `buildCanonicalProfile`\n * 5. Collects errors without aborting (partial failure tolerance)\n *\n * @param bundle - A parsed FHIR Bundle object containing StructureDefinition entries.\n * @param options - Optional filters to control which entries are loaded.\n * @returns BundleLoadResult with profiles, errors, and statistics.\n */\nexport function loadBundleFromObject(\n bundle: BundleShape,\n options?: BundleLoadOptions,\n): BundleLoadResult {\n const result = emptyResult();\n\n const definitions = extractStructureDefinitions(bundle);\n result.stats.total = definitions.length;\n\n for (const sd of definitions) {\n const name = (sd.name as string) ?? '<unknown>';\n const url = (sd.url as string) ?? '<unknown>';\n\n // Apply filters\n if (!shouldInclude(sd, options)) {\n result.stats.skipped++;\n continue;\n }\n\n // Parse the StructureDefinition\n try {\n const parseResult = parseStructureDefinition(sd, 'StructureDefinition');\n\n if (!parseResult.success) {\n result.stats.failed++;\n const errorIssues = parseResult.issues.filter((i) => i.severity === 'error');\n result.errors.push({\n name,\n url,\n error: new Error(`Parse failed for ${name}: ${errorIssues.map((i) => i.message).join('; ')}`),\n parseIssues: parseResult.issues,\n });\n continue;\n }\n\n // Convert to CanonicalProfile\n const profile = buildCanonicalProfile(parseResult.data);\n result.profiles.push(profile);\n result.stats.loaded++;\n } catch (err) {\n result.stats.failed++;\n result.errors.push({\n name,\n url,\n error: err instanceof Error ? err : new Error(String(err)),\n });\n }\n }\n\n return result;\n}\n\n/**\n * Load CanonicalProfiles from a FHIR Bundle JSON file.\n *\n * Reads the file synchronously (spec files are loaded once at startup),\n * parses the JSON, and delegates to `loadBundleFromObject`.\n *\n * @param filePath - Absolute path to a FHIR Bundle JSON file.\n * @param options - Optional filters to control which entries are loaded.\n * @returns BundleLoadResult with profiles, errors, and statistics.\n * @throws Error if the file cannot be read or is not valid JSON.\n */\nexport function loadBundleFromFile(\n filePath: string,\n options?: BundleLoadOptions,\n): BundleLoadResult {\n const raw = readFileSync(filePath, 'utf-8');\n const bundle: BundleShape = JSON.parse(raw);\n return loadBundleFromObject(bundle, options);\n}\n\n/**\n * Load and merge multiple bundle files in order.\n *\n * Later bundles override earlier ones for the same canonical URL.\n * This supports the standard loading order:\n * 1. profiles-types.json \u2014 type system (no tables)\n * 2. profiles-resources.json \u2014 clinical resources\n * 3. profiles-others.json \u2014 conformance resources\n * 4. profiles-platform.json \u2014 platform resources (Phase 9)\n *\n * @param filePaths - Array of absolute paths to FHIR Bundle JSON files.\n * @param options - Optional filters applied to each bundle.\n * @returns Merged BundleLoadResult with deduplicated profiles.\n */\nexport function loadBundlesFromFiles(\n filePaths: string[],\n options?: BundleLoadOptions,\n): BundleLoadResult {\n const merged = emptyResult();\n const profileMap = new Map<string, CanonicalProfile>();\n\n for (const filePath of filePaths) {\n const bundleResult = loadBundleFromFile(filePath, options);\n\n // Merge stats\n merged.stats.total += bundleResult.stats.total;\n merged.stats.skipped += bundleResult.stats.skipped;\n merged.stats.failed += bundleResult.stats.failed;\n\n // Merge errors\n merged.errors.push(...bundleResult.errors);\n\n // Merge profiles (later overrides earlier for same URL)\n for (const profile of bundleResult.profiles) {\n profileMap.set(profile.url, profile);\n }\n }\n\n merged.profiles = Array.from(profileMap.values());\n merged.stats.loaded = merged.profiles.length;\n\n return merged;\n}\n", "/**\n * fhir-profile \u2014 Canonical Profile Builder\n *\n * Converts a StructureDefinition (with populated snapshot) into the\n * internal {@link CanonicalProfile} semantic model defined in Phase 1.\n *\n * The CanonicalProfile is MedXAI's own abstraction optimized for\n * downstream consumption (validation, runtime, application layer):\n * - Pre-resolved inheritance (flattened snapshot)\n * - Semantic types (`max: 'unbounded'` instead of `\"*\"`)\n * - Non-optional flags (mustSupport/isModifier/isSummary always boolean)\n * - O(1) element lookup via `Map<string, CanonicalElement>`\n *\n * Exported functions:\n * - {@link buildCanonicalProfile} \u2014 convert full SD \u2192 CanonicalProfile\n * - {@link buildCanonicalElement} \u2014 convert single ElementDefinition \u2192 CanonicalElement\n * - {@link buildTypeConstraints} \u2014 convert ElementDefinitionType[] \u2192 TypeConstraint[]\n * - {@link buildBindingConstraint} \u2014 convert ElementDefinitionBinding \u2192 BindingConstraint\n * - {@link buildInvariants} \u2014 convert ElementDefinitionConstraint[] \u2192 Invariant[]\n * - {@link buildSlicingDefinition} \u2014 convert ElementDefinitionSlicing \u2192 SlicingDefinition\n *\n * @module fhir-profile\n */\n\nimport type {\n CanonicalProfile,\n CanonicalElement,\n TypeConstraint,\n BindingConstraint,\n Invariant,\n SlicingDefinition,\n SlicingDiscriminatorDef,\n} from '../model/index.js';\nimport type {\n ElementDefinition,\n ElementDefinitionType,\n ElementDefinitionBinding,\n ElementDefinitionConstraint,\n ElementDefinitionSlicing,\n StructureDefinition,\n} from '../model/index.js';\n\n// =============================================================================\n// Section 1: buildCanonicalProfile\n// =============================================================================\n\n/**\n * Convert a StructureDefinition (with snapshot) to a CanonicalProfile.\n *\n * Precondition: `sd.snapshot` must exist (generated by SnapshotGenerator).\n * If snapshot is missing, throws an error.\n *\n * @param sd - The StructureDefinition with populated snapshot.\n * @returns The internal CanonicalProfile representation.\n * @throws Error if sd.snapshot is missing.\n */\nexport function buildCanonicalProfile(sd: StructureDefinition): CanonicalProfile {\n if (!sd.snapshot?.element?.length) {\n throw new Error(\n `Cannot build CanonicalProfile: StructureDefinition '${sd.url ?? 'unknown'}' has no snapshot`,\n );\n }\n\n const elements = new Map<string, CanonicalElement>();\n\n for (const el of sd.snapshot.element) {\n const canonical = buildCanonicalElement(el);\n elements.set(canonical.path, canonical);\n }\n\n return {\n url: sd.url as string,\n version: sd.version ? (sd.version as string) : undefined,\n name: sd.name as string,\n kind: sd.kind,\n type: sd.type as string,\n baseProfile: sd.baseDefinition ? (sd.baseDefinition as string) : undefined,\n abstract: sd.abstract === true,\n derivation: sd.derivation,\n elements,\n };\n}\n\n// =============================================================================\n// Section 2: buildCanonicalElement\n// =============================================================================\n\n/**\n * Convert a single ElementDefinition to a CanonicalElement.\n *\n * Applies the following normalizations:\n * - `max: \"*\"` \u2192 `max: 'unbounded'`; numeric strings \u2192 numbers\n * - `mustSupport/isModifier/isSummary: undefined` \u2192 `false`\n * - `constraint: undefined` \u2192 `[]`\n * - `type: undefined` \u2192 `[]`\n *\n * @param ed - The ElementDefinition from a snapshot.\n * @returns The normalized CanonicalElement.\n */\nexport function buildCanonicalElement(ed: ElementDefinition): CanonicalElement {\n const path = (ed.path as string) ?? '';\n const id = (ed.id as string) ?? path;\n\n // Convert max: \"*\" \u2192 'unbounded', numeric string \u2192 number\n const max = convertMax(ed.max as string | undefined);\n\n // Convert min: default to 0\n const min = typeof ed.min === 'number' ? ed.min : 0;\n\n return {\n path,\n id,\n min,\n max,\n types: buildTypeConstraints(ed.type),\n binding: buildBindingConstraint(ed.binding),\n constraints: buildInvariants(ed.constraint),\n slicing: buildSlicingDefinition(ed.slicing),\n mustSupport: ed.mustSupport === true,\n isModifier: ed.isModifier === true,\n isSummary: ed.isSummary === true,\n };\n}\n\n// =============================================================================\n// Section 3: buildTypeConstraints\n// =============================================================================\n\n/**\n * Convert ElementDefinitionType[] to TypeConstraint[].\n *\n * Returns an empty array if types is undefined or empty.\n *\n * @param types - The FHIR type array from an ElementDefinition.\n * @returns Normalized TypeConstraint array.\n */\nexport function buildTypeConstraints(\n types: readonly ElementDefinitionType[] | undefined,\n): TypeConstraint[] {\n if (!types || types.length === 0) {\n return [];\n }\n\n return types.map((t) => {\n const constraint: TypeConstraint = {\n code: t.code as string,\n };\n\n if (t.profile && (t.profile as unknown[]).length > 0) {\n constraint.profiles = (t.profile as unknown[]).map((p) => p as string);\n }\n\n if (t.targetProfile && (t.targetProfile as unknown[]).length > 0) {\n constraint.targetProfiles = (t.targetProfile as unknown[]).map((p) => p as string);\n }\n\n return constraint;\n });\n}\n\n// =============================================================================\n// Section 4: buildBindingConstraint\n// =============================================================================\n\n/**\n * Convert ElementDefinitionBinding to BindingConstraint.\n *\n * Returns undefined if binding is undefined or has no strength.\n *\n * @param binding - The FHIR binding from an ElementDefinition.\n * @returns Normalized BindingConstraint or undefined.\n */\nexport function buildBindingConstraint(\n binding: ElementDefinitionBinding | undefined,\n): BindingConstraint | undefined {\n if (!binding || !binding.strength) {\n return undefined;\n }\n\n const result: BindingConstraint = {\n strength: binding.strength,\n };\n\n if (binding.valueSet) {\n result.valueSetUrl = binding.valueSet as string;\n }\n\n if (binding.description) {\n result.description = binding.description as string;\n }\n\n return result;\n}\n\n// =============================================================================\n// Section 5: buildInvariants\n// =============================================================================\n\n/**\n * Convert ElementDefinitionConstraint[] to Invariant[].\n *\n * Returns an empty array if constraints is undefined or empty.\n *\n * @param constraints - The FHIR constraint array from an ElementDefinition.\n * @returns Normalized Invariant array.\n */\nexport function buildInvariants(\n constraints: readonly ElementDefinitionConstraint[] | undefined,\n): Invariant[] {\n if (!constraints || constraints.length === 0) {\n return [];\n }\n\n return constraints.map((c) => {\n const invariant: Invariant = {\n key: c.key as string,\n severity: c.severity,\n human: c.human as string,\n };\n\n if (c.expression) {\n invariant.expression = c.expression as string;\n }\n\n if (c.source) {\n invariant.source = c.source as string;\n }\n\n return invariant;\n });\n}\n\n// =============================================================================\n// Section 6: buildSlicingDefinition\n// =============================================================================\n\n/**\n * Convert ElementDefinitionSlicing to SlicingDefinition.\n *\n * Returns undefined if slicing is undefined.\n * Normalizes `ordered` to boolean (default false).\n *\n * @param slicing - The FHIR slicing from an ElementDefinition.\n * @returns Normalized SlicingDefinition or undefined.\n */\nexport function buildSlicingDefinition(\n slicing: ElementDefinitionSlicing | undefined,\n): SlicingDefinition | undefined {\n if (!slicing) {\n return undefined;\n }\n\n const discriminators: SlicingDiscriminatorDef[] = (slicing.discriminator ?? []).map((d) => ({\n type: d.type,\n path: d.path as string,\n }));\n\n const result: SlicingDefinition = {\n discriminators,\n rules: slicing.rules,\n ordered: slicing.ordered === true,\n };\n\n if (slicing.description) {\n result.description = slicing.description as string;\n }\n\n return result;\n}\n\n// =============================================================================\n// Section 7: Internal Helpers\n// =============================================================================\n\n/**\n * Convert FHIR max string to `number | 'unbounded'`.\n *\n * - `\"*\"` \u2192 `'unbounded'`\n * - `\"0\"`, `\"1\"`, `\"5\"` \u2192 `0`, `1`, `5`\n * - `undefined` \u2192 `1` (FHIR default)\n */\nfunction convertMax(max: string | undefined): number | 'unbounded' {\n if (max === undefined || max === null) {\n return 1; // FHIR default\n }\n if (max === '*') {\n return 'unbounded';\n }\n const num = parseInt(max, 10);\n return isNaN(num) ? 1 : num;\n}\n", "/**\n * fhir-context \u2014 InnerType Extractor\n *\n * Extracts inner types (BackboneElement sub-types) from a {@link CanonicalProfile}.\n * These inner types represent nested complex structures within a FHIR resource,\n * such as `Patient.contact` \u2192 `PatientContact`.\n *\n * Inspired by Medplum's `StructureDefinitionParser.enterInnerType()` and\n * `buildTypeName()` from `@medplum/core/src/typeschema/types.ts`.\n *\n * ## Algorithm\n *\n * 1. Traverse all elements in the profile's `elements` Map\n * 2. Identify elements whose `types` include `BackboneElement` or `Element`\n * 3. For each such element, collect all direct child elements (path prefix match)\n * 4. Build a new `CanonicalProfile` for the inner type with a generated name\n *\n * ## Naming Convention\n *\n * Path segments are PascalCase-joined:\n * - `Patient.contact` \u2192 `PatientContact`\n * - `Bundle.entry.request` \u2192 `BundleEntryRequest`\n * - `Observation.component` \u2192 `ObservationComponent`\n *\n * @module fhir-context\n */\n\nimport type { CanonicalProfile, CanonicalElement } from '../model/canonical-profile.js';\n\n// =============================================================================\n// Section 1: buildTypeName\n// =============================================================================\n\n/**\n * Build a PascalCase type name from path segments.\n *\n * @param components - Path segments (e.g., `['Patient', 'contact']`)\n * @returns PascalCase type name (e.g., `'PatientContact'`)\n *\n * @example\n * ```typescript\n * buildTypeName(['Patient', 'contact']) // \u2192 'PatientContact'\n * buildTypeName(['Bundle', 'entry', 'request']) // \u2192 'BundleEntryRequest'\n * buildTypeName(['Patient']) // \u2192 'Patient'\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 * Capitalize the first letter of a string.\n * @internal\n */\nfunction capitalize(s: string): string {\n if (s.length === 0) return s;\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\n// =============================================================================\n// Section 2: isBackboneElement\n// =============================================================================\n\n/**\n * Check if an element defines a BackboneElement or Element inner type.\n *\n * An element is an inner type root if:\n * - Its `types` array contains a type with `code === 'BackboneElement'` or `code === 'Element'`\n * - It is not the root element of the profile (path has at least one dot)\n *\n * @param element - The canonical element to check\n * @returns `true` if this element defines an inner type\n */\nexport function isBackboneElementType(element: CanonicalElement): boolean {\n return element.types.some(\n (t) => t.code === 'BackboneElement' || t.code === 'Element',\n );\n}\n\n// =============================================================================\n// Section 3: extractInnerTypes\n// =============================================================================\n\n/**\n * Extract inner types from a CanonicalProfile.\n *\n * Scans the profile's elements for BackboneElement/Element types and creates\n * independent `CanonicalProfile` instances for each, containing only their\n * direct child elements.\n *\n * The returned Map is keyed by the generated type name (e.g., `'PatientContact'`).\n * Each inner type has its `parentType` set to the profile's type name.\n *\n * **Note:** This function also handles nested BackboneElements. For example,\n * if `Bundle.entry` is a BackboneElement containing `Bundle.entry.request`\n * (also a BackboneElement), both `BundleEntry` and `BundleEntryRequest` will\n * be extracted. `BundleEntryRequest` will have `parentType: 'BundleEntry'`.\n *\n * @param profile - The CanonicalProfile to extract inner types from\n * @returns Map of inner type name \u2192 CanonicalProfile\n *\n * @example\n * ```typescript\n * const innerTypes = extractInnerTypes(patientProfile);\n * // innerTypes.get('PatientContact') \u2192 CanonicalProfile for Patient.contact\n * // innerTypes.get('PatientCommunication') \u2192 CanonicalProfile for Patient.communication\n * // innerTypes.get('PatientLink') \u2192 CanonicalProfile for Patient.link\n * ```\n */\nexport function extractInnerTypes(\n profile: CanonicalProfile,\n): Map<string, CanonicalProfile> {\n const innerTypes = new Map<string, CanonicalProfile>();\n\n // Step 1: Identify all BackboneElement roots\n const backboneRoots: Array<{ path: string; typeName: string }> = [];\n\n for (const [path, element] of profile.elements) {\n // Skip root element\n if (!path.includes('.')) continue;\n\n if (isBackboneElementType(element)) {\n const segments = path.split('.');\n const typeName = buildTypeName(segments);\n backboneRoots.push({ path, typeName });\n }\n }\n\n // Step 2: For each backbone root, collect direct child elements\n for (const { path: rootPath, typeName } of backboneRoots) {\n const childElements = new Map<string, CanonicalElement>();\n const prefix = rootPath + '.';\n\n for (const [elementPath, element] of profile.elements) {\n // Must start with the root path + '.'\n if (!elementPath.startsWith(prefix)) continue;\n\n // Must be a DIRECT child \u2014 no further dots after the prefix\n const remainder = elementPath.substring(prefix.length);\n if (remainder.includes('.')) continue;\n\n childElements.set(elementPath, element);\n }\n\n // Determine parent type name\n const rootSegments = rootPath.split('.');\n let parentTypeName: string;\n if (rootSegments.length === 2) {\n // Direct child of resource (e.g., Patient.contact \u2192 parent is Patient)\n parentTypeName = rootSegments[0];\n } else {\n // Nested backbone (e.g., Bundle.entry.request \u2192 parent is BundleEntry)\n parentTypeName = buildTypeName(rootSegments.slice(0, -1));\n }\n\n const innerProfile: CanonicalProfile = {\n url: profile.url + '#' + typeName,\n name: typeName,\n kind: profile.kind,\n type: typeName,\n abstract: false,\n elements: childElements,\n parentType: parentTypeName,\n };\n\n innerTypes.set(typeName, innerProfile);\n }\n\n return innerTypes;\n}\n", "/**\n * fhir-profile \u2014 Public Interfaces & Types\n *\n * Defines the core abstractions for the FHIR profile module:\n * - {@link SnapshotGeneratorOptions} \u2014 generation configuration\n * - {@link SnapshotResult} \u2014 generation output\n * - {@link SnapshotIssue} \u2014 issue reporting\n * - {@link DiffElementTracker} \u2014 internal differential consumption tracking\n * - {@link TraversalScope} \u2014 cursor-based scope for base-driven traversal\n *\n * This module implements the snapshot generation algorithm conceptually\n * equivalent to HAPI FHIR's `ProfileUtilities.generateSnapshot()`.\n *\n * @module fhir-profile\n */\n\nimport type {\n CanonicalProfile,\n ElementDefinition,\n StructureDefinition,\n} from '../model/index.js';\n\n// =============================================================================\n// Section 1: Snapshot Generation Options\n// =============================================================================\n\n/**\n * Configuration options for snapshot generation.\n *\n * @example\n * ```typescript\n * const options: SnapshotGeneratorOptions = {\n * throwOnError: false,\n * maxRecursionDepth: 50,\n * generateCanonical: true,\n * };\n * ```\n */\nexport interface SnapshotGeneratorOptions {\n /**\n * Whether to throw on the first error or collect all errors.\n *\n * When `true`, the generator throws immediately on the first error\n * (matching HAPI's \"exception mode\"). When `false` (default), errors\n * are collected in {@link SnapshotResult.issues} and generation\n * continues as far as possible.\n *\n * @default false\n */\n readonly throwOnError?: boolean;\n\n /**\n * Maximum recursion depth for nested snapshot generation.\n *\n * Snapshot generation can recursively trigger generation of other\n * profiles (e.g., when a base profile lacks a snapshot, or when\n * expanding into datatype definitions). This limit prevents runaway\n * recursion in pathological or circular profiles.\n *\n * @default 50\n */\n readonly maxRecursionDepth?: number;\n\n /**\n * Whether to generate a {@link CanonicalProfile} alongside the snapshot.\n *\n * When `true`, the result includes a `canonical` field containing\n * the MedXAI internal semantic model derived from the generated snapshot.\n *\n * @default false\n */\n readonly generateCanonical?: boolean;\n}\n\n// =============================================================================\n// Section 2: Snapshot Result\n// =============================================================================\n\n/**\n * Result of snapshot generation.\n *\n * Contains the StructureDefinition with its populated snapshot, any issues\n * encountered during generation, and optionally a {@link CanonicalProfile}.\n *\n * @example\n * ```typescript\n * const result = await generator.generate(sd);\n * if (result.success) {\n * console.log(`Generated ${result.structureDefinition.snapshot?.element.length} elements`);\n * } else {\n * console.error('Errors:', result.issues.filter(i => i.severity === 'error'));\n * }\n * ```\n */\nexport interface SnapshotResult {\n /** The StructureDefinition with populated snapshot. */\n readonly structureDefinition: StructureDefinition;\n\n /**\n * Optional {@link CanonicalProfile} if\n * {@link SnapshotGeneratorOptions.generateCanonical} was `true`.\n */\n readonly canonical?: CanonicalProfile;\n\n /** Issues encountered during generation (warnings + errors). */\n readonly issues: readonly SnapshotIssue[];\n\n /**\n * Whether generation completed successfully.\n *\n * `true` when no error-severity issues were recorded.\n * Warnings and informational issues do not affect this flag.\n */\n readonly success: boolean;\n}\n\n// =============================================================================\n// Section 3: Snapshot Issue\n// =============================================================================\n\n/**\n * An issue encountered during snapshot generation.\n *\n * Mirrors the concept of HAPI's `ValidationMessage` but scoped to\n * snapshot generation. Issues are collected during generation and\n * returned in {@link SnapshotResult.issues}.\n *\n * @example\n * ```typescript\n * const issue: SnapshotIssue = {\n * severity: 'error',\n * code: 'CARDINALITY_VIOLATION',\n * message: 'Derived min (0) is less than base min (1)',\n * path: 'Patient.identifier',\n * };\n * ```\n */\nexport interface SnapshotIssue {\n /** Severity level of the issue. */\n readonly severity: 'error' | 'warning' | 'information';\n\n /** Machine-readable issue code. */\n readonly code: SnapshotIssueCode;\n\n /** Human-readable description of the issue. */\n readonly message: string;\n\n /** Element path where the issue occurred (e.g., `'Patient.identifier'`). */\n readonly path?: string;\n\n /** Additional details for debugging. */\n readonly details?: string;\n}\n\n// =============================================================================\n// Section 4: Snapshot Issue Codes\n// =============================================================================\n\n/**\n * Machine-readable issue codes for snapshot generation.\n *\n * Each code corresponds to a specific category of problem that can\n * occur during the snapshot generation process.\n */\nexport type SnapshotIssueCode =\n /** Circular dependency detected in profile chain. */\n | 'CIRCULAR_DEPENDENCY'\n /** Base StructureDefinition could not be loaded. */\n | 'BASE_NOT_FOUND'\n /** Base StructureDefinition exists but has no snapshot. */\n | 'BASE_MISSING_SNAPSHOT'\n /** Differential element was not consumed during generation. */\n | 'DIFFERENTIAL_NOT_CONSUMED'\n /** Cardinality constraint violation (min/max tightening rules). */\n | 'CARDINALITY_VIOLATION'\n /** Type constraint is incompatible with base types. */\n | 'TYPE_INCOMPATIBLE'\n /** Binding constraint violation (e.g., relaxing REQUIRED binding). */\n | 'BINDING_VIOLATION'\n /** Slicing-related error (compatibility, closed slicing, etc.). */\n | 'SLICING_ERROR'\n /** Differential path not found in base snapshot. */\n | 'PATH_NOT_FOUND'\n /** Generic invalid constraint (catch-all for other violations). */\n | 'INVALID_CONSTRAINT'\n /** Internal error in the generator (should not happen). */\n | 'INTERNAL_ERROR';\n\n// =============================================================================\n// Section 5: Internal Types \u2014 Differential Tracking\n// =============================================================================\n\n/**\n * Tracks a differential element during snapshot generation.\n *\n * Implements the HAPI marker pattern where each differential element\n * is tagged with `userData(GENERATED_IN_SNAPSHOT)` after being consumed\n * by the merge algorithm. At the end of generation, any tracker with\n * `consumed === false` indicates an unmatched differential element.\n *\n * @internal Used by {@link ElementMerger} and {@link SnapshotGenerator}.\n */\nexport interface DiffElementTracker {\n /** The original differential ElementDefinition. */\n readonly element: ElementDefinition;\n\n /**\n * Whether this element has been consumed (matched and merged)\n * during snapshot generation.\n *\n * Set to `true` by the merge algorithm when the element is\n * successfully applied to the snapshot. Checked post-generation\n * to detect unmatched differential elements.\n */\n consumed: boolean;\n}\n\n// =============================================================================\n// Section 6: Internal Types \u2014 Traversal Scope\n// =============================================================================\n\n/**\n * Cursor-based scope for base-driven traversal.\n *\n * Used by the element merger (`processPaths` equivalent) to define\n * the current working range within a list of ElementDefinitions.\n * Both `start` and `end` are inclusive indices.\n *\n * This mirrors HAPI's `baseCursor/baseLimit` and `diffCursor/diffLimit`\n * parameter pairs in `processPaths()`.\n *\n * @example\n * ```typescript\n * // Scope covering elements[2] through elements[5]\n * const scope: TraversalScope = {\n * elements: baseSnapshot.element,\n * start: 2,\n * end: 5,\n * };\n * ```\n *\n * @internal Used by {@link ElementMerger}.\n */\nexport interface TraversalScope {\n /** The element list being traversed. */\n readonly elements: readonly ElementDefinition[];\n\n /** Start index (inclusive). */\n readonly start: number;\n\n /** End index (inclusive). */\n readonly end: number;\n}\n\n// =============================================================================\n// Section 7: Helper Functions\n// =============================================================================\n\n/**\n * Create a {@link SnapshotIssue} with the given parameters.\n *\n * Convenience factory to reduce boilerplate when recording issues.\n */\nexport function createSnapshotIssue(\n severity: SnapshotIssue['severity'],\n code: SnapshotIssueCode,\n message: string,\n path?: string,\n details?: string,\n): SnapshotIssue {\n const issue: SnapshotIssue = { severity, code, message };\n if (path !== undefined) {\n (issue as { path: string }).path = path;\n }\n if (details !== undefined) {\n (issue as { details: string }).details = details;\n }\n return issue;\n}\n\n/**\n * Create a {@link DiffElementTracker} for a differential element.\n *\n * @param element - The differential ElementDefinition to track.\n * @returns A tracker with `consumed` set to `false`.\n */\nexport function createDiffTracker(element: ElementDefinition): DiffElementTracker {\n return { element, consumed: false };\n}\n", "/**\n * fhir-profile \u2014 Path Utility Functions\n *\n * Path matching and manipulation utilities used by the snapshot generation\n * algorithm. These functions underpin the base-driven traversal in\n * {@link ElementMerger} (the `processPaths` equivalent).\n *\n * Key concepts:\n * - **Element path**: dot-separated segments like `\"Patient.name.given\"`\n * - **Choice type path**: ends with `[x]`, e.g. `\"Observation.value[x]\"`\n * - **Concrete choice path**: resolved form, e.g. `\"Observation.valueString\"`\n * - **Slice name**: stored in element id with `:` separator, e.g. `\"Patient.identifier:MRN\"`\n *\n * @module fhir-profile\n */\n\nimport type { ElementDefinition } from '../model/index.js';\nimport type { DiffElementTracker, TraversalScope } from './types.js';\n\n// =============================================================================\n// Section 1: Basic Path Operations\n// =============================================================================\n\n/**\n * Check whether two paths match exactly.\n *\n * @example\n * pathMatches('Patient.name', 'Patient.name') // true\n * pathMatches('Patient.name', 'Patient.identifier') // false\n */\nexport function pathMatches(basePath: string, diffPath: string): boolean {\n return basePath === diffPath;\n}\n\n/**\n * Check whether `childPath` is a direct child of `parentPath`.\n *\n * A direct child has exactly one more segment than the parent.\n *\n * @example\n * isDirectChild('Patient.name', 'Patient.name.given') // true\n * isDirectChild('Patient.name', 'Patient.name.given.value') // false\n * isDirectChild('Patient.name', 'Patient.identifier') // false\n */\nexport function isDirectChild(parentPath: string, childPath: string): boolean {\n if (!childPath.startsWith(parentPath + '.')) {\n return false;\n }\n const remainder = childPath.slice(parentPath.length + 1);\n return remainder.length > 0 && !remainder.includes('.');\n}\n\n/**\n * Check whether `descendantPath` is a descendant of `ancestorPath`\n * (at any depth).\n *\n * @example\n * isDescendant('Patient.name', 'Patient.name.given') // true\n * isDescendant('Patient.name', 'Patient.name.given.value') // true\n * isDescendant('Patient.name', 'Patient.name') // false\n * isDescendant('Patient.name', 'Patient.identifier') // false\n */\nexport function isDescendant(ancestorPath: string, descendantPath: string): boolean {\n return descendantPath.startsWith(ancestorPath + '.');\n}\n\n/**\n * Get the depth (number of segments) of a path.\n *\n * @example\n * pathDepth('Patient') // 1\n * pathDepth('Patient.name') // 2\n * pathDepth('Patient.name.given') // 3\n */\nexport function pathDepth(path: string): number {\n if (path.length === 0) return 0;\n let count = 1;\n for (let i = 0; i < path.length; i++) {\n if (path.charCodeAt(i) === 46 /* '.' */) count++;\n }\n return count;\n}\n\n/**\n * Get the parent path (everything before the last `.`).\n *\n * @example\n * parentPath('Patient.name.given') // 'Patient.name'\n * parentPath('Patient.name') // 'Patient'\n * parentPath('Patient') // undefined\n */\nexport function parentPath(path: string): string | undefined {\n const lastDot = path.lastIndexOf('.');\n return lastDot === -1 ? undefined : path.slice(0, lastDot);\n}\n\n/**\n * Get the last segment (tail) of a path.\n *\n * @example\n * tailSegment('Patient.name.given') // 'given'\n * tailSegment('Patient') // 'Patient'\n */\nexport function tailSegment(path: string): string {\n const lastDot = path.lastIndexOf('.');\n return lastDot === -1 ? path : path.slice(lastDot + 1);\n}\n\n// =============================================================================\n// Section 2: Choice Type Path Operations\n// =============================================================================\n\n/**\n * Check whether a path ends with `[x]` (choice type wildcard).\n *\n * @example\n * isChoiceTypePath('Observation.value[x]') // true\n * isChoiceTypePath('Observation.valueString') // false\n * isChoiceTypePath('Observation.value') // false\n */\nexport function isChoiceTypePath(path: string): boolean {\n return path.endsWith('[x]');\n}\n\n/**\n * Check whether `concretePath` matches a choice type `choicePath`.\n *\n * The concrete path must share the same prefix (minus `[x]`) and the\n * remaining suffix must start with an uppercase letter (the type name).\n *\n * @example\n * matchesChoiceType('Observation.value[x]', 'Observation.valueString') // true\n * matchesChoiceType('Observation.value[x]', 'Observation.valueQuantity') // true\n * matchesChoiceType('Observation.value[x]', 'Observation.code') // false\n * matchesChoiceType('Observation.value[x]', 'Observation.value') // false\n */\nexport function matchesChoiceType(choicePath: string, concretePath: string): boolean {\n if (!choicePath.endsWith('[x]')) return false;\n const base = choicePath.slice(0, -3); // Remove '[x]'\n if (!concretePath.startsWith(base)) return false;\n const suffix = concretePath.slice(base.length);\n // Suffix must be non-empty and start with uppercase (type name)\n return suffix.length > 0 && suffix.charCodeAt(0) >= 65 && suffix.charCodeAt(0) <= 90;\n}\n\n/**\n * Extract the type name from a concrete choice path given the choice base.\n *\n * @example\n * extractChoiceTypeName('Observation.value[x]', 'Observation.valueString') // 'String'\n * extractChoiceTypeName('Observation.value[x]', 'Observation.valueQuantity') // 'Quantity'\n * extractChoiceTypeName('Observation.value[x]', 'Observation.code') // undefined\n */\nexport function extractChoiceTypeName(\n choicePath: string,\n concretePath: string,\n): string | undefined {\n if (!matchesChoiceType(choicePath, concretePath)) return undefined;\n const base = choicePath.slice(0, -3);\n return concretePath.slice(base.length);\n}\n\n// =============================================================================\n// Section 3: Slice Path Operations\n// =============================================================================\n\n/**\n * Check whether an element id contains a slice name (`:` separator).\n *\n * In FHIR, slice names appear in element ids, not in paths.\n * Format: `\"ResourceType.path:sliceName\"` or `\"ResourceType.path:sliceName.child\"`\n *\n * @example\n * hasSliceName('Patient.identifier:MRN') // true\n * hasSliceName('Patient.identifier:MRN.system') // true\n * hasSliceName('Patient.identifier') // false\n */\nexport function hasSliceName(elementId: string): boolean {\n return elementId.includes(':');\n}\n\n/**\n * Extract the first slice name from an element id.\n *\n * @example\n * extractSliceName('Patient.identifier:MRN') // 'MRN'\n * extractSliceName('Patient.identifier:MRN.system') // 'MRN'\n * extractSliceName('Patient.identifier') // undefined\n */\nexport function extractSliceName(elementId: string): string | undefined {\n const colonIdx = elementId.indexOf(':');\n if (colonIdx === -1) return undefined;\n // Slice name ends at the next '.' or end of string\n const afterColon = elementId.slice(colonIdx + 1);\n const dotIdx = afterColon.indexOf('.');\n return dotIdx === -1 ? afterColon : afterColon.slice(0, dotIdx);\n}\n\n// =============================================================================\n// Section 4: Scope Computation (processPaths core dependency)\n// =============================================================================\n\n/**\n * Compute the child element scope for a parent element in a list.\n *\n * Returns a {@link TraversalScope} covering all direct and indirect\n * children of the element at `parentIndex`. Both `start` and `end`\n * are inclusive indices.\n *\n * Returns `undefined` if the parent has no children.\n *\n * @example\n * // elements: [Patient, Patient.id, Patient.name, Patient.name.given,\n * // Patient.name.family, Patient.identifier]\n * getChildScope(elements, 2)\n * // \u2192 { elements, start: 3, end: 4 } (Patient.name.given, Patient.name.family)\n */\nexport function getChildScope(\n elements: readonly ElementDefinition[],\n parentIndex: number,\n): TraversalScope | undefined {\n if (parentIndex < 0 || parentIndex >= elements.length) return undefined;\n\n const parentPath = elements[parentIndex].path;\n if (!parentPath) return undefined;\n\n const prefix = parentPath + '.';\n const start = parentIndex + 1;\n\n // Find the last child element (all descendants share the prefix)\n let end = -1;\n for (let i = start; i < elements.length; i++) {\n const p = elements[i].path;\n if (p && p.startsWith(prefix)) {\n end = i;\n } else {\n break;\n }\n }\n\n if (end === -1) return undefined;\n\n return { elements, start, end };\n}\n\n/**\n * Find differential elements matching `basePath` within the given scope.\n *\n * Matching rules (mirrors HAPI `getDiffMatches`):\n * 1. Exact path match\n * 2. Choice type match (base ends with `[x]`, diff has concrete type)\n * 3. Same path with different sliceName (slice match)\n *\n * Only considers unconsumed trackers within `[diffStart, diffEnd]` inclusive.\n */\nexport function getDiffMatches(\n differential: readonly DiffElementTracker[],\n basePath: string,\n diffStart: number,\n diffEnd: number,\n): DiffElementTracker[] {\n const matches: DiffElementTracker[] = [];\n const isChoice = isChoiceTypePath(basePath);\n\n for (let i = diffStart; i <= diffEnd && i < differential.length; i++) {\n const tracker = differential[i];\n const diffPath = tracker.element.path;\n if (!diffPath) continue;\n\n // Exact path match\n if (diffPath === basePath) {\n matches.push(tracker);\n continue;\n }\n\n // Choice type match: base is value[x], diff is valueString\n if (isChoice && matchesChoiceType(basePath, diffPath)) {\n matches.push(tracker);\n continue;\n }\n }\n\n return matches;\n}\n\n/**\n * Check whether the differential contains descendant elements of `basePath`\n * within the given scope.\n *\n * This corresponds to HAPI's `hasInnerDiffMatches()` \u2014 it detects whether\n * the diff constrains children of an element even when the element itself\n * has no direct diff match.\n */\nexport function hasInnerDiffMatches(\n differential: readonly DiffElementTracker[],\n basePath: string,\n diffStart: number,\n diffEnd: number,\n): boolean {\n const prefix = basePath + '.';\n const isChoice = isChoiceTypePath(basePath);\n const choiceBase = isChoice ? basePath.slice(0, -3) : '';\n\n for (let i = diffStart; i <= diffEnd && i < differential.length; i++) {\n const diffPath = differential[i].element.path;\n if (!diffPath) continue;\n\n // Direct descendant\n if (diffPath.startsWith(prefix)) {\n return true;\n }\n\n // Choice type descendant: base is value[x], diff is valueString.extension\n if (isChoice && diffPath.startsWith(choiceBase)) {\n const afterBase = diffPath.slice(choiceBase.length);\n // Must have uppercase type name then a dot for children\n if (\n afterBase.length > 1 &&\n afterBase.charCodeAt(0) >= 65 &&\n afterBase.charCodeAt(0) <= 90 &&\n afterBase.includes('.')\n ) {\n return true;\n }\n }\n }\n\n return false;\n}\n\n// =============================================================================\n// Section 5: Path Rewriting\n// =============================================================================\n\n/**\n * Rewrite a path from one prefix to another.\n *\n * Used during datatype expansion: when diving into a complex type's\n * snapshot, paths need to be rewritten from the datatype's namespace\n * to the target element's namespace.\n *\n * @example\n * rewritePath('Identifier.system', 'Identifier', 'Patient.identifier')\n * // \u2192 'Patient.identifier.system'\n *\n * rewritePath('Identifier', 'Identifier', 'Patient.identifier')\n * // \u2192 'Patient.identifier'\n *\n * rewritePath('HumanName.given', 'HumanName', 'Patient.name')\n * // \u2192 'Patient.name.given'\n */\nexport function rewritePath(\n sourcePath: string,\n sourcePrefix: string,\n targetPrefix: string,\n): string {\n if (sourcePath === sourcePrefix) {\n return targetPrefix;\n }\n if (sourcePath.startsWith(sourcePrefix + '.')) {\n return targetPrefix + sourcePath.slice(sourcePrefix.length);\n }\n // Fallback: return as-is if prefix doesn't match\n return sourcePath;\n}\n", "/**\n * fhir-profile \u2014 Constraint Merging Engine\n *\n * Implements field-level merging of differential ElementDefinition constraints\n * onto snapshot elements. This is the most granular part of snapshot generation.\n *\n * Corresponds to HAPI FHIR R4:\n * - `ProfileUtilities.updateFromDefinition()` \u2192 {@link mergeConstraints}\n * - `ProfileUtilities.updateFromBase()` \u2192 {@link setBaseTraceability}\n *\n * Merge strategies per field (from HAPI research):\n * - **Overwrite**: short, definition, comment, requirements, label, fixed, pattern,\n * maxLength, minValue, maxValue, mustSupport, defaultValue, meaningWhenMissing\n * - **Validate-then-overwrite**: min, max, type[], binding\n * - **Append/union**: constraint[], alias[], example[], mapping[]\n * - **Conditional**: isModifier (extensions only), isSummary (base guard)\n *\n * @module fhir-profile\n */\n\nimport type {\n ElementDefinition,\n ElementDefinitionBase,\n ElementDefinitionBinding,\n ElementDefinitionConstraint,\n ElementDefinitionExample,\n ElementDefinitionMapping,\n ElementDefinitionType,\n FhirString,\n FhirUnsignedInt,\n} from '../model/index.js';\nimport type { SnapshotIssue } from './types.js';\nimport { createSnapshotIssue } from './types.js';\n\n// =============================================================================\n// Section 1: Main Entry Point \u2014 mergeConstraints\n// =============================================================================\n\n/**\n * Apply differential constraints onto a snapshot element.\n *\n * Corresponds to HAPI `updateFromDefinition(dest, source, ...)`.\n * The `dest` element is mutated in place and also returned.\n *\n * @param dest - The working snapshot element (initially cloned from base).\n * @param source - The differential element to apply.\n * @param issues - Mutable array to collect issues.\n * @returns The mutated `dest` element.\n */\nexport function mergeConstraints(\n dest: ElementDefinition,\n source: ElementDefinition,\n issues: SnapshotIssue[],\n): ElementDefinition {\n const path = dest.path ?? source.path ?? '<unknown>';\n\n // --- Cardinality (validate-then-overwrite) ---\n mergeCardinality(dest, source, issues, path);\n\n // --- Types (validate-then-replace) ---\n if (source.type !== undefined) {\n const merged = mergeTypes(dest.type, source.type, issues, path);\n dest.type = merged;\n }\n\n // --- Binding (validate-then-overwrite) ---\n if (source.binding !== undefined) {\n const merged = mergeBinding(dest.binding, source.binding, issues, path);\n dest.binding = merged;\n }\n\n // --- Documentation fields (pure overwrite) ---\n if (source.short !== undefined) dest.short = source.short;\n if (source.definition !== undefined) dest.definition = source.definition;\n if (source.comment !== undefined) dest.comment = source.comment;\n if (source.requirements !== undefined) dest.requirements = source.requirements;\n if (source.label !== undefined) dest.label = source.label;\n\n // --- Value constraints (pure overwrite) ---\n if (source.fixed !== undefined) dest.fixed = source.fixed;\n if (source.pattern !== undefined) dest.pattern = source.pattern;\n if (source.maxLength !== undefined) dest.maxLength = source.maxLength;\n if (source.minValue !== undefined) dest.minValue = source.minValue;\n if (source.maxValue !== undefined) dest.maxValue = source.maxValue;\n if (source.defaultValue !== undefined) dest.defaultValue = source.defaultValue;\n if (source.meaningWhenMissing !== undefined) dest.meaningWhenMissing = source.meaningWhenMissing;\n if (source.orderMeaning !== undefined) dest.orderMeaning = source.orderMeaning;\n\n // --- Flags (overwrite / conditional) ---\n if (source.mustSupport !== undefined) dest.mustSupport = source.mustSupport;\n\n // isSummary: guard \u2014 if base already has it, do not allow change\n if (source.isSummary !== undefined) {\n if (dest.isSummary !== undefined && dest.isSummary !== source.isSummary) {\n issues.push(\n createSnapshotIssue(\n 'warning',\n 'INVALID_CONSTRAINT',\n `Cannot change isSummary from ${String(dest.isSummary)} to ${String(source.isSummary)}`,\n path,\n ),\n );\n } else {\n dest.isSummary = source.isSummary;\n }\n }\n\n // isModifier: conditional \u2014 only extensions can change this\n if (source.isModifier !== undefined) {\n dest.isModifier = source.isModifier;\n }\n if (source.isModifierReason !== undefined) {\n dest.isModifierReason = source.isModifierReason;\n }\n\n // --- Slicing (overwrite if present in diff) ---\n if (source.slicing !== undefined) dest.slicing = source.slicing;\n if (source.sliceName !== undefined) dest.sliceName = source.sliceName;\n if (source.sliceIsConstraining !== undefined) dest.sliceIsConstraining = source.sliceIsConstraining;\n\n // --- Other identity fields ---\n if (source.representation !== undefined) dest.representation = source.representation;\n if (source.code !== undefined) dest.code = source.code;\n if (source.contentReference !== undefined) dest.contentReference = source.contentReference;\n if (source.condition !== undefined) dest.condition = source.condition;\n\n // --- Append/union fields ---\n dest.constraint = mergeConstraintList(dest.constraint, source.constraint);\n dest.alias = mergeStringArray(dest.alias, source.alias) as FhirString[] | undefined;\n dest.example = mergeExampleList(dest.example, source.example);\n dest.mapping = mergeMappingList(dest.mapping, source.mapping);\n\n return dest;\n}\n\n// =============================================================================\n// Section 2: Base Traceability \u2014 setBaseTraceability\n// =============================================================================\n\n/**\n * Populate `dest.base` with traceability information from the base element.\n *\n * Corresponds to HAPI `updateFromBase(derived, base)`.\n * If `base` already has a `.base`, we copy from `base.base` (preserving\n * original ancestry). Otherwise we copy from `base` directly.\n *\n * @param dest - The element to set base traceability on.\n * @param base - The base element to derive traceability from.\n */\nexport function setBaseTraceability(\n dest: ElementDefinition,\n base: ElementDefinition,\n): void {\n const baseInfo: ElementDefinitionBase = base.base\n ? {\n path: base.base.path,\n min: base.base.min,\n max: base.base.max,\n }\n : {\n path: base.path ?? ('' as FhirString),\n min: base.min ?? (0 as FhirUnsignedInt),\n max: base.max ?? ('*' as FhirString),\n };\n\n dest.base = baseInfo;\n}\n\n// =============================================================================\n// Section 3: Cardinality Merging\n// =============================================================================\n\n/**\n * Merge cardinality constraints (min/max) with validation.\n *\n * Rules:\n * - `derived.min` must be >= `base.min` (except for slices)\n * - `derived.max` must be <= `base.max`\n *\n * @internal Exported for direct testing.\n */\nexport function mergeCardinality(\n dest: ElementDefinition,\n source: ElementDefinition,\n issues: SnapshotIssue[],\n path?: string,\n): void {\n const elementPath = path ?? dest.path ?? '<unknown>';\n\n // --- min ---\n if (source.min !== undefined) {\n const baseMin = dest.min ?? 0;\n const derivedMin = source.min;\n\n // Slice exception: slices can have min < base min\n const isSlice = source.sliceName !== undefined && source.sliceName !== '';\n\n if (!isSlice && derivedMin < baseMin) {\n issues.push(\n createSnapshotIssue(\n 'error',\n 'CARDINALITY_VIOLATION',\n `Derived min (${derivedMin}) is less than base min (${baseMin})`,\n elementPath,\n ),\n );\n }\n dest.min = derivedMin;\n }\n\n // --- max ---\n if (source.max !== undefined) {\n const baseMax = dest.max ?? '*';\n const derivedMax = source.max;\n\n if (isLargerMax(derivedMax, baseMax)) {\n issues.push(\n createSnapshotIssue(\n 'error',\n 'CARDINALITY_VIOLATION',\n `Derived max (${derivedMax}) is greater than base max (${baseMax})`,\n elementPath,\n ),\n );\n }\n dest.max = derivedMax;\n }\n}\n\n// =============================================================================\n// Section 4: Type Merging\n// =============================================================================\n\n/**\n * Merge type constraints with compatibility validation.\n *\n * Each derived type must be compatible with at least one base type.\n * Special allowances: Extension, Element, *, Resource/DomainResource.\n *\n * If valid, derived types replace base types entirely.\n *\n * @returns The merged type array (derived types if valid, base types if no diff).\n */\nexport function mergeTypes(\n baseTypes: readonly ElementDefinitionType[] | undefined,\n diffTypes: readonly ElementDefinitionType[] | undefined,\n issues: SnapshotIssue[],\n path: string,\n): ElementDefinitionType[] | undefined {\n if (diffTypes === undefined || diffTypes.length === 0) {\n return baseTypes ? [...baseTypes] : undefined;\n }\n\n if (baseTypes === undefined || baseTypes.length === 0) {\n // No base types to validate against \u2014 accept derived as-is\n return [...diffTypes];\n }\n\n // Validate each derived type against base types\n for (const derivedType of diffTypes) {\n if (!isTypeCompatible(derivedType, baseTypes)) {\n issues.push(\n createSnapshotIssue(\n 'error',\n 'TYPE_INCOMPATIBLE',\n `Type '${derivedType.code}' is not compatible with base types [${baseTypes.map((t) => t.code).join(', ')}]`,\n path,\n ),\n );\n }\n }\n\n // Replace base types with derived types (HAPI behavior)\n return [...diffTypes];\n}\n\n/**\n * Check whether a derived type is compatible with at least one base type.\n *\n * Special allowances (from HAPI):\n * - `Extension`, `Element`, `*` are always compatible\n * - `Resource`/`DomainResource` are compatible with concrete resource types\n * - `uri` is compatible with `string` (historical workaround)\n */\nfunction isTypeCompatible(\n derivedType: ElementDefinitionType,\n baseTypes: readonly ElementDefinitionType[],\n): boolean {\n const dc = derivedType.code;\n\n // Universal wildcards\n if (dc === 'Extension' || dc === 'Element' || dc === '*') return true;\n\n for (const baseType of baseTypes) {\n const bc = baseType.code;\n\n // Exact match\n if (dc === bc) return true;\n\n // Base wildcard\n if (bc === '*' || bc === 'Element') return true;\n\n // Resource compatibility\n if (bc === 'Resource' || bc === 'DomainResource') return true;\n\n // Historical workaround: uri vs string\n if ((dc === 'uri' && bc === 'string') || (dc === 'string' && bc === 'uri')) return true;\n }\n\n return false;\n}\n\n// =============================================================================\n// Section 5: Binding Merging\n// =============================================================================\n\n/**\n * Merge binding constraints with strength validation.\n *\n * Rules:\n * - Cannot relax a REQUIRED binding (REQUIRED \u2192 anything else = error)\n * - Derived binding replaces base binding\n *\n * @returns The merged binding.\n */\nexport function mergeBinding(\n baseBinding: ElementDefinitionBinding | undefined,\n diffBinding: ElementDefinitionBinding | undefined,\n issues: SnapshotIssue[],\n path: string,\n): ElementDefinitionBinding | undefined {\n if (diffBinding === undefined) return baseBinding;\n\n // Validate: cannot relax REQUIRED binding\n if (baseBinding && baseBinding.strength === 'required' && diffBinding.strength !== 'required') {\n issues.push(\n createSnapshotIssue(\n 'error',\n 'BINDING_VIOLATION',\n `Cannot relax REQUIRED binding to '${diffBinding.strength}'`,\n path,\n ),\n );\n }\n\n // Replace base binding with derived binding (HAPI behavior)\n return { ...diffBinding };\n}\n\n// =============================================================================\n// Section 6: Constraint (Invariant) List Merging\n// =============================================================================\n\n/**\n * Merge constraint (invariant) lists by appending derived constraints,\n * de-duplicating by `key`.\n *\n * Base constraints are kept; derived constraints with the same key\n * replace the base version.\n *\n * @returns The merged constraint array.\n */\nexport function mergeConstraintList(\n baseConstraints: readonly ElementDefinitionConstraint[] | undefined,\n diffConstraints: readonly ElementDefinitionConstraint[] | undefined,\n): ElementDefinitionConstraint[] | undefined {\n if (!diffConstraints || diffConstraints.length === 0) {\n return baseConstraints ? [...baseConstraints] : undefined;\n }\n if (!baseConstraints || baseConstraints.length === 0) {\n return [...diffConstraints];\n }\n\n // Start with base constraints\n const result = [...baseConstraints];\n const keySet = new Set(result.map((c) => c.key));\n\n for (const dc of diffConstraints) {\n if (keySet.has(dc.key)) {\n // Replace existing constraint with same key\n const idx = result.findIndex((c) => c.key === dc.key);\n if (idx !== -1) result[idx] = { ...dc };\n } else {\n result.push({ ...dc });\n keySet.add(dc.key);\n }\n }\n\n return result;\n}\n\n// =============================================================================\n// Section 7: Array Union Helpers\n// =============================================================================\n\n/**\n * Merge string arrays (alias) by union.\n */\nfunction mergeStringArray(\n base: readonly string[] | undefined,\n diff: readonly string[] | undefined,\n): string[] | undefined {\n if (!diff || diff.length === 0) return base ? [...base] : undefined;\n if (!base || base.length === 0) return [...diff];\n\n const set = new Set(base);\n const result = [...base];\n for (const item of diff) {\n if (!set.has(item)) {\n result.push(item);\n set.add(item);\n }\n }\n return result;\n}\n\n/**\n * Merge example lists by union (based on label).\n */\nfunction mergeExampleList(\n base: readonly ElementDefinitionExample[] | undefined,\n diff: readonly ElementDefinitionExample[] | undefined,\n): ElementDefinitionExample[] | undefined {\n if (!diff || diff.length === 0) return base ? [...base] : undefined;\n if (!base || base.length === 0) return [...diff];\n\n const result = [...base];\n const labelSet = new Set(result.map((e) => e.label));\n for (const ex of diff) {\n if (!labelSet.has(ex.label)) {\n result.push({ ...ex });\n labelSet.add(ex.label);\n }\n }\n return result;\n}\n\n/**\n * Merge mapping lists by union (based on identity + map).\n */\nfunction mergeMappingList(\n base: readonly ElementDefinitionMapping[] | undefined,\n diff: readonly ElementDefinitionMapping[] | undefined,\n): ElementDefinitionMapping[] | undefined {\n if (!diff || diff.length === 0) return base ? [...base] : undefined;\n if (!base || base.length === 0) return [...diff];\n\n const result = [...base];\n const keySet = new Set(result.map((m) => `${m.identity}|${m.map}`));\n for (const dm of diff) {\n const key = `${dm.identity}|${dm.map}`;\n if (!keySet.has(key)) {\n result.push({ ...dm });\n keySet.add(key);\n }\n }\n return result;\n}\n\n// =============================================================================\n// Section 8: Max Comparison Utility\n// =============================================================================\n\n/**\n * Determine whether max value `a` is larger than max value `b`.\n *\n * FHIR max is either a non-negative integer string or `\"*\"` (unbounded).\n * `\"*\"` is treated as infinity.\n *\n * @example\n * isLargerMax('5', '3') // true\n * isLargerMax('*', '3') // true\n * isLargerMax('3', '*') // false\n * isLargerMax('3', '3') // false\n * isLargerMax('*', '*') // false\n */\nexport function isLargerMax(a: string, b: string): boolean {\n if (a === b) return false;\n if (b === '*') return false; // nothing is larger than unbounded\n if (a === '*') return true; // unbounded is larger than any number\n\n const numA = parseInt(a, 10);\n const numB = parseInt(b, 10);\n\n if (isNaN(numA) || isNaN(numB)) return false;\n return numA > numB;\n}\n", "/**\n * fhir-profile \u2014 Element Merger (Core Merge Loop)\n *\n * Implements the base-driven merge loop for snapshot generation,\n * corresponding to HAPI FHIR R4's `ProfileUtilities.processPaths()`.\n *\n * This is the **core engine** of snapshot generation. It walks the base\n * snapshot element-by-element, finds matching differential entries, and\n * produces the merged snapshot output.\n *\n * Four major branches:\n * - **Branch A**: No diff match \u2192 inherit base as-is (may recurse for inner diffs)\n * - **Branch B**: Single diff match \u2192 merge constraints, recurse into children/datatype\n * - **Branch C**: Type slicing \u2192 multiple diffs constrain different types\n * - **Branch D**: Explicit slicing \u2192 multiple diffs with sliceNames\n *\n * @module fhir-profile\n */\n\nimport type { ElementDefinition } from '../model/index.js';\nimport type { FhirContext } from '../context/types.js';\nimport type { DiffElementTracker, SnapshotIssue, TraversalScope } from './types.js';\nimport { createSnapshotIssue, createDiffTracker } from './types.js';\nimport {\n getChildScope,\n getDiffMatches,\n hasInnerDiffMatches,\n isChoiceTypePath,\n matchesChoiceType,\n extractChoiceTypeName,\n rewritePath,\n} from './path-utils.js';\nimport { mergeConstraints, setBaseTraceability } from './constraint-merger.js';\n\n// =============================================================================\n// Section 1: MergeContext\n// =============================================================================\n\n/**\n * Shared state passed through all recursive `processPaths` calls.\n */\nexport interface MergeContext {\n /** FhirContext for loading datatype definitions (async). `undefined` for sync-only tests. */\n readonly fhirContext?: FhirContext;\n /** Preloaded datatype snapshots cache (url \u2192 snapshot elements). */\n readonly datatypeCache: Map<string, readonly ElementDefinition[]>;\n /** Issue collector. */\n readonly issues: SnapshotIssue[];\n /** URL of the profile being generated. */\n readonly profileUrl: string;\n /** Current recursion depth. */\n depth: number;\n /** Maximum allowed recursion depth. */\n readonly maxDepth: number;\n}\n\n/**\n * Create a default MergeContext.\n */\nexport function createMergeContext(\n profileUrl: string,\n options?: {\n fhirContext?: FhirContext;\n maxDepth?: number;\n },\n): MergeContext {\n return {\n fhirContext: options?.fhirContext,\n datatypeCache: new Map(),\n issues: [],\n profileUrl,\n depth: 0,\n maxDepth: options?.maxDepth ?? 50,\n };\n}\n\n// =============================================================================\n// Section 2: Deep Clone Helper\n// =============================================================================\n\n/**\n * Deep clone an ElementDefinition.\n *\n * Uses structured clone for a true deep copy. Falls back to\n * JSON round-trip if structuredClone is unavailable.\n */\nfunction cloneElement(element: ElementDefinition): ElementDefinition {\n if (typeof structuredClone === 'function') {\n return structuredClone(element);\n }\n return JSON.parse(JSON.stringify(element)) as ElementDefinition;\n}\n\n// =============================================================================\n// Section 3: Core Merge Loop \u2014 processPaths\n// =============================================================================\n\n/**\n * Base-driven merge loop (corresponds to HAPI `processPaths`).\n *\n * Walks the base snapshot within `baseScope`, finds matching differential\n * entries within `[diffStart, diffEnd]`, and appends merged elements to `result`.\n *\n * @param context - Shared merge state.\n * @param result - Mutable output array to append merged elements to.\n * @param baseElements - The base snapshot element list.\n * @param baseCursor - Start index in baseElements (inclusive).\n * @param baseLimit - End index in baseElements (inclusive).\n * @param diffTrackers - The differential element trackers.\n * @param diffStart - Start index in diffTrackers (inclusive).\n * @param diffEnd - End index in diffTrackers (inclusive).\n * @param contextPathSrc - Source path prefix for rewriting (e.g., datatype name).\n * @param contextPathDst - Destination path prefix for rewriting.\n */\nexport function processPaths(\n context: MergeContext,\n result: ElementDefinition[],\n baseElements: readonly ElementDefinition[],\n baseCursor: number,\n baseLimit: number,\n diffTrackers: readonly DiffElementTracker[],\n diffStart: number,\n diffEnd: number,\n contextPathSrc: string,\n contextPathDst: string,\n): void {\n // Recursion depth guard\n if (context.depth > context.maxDepth) {\n context.issues.push(\n createSnapshotIssue(\n 'error',\n 'INTERNAL_ERROR',\n `Maximum recursion depth (${context.maxDepth}) exceeded`,\n contextPathDst,\n ),\n );\n return;\n }\n\n context.depth++;\n\n try {\n let bc = baseCursor;\n\n while (bc <= baseLimit && bc < baseElements.length) {\n const currentBase = baseElements[bc];\n const basePath = currentBase.path;\n if (!basePath) {\n bc++;\n continue;\n }\n\n // Rewrite path from source context to destination context\n const cpath = rewritePath(basePath, contextPathSrc, contextPathDst);\n\n // Find differential matches for this base path\n const diffMatches = getDiffMatchesForPath(\n diffTrackers, cpath, diffStart, diffEnd, contextPathSrc, contextPathDst,\n );\n\n // Determine if base element is already sliced\n const baseSliced = currentBase.slicing !== undefined;\n\n if (!baseSliced) {\n if (diffMatches.length === 0) {\n // ---------------------------------------------------------------\n // Branch A: No diff match \u2014 inherit base as-is\n // ---------------------------------------------------------------\n const outcome = cloneElement(currentBase);\n outcome.path = cpath as typeof outcome.path;\n setBaseTraceability(outcome, currentBase);\n result.push(outcome);\n\n // Check for inner diff matches (children constrained without parent match)\n const childScopeA = getChildScope(baseElements, bc);\n if (hasInnerDiffMatches(diffTrackers, cpath, diffStart, diffEnd)) {\n if (childScopeA) {\n // Base has children \u2014 recurse into them\n processPaths(\n context, result,\n baseElements, childScopeA.start, childScopeA.end,\n diffTrackers, diffStart, diffEnd,\n contextPathSrc, contextPathDst,\n );\n // Skip past children in base (already handled by recursion)\n bc = childScopeA.end + 1;\n continue;\n } else {\n // Base has no children \u2014 need datatype expansion\n expandDatatype(\n context, result, outcome,\n diffTrackers, diffStart, diffEnd,\n cpath,\n );\n bc++;\n continue;\n }\n } else if (childScopeA) {\n // No inner diff but base has children \u2014 copy them as-is\n copyBaseChildren(result, baseElements, childScopeA, contextPathSrc, contextPathDst);\n bc = childScopeA.end + 1;\n continue;\n }\n\n bc++;\n\n } else if (diffMatches.length === 1 && !hasDiffSlicing(diffMatches[0])) {\n // ---------------------------------------------------------------\n // Branch B: Single non-slicing diff match \u2014 most common path\n // ---------------------------------------------------------------\n const diffMatch = diffMatches[0];\n const outcome = cloneElement(currentBase);\n outcome.path = cpath as typeof outcome.path;\n setBaseTraceability(outcome, currentBase);\n mergeConstraints(outcome, diffMatch.element, context.issues);\n\n // Handle choice type narrowing\n if (isChoiceTypePath(basePath) && !isChoiceTypePath(diffMatch.element.path ?? '')) {\n narrowChoiceType(outcome, diffMatch.element.path ?? '', basePath);\n }\n\n // Mark diff as consumed\n diffMatch.consumed = true;\n\n result.push(outcome);\n\n // Recurse into children\n const childScope = getChildScope(baseElements, bc);\n const innerDiffScope = getInnerDiffScope(diffTrackers, cpath, diffStart, diffEnd);\n\n if (childScope && innerDiffScope) {\n // Both base children and inner diff exist\n processPaths(\n context, result,\n baseElements, childScope.start, childScope.end,\n diffTrackers, innerDiffScope.start, innerDiffScope.end,\n contextPathSrc, contextPathDst,\n );\n } else if (!childScope && innerDiffScope) {\n // No base children but diff has children \u2014 datatype expansion\n expandDatatype(\n context, result, outcome,\n diffTrackers, innerDiffScope.start, innerDiffScope.end,\n cpath,\n );\n } else if (childScope && !innerDiffScope) {\n // Base children but no inner diff \u2014 copy base children as-is\n copyBaseChildren(result, baseElements, childScope, contextPathSrc, contextPathDst);\n }\n // else: no children on either side \u2014 nothing to do\n\n // Advance past base element and its children\n if (childScope) {\n bc = childScope.end + 1;\n } else {\n bc = skipChildren(baseElements, bc, basePath);\n }\n\n } else if (diffMatches.length > 1 && diffsConstrainTypes(diffMatches, cpath)) {\n // ---------------------------------------------------------------\n // Branch C: Type slicing\n // ---------------------------------------------------------------\n processTypeSlicing(\n context, result, currentBase,\n diffMatches, baseElements, bc, baseLimit,\n diffTrackers, diffStart, diffEnd,\n contextPathSrc, contextPathDst, cpath,\n );\n {\n const cs = getChildScope(baseElements, bc);\n bc = cs ? cs.end + 1 : bc + 1;\n }\n\n } else {\n // ---------------------------------------------------------------\n // Branch D: Explicit slicing (multiple diffs with sliceNames)\n // ---------------------------------------------------------------\n processExplicitSlicing(\n context, result, currentBase,\n diffMatches, baseElements, bc, baseLimit,\n diffTrackers, diffStart, diffEnd,\n contextPathSrc, contextPathDst, cpath,\n );\n {\n const cs = getChildScope(baseElements, bc);\n bc = cs ? cs.end + 1 : bc + 1;\n }\n }\n } else {\n // =================================================================\n // Base is already sliced \u2014 align slices by sliceName\n // =================================================================\n processBaseSliced(\n context, result, currentBase,\n diffMatches, baseElements, bc, baseLimit,\n diffTrackers, diffStart, diffEnd,\n contextPathSrc, contextPathDst, cpath,\n );\n {\n const cs = getChildScope(baseElements, bc);\n bc = cs ? cs.end + 1 : bc + 1;\n }\n }\n }\n } finally {\n context.depth--;\n }\n}\n\n// =============================================================================\n// Section 4: Diff Matching Helpers\n// =============================================================================\n\n/**\n * Find diff matches for a rewritten path.\n * Delegates to getDiffMatches but handles path rewriting context.\n */\nfunction getDiffMatchesForPath(\n diffTrackers: readonly DiffElementTracker[],\n cpath: string,\n diffStart: number,\n diffEnd: number,\n _contextPathSrc: string,\n _contextPathDst: string,\n): DiffElementTracker[] {\n return getDiffMatches(diffTrackers, cpath, diffStart, diffEnd);\n}\n\n/**\n * Check if a diff tracker introduces slicing.\n */\nfunction hasDiffSlicing(tracker: DiffElementTracker): boolean {\n return tracker.element.slicing !== undefined;\n}\n\n/**\n * Check if multiple diff matches constrain different types (type slicing).\n *\n * Type slicing is detected when:\n * - All diff matches have type constraints\n * - The types differ between matches\n * - OR the diff paths are concrete choice type paths (e.g., valueString, valueQuantity)\n */\nfunction diffsConstrainTypes(\n diffMatches: readonly DiffElementTracker[],\n basePath: string,\n): boolean {\n if (diffMatches.length < 2) return false;\n\n // Check if base is a choice type and diffs use concrete paths\n if (isChoiceTypePath(basePath)) {\n const allConcrete = diffMatches.every((dm) => {\n const dp = dm.element.path ?? '';\n return matchesChoiceType(basePath, dp);\n });\n if (allConcrete) return true;\n }\n\n // Check if diffs have different type constraints\n const typeSets = diffMatches.map((dm) => {\n const types = dm.element.type;\n if (!types || types.length === 0) return '';\n return types.map((t) => t.code).sort().join(',');\n });\n\n const uniqueTypes = new Set(typeSets.filter((t) => t !== ''));\n return uniqueTypes.size > 1;\n}\n\n/**\n * Get the scope of inner diff elements (children of cpath).\n */\nfunction getInnerDiffScope(\n diffTrackers: readonly DiffElementTracker[],\n parentPath: string,\n diffStart: number,\n diffEnd: number,\n): { start: number; end: number } | undefined {\n const prefix = parentPath + '.';\n let start = -1;\n let end = -1;\n\n for (let i = diffStart; i <= diffEnd && i < diffTrackers.length; i++) {\n const dp = diffTrackers[i].element.path ?? '';\n if (dp.startsWith(prefix)) {\n if (start === -1) start = i;\n end = i;\n }\n }\n\n if (start === -1) return undefined;\n return { start, end };\n}\n\n// =============================================================================\n// Section 5: Base Traversal Helpers\n// =============================================================================\n\n/**\n * Skip past all children of the element at `index` and return the next\n * sibling index.\n */\nfunction skipChildren(\n elements: readonly ElementDefinition[],\n index: number,\n parentPath: string,\n): number {\n const prefix = parentPath + '.';\n let i = index + 1;\n while (i < elements.length) {\n const p = elements[i].path ?? '';\n if (!p.startsWith(prefix)) break;\n i++;\n }\n return i;\n}\n\n/**\n * Copy base children as-is into result (with path rewriting).\n */\nfunction copyBaseChildren(\n result: ElementDefinition[],\n baseElements: readonly ElementDefinition[],\n childScope: TraversalScope,\n contextPathSrc: string,\n contextPathDst: string,\n): void {\n for (let i = childScope.start; i <= childScope.end; i++) {\n const child = cloneElement(baseElements[i]);\n if (child.path) {\n child.path = rewritePath(\n child.path, contextPathSrc, contextPathDst,\n ) as typeof child.path;\n }\n setBaseTraceability(child, baseElements[i]);\n result.push(child);\n }\n}\n\n// =============================================================================\n// Section 6: Choice Type Narrowing\n// =============================================================================\n\n/**\n * Narrow a choice type element's types based on the concrete diff path.\n *\n * When base has `value[x]` with multiple types and diff uses `valueString`,\n * narrow outcome.type to only the matching type.\n */\nfunction narrowChoiceType(\n outcome: ElementDefinition,\n diffPath: string,\n basePath: string,\n): void {\n const typeName = extractChoiceTypeName(basePath, diffPath);\n if (!typeName || !outcome.type || outcome.type.length <= 1) return;\n\n const lowerTypeName = typeName.charAt(0).toLowerCase() + typeName.slice(1);\n const matched = outcome.type.filter(\n (t) => t.code === typeName || t.code === lowerTypeName,\n );\n\n if (matched.length > 0) {\n outcome.type = matched;\n }\n}\n\n// =============================================================================\n// Section 7: Datatype Expansion\n// =============================================================================\n\n/**\n * Expand into a complex datatype's snapshot when the base has no children\n * but the diff constrains child elements.\n *\n * Steps:\n * 1. Determine the datatype from outcome.type[0].code\n * 2. Look up the datatype snapshot from cache\n * 3. Recurse processPaths with the datatype snapshot as new base\n * 4. Path rewriting: DatatypeName.x \u2192 parentPath.x\n */\nfunction expandDatatype(\n context: MergeContext,\n result: ElementDefinition[],\n outcome: ElementDefinition,\n diffTrackers: readonly DiffElementTracker[],\n diffStart: number,\n diffEnd: number,\n parentPath: string,\n): void {\n // Determine the datatype\n const types = outcome.type;\n if (!types || types.length === 0) {\n context.issues.push(\n createSnapshotIssue(\n 'error',\n 'INTERNAL_ERROR',\n 'Cannot expand datatype: element has no type',\n parentPath,\n ),\n );\n return;\n }\n\n // Use the first type (or single type) for expansion\n const typeCode = types[0].code as string;\n if (!typeCode) return;\n\n // Look up datatype snapshot from cache\n const dtUrl = `http://hl7.org/fhir/StructureDefinition/${typeCode}`;\n const dtElements = context.datatypeCache.get(dtUrl);\n\n if (!dtElements || dtElements.length === 0) {\n context.issues.push(\n createSnapshotIssue(\n 'warning',\n 'BASE_NOT_FOUND',\n `Datatype '${typeCode}' snapshot not available in cache for expansion`,\n parentPath,\n ),\n );\n return;\n }\n\n // The datatype snapshot's first element is the root (e.g., \"Identifier\")\n // Children start at index 1\n if (dtElements.length < 2) return; // No children to expand\n\n const dtRoot = dtElements[0].path as string;\n\n // Recurse with datatype snapshot as new base, rewriting paths\n processPaths(\n context, result,\n dtElements, 1, dtElements.length - 1,\n diffTrackers, diffStart, diffEnd,\n dtRoot, parentPath,\n );\n}\n\n// =============================================================================\n// Section 8: Type Slicing (Branch C)\n// =============================================================================\n\n/**\n * Process type slicing: multiple diff entries constrain different types\n * of a choice element.\n *\n * Inserts a slicing root element, then processes each type-slice.\n */\nfunction processTypeSlicing(\n context: MergeContext,\n result: ElementDefinition[],\n currentBase: ElementDefinition,\n diffMatches: DiffElementTracker[],\n baseElements: readonly ElementDefinition[],\n baseCursor: number,\n _baseLimit: number,\n diffTrackers: readonly DiffElementTracker[],\n diffStart: number,\n diffEnd: number,\n contextPathSrc: string,\n contextPathDst: string,\n cpath: string,\n): void {\n // Insert the slicing root (unsliced element with slicing info)\n const slicingRoot = cloneElement(currentBase);\n slicingRoot.path = cpath as typeof slicingRoot.path;\n setBaseTraceability(slicingRoot, currentBase);\n\n // Add synthetic slicing if not already present\n if (!slicingRoot.slicing) {\n slicingRoot.slicing = {\n discriminator: [{ type: 'type' as any, path: '$this' as any }],\n rules: 'open' as any,\n ordered: false as any,\n };\n }\n result.push(slicingRoot);\n\n // Process each type-slice\n for (const dm of diffMatches) {\n const outcome = cloneElement(currentBase);\n outcome.path = cpath as typeof outcome.path;\n setBaseTraceability(outcome, currentBase);\n mergeConstraints(outcome, dm.element, context.issues);\n\n // Narrow type for choice types\n if (isChoiceTypePath(currentBase.path ?? '') && dm.element.path) {\n narrowChoiceType(outcome, dm.element.path, currentBase.path ?? '');\n }\n\n // Set sliceName from type if not already set\n if (!outcome.sliceName && dm.element.type && dm.element.type.length > 0) {\n outcome.sliceName = dm.element.type[0].code as unknown as typeof outcome.sliceName;\n }\n\n dm.consumed = true;\n result.push(outcome);\n\n // Recurse into children if needed\n const childScope = getChildScope(baseElements, baseCursor);\n const innerDiffScope = getInnerDiffScope(diffTrackers, dm.element.path ?? cpath, diffStart, diffEnd);\n\n if (innerDiffScope) {\n if (childScope) {\n processPaths(\n context, result,\n baseElements, childScope.start, childScope.end,\n diffTrackers, innerDiffScope.start, innerDiffScope.end,\n contextPathSrc, contextPathDst,\n );\n } else {\n expandDatatype(\n context, result, outcome,\n diffTrackers, innerDiffScope.start, innerDiffScope.end,\n dm.element.path ?? cpath,\n );\n }\n }\n }\n}\n\n// =============================================================================\n// Section 9: Explicit Slicing (Branch D)\n// =============================================================================\n\n/**\n * Process explicit slicing: multiple diff entries with sliceNames.\n *\n * Inserts a slicing root, then processes each slice against the same\n * base subtree.\n */\nfunction processExplicitSlicing(\n context: MergeContext,\n result: ElementDefinition[],\n currentBase: ElementDefinition,\n diffMatches: DiffElementTracker[],\n baseElements: readonly ElementDefinition[],\n baseCursor: number,\n _baseLimit: number,\n diffTrackers: readonly DiffElementTracker[],\n diffStart: number,\n diffEnd: number,\n contextPathSrc: string,\n contextPathDst: string,\n cpath: string,\n): void {\n // First diff match may be the slicing definition itself\n let slicingDef: DiffElementTracker | undefined;\n const slices: DiffElementTracker[] = [];\n\n for (const dm of diffMatches) {\n if (dm.element.slicing && !dm.element.sliceName) {\n slicingDef = dm;\n } else {\n slices.push(dm);\n }\n }\n\n // Insert slicing root\n const slicingRoot = cloneElement(currentBase);\n slicingRoot.path = cpath as typeof slicingRoot.path;\n setBaseTraceability(slicingRoot, currentBase);\n\n if (slicingDef) {\n mergeConstraints(slicingRoot, slicingDef.element, context.issues);\n slicingDef.consumed = true;\n }\n\n result.push(slicingRoot);\n\n // Process each slice\n for (const slice of slices) {\n const outcome = cloneElement(currentBase);\n outcome.path = cpath as typeof outcome.path;\n setBaseTraceability(outcome, currentBase);\n mergeConstraints(outcome, slice.element, context.issues);\n slice.consumed = true;\n result.push(outcome);\n\n // Recurse into children for this slice\n const childScope = getChildScope(baseElements, baseCursor);\n const slicePath = slice.element.id ?? slice.element.path ?? cpath;\n const innerDiffScope = getInnerDiffScope(diffTrackers, slicePath, diffStart, diffEnd);\n\n if (childScope && innerDiffScope) {\n processPaths(\n context, result,\n baseElements, childScope.start, childScope.end,\n diffTrackers, innerDiffScope.start, innerDiffScope.end,\n contextPathSrc, contextPathDst,\n );\n } else if (!childScope && innerDiffScope) {\n expandDatatype(\n context, result, outcome,\n diffTrackers, innerDiffScope.start, innerDiffScope.end,\n cpath,\n );\n }\n }\n}\n\n// =============================================================================\n// Section 10: Base Already Sliced\n// =============================================================================\n\n/**\n * Handle the case where the base element is already sliced.\n *\n * Aligns diff slices with base slices by sliceName:\n * - Matching slices: merge constraints\n * - Non-matching base slices: copy as-is\n * - New diff slices: append at end (if slicing is not CLOSED)\n */\nfunction processBaseSliced(\n context: MergeContext,\n result: ElementDefinition[],\n currentBase: ElementDefinition,\n diffMatches: DiffElementTracker[],\n baseElements: readonly ElementDefinition[],\n baseCursor: number,\n baseLimit: number,\n _diffTrackers: readonly DiffElementTracker[],\n _diffStart: number,\n _diffEnd: number,\n contextPathSrc: string,\n contextPathDst: string,\n cpath: string,\n): void {\n // Copy the slicing root\n const slicingRoot = cloneElement(currentBase);\n slicingRoot.path = cpath as typeof slicingRoot.path;\n setBaseTraceability(slicingRoot, currentBase);\n\n // Merge slicing definition from diff if present\n const slicingDiff = diffMatches.find((dm) => dm.element.slicing && !dm.element.sliceName);\n if (slicingDiff) {\n mergeConstraints(slicingRoot, slicingDiff.element, context.issues);\n slicingDiff.consumed = true;\n }\n\n result.push(slicingRoot);\n\n // Collect base slices (siblings with same path after the slicing root)\n const basePath = currentBase.path ?? '';\n const baseSlices: { index: number; sliceName: string | undefined }[] = [];\n for (let i = baseCursor + 1; i <= baseLimit && i < baseElements.length; i++) {\n const ep = baseElements[i].path ?? '';\n if (ep === basePath && baseElements[i].sliceName) {\n baseSlices.push({ index: i, sliceName: baseElements[i].sliceName as string | undefined });\n } else if (!ep.startsWith(basePath + '.') && ep !== basePath) {\n break;\n }\n }\n\n // Build diff slice map by sliceName\n const diffSliceMap = new Map<string, DiffElementTracker>();\n const unmatchedDiffSlices: DiffElementTracker[] = [];\n for (const dm of diffMatches) {\n if (dm === slicingDiff) continue;\n const sn = dm.element.sliceName as string | undefined;\n if (sn) {\n diffSliceMap.set(sn, dm);\n } else {\n unmatchedDiffSlices.push(dm);\n }\n }\n\n // Align: process base slices in order\n for (const bs of baseSlices) {\n const baseSliceElement = baseElements[bs.index];\n const outcome = cloneElement(baseSliceElement);\n outcome.path = cpath as typeof outcome.path;\n setBaseTraceability(outcome, baseSliceElement);\n\n const matchingDiff = bs.sliceName ? diffSliceMap.get(bs.sliceName) : undefined;\n if (matchingDiff) {\n mergeConstraints(outcome, matchingDiff.element, context.issues);\n matchingDiff.consumed = true;\n diffSliceMap.delete(bs.sliceName!);\n }\n\n result.push(outcome);\n\n // Copy children of this base slice\n const sliceChildScope = getChildScope(baseElements, bs.index);\n if (sliceChildScope) {\n copyBaseChildren(result, baseElements, sliceChildScope, contextPathSrc, contextPathDst);\n }\n }\n\n // Append new diff slices (not matching any base slice)\n const isClosed = currentBase.slicing?.rules === 'closed';\n for (const [sliceName, dm] of diffSliceMap) {\n if (isClosed) {\n context.issues.push(\n createSnapshotIssue(\n 'error',\n 'SLICING_ERROR',\n `Cannot add new slice '${sliceName}' to closed slicing`,\n cpath,\n ),\n );\n }\n const outcome = cloneElement(currentBase);\n outcome.path = cpath as typeof outcome.path;\n setBaseTraceability(outcome, currentBase);\n mergeConstraints(outcome, dm.element, context.issues);\n dm.consumed = true;\n result.push(outcome);\n }\n\n // Handle unmatched diff entries\n for (const dm of unmatchedDiffSlices) {\n if (!dm.consumed) {\n dm.consumed = true;\n }\n }\n}\n\n// =============================================================================\n// Section 11: Public Convenience \u2014 mergeSnapshot\n// =============================================================================\n\n/**\n * High-level convenience function: merge a base snapshot with a differential\n * to produce a new snapshot element list.\n *\n * This is the primary entry point for testing and for the SnapshotGenerator\n * orchestrator (Task 4.5).\n *\n * @param baseElements - The base profile's snapshot elements.\n * @param diffElements - The differential elements to apply.\n * @param context - Merge context (or auto-created if not provided).\n * @returns The merged snapshot element list.\n */\nexport function mergeSnapshot(\n baseElements: readonly ElementDefinition[],\n diffElements: readonly ElementDefinition[],\n context?: MergeContext,\n): { elements: ElementDefinition[]; issues: SnapshotIssue[] } {\n const ctx = context ?? createMergeContext('');\n\n // Wrap diff elements in trackers\n const diffTrackers = diffElements.map(createDiffTracker);\n\n // Determine root path from base\n const rootPath = baseElements.length > 0 ? (baseElements[0].path as string) ?? '' : '';\n\n // Run the merge loop\n const result: ElementDefinition[] = [];\n processPaths(\n ctx, result,\n baseElements, 0, baseElements.length - 1,\n diffTrackers, 0, diffTrackers.length - 1,\n rootPath, rootPath,\n );\n\n // Check for unconsumed differential elements\n for (const tracker of diffTrackers) {\n if (!tracker.consumed) {\n ctx.issues.push(\n createSnapshotIssue(\n 'warning',\n 'DIFFERENTIAL_NOT_CONSUMED',\n `Differential element '${tracker.element.path ?? tracker.element.id ?? '<unknown>'}' was not consumed`,\n tracker.element.path as string | undefined,\n ),\n );\n }\n }\n\n return { elements: result, issues: ctx.issues };\n}\n", "/**\n * fhir-profile \u2014 Error Types\n *\n * Structured error hierarchy for the FHIR profile module.\n * All errors extend {@link ProfileError} so consumers can catch\n * profile-related failures with a single `catch` clause.\n *\n * Error hierarchy:\n * ```\n * ProfileError (base)\n * \u251C\u2500\u2500 SnapshotCircularDependencyError\n * \u251C\u2500\u2500 BaseNotFoundError\n * \u251C\u2500\u2500 ConstraintViolationError\n * \u2514\u2500\u2500 UnconsumedDifferentialError\n * ```\n *\n * @module fhir-profile\n */\n\n// =============================================================================\n// Section 1: Base Error\n// =============================================================================\n\n/**\n * Base error class for all fhir-profile failures.\n *\n * Provides a stable `name` property and preserves the original `cause`\n * when wrapping lower-level errors.\n *\n * @example\n * ```typescript\n * try {\n * await generator.generate(sd);\n * } catch (err) {\n * if (err instanceof ProfileError) {\n * // Handle any profile-related error\n * }\n * }\n * ```\n */\nexport class ProfileError extends Error {\n override readonly name: string = 'ProfileError';\n\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n // Restore prototype chain (required for `instanceof` after transpilation)\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n// =============================================================================\n// Section 2: SnapshotCircularDependencyError\n// =============================================================================\n\n/**\n * Thrown when snapshot generation detects a circular dependency in the\n * profile chain.\n *\n * This occurs when profile A's base chain eventually references A again,\n * which would cause infinite recursion during snapshot generation.\n * HAPI detects this via a `snapshotStack` of URLs currently being generated.\n *\n * @example\n * ```typescript\n * throw new SnapshotCircularDependencyError(\n * 'http://example.org/ProfileA',\n * [\n * 'http://example.org/ProfileA',\n * 'http://example.org/ProfileB',\n * 'http://example.org/ProfileA', // cycle back\n * ]\n * );\n * ```\n */\nexport class SnapshotCircularDependencyError extends ProfileError {\n override readonly name = 'SnapshotCircularDependencyError';\n\n /** The canonical URL of the profile that triggered the cycle. */\n readonly url: string;\n\n /** The full chain of URLs forming the cycle. */\n readonly chain: readonly string[];\n\n constructor(url: string, chain: string[]) {\n const display = chain.join(' \u2192 ');\n super(`Circular snapshot dependency detected for ${url}: ${display}`);\n this.url = url;\n this.chain = chain;\n }\n}\n\n// =============================================================================\n// Section 3: BaseNotFoundError\n// =============================================================================\n\n/**\n * Thrown when the base StructureDefinition required for snapshot generation\n * cannot be loaded from any source.\n *\n * This is a fatal error \u2014 snapshot generation cannot proceed without the\n * base profile's snapshot to merge against.\n *\n * @example\n * ```typescript\n * throw new BaseNotFoundError(\n * 'http://hl7.org/fhir/StructureDefinition/Patient',\n * 'http://hl7.org/fhir/StructureDefinition/UnknownBase'\n * );\n * ```\n */\nexport class BaseNotFoundError extends ProfileError {\n override readonly name = 'BaseNotFoundError';\n\n /** The canonical URL of the derived profile being generated. */\n readonly derivedUrl: string;\n\n /** The canonical URL of the base that could not be found. */\n readonly baseUrl: string;\n\n constructor(derivedUrl: string, baseUrl: string, cause?: Error) {\n super(\n `Base StructureDefinition not found for ${derivedUrl}: ${baseUrl}`,\n cause ? { cause } : undefined,\n );\n this.derivedUrl = derivedUrl;\n this.baseUrl = baseUrl;\n }\n}\n\n// =============================================================================\n// Section 4: ConstraintViolationError\n// =============================================================================\n\n/**\n * Thrown when constraint merging detects an illegal tightening or\n * incompatible constraint.\n *\n * This covers violations such as:\n * - Cardinality loosening (`derived.min < base.min`)\n * - Cardinality widening (`derived.max > base.max`)\n * - Type expansion (derived types not a subset of base types)\n * - Binding relaxation (relaxing a REQUIRED binding)\n *\n * Only thrown when {@link SnapshotGeneratorOptions.throwOnError} is `true`.\n * Otherwise, violations are recorded as issues in the result.\n *\n * @example\n * ```typescript\n * throw new ConstraintViolationError(\n * 'CARDINALITY_VIOLATION',\n * 'Patient.identifier',\n * 'Derived min (0) is less than base min (1)'\n * );\n * ```\n */\nexport class ConstraintViolationError extends ProfileError {\n override readonly name = 'ConstraintViolationError';\n\n /** The type of constraint violation. */\n readonly violationType: string;\n\n /** The element path where the violation occurred. */\n readonly path: string;\n\n constructor(violationType: string, path: string, message: string) {\n super(`Constraint violation at ${path}: ${message}`);\n this.violationType = violationType;\n this.path = path;\n }\n}\n\n// =============================================================================\n// Section 5: UnconsumedDifferentialError\n// =============================================================================\n\n/**\n * Thrown when differential elements remain unconsumed after snapshot\n * generation completes.\n *\n * This indicates that the algorithm could not find a matching base\n * element for one or more differential entries. Common causes:\n * - Incorrect path in differential\n * - Slicing mismatch\n * - Unsupported constraint pattern\n *\n * HAPI detects this via the `GENERATED_IN_SNAPSHOT` marker pattern.\n *\n * Only thrown when {@link SnapshotGeneratorOptions.throwOnError} is `true`.\n * Otherwise, each unconsumed element is recorded as an issue.\n *\n * @example\n * ```typescript\n * throw new UnconsumedDifferentialError([\n * 'Patient.nonExistentField',\n * 'Patient.identifier:BadSlice',\n * ]);\n * ```\n */\nexport class UnconsumedDifferentialError extends ProfileError {\n override readonly name = 'UnconsumedDifferentialError';\n\n /** Paths of the unconsumed differential elements. */\n readonly unconsumedPaths: readonly string[];\n\n constructor(unconsumedPaths: string[]) {\n const count = unconsumedPaths.length;\n const pathList = unconsumedPaths.slice(0, 5).join(', ');\n const suffix = count > 5 ? `, ... (${count} total)` : '';\n super(\n `${count} differential element(s) not consumed during snapshot generation: ${pathList}${suffix}`,\n );\n this.unconsumedPaths = unconsumedPaths;\n }\n}\n", "/**\n * fhir-profile \u2014 Snapshot Generator (Orchestrator)\n *\n * Implements the top-level snapshot generation workflow, corresponding to\n * HAPI FHIR R4's `ProfileUtilities.generateSnapshot()`.\n *\n * This is the **orchestrator** that coordinates:\n * 1. Input validation\n * 2. Circular dependency detection (generation stack)\n * 3. Base SD loading (recursive snapshot generation if needed)\n * 4. Datatype cache population\n * 5. Merge loop delegation to {@link processPaths}\n * 6. Post-processing (unconsumed diff, element IDs)\n * 7. Result caching\n *\n * @module fhir-profile\n */\n\nimport type { ElementDefinition, StructureDefinition } from '../model/index.js';\nimport type { FhirContext } from '../context/types.js';\nimport type { SnapshotGeneratorOptions, SnapshotResult, SnapshotIssue } from './types.js';\nimport { createSnapshotIssue, createDiffTracker } from './types.js';\nimport type { MergeContext } from './element-merger.js';\nimport { createMergeContext, processPaths } from './element-merger.js';\nimport {\n SnapshotCircularDependencyError,\n BaseNotFoundError,\n UnconsumedDifferentialError,\n} from './errors.js';\n\n// =============================================================================\n// Section 1: SnapshotGenerator Class\n// =============================================================================\n\n/**\n * Snapshot Generator \u2014 top-level orchestrator for snapshot generation.\n *\n * Corresponds to HAPI's `ProfileUtilities.generateSnapshot()`.\n *\n * @example\n * ```typescript\n * const generator = new SnapshotGenerator(fhirContext, { throwOnError: false });\n * const result = await generator.generate(myProfile);\n * if (result.success) {\n * console.log('Snapshot generated with', result.structureDefinition.snapshot?.element.length, 'elements');\n * }\n * ```\n */\nexport class SnapshotGenerator {\n private readonly context: FhirContext;\n private readonly options: SnapshotGeneratorOptions;\n\n /** URLs currently being generated \u2014 for circular dependency detection. */\n private readonly generationStack: Set<string> = new Set();\n\n constructor(context: FhirContext, options: SnapshotGeneratorOptions = {}) {\n this.context = context;\n this.options = options;\n }\n\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n\n /**\n * Generate a snapshot for a StructureDefinition.\n *\n * @param sd - StructureDefinition with a differential to expand.\n * @returns SnapshotResult with the populated snapshot and any issues.\n * @throws {SnapshotCircularDependencyError} if circular reference detected\n * @throws {BaseNotFoundError} if base SD cannot be loaded\n * @throws {UnconsumedDifferentialError} if throwOnError and unconsumed diffs\n */\n async generate(sd: StructureDefinition): Promise<SnapshotResult> {\n const issues: SnapshotIssue[] = [];\n const url = sd.url as string;\n\n // ----- Step 1: Input validation -----\n const validationError = this.validateInput(sd, issues);\n if (validationError) {\n return this.buildResult(sd, issues);\n }\n\n // ----- Step 2: Circular dependency detection -----\n if (this.generationStack.has(url)) {\n const chain = [...this.generationStack, url];\n throw new SnapshotCircularDependencyError(url, chain);\n }\n this.generationStack.add(url);\n\n try {\n // ----- Step 2b: Handle root types (no baseDefinition) -----\n if (!sd.baseDefinition) {\n // Root types (Element, Resource) \u2014 use differential as snapshot\n const diffElements = sd.differential?.element ?? [];\n if (diffElements.length > 0) {\n const cloned = deepCloneElements(diffElements);\n ensureElementIds(cloned);\n sd.snapshot = { element: cloned } as typeof sd.snapshot;\n } else {\n sd.snapshot = { element: [] } as typeof sd.snapshot;\n }\n return this.buildResult(sd, issues);\n }\n\n // ----- Step 3: Load base StructureDefinition -----\n const baseUrl = sd.baseDefinition as string;\n const baseSd = await this.loadBase(sd, baseUrl, issues);\n if (!baseSd) {\n return this.buildResult(sd, issues);\n }\n\n // Recursively ensure base has a snapshot\n if (!baseSd.snapshot?.element?.length) {\n const baseResult = await this.generate(baseSd);\n if (!baseResult.success) {\n issues.push(\n createSnapshotIssue(\n 'error',\n 'BASE_MISSING_SNAPSHOT',\n `Failed to generate snapshot for base '${baseUrl}'`,\n url,\n ),\n );\n return this.buildResult(sd, issues);\n }\n }\n\n const baseElements = baseSd.snapshot!.element;\n\n // ----- Step 4: Prepare differential -----\n const diffElements = sd.differential?.element ?? [];\n if (diffElements.length === 0) {\n // No differential \u2014 just clone the base snapshot\n sd.snapshot = {\n element: deepCloneElements(baseElements),\n } as typeof sd.snapshot;\n return this.buildResult(sd, issues);\n }\n\n // ----- Step 5: Populate datatype cache -----\n const mergeCtx = createMergeContext(url, {\n fhirContext: this.context,\n maxDepth: this.options.maxRecursionDepth ?? 50,\n });\n await this.populateDatatypeCache(mergeCtx, baseElements, diffElements);\n\n // ----- Step 6: Run merge loop -----\n const diffTrackers = diffElements.map(createDiffTracker);\n const rootPath = baseElements.length > 0\n ? (baseElements[0].path as string) ?? ''\n : '';\n\n const result: ElementDefinition[] = [];\n processPaths(\n mergeCtx,\n result,\n baseElements, 0, baseElements.length - 1,\n diffTrackers, 0, diffTrackers.length - 1,\n rootPath, rootPath,\n );\n\n // Collect merge issues\n issues.push(...mergeCtx.issues);\n\n // ----- Step 7: Post-processing -----\n\n // 7a: Check for unconsumed differential elements\n const unconsumedPaths: string[] = [];\n for (const tracker of diffTrackers) {\n if (!tracker.consumed) {\n const path = (tracker.element.path as string)\n ?? (tracker.element.id as string)\n ?? '<unknown>';\n unconsumedPaths.push(path);\n issues.push(\n createSnapshotIssue(\n 'warning',\n 'DIFFERENTIAL_NOT_CONSUMED',\n `Differential element '${path}' was not consumed`,\n path,\n ),\n );\n }\n }\n\n if (unconsumedPaths.length > 0 && this.options.throwOnError) {\n throw new UnconsumedDifferentialError(unconsumedPaths);\n }\n\n // 7b: Ensure element IDs\n ensureElementIds(result);\n\n // ----- Step 8: Assemble result -----\n sd.snapshot = {\n element: result,\n } as typeof sd.snapshot;\n\n // Cache the updated SD back into context\n try {\n this.context.registerStructureDefinition(sd);\n } catch {\n // Non-fatal: caching failure shouldn't break generation\n }\n\n return this.buildResult(sd, issues);\n\n } catch (err) {\n // On error, clear snapshot and re-throw\n sd.snapshot = undefined;\n throw err;\n } finally {\n this.generationStack.delete(url);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private Helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Validate input StructureDefinition.\n * Returns true if there's a fatal validation error.\n */\n private validateInput(sd: StructureDefinition, issues: SnapshotIssue[]): boolean {\n if (!sd) {\n issues.push(\n createSnapshotIssue('error', 'INTERNAL_ERROR', 'StructureDefinition is null or undefined'),\n );\n return true;\n }\n\n if (!sd.url) {\n issues.push(\n createSnapshotIssue('error', 'INTERNAL_ERROR', 'StructureDefinition.url is required'),\n );\n return true;\n }\n\n // Root types (Element, Resource) don't need baseDefinition\n const isRootType = isRootStructureDefinition(sd);\n if (!sd.baseDefinition && !isRootType) {\n issues.push(\n createSnapshotIssue(\n 'error',\n 'BASE_NOT_FOUND',\n `StructureDefinition '${sd.url}' has no baseDefinition and is not a root type`,\n sd.url as string,\n ),\n );\n return true;\n }\n\n return false;\n }\n\n /**\n * Load the base StructureDefinition.\n */\n private async loadBase(\n sd: StructureDefinition,\n baseUrl: string,\n issues: SnapshotIssue[],\n ): Promise<StructureDefinition | undefined> {\n try {\n return await this.context.loadStructureDefinition(baseUrl);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n issues.push(\n createSnapshotIssue(\n 'error',\n 'BASE_NOT_FOUND',\n `Cannot load base '${baseUrl}' for '${sd.url}': ${msg}`,\n sd.url as string,\n ),\n );\n\n if (this.options.throwOnError) {\n throw new BaseNotFoundError(sd.url as string, baseUrl, err instanceof Error ? err : undefined);\n }\n\n return undefined;\n }\n }\n\n /**\n * Populate the datatype cache with snapshots of types referenced by\n * the differential's child paths.\n *\n * Scans both base elements and diff elements for type codes, then\n * pre-loads their StructureDefinitions into the merge context cache.\n */\n private async populateDatatypeCache(\n mergeCtx: MergeContext,\n baseElements: readonly ElementDefinition[],\n diffElements: readonly ElementDefinition[],\n ): Promise<void> {\n // Collect unique type codes from base elements that have diff children\n const typeCodes = new Set<string>();\n\n for (const base of baseElements) {\n if (base.type) {\n for (const t of base.type) {\n const code = t.code as string;\n if (code && isComplexType(code)) {\n typeCodes.add(code);\n }\n }\n }\n }\n\n // Also check diff elements for type codes\n for (const diff of diffElements) {\n if (diff.type) {\n for (const t of diff.type) {\n const code = t.code as string;\n if (code && isComplexType(code)) {\n typeCodes.add(code);\n }\n }\n }\n }\n\n // Load each datatype's snapshot into cache\n for (const code of typeCodes) {\n const dtUrl = `http://hl7.org/fhir/StructureDefinition/${code}`;\n if (mergeCtx.datatypeCache.has(dtUrl)) continue;\n\n try {\n const dtSd = await this.context.loadStructureDefinition(dtUrl);\n if (dtSd?.snapshot?.element) {\n mergeCtx.datatypeCache.set(dtUrl, dtSd.snapshot.element);\n }\n } catch {\n // Non-fatal: datatype not available, expansion will report issue\n }\n }\n }\n\n /**\n * Build a SnapshotResult from the current state.\n */\n private buildResult(sd: StructureDefinition, issues: SnapshotIssue[]): SnapshotResult {\n const hasErrors = issues.some((i) => i.severity === 'error');\n return {\n structureDefinition: sd,\n issues,\n success: !hasErrors,\n };\n }\n}\n\n// =============================================================================\n// Section 2: Helper Functions\n// =============================================================================\n\n/**\n * Check if a StructureDefinition is a root type (Element or Resource)\n * that doesn't require a baseDefinition.\n */\nfunction isRootStructureDefinition(sd: StructureDefinition): boolean {\n const type = sd.type as string;\n return type === 'Element' || type === 'Resource';\n}\n\n/**\n * Check if a type code represents a complex type that can be expanded.\n * Excludes primitive types and special types.\n */\nfunction isComplexType(code: string): boolean {\n // Primitive types start with lowercase\n if (code.charAt(0) === code.charAt(0).toLowerCase() && code !== 'xhtml') {\n return false;\n }\n // Special types that shouldn't be expanded\n const skipTypes = new Set([\n 'Resource', 'DomainResource', 'Element', 'BackboneElement',\n 'Extension', 'Narrative',\n ]);\n return !skipTypes.has(code);\n}\n\n/**\n * Deep clone an array of ElementDefinitions.\n */\nfunction deepCloneElements(elements: readonly ElementDefinition[]): ElementDefinition[] {\n if (typeof structuredClone === 'function') {\n return structuredClone(elements as ElementDefinition[]);\n }\n return JSON.parse(JSON.stringify(elements)) as ElementDefinition[];\n}\n\n/**\n * Ensure all elements have an `id` property.\n *\n * If an element lacks an `id`, generates one from its path and sliceName.\n * This follows the FHIR convention: `path` for unsliced elements,\n * `path:sliceName` for sliced elements.\n */\nfunction ensureElementIds(elements: ElementDefinition[]): void {\n for (const el of elements) {\n if (!el.id && el.path) {\n const path = el.path as string;\n const sliceName = el.sliceName as string | undefined;\n el.id = (sliceName ? `${path}:${sliceName}` : path) as typeof el.id;\n }\n }\n}\n", "/**\n * fhir-profile \u2014 Element Sorter\n *\n * Sorting and ordering utilities for snapshot generation.\n * Corresponds to HAPI FHIR R4's `sortDifferential()` + `sortElements()`.\n *\n * Key concepts:\n * - The authoritative order is the **base snapshot element order**, not alphabetical\n * - Differential elements may need pre-sorting before merge\n * - Sorting builds a tree, sorts each level by base index, then flattens\n *\n * Exported functions:\n * - {@link sortDifferential} \u2014 sort diff elements by base snapshot order\n * - {@link findBaseIndex} \u2014 locate a path in the base snapshot\n * - {@link validateElementOrder} \u2014 verify snapshot ordering post-generation\n * - {@link ensureElementIds} \u2014 generate element IDs from path + sliceName\n *\n * @module fhir-profile\n */\n\nimport type { ElementDefinition } from '../model/index.js';\nimport type { SnapshotIssue } from './types.js';\nimport { createSnapshotIssue } from './types.js';\nimport {\n isChoiceTypePath,\n matchesChoiceType,\n parentPath,\n} from './path-utils.js';\n\n// =============================================================================\n// Section 1: Tree Node for Sorting\n// =============================================================================\n\n/**\n * Internal tree node used during differential sorting.\n * Each node represents an element and its children in the hierarchy.\n */\ninterface SortNode {\n /** The element this node represents. */\n element: ElementDefinition;\n /** Index in the base snapshot (-1 if not found). */\n baseIndex: number;\n /** Child nodes (direct children in the element tree). */\n children: SortNode[];\n}\n\n// =============================================================================\n// Section 2: findBaseIndex\n// =============================================================================\n\n/**\n * Find the index of a path in the base snapshot.\n *\n * Handles:\n * - Exact path match\n * - Choice type match (e.g., `valueString` matches `value[x]`)\n * - Slice paths (strips `:sliceName` from id to match by path)\n *\n * @param baseSnapshot - The base snapshot element list.\n * @param path - The path to find.\n * @param sliceName - Optional slice name for disambiguation.\n * @returns The index in baseSnapshot, or -1 if not found.\n */\nexport function findBaseIndex(\n baseSnapshot: readonly ElementDefinition[],\n path: string,\n sliceName?: string,\n): number {\n // 1. Exact path match (prefer sliceName match if provided)\n if (sliceName) {\n for (let i = 0; i < baseSnapshot.length; i++) {\n const el = baseSnapshot[i];\n if ((el.path as string) === path && (el.sliceName as string) === sliceName) {\n return i;\n }\n }\n }\n\n // 2. Exact path match (no sliceName or fallback)\n for (let i = 0; i < baseSnapshot.length; i++) {\n if ((baseSnapshot[i].path as string) === path) {\n return i;\n }\n }\n\n // 3. Choice type match: path like \"Observation.valueString\" \u2192 base \"Observation.value[x]\"\n for (let i = 0; i < baseSnapshot.length; i++) {\n const basePath = baseSnapshot[i].path as string;\n if (isChoiceTypePath(basePath) && matchesChoiceType(basePath, path)) {\n return i;\n }\n }\n\n return -1;\n}\n\n// =============================================================================\n// Section 3: sortDifferential\n// =============================================================================\n\n/**\n * Sort differential elements according to base snapshot order.\n *\n * Corresponds to HAPI's `sortDifferential()`. The algorithm:\n * 1. Build a tree from the differential elements (parent-child by path)\n * 2. Assign each node a base index via {@link findBaseIndex}\n * 3. Sort children at each level by base index\n * 4. Flatten the tree back to a linear list\n *\n * Elements not found in the base are placed at the end of their level\n * and an issue is recorded.\n *\n * @param differential - The differential elements to sort (not mutated).\n * @param baseSnapshot - The base snapshot providing the authoritative order.\n * @param issues - Issue collector for recording problems.\n * @returns A new array of elements in sorted order.\n */\nexport function sortDifferential(\n differential: readonly ElementDefinition[],\n baseSnapshot: readonly ElementDefinition[],\n issues: SnapshotIssue[],\n): ElementDefinition[] {\n if (differential.length <= 1) {\n return [...differential];\n }\n\n // Build tree\n const root: SortNode = {\n element: differential[0],\n baseIndex: findBaseIndex(baseSnapshot, differential[0].path as string),\n children: [],\n };\n\n // Map from path to node for parent lookup\n const nodeMap = new Map<string, SortNode>();\n const rootPath = differential[0].path as string;\n nodeMap.set(rootPath, root);\n\n for (let i = 1; i < differential.length; i++) {\n const el = differential[i];\n const elPath = el.path as string;\n const elSliceName = el.sliceName as string | undefined;\n\n const node: SortNode = {\n element: el,\n baseIndex: findBaseIndex(baseSnapshot, elPath, elSliceName),\n children: [],\n };\n\n // Find parent: walk up the path hierarchy\n let parent: SortNode | undefined;\n const pp = parentPath(elPath);\n if (pp) {\n parent = nodeMap.get(pp);\n }\n\n // If no parent found, check if this is a slice sibling (same path as existing node)\n if (!parent) {\n // Slice siblings attach to the same parent as the first element with this path\n const existingNode = nodeMap.get(elPath);\n if (existingNode) {\n // Find the parent of the existing node\n for (const [, n] of nodeMap) {\n if (n.children.includes(existingNode)) {\n parent = n;\n break;\n }\n }\n }\n }\n\n // Fallback: attach to root\n if (!parent) {\n parent = root;\n }\n\n parent.children.push(node);\n\n // Register in nodeMap (first occurrence of this path wins)\n const nodeKey = elSliceName ? `${elPath}:${elSliceName}` : elPath;\n if (!nodeMap.has(nodeKey)) {\n nodeMap.set(nodeKey, node);\n }\n // Also register by plain path if not already present\n if (!nodeMap.has(elPath)) {\n nodeMap.set(elPath, node);\n }\n }\n\n // Sort children at each level by baseIndex\n sortNodeChildren(root);\n\n // Check for elements not found in base\n checkUnfoundElements(root, issues);\n\n // Flatten tree back to linear list\n const result: ElementDefinition[] = [];\n flattenTree(root, result);\n\n return result;\n}\n\n/**\n * Recursively sort children of a node by baseIndex.\n */\nfunction sortNodeChildren(node: SortNode): void {\n if (node.children.length > 1) {\n node.children.sort((a, b) => {\n // Elements not found in base go to end\n const ai = a.baseIndex === -1 ? Number.MAX_SAFE_INTEGER : a.baseIndex;\n const bi = b.baseIndex === -1 ? Number.MAX_SAFE_INTEGER : b.baseIndex;\n return ai - bi;\n });\n }\n for (const child of node.children) {\n sortNodeChildren(child);\n }\n}\n\n/**\n * Check for elements with baseIndex === -1 and record issues.\n */\nfunction checkUnfoundElements(node: SortNode, issues: SnapshotIssue[]): void {\n if (node.baseIndex === -1 && node.element.path) {\n issues.push(\n createSnapshotIssue(\n 'warning',\n 'PATH_NOT_FOUND',\n `Differential path '${node.element.path}' not found in base snapshot`,\n node.element.path as string,\n ),\n );\n }\n for (const child of node.children) {\n checkUnfoundElements(child, issues);\n }\n}\n\n/**\n * Flatten a sort tree back to a linear element list (pre-order traversal).\n */\nfunction flattenTree(node: SortNode, result: ElementDefinition[]): void {\n result.push(node.element);\n for (const child of node.children) {\n flattenTree(child, result);\n }\n}\n\n// =============================================================================\n// Section 4: validateElementOrder\n// =============================================================================\n\n/**\n * Validate that snapshot elements are in correct order.\n *\n * Rules:\n * - Parent elements must appear before their children\n * - Slice elements must appear after their slicing root\n * - No duplicate paths (unless sliced)\n *\n * @param snapshot - The snapshot elements to validate.\n * @param issues - Issue collector for recording problems.\n * @returns `true` if order is valid, `false` if any violations found.\n */\nexport function validateElementOrder(\n snapshot: readonly ElementDefinition[],\n issues: SnapshotIssue[],\n): boolean {\n let valid = true;\n const seenPaths = new Map<string, number>(); // path \u2192 first index\n\n for (let i = 0; i < snapshot.length; i++) {\n const el = snapshot[i];\n const elPath = el.path as string;\n if (!elPath) continue;\n\n // Rule 1: Parent must appear before child\n const pp = parentPath(elPath);\n if (pp && !seenPaths.has(pp)) {\n // Check if parent path exists anywhere earlier\n let parentFound = false;\n for (let j = 0; j < i; j++) {\n if ((snapshot[j].path as string) === pp) {\n parentFound = true;\n break;\n }\n }\n if (!parentFound && i > 0) {\n // Root element (index 0) has no parent \u2014 that's fine\n issues.push(\n createSnapshotIssue(\n 'error',\n 'INTERNAL_ERROR',\n `Element '${elPath}' appears before its parent '${pp}'`,\n elPath,\n ),\n );\n valid = false;\n }\n }\n\n // Rule 2: Slice must appear after slicing root (same path without sliceName)\n if (el.sliceName) {\n const rootIdx = seenPaths.get(elPath);\n if (rootIdx === undefined) {\n // No slicing root seen yet \u2014 could be a problem if there should be one\n // But some profiles define slices without explicit root in diff\n // This is a warning, not an error\n }\n }\n\n // Rule 3: Track paths for duplicate/ordering checks\n if (!seenPaths.has(elPath)) {\n seenPaths.set(elPath, i);\n }\n }\n\n return valid;\n}\n\n// =============================================================================\n// Section 5: ensureElementIds\n// =============================================================================\n\n/**\n * Ensure all elements have an `id` property.\n *\n * If an element lacks an `id`, generates one from its path and sliceName.\n * This follows the FHIR convention:\n * - Unsliced: `id = path` (e.g., `\"Patient.name\"`)\n * - Sliced: `id = path:sliceName` (e.g., `\"Patient.identifier:MRN\"`)\n *\n * Corresponds to HAPI's `setIds()`.\n *\n * @param elements - The elements to process (mutated in place).\n * @param resourceType - The resource type name (used for the root element).\n */\nexport function ensureElementIds(\n elements: ElementDefinition[],\n resourceType?: string,\n): void {\n for (const el of elements) {\n if (!el.id && el.path) {\n const path = el.path as string;\n const sliceName = el.sliceName as string | undefined;\n el.id = (sliceName ? `${path}:${sliceName}` : path) as typeof el.id;\n }\n }\n\n // Optionally ensure root element id matches resourceType\n if (resourceType && elements.length > 0) {\n const root = elements[0];\n const rootPath = root.path as string | undefined;\n if (rootPath === resourceType && !root.id) {\n root.id = resourceType as typeof root.id;\n }\n }\n}\n", "/**\n * fhir-profile \u2014 Slicing Handler\n *\n * Dedicated module for FHIR slicing operations during snapshot generation.\n * Corresponds to the slicing branches in HAPI FHIR R4's `processPaths()`.\n *\n * Slicing is the **second most complex** part of snapshot generation\n * (after `processPaths` itself). This module extracts slicing logic into\n * well-tested, independently callable functions.\n *\n * Two primary scenarios:\n * - **Case A (handleNewSlicing)**: Base is unsliced, differential introduces slicing\n * - **Case B (handleExistingSlicing)**: Base is already sliced, differential modifies/extends\n *\n * Supporting functions:\n * - {@link getSliceSiblings} \u2014 collect base slice siblings\n * - {@link validateSlicingCompatibility} \u2014 check diff slicing vs base slicing\n * - {@link diffsConstrainTypes} \u2014 detect type slicing pattern\n * - {@link makeExtensionSlicing} \u2014 synthesize default extension slicing\n *\n * @module fhir-profile\n */\n\nimport type {\n ElementDefinition,\n ElementDefinitionSlicing,\n ElementDefinitionType,\n} from '../model/index.js';\nimport type { DiffElementTracker, SnapshotIssue, TraversalScope } from './types.js';\nimport { createSnapshotIssue } from './types.js';\nimport type { MergeContext } from './element-merger.js';\nimport { processPaths } from './element-merger.js';\nimport { mergeConstraints, setBaseTraceability } from './constraint-merger.js';\nimport { getChildScope, isChoiceTypePath, matchesChoiceType } from './path-utils.js';\n\n// =============================================================================\n// Section 1: Deep Clone Helper\n// =============================================================================\n\n/**\n * Deep clone an ElementDefinition.\n */\nfunction cloneElement(element: ElementDefinition): ElementDefinition {\n if (typeof structuredClone === 'function') {\n return structuredClone(element);\n }\n return JSON.parse(JSON.stringify(element)) as ElementDefinition;\n}\n\n// =============================================================================\n// Section 2: makeExtensionSlicing\n// =============================================================================\n\n/**\n * Generate the default slicing definition for extension elements.\n *\n * Corresponds to HAPI's `makeExtensionSlicing()`. Extension elements\n * are always sliced by `url` using the `value` discriminator type.\n *\n * @returns A new {@link ElementDefinitionSlicing} for extensions.\n */\nexport function makeExtensionSlicing(): ElementDefinitionSlicing {\n return {\n discriminator: [\n {\n type: 'value' as any,\n path: 'url' as any,\n },\n ],\n rules: 'open' as any,\n ordered: false as any,\n };\n}\n\n// =============================================================================\n// Section 3: getSliceSiblings\n// =============================================================================\n\n/**\n * Get all sibling slices from a base snapshot starting after the slicing root.\n *\n * Corresponds to HAPI's `getSiblings()`. Collects all elements with the\n * same path as the slicing root that have a `sliceName`, plus their children.\n *\n * @param elements - The base snapshot element list.\n * @param slicingRootIndex - Index of the slicing root element.\n * @returns Array of slice elements (each with sliceName) and their children.\n */\nexport function getSliceSiblings(\n elements: readonly ElementDefinition[],\n slicingRootIndex: number,\n): ElementDefinition[] {\n if (slicingRootIndex < 0 || slicingRootIndex >= elements.length) return [];\n\n const rootPath = elements[slicingRootIndex].path ?? '';\n const siblings: ElementDefinition[] = [];\n const prefix = rootPath + '.';\n\n for (let i = slicingRootIndex + 1; i < elements.length; i++) {\n const ep = elements[i].path ?? '';\n if (ep === rootPath) {\n // Same path \u2014 this is a slice sibling\n siblings.push(elements[i]);\n } else if (ep.startsWith(prefix)) {\n // Child of a slice \u2014 include it\n siblings.push(elements[i]);\n } else {\n // Past the slicing group\n break;\n }\n }\n\n return siblings;\n}\n\n// =============================================================================\n// Section 4: validateSlicingCompatibility\n// =============================================================================\n\n/**\n * Validate that a differential slicing definition is compatible with\n * the base slicing definition.\n *\n * Rules:\n * - Discriminators must match (same type and path, in same order)\n * - `ordered` cannot change from `true` to `false`\n * - `rules` cannot relax from `closed` to `open`/`openAtEnd`\n *\n * @param baseSlicing - The base element's slicing definition.\n * @param diffSlicing - The differential element's slicing definition.\n * @param issues - Issue collector for recording incompatibilities.\n * @param path - Element path for issue reporting.\n * @returns `true` if compatible, `false` if incompatible.\n */\nexport function validateSlicingCompatibility(\n baseSlicing: ElementDefinitionSlicing,\n diffSlicing: ElementDefinitionSlicing,\n issues: SnapshotIssue[],\n path: string,\n): boolean {\n let compatible = true;\n\n // Check discriminator compatibility\n const baseDiscs = baseSlicing.discriminator ?? [];\n const diffDiscs = diffSlicing.discriminator ?? [];\n\n if (diffDiscs.length > 0) {\n if (diffDiscs.length !== baseDiscs.length) {\n issues.push(\n createSnapshotIssue(\n 'error',\n 'SLICING_ERROR',\n `Slicing discriminator count mismatch: base has ${baseDiscs.length}, diff has ${diffDiscs.length}`,\n path,\n ),\n );\n compatible = false;\n } else {\n for (let i = 0; i < baseDiscs.length; i++) {\n const bd = baseDiscs[i];\n const dd = diffDiscs[i];\n if (bd.type !== dd.type || bd.path !== dd.path) {\n issues.push(\n createSnapshotIssue(\n 'error',\n 'SLICING_ERROR',\n `Slicing discriminator[${i}] mismatch: base={type:${bd.type},path:${bd.path}}, diff={type:${dd.type},path:${dd.path}}`,\n path,\n ),\n );\n compatible = false;\n }\n }\n }\n }\n\n // Check ordered: cannot change from true to false\n if (baseSlicing.ordered === true && diffSlicing.ordered === false) {\n issues.push(\n createSnapshotIssue(\n 'error',\n 'SLICING_ERROR',\n 'Cannot change slicing ordered from true to false',\n path,\n ),\n );\n compatible = false;\n }\n\n // Check rules: cannot relax from closed to open/openAtEnd\n const rulesOrder: Record<string, number> = { closed: 0, openAtEnd: 1, open: 2 };\n const baseRulesVal = rulesOrder[baseSlicing.rules as string] ?? 2;\n const diffRulesVal = rulesOrder[diffSlicing.rules as string] ?? 2;\n\n if (diffRulesVal > baseRulesVal) {\n issues.push(\n createSnapshotIssue(\n 'error',\n 'SLICING_ERROR',\n `Cannot relax slicing rules from '${baseSlicing.rules}' to '${diffSlicing.rules}'`,\n path,\n ),\n );\n compatible = false;\n }\n\n return compatible;\n}\n\n// =============================================================================\n// Section 5: diffsConstrainTypes\n// =============================================================================\n\n/**\n * Detect whether diff matches constitute type slicing.\n *\n * Corresponds to HAPI's `diffsConstrainTypes()`. Type slicing is detected when:\n * - Multiple diff matches exist\n * - All diff matches constrain different types, OR\n * - The base is a choice type `[x]` and diffs use concrete type paths\n *\n * @param diffMatches - The differential element trackers that matched a base path.\n * @param basePath - The base element path.\n * @param baseTypes - The base element's type list (optional).\n * @returns `true` if the diffs represent type slicing.\n */\nexport function diffsConstrainTypes(\n diffMatches: readonly DiffElementTracker[],\n basePath: string,\n baseTypes: readonly ElementDefinitionType[] | undefined,\n): boolean {\n if (diffMatches.length < 2) return false;\n\n // Check if base is a choice type and diffs use concrete paths\n if (isChoiceTypePath(basePath)) {\n const allConcrete = diffMatches.every((dm) => {\n const dp = dm.element.path ?? '';\n return matchesChoiceType(basePath, dp);\n });\n if (allConcrete) return true;\n }\n\n // Check if diffs have different type constraints\n const typeSets = diffMatches.map((dm) => {\n const types = dm.element.type;\n if (!types || types.length === 0) return '';\n return types.map((t) => t.code).sort().join(',');\n });\n\n const nonEmpty = typeSets.filter((t) => t !== '');\n if (nonEmpty.length < 2) return false;\n\n const uniqueTypes = new Set(nonEmpty);\n return uniqueTypes.size > 1;\n}\n\n// =============================================================================\n// Section 6: handleNewSlicing (Case A)\n// =============================================================================\n\n/**\n * Handle Case A: Base is unsliced, differential introduces slicing.\n *\n * Steps:\n * 1. Create slicing root element (from diff slicing definition or synthesized extension slicing)\n * 2. Add slicing root to result\n * 3. For each diff slice, recursively process against the same base range\n *\n * @param context - Shared merge state.\n * @param result - Mutable output array.\n * @param currentBase - The base element being sliced.\n * @param baseScope - Scope of the base element and its children.\n * @param diffMatches - Diff trackers that matched this base path.\n * @param diffTrackers - All diff trackers (for recursive calls).\n * @param diffStart - Start index in diffTrackers.\n * @param diffEnd - End index in diffTrackers.\n * @param contextPathSrc - Source path prefix for rewriting.\n * @param contextPathDst - Destination path prefix for rewriting.\n * @param cpath - The current (rewritten) path.\n */\nexport function handleNewSlicing(\n context: MergeContext,\n result: ElementDefinition[],\n currentBase: ElementDefinition,\n baseScope: TraversalScope,\n diffMatches: DiffElementTracker[],\n diffTrackers: readonly DiffElementTracker[],\n diffStart: number,\n diffEnd: number,\n contextPathSrc: string,\n contextPathDst: string,\n cpath: string,\n): void {\n // Separate slicing definition from slice entries\n let slicingDef: DiffElementTracker | undefined;\n const slices: DiffElementTracker[] = [];\n\n for (const dm of diffMatches) {\n if (dm.element.slicing && !dm.element.sliceName) {\n slicingDef = dm;\n } else {\n slices.push(dm);\n }\n }\n\n // Build slicing root\n const slicingRoot = cloneElement(currentBase);\n slicingRoot.path = cpath as typeof slicingRoot.path;\n setBaseTraceability(slicingRoot, currentBase);\n\n if (slicingDef) {\n // Merge the slicing definition from diff\n mergeConstraints(slicingRoot, slicingDef.element, context.issues);\n slicingDef.consumed = true;\n } else if (isExtensionPath(cpath)) {\n // Auto-generate extension slicing\n slicingRoot.slicing = makeExtensionSlicing();\n }\n\n // Ensure slicing root has slicing metadata\n if (!slicingRoot.slicing && slices.length > 0) {\n // Synthesize a basic open slicing\n slicingRoot.slicing = {\n rules: 'open' as any,\n ordered: false as any,\n };\n }\n\n result.push(slicingRoot);\n\n // Copy base children for the slicing root (unsliced content)\n const childScope = getChildScope(baseScope.elements, findIndexInScope(baseScope, currentBase));\n if (childScope) {\n copyBaseChildrenToResult(result, baseScope.elements, childScope, contextPathSrc, contextPathDst);\n }\n\n // Process each slice against the same base range\n for (const slice of slices) {\n const outcome = cloneElement(currentBase);\n outcome.path = cpath as typeof outcome.path;\n setBaseTraceability(outcome, currentBase);\n mergeConstraints(outcome, slice.element, context.issues);\n slice.consumed = true;\n result.push(outcome);\n\n // Recurse into children for this slice\n const slicePath = slice.element.path ?? cpath;\n const innerDiffScope = getInnerDiffScope(diffTrackers, slicePath, diffStart, diffEnd);\n\n if (childScope && innerDiffScope) {\n processPaths(\n context, result,\n baseScope.elements, childScope.start, childScope.end,\n diffTrackers, innerDiffScope.start, innerDiffScope.end,\n contextPathSrc, contextPathDst,\n );\n }\n }\n}\n\n// =============================================================================\n// Section 7: handleExistingSlicing (Case B)\n// =============================================================================\n\n/**\n * Handle Case B: Base is already sliced, differential modifies/extends slices.\n *\n * Steps:\n * 1. Copy base slicing root (merge diff slicing definition if present)\n * 2. Collect base slice siblings\n * 3. Align base slices with diff slices by sliceName\n * 4. Matched slices \u2192 merge constraints\n * 5. Unmatched base slices \u2192 copy as-is\n * 6. Remaining diff slices \u2192 append as new (only if open/openAtEnd)\n *\n * @param context - Shared merge state.\n * @param result - Mutable output array.\n * @param currentBase - The base slicing root element.\n * @param baseScope - Scope of the base element and its children.\n * @param diffMatches - Diff trackers that matched this base path.\n * @param diffTrackers - All diff trackers (for recursive calls).\n * @param diffStart - Start index in diffTrackers.\n * @param diffEnd - End index in diffTrackers.\n * @param contextPathSrc - Source path prefix for rewriting.\n * @param contextPathDst - Destination path prefix for rewriting.\n * @param cpath - The current (rewritten) path.\n */\nexport function handleExistingSlicing(\n context: MergeContext,\n result: ElementDefinition[],\n currentBase: ElementDefinition,\n baseScope: TraversalScope,\n diffMatches: DiffElementTracker[],\n diffTrackers: readonly DiffElementTracker[],\n diffStart: number,\n diffEnd: number,\n contextPathSrc: string,\n contextPathDst: string,\n cpath: string,\n): void {\n // Separate slicing definition from slice entries\n let slicingDiff: DiffElementTracker | undefined;\n const diffSlices: DiffElementTracker[] = [];\n\n for (const dm of diffMatches) {\n if (dm.element.slicing && !dm.element.sliceName) {\n slicingDiff = dm;\n } else {\n diffSlices.push(dm);\n }\n }\n\n // Build slicing root\n const slicingRoot = cloneElement(currentBase);\n slicingRoot.path = cpath as typeof slicingRoot.path;\n setBaseTraceability(slicingRoot, currentBase);\n\n if (slicingDiff) {\n // Validate compatibility before merging\n if (currentBase.slicing && slicingDiff.element.slicing) {\n validateSlicingCompatibility(\n currentBase.slicing, slicingDiff.element.slicing,\n context.issues, cpath,\n );\n }\n mergeConstraints(slicingRoot, slicingDiff.element, context.issues);\n slicingDiff.consumed = true;\n }\n\n result.push(slicingRoot);\n\n // Collect base slice entries\n const rootIndex = findIndexInScope(baseScope, currentBase);\n\n // Extract base slices (elements with same path + sliceName)\n const basePath = currentBase.path ?? '';\n const baseSliceEntries: { element: ElementDefinition; index: number; sliceName: string }[] = [];\n for (let i = rootIndex + 1; i < baseScope.elements.length; i++) {\n const ep = baseScope.elements[i].path ?? '';\n if (ep === basePath && baseScope.elements[i].sliceName) {\n baseSliceEntries.push({\n element: baseScope.elements[i],\n index: i,\n sliceName: baseScope.elements[i].sliceName as string,\n });\n } else if (!ep.startsWith(basePath + '.') && ep !== basePath) {\n break;\n }\n }\n\n // Build diff slice map by sliceName\n const diffSliceMap = new Map<string, DiffElementTracker>();\n const unmatchedDiffSlices: DiffElementTracker[] = [];\n for (const dm of diffSlices) {\n const sn = dm.element.sliceName as string | undefined;\n if (sn) {\n diffSliceMap.set(sn, dm);\n } else {\n unmatchedDiffSlices.push(dm);\n }\n }\n\n // Align: process base slices in order\n for (const bs of baseSliceEntries) {\n const outcome = cloneElement(bs.element);\n outcome.path = cpath as typeof outcome.path;\n setBaseTraceability(outcome, bs.element);\n\n const matchingDiff = diffSliceMap.get(bs.sliceName);\n if (matchingDiff) {\n mergeConstraints(outcome, matchingDiff.element, context.issues);\n matchingDiff.consumed = true;\n diffSliceMap.delete(bs.sliceName);\n }\n\n result.push(outcome);\n\n // Copy children of this base slice\n const sliceChildScope = getChildScope(baseScope.elements, bs.index);\n if (sliceChildScope) {\n // If there's a matching diff with inner children, recurse\n if (matchingDiff) {\n const slicePath = matchingDiff.element.path ?? cpath;\n const innerDiffScope = getInnerDiffScope(diffTrackers, slicePath, diffStart, diffEnd);\n if (innerDiffScope) {\n processPaths(\n context, result,\n baseScope.elements, sliceChildScope.start, sliceChildScope.end,\n diffTrackers, innerDiffScope.start, innerDiffScope.end,\n contextPathSrc, contextPathDst,\n );\n continue;\n }\n }\n copyBaseChildrenToResult(result, baseScope.elements, sliceChildScope, contextPathSrc, contextPathDst);\n }\n }\n\n // Append new diff slices (not matching any base slice)\n const isClosed = (currentBase.slicing?.rules as string) === 'closed';\n for (const [sliceName, dm] of diffSliceMap) {\n if (isClosed) {\n context.issues.push(\n createSnapshotIssue(\n 'error',\n 'SLICING_ERROR',\n `Cannot add new slice '${sliceName}' to closed slicing`,\n cpath,\n ),\n );\n }\n const outcome = cloneElement(currentBase);\n outcome.path = cpath as typeof outcome.path;\n setBaseTraceability(outcome, currentBase);\n mergeConstraints(outcome, dm.element, context.issues);\n dm.consumed = true;\n result.push(outcome);\n }\n\n // Handle unmatched diff entries (no sliceName)\n for (const dm of unmatchedDiffSlices) {\n if (!dm.consumed) {\n dm.consumed = true;\n }\n }\n}\n\n// =============================================================================\n// Section 8: Internal Helpers\n// =============================================================================\n\n/**\n * Check if a path refers to an extension element.\n */\nfunction isExtensionPath(path: string): boolean {\n return path.endsWith('.extension') || path.endsWith('.modifierExtension');\n}\n\n/**\n * Find the index of an element within a scope's element list.\n */\nfunction findIndexInScope(scope: TraversalScope, element: ElementDefinition): number {\n for (let i = scope.start; i <= scope.end; i++) {\n if (scope.elements[i] === element) return i;\n }\n // Fallback: search from 0\n for (let i = 0; i < scope.elements.length; i++) {\n if (scope.elements[i] === element) return i;\n }\n return scope.start;\n}\n\n/**\n * Get the scope of inner diff elements (children of parentPath).\n */\nfunction getInnerDiffScope(\n diffTrackers: readonly DiffElementTracker[],\n parentPath: string,\n diffStart: number,\n diffEnd: number,\n): { start: number; end: number } | undefined {\n const prefix = parentPath + '.';\n let start = -1;\n let end = -1;\n\n for (let i = diffStart; i <= diffEnd && i < diffTrackers.length; i++) {\n const dp = diffTrackers[i].element.path ?? '';\n if (dp.startsWith(prefix)) {\n if (start === -1) start = i;\n end = i;\n }\n }\n\n if (start === -1) return undefined;\n return { start, end };\n}\n\n/**\n * Copy base children as-is into result (with path rewriting).\n */\nfunction copyBaseChildrenToResult(\n result: ElementDefinition[],\n baseElements: readonly ElementDefinition[],\n childScope: TraversalScope,\n contextPathSrc: string,\n contextPathDst: string,\n): void {\n for (let i = childScope.start; i <= childScope.end; i++) {\n const child = cloneElement(baseElements[i]);\n if (child.path && contextPathSrc !== contextPathDst) {\n const p = child.path as string;\n if (p.startsWith(contextPathSrc + '.')) {\n child.path = (contextPathDst + p.slice(contextPathSrc.length)) as typeof child.path;\n } else if (p === contextPathSrc) {\n child.path = contextPathDst as typeof child.path;\n }\n }\n setBaseTraceability(child, baseElements[i]);\n result.push(child);\n }\n}\n", "/**\n * fhir-validator \u2014 Public Interfaces & Types\n *\n * Defines the core abstractions for the FHIR validator module:\n * - {@link ValidationOptions} \u2014 validation configuration\n * - {@link ValidationResult} \u2014 validation output\n * - {@link ValidationIssue} \u2014 issue reporting\n * - {@link ValidationIssueCode} \u2014 machine-readable issue codes\n * - {@link ValidationContext} \u2014 internal validation state\n *\n * This module implements structural validation of FHIR resource instances\n * against profile snapshots generated by the fhir-profile module.\n *\n * @module fhir-validator\n */\n\nimport type { CanonicalProfile, Resource } from '../model/index.js';\n\n// =============================================================================\n// Section 1: Validation Options\n// =============================================================================\n\n/**\n * Configuration options for structural validation.\n *\n * @example\n * ```typescript\n * const options: ValidationOptions = {\n * profileUrl: 'http://hl7.org/fhir/StructureDefinition/Patient',\n * validateSlicing: true,\n * validateFixed: true,\n * failFast: false,\n * };\n * ```\n */\nexport interface ValidationOptions {\n /**\n * Profile URL to validate against.\n *\n * If not specified, the validator will attempt to extract the profile\n * from `resource.meta.profile[0]`. If neither is available, the\n * validator falls back to the base resource type\n * (e.g., `http://hl7.org/fhir/StructureDefinition/{resourceType}`).\n */\n readonly profileUrl?: string;\n\n /**\n * Whether to validate slicing constraints.\n *\n * When `true` (default), the validator checks that array elements\n * match their declared slices and that closed slicing rules are\n * respected.\n *\n * @default true\n */\n readonly validateSlicing?: boolean;\n\n /**\n * Whether to validate fixed and pattern value constraints.\n *\n * When `true` (default), the validator checks that element values\n * match any `fixed[x]` or `pattern[x]` constraints declared in\n * the profile.\n *\n * @default true\n */\n readonly validateFixed?: boolean;\n\n /**\n * Maximum depth for nested validation.\n *\n * Prevents runaway recursion in deeply nested or pathological\n * resource structures.\n *\n * @default 50\n */\n readonly maxDepth?: number;\n\n /**\n * Whether to stop on the first error or collect all issues.\n *\n * When `true`, the validator throws a {@link ValidationFailedError}\n * on the first error-severity issue. When `false` (default), all\n * issues are collected and returned in the result.\n *\n * @default false\n */\n readonly failFast?: boolean;\n\n /**\n * Whether to skip FHIRPath invariant validation.\n *\n * When `true`, constraint expressions from the profile are not\n * evaluated. Useful for performance or when FHIRPath evaluation\n * is not needed.\n *\n * @default false\n */\n readonly skipInvariants?: boolean;\n}\n\n// =============================================================================\n// Section 2: Validation Result\n// =============================================================================\n\n/**\n * Result of structural validation.\n *\n * Contains the overall validity status, the validated resource, and\n * all issues encountered during validation.\n *\n * @example\n * ```typescript\n * const result = await validator.validate(patient);\n * if (result.valid) {\n * console.log('Resource is valid');\n * } else {\n * for (const issue of result.issues) {\n * console.error(`${issue.severity}: ${issue.message} (at ${issue.path})`);\n * }\n * }\n * ```\n */\nexport interface ValidationResult {\n /**\n * Whether the resource is valid.\n *\n * `true` when no error-severity issues were recorded.\n * Warnings and informational issues do not affect this flag.\n */\n readonly valid: boolean;\n\n /** The resource that was validated. */\n readonly resource: Resource;\n\n /** The profile that was validated against. */\n readonly profileUrl: string;\n\n /** The resolved CanonicalProfile used for validation. */\n readonly profile: CanonicalProfile;\n\n /** Issues encountered during validation (errors + warnings + info). */\n readonly issues: readonly ValidationIssue[];\n}\n\n// =============================================================================\n// Section 3: Validation Issue\n// =============================================================================\n\n/**\n * A single issue encountered during validation.\n *\n * Mirrors the concept of FHIR OperationOutcome.issue but scoped to\n * structural validation. Issues are collected during validation and\n * returned in {@link ValidationResult.issues}.\n *\n * @example\n * ```typescript\n * const issue: ValidationIssue = {\n * severity: 'error',\n * code: 'CARDINALITY_MIN_VIOLATION',\n * message: \"Element 'Patient.name' requires at least 1 value(s), but found 0\",\n * path: 'Patient.name',\n * expression: 'Patient.name',\n * };\n * ```\n */\nexport interface ValidationIssue {\n /** Severity level of the issue. */\n readonly severity: 'error' | 'warning' | 'information';\n\n /** Machine-readable issue code. */\n readonly code: ValidationIssueCode;\n\n /** Human-readable description of the issue. */\n readonly message: string;\n\n /**\n * Element path where the issue occurred (dot-notation).\n *\n * @example `'Patient.name'`, `'Observation.value[x]'`\n */\n readonly path?: string;\n\n /**\n * FHIRPath expression pointing to the problematic element.\n *\n * Typically identical to `path` for structural validation, but may\n * differ for sliced elements or choice types.\n *\n * @example `'Patient.identifier.where(system=\"urn:oid:1.2.3\")'`\n */\n readonly expression?: string;\n\n /** Additional diagnostic information for debugging. */\n readonly diagnostics?: string;\n}\n\n// =============================================================================\n// Section 4: Validation Issue Codes\n// =============================================================================\n\n/**\n * Machine-readable issue codes for structural validation.\n *\n * Each code corresponds to a specific category of validation failure.\n * Codes are designed to be stable across versions for programmatic\n * consumption.\n */\nexport type ValidationIssueCode =\n // \u2500\u2500\u2500 Cardinality \u2500\u2500\u2500\n /** Element has fewer values than the minimum cardinality. */\n | 'CARDINALITY_MIN_VIOLATION'\n /** Element has more values than the maximum cardinality. */\n | 'CARDINALITY_MAX_VIOLATION'\n\n // \u2500\u2500\u2500 Type \u2500\u2500\u2500\n /** Value type does not match any of the allowed types. */\n | 'TYPE_MISMATCH'\n /** Choice type field uses an unsupported type suffix. */\n | 'INVALID_CHOICE_TYPE'\n\n // \u2500\u2500\u2500 Required Elements \u2500\u2500\u2500\n /** A required element (min \u2265 1) is missing from the resource. */\n | 'REQUIRED_ELEMENT_MISSING'\n\n // \u2500\u2500\u2500 Fixed / Pattern \u2500\u2500\u2500\n /** Value does not match the fixed value constraint. */\n | 'FIXED_VALUE_MISMATCH'\n /** Value does not match the pattern value constraint (partial match). */\n | 'PATTERN_VALUE_MISMATCH'\n\n // \u2500\u2500\u2500 Slicing \u2500\u2500\u2500\n /** Value does not match any slice discriminator in a closed slicing. */\n | 'SLICING_NO_MATCH'\n /** Slice cardinality violation (too few or too many values in a slice). */\n | 'SLICING_CARDINALITY_VIOLATION'\n /** Ordered slicing constraint violated (values out of order). */\n | 'SLICING_ORDER_VIOLATION'\n\n // \u2500\u2500\u2500 Reference \u2500\u2500\u2500\n /** Reference target does not match any of the allowed target profiles. */\n | 'REFERENCE_TARGET_MISMATCH'\n\n // \u2500\u2500\u2500 Profile \u2500\u2500\u2500\n /** The specified profile could not be found or loaded. */\n | 'PROFILE_NOT_FOUND'\n /** Resource type does not match the profile's type. */\n | 'RESOURCE_TYPE_MISMATCH'\n\n // \u2500\u2500\u2500 Unknown \u2500\u2500\u2500\n /** Resource contains an element not defined in the profile. */\n | 'UNKNOWN_ELEMENT'\n\n // \u2500\u2500\u2500 Invariant \u2500\u2500\u2500\n /** FHIRPath invariant evaluation is not yet supported (skipped). */\n | 'INVARIANT_NOT_EVALUATED'\n /** FHIRPath invariant constraint evaluated to false. */\n | 'INVARIANT_VIOLATION'\n /** FHIRPath invariant expression failed to evaluate (runtime error). */\n | 'INVARIANT_EVALUATION_ERROR'\n\n // \u2500\u2500\u2500 Internal \u2500\u2500\u2500\n /** Internal validator error (should not happen). */\n | 'INTERNAL_ERROR';\n\n// =============================================================================\n// Section 5: Validation Context (Internal)\n// =============================================================================\n\n/**\n * Internal state passed through the validation traversal.\n *\n * Tracks the current depth, accumulated issues, and options\n * for the validation run.\n *\n * @internal Used by the StructureValidator and validation rules.\n */\nexport interface ValidationContext {\n /** The CanonicalProfile being validated against. */\n readonly profile: CanonicalProfile;\n\n /** Mutable array of accumulated issues. */\n readonly issues: ValidationIssue[];\n\n /** Resolved validation options. */\n readonly options: Required<ValidationOptions>;\n\n /** Current traversal depth (for maxDepth enforcement). */\n depth: number;\n}\n\n// =============================================================================\n// Section 6: Helper Functions\n// =============================================================================\n\n/**\n * Create a {@link ValidationIssue} with the given parameters.\n *\n * Convenience factory to reduce boilerplate when recording issues.\n *\n * @param severity - Issue severity level.\n * @param code - Machine-readable issue code.\n * @param message - Human-readable description.\n * @param options - Optional path, expression, and diagnostics.\n * @returns A frozen ValidationIssue object.\n */\nexport function createValidationIssue(\n severity: ValidationIssue['severity'],\n code: ValidationIssueCode,\n message: string,\n options?: {\n path?: string;\n expression?: string;\n diagnostics?: string;\n },\n): ValidationIssue {\n const issue: ValidationIssue = { severity, code, message };\n if (options?.path !== undefined) {\n (issue as { path: string }).path = options.path;\n }\n if (options?.expression !== undefined) {\n (issue as { expression: string }).expression = options.expression;\n }\n if (options?.diagnostics !== undefined) {\n (issue as { diagnostics: string }).diagnostics = options.diagnostics;\n }\n return issue;\n}\n\n/**\n * Create a {@link ValidationContext} with resolved defaults.\n *\n * @param profile - The CanonicalProfile to validate against.\n * @param options - User-provided options (defaults applied for missing fields).\n * @returns A new ValidationContext ready for traversal.\n *\n * @internal\n */\nexport function createValidationContext(\n profile: CanonicalProfile,\n options?: ValidationOptions,\n): ValidationContext {\n return {\n profile,\n issues: [],\n options: {\n profileUrl: options?.profileUrl ?? profile.url,\n validateSlicing: options?.validateSlicing ?? true,\n validateFixed: options?.validateFixed ?? true,\n maxDepth: options?.maxDepth ?? 50,\n failFast: options?.failFast ?? false,\n skipInvariants: options?.skipInvariants ?? false,\n },\n depth: 0,\n };\n}\n\n/**\n * Resolve default validation options.\n *\n * Fills in missing fields with sensible defaults.\n *\n * @param options - User-provided options (may be partial).\n * @returns Fully resolved options with all fields populated.\n */\nexport function resolveValidationOptions(\n options?: ValidationOptions,\n): Required<ValidationOptions> {\n return {\n profileUrl: options?.profileUrl ?? '',\n validateSlicing: options?.validateSlicing ?? true,\n validateFixed: options?.validateFixed ?? true,\n maxDepth: options?.maxDepth ?? 50,\n failFast: options?.failFast ?? false,\n skipInvariants: options?.skipInvariants ?? false,\n };\n}\n\n/**\n * Check whether a validation result has any error-severity issues.\n *\n * @param issues - The issues to check.\n * @returns `true` if any issue has severity `'error'`.\n */\nexport function hasValidationErrors(\n issues: readonly ValidationIssue[],\n): boolean {\n return issues.some((i) => i.severity === 'error');\n}\n\n/**\n * Filter issues by severity.\n *\n * @param issues - The issues to filter.\n * @param severity - The severity to filter by.\n * @returns Issues matching the specified severity.\n */\nexport function filterIssuesBySeverity(\n issues: readonly ValidationIssue[],\n severity: ValidationIssue['severity'],\n): ValidationIssue[] {\n return issues.filter((i) => i.severity === severity);\n}\n\n/**\n * Filter issues by code.\n *\n * @param issues - The issues to filter.\n * @param code - The issue code to filter by.\n * @returns Issues matching the specified code.\n */\nexport function filterIssuesByCode(\n issues: readonly ValidationIssue[],\n code: ValidationIssueCode,\n): ValidationIssue[] {\n return issues.filter((i) => i.code === code);\n}\n", "/**\n * fhir-validator \u2014 Path Extractor\n *\n * Extracts values from FHIR resource instances using element paths.\n * Handles nested objects, arrays, and choice type (`[x]`) paths.\n *\n * This is the core utility that bridges CanonicalProfile element paths\n * (e.g., `Patient.name.family`) to actual values in a resource JSON object.\n *\n * @module fhir-validator\n */\n\n// =============================================================================\n// Section 1: Constants\n// =============================================================================\n\n/**\n * Known FHIR type suffixes for choice type resolution.\n *\n * When encountering a `[x]` path like `Observation.value[x]`, the extractor\n * checks for concrete properties like `valueString`, `valueQuantity`, etc.\n * Suffixes are capitalized per FHIR JSON serialization rules.\n */\nconst CHOICE_TYPE_SUFFIXES: readonly string[] = [\n // Primitive types\n 'Boolean',\n 'Integer',\n 'Decimal',\n 'String',\n 'Uri',\n 'Url',\n 'Canonical',\n 'Base64Binary',\n 'Instant',\n 'Date',\n 'DateTime',\n 'Time',\n 'Code',\n 'Oid',\n 'Id',\n 'Markdown',\n 'UnsignedInt',\n 'PositiveInt',\n 'Uuid',\n // Complex types\n 'Address',\n 'Age',\n 'Annotation',\n 'Attachment',\n 'CodeableConcept',\n 'Coding',\n 'ContactPoint',\n 'Count',\n 'Distance',\n 'Duration',\n 'HumanName',\n 'Identifier',\n 'Money',\n 'Period',\n 'Quantity',\n 'Range',\n 'Ratio',\n 'Reference',\n 'SampledData',\n 'Signature',\n 'Timing',\n 'ContactDetail',\n 'Contributor',\n 'DataRequirement',\n 'Expression',\n 'ParameterDefinition',\n 'RelatedArtifact',\n 'TriggerDefinition',\n 'UsageContext',\n 'Dosage',\n 'Meta',\n];\n\n// =============================================================================\n// Section 2: extractValues\n// =============================================================================\n\n/**\n * Extract values from a resource instance using an element path.\n *\n * Navigates the resource object following the dot-separated path segments.\n * Arrays are automatically expanded \u2014 if an intermediate node is an array,\n * extraction continues into each element.\n *\n * @param resource - The resource object to extract from.\n * @param path - Element path (e.g., `'Patient.name.family'`).\n * @returns Array of extracted values (empty if path not found).\n *\n * @example\n * ```typescript\n * const patient = {\n * resourceType: 'Patient',\n * name: [\n * { family: 'Smith', given: ['John', 'James'] },\n * { family: 'Doe' },\n * ],\n * };\n *\n * extractValues(patient, 'Patient.name')\n * // \u2192 [{ family: 'Smith', given: ['John', 'James'] }, { family: 'Doe' }]\n *\n * extractValues(patient, 'Patient.name.family')\n * // \u2192 ['Smith', 'Doe']\n *\n * extractValues(patient, 'Patient.name.given')\n * // \u2192 ['John', 'James']\n * ```\n */\nexport function extractValues(\n resource: Record<string, unknown>,\n path: string,\n): unknown[] {\n if (!resource || typeof resource !== 'object') {\n return [];\n }\n\n const segments = path.split('.');\n\n // First segment is the resource type (e.g., 'Patient')\n // If the path is just the resource type, return the resource itself\n if (segments.length === 0) {\n return [];\n }\n\n if (segments.length === 1) {\n // Root path \u2014 return the resource itself if type matches\n if (resource.resourceType === segments[0] || segments[0] === '') {\n return [resource];\n }\n return [];\n }\n\n // Skip the first segment (resource type) and navigate from there\n const propertySegments = segments.slice(1);\n return extractFromNode(resource, propertySegments, 0);\n}\n\n/**\n * Recursively extract values from a node following path segments.\n *\n * @internal\n */\nfunction extractFromNode(\n node: unknown,\n segments: string[],\n index: number,\n): unknown[] {\n // If we've consumed all segments, return the current node (including null)\n if (index >= segments.length) {\n return [node];\n }\n\n // Cannot traverse further into null/undefined\n if (node === null || node === undefined) {\n return [];\n }\n\n // If current node is an array, recurse into each element\n if (Array.isArray(node)) {\n const results: unknown[] = [];\n for (const item of node) {\n results.push(...extractFromNode(item, segments, index));\n }\n return results;\n }\n\n // Current node must be an object\n if (typeof node !== 'object') {\n return [];\n }\n\n const obj = node as Record<string, unknown>;\n const segment = segments[index];\n\n // Check for choice type path (ends with [x])\n if (segment.endsWith('[x]')) {\n return extractChoiceTypeValues(obj, segments, index);\n }\n\n // Standard property lookup\n const value = obj[segment];\n\n if (value === undefined) {\n return [];\n }\n\n // If value is an array and we have more segments, expand into each element\n if (Array.isArray(value) && index < segments.length - 1) {\n const results: unknown[] = [];\n for (const item of value) {\n results.push(...extractFromNode(item, segments, index + 1));\n }\n return results;\n }\n\n // If value is an array and this is the last segment, return all elements\n if (Array.isArray(value) && index === segments.length - 1) {\n return value;\n }\n\n // Continue recursion\n return extractFromNode(value, segments, index + 1);\n}\n\n/**\n * Extract values for a choice type path segment (e.g., `value[x]`).\n *\n * Searches the object for any concrete property matching the choice base\n * with a known type suffix (e.g., `valueString`, `valueQuantity`).\n *\n * @internal\n */\nfunction extractChoiceTypeValues(\n obj: Record<string, unknown>,\n segments: string[],\n index: number,\n): unknown[] {\n const segment = segments[index];\n const baseName = segment.slice(0, -3); // Remove '[x]'\n\n // Try each known suffix\n for (const suffix of CHOICE_TYPE_SUFFIXES) {\n const concreteKey = baseName + suffix;\n if (concreteKey in obj) {\n const value = obj[concreteKey];\n return extractFromNode(value, segments, index + 1);\n }\n }\n\n // Fallback: scan object keys for any property starting with baseName\n // followed by an uppercase letter (handles custom/unknown types)\n for (const key of Object.keys(obj)) {\n if (\n key.startsWith(baseName) &&\n key.length > baseName.length &&\n key[baseName.length] >= 'A' &&\n key[baseName.length] <= 'Z'\n ) {\n const value = obj[key];\n return extractFromNode(value, segments, index + 1);\n }\n }\n\n return [];\n}\n\n// =============================================================================\n// Section 3: pathExists\n// =============================================================================\n\n/**\n * Check if a path exists in the resource (even if value is null/undefined).\n *\n * Unlike `extractValues`, this checks for property existence rather than\n * value presence. A property set to `null` or `undefined` still \"exists\".\n *\n * @param resource - The resource object to check.\n * @param path - Element path (e.g., `'Patient.name'`).\n * @returns `true` if the path exists in the resource.\n *\n * @example\n * ```typescript\n * pathExists({ resourceType: 'Patient', name: [] }, 'Patient.name')\n * // \u2192 true\n *\n * pathExists({ resourceType: 'Patient' }, 'Patient.name')\n * // \u2192 false\n * ```\n */\nexport function pathExists(\n resource: Record<string, unknown>,\n path: string,\n): boolean {\n if (!resource || typeof resource !== 'object') {\n return false;\n }\n\n const segments = path.split('.');\n\n if (segments.length <= 1) {\n return true; // Root path always exists\n }\n\n const propertySegments = segments.slice(1);\n return propertyExistsInNode(resource, propertySegments, 0);\n}\n\n/**\n * Recursively check if a property exists in a node.\n *\n * @internal\n */\nfunction propertyExistsInNode(\n node: unknown,\n segments: string[],\n index: number,\n): boolean {\n if (node === null || node === undefined) {\n return false;\n }\n\n if (index >= segments.length) {\n return true;\n }\n\n // If current node is an array, check any element\n if (Array.isArray(node)) {\n return node.some((item) => propertyExistsInNode(item, segments, index));\n }\n\n if (typeof node !== 'object') {\n return false;\n }\n\n const obj = node as Record<string, unknown>;\n const segment = segments[index];\n\n // Choice type\n if (segment.endsWith('[x]')) {\n const baseName = segment.slice(0, -3);\n for (const key of Object.keys(obj)) {\n if (\n key.startsWith(baseName) &&\n key.length > baseName.length &&\n key[baseName.length] >= 'A' &&\n key[baseName.length] <= 'Z'\n ) {\n return propertyExistsInNode(obj[key], segments, index + 1);\n }\n }\n return false;\n }\n\n // Standard property\n if (!(segment in obj)) {\n return false;\n }\n\n const value = obj[segment];\n\n // If value is an array, check within elements\n if (Array.isArray(value)) {\n if (index === segments.length - 1) {\n return true; // The array property itself exists\n }\n return value.some((item) => propertyExistsInNode(item, segments, index + 1));\n }\n\n return propertyExistsInNode(value, segments, index + 1);\n}\n\n// =============================================================================\n// Section 4: findChoiceTypeField\n// =============================================================================\n\n/**\n * Find the concrete choice type property name in an object.\n *\n * Given a choice base name (e.g., `'value'`), searches the object for\n * a property like `valueString`, `valueQuantity`, etc.\n *\n * @param obj - The object to search.\n * @param baseName - The choice type base name (without `[x]`).\n * @returns The concrete property name, or `undefined` if not found.\n *\n * @example\n * ```typescript\n * findChoiceTypeField({ valueQuantity: { value: 120 } }, 'value')\n * // \u2192 'valueQuantity'\n *\n * findChoiceTypeField({ code: '12345' }, 'value')\n * // \u2192 undefined\n * ```\n */\nexport function findChoiceTypeField(\n obj: Record<string, unknown>,\n baseName: string,\n): string | undefined {\n // Try known suffixes first (fast path)\n for (const suffix of CHOICE_TYPE_SUFFIXES) {\n const key = baseName + suffix;\n if (key in obj) {\n return key;\n }\n }\n\n // Fallback: scan keys\n for (const key of Object.keys(obj)) {\n if (\n key.startsWith(baseName) &&\n key.length > baseName.length &&\n key[baseName.length] >= 'A' &&\n key[baseName.length] <= 'Z'\n ) {\n return key;\n }\n }\n\n return undefined;\n}\n\n// =============================================================================\n// Section 5: normalizeChoicePath\n// =============================================================================\n\n/**\n * Normalize a choice type path to a concrete path.\n *\n * Replaces the `[x]` suffix with the actual type suffix found in the object.\n *\n * @param basePath - The choice type path (e.g., `'Observation.value[x]'`).\n * @param concreteField - The concrete field name (e.g., `'valueQuantity'`).\n * @returns The normalized path (e.g., `'Observation.valueQuantity'`).\n *\n * @example\n * ```typescript\n * normalizeChoicePath('Observation.value[x]', 'valueQuantity')\n * // \u2192 'Observation.valueQuantity'\n *\n * normalizeChoicePath('Extension.value[x]', 'valueString')\n * // \u2192 'Extension.valueString'\n * ```\n */\nexport function normalizeChoicePath(\n basePath: string,\n concreteField: string,\n): string {\n if (!basePath.endsWith('[x]')) {\n return basePath;\n }\n\n // Replace the last segment (which ends with [x]) with the concrete field\n const lastDot = basePath.lastIndexOf('.');\n if (lastDot === -1) {\n return concreteField;\n }\n\n return basePath.slice(0, lastDot + 1) + concreteField;\n}\n\n// =============================================================================\n// Section 6: extractChoiceTypeSuffix\n// =============================================================================\n\n/**\n * Extract the type suffix from a concrete choice type property name.\n *\n * @param concreteField - The concrete field name (e.g., `'valueQuantity'`).\n * @param baseName - The choice type base name (e.g., `'value'`).\n * @returns The type suffix (e.g., `'Quantity'`), or `undefined` if not a match.\n *\n * @example\n * ```typescript\n * extractChoiceTypeSuffix('valueQuantity', 'value')\n * // \u2192 'Quantity'\n *\n * extractChoiceTypeSuffix('valueString', 'value')\n * // \u2192 'String'\n *\n * extractChoiceTypeSuffix('code', 'value')\n * // \u2192 undefined\n * ```\n */\nexport function extractChoiceTypeSuffix(\n concreteField: string,\n baseName: string,\n): string | undefined {\n if (!concreteField.startsWith(baseName)) {\n return undefined;\n }\n\n if (concreteField.length <= baseName.length) {\n return undefined;\n }\n\n const suffix = concreteField.slice(baseName.length);\n if (suffix[0] >= 'A' && suffix[0] <= 'Z') {\n return suffix;\n }\n\n return undefined;\n}\n", "/**\n * fhir-validator \u2014 Validation Rules: Cardinality, Type, Fixed/Pattern & Reference\n *\n * Implements the core structural validation rules:\n * - {@link validateCardinality} \u2014 min/max cardinality checks\n * - {@link validateType} \u2014 FHIR type constraint checks\n * - {@link inferFhirType} \u2014 heuristic FHIR type inference from JS values\n * - {@link validateRequired} \u2014 required element (min\u22651) presence check\n * - {@link validateFixed} \u2014 fixed value exact-match checks\n * - {@link validatePattern} \u2014 pattern value partial-match checks\n * - {@link matchesPattern} \u2014 recursive partial object matching\n * - {@link deepEqual} \u2014 recursive deep equality comparison\n * - {@link validateReference} \u2014 reference target profile checks\n * - {@link extractReferenceType} \u2014 extract resource type from reference string\n *\n * These functions operate on individual {@link CanonicalElement} definitions\n * and produce {@link ValidationIssue} entries when violations are found.\n *\n * @module fhir-validator\n */\n\nimport type { CanonicalElement } from '../model/canonical-profile.js';\nimport type { ValidationIssue } from './types.js';\nimport { createValidationIssue } from './types.js';\n\n// =============================================================================\n// Section 1: validateCardinality\n// =============================================================================\n\n/**\n * Validate cardinality (min/max) for an element.\n *\n * Checks that the number of values found for an element falls within\n * the allowed range defined by `element.min` and `element.max`.\n *\n * @param element - The canonical element definition with min/max constraints.\n * @param values - The extracted values for this element.\n * @param issues - Mutable array to push validation issues into.\n *\n * @example\n * ```typescript\n * // element: min=1, max=1\n * validateCardinality(element, [], issues);\n * // \u2192 issues: [{ code: 'CARDINALITY_MIN_VIOLATION', ... }]\n * ```\n */\nexport function validateCardinality(\n element: CanonicalElement,\n values: unknown[],\n issues: ValidationIssue[],\n): void {\n const count = values.length;\n\n // Check minimum cardinality\n if (element.min > 0 && count < element.min) {\n issues.push(\n createValidationIssue(\n 'error',\n 'CARDINALITY_MIN_VIOLATION',\n `Element '${element.path}' requires at least ${element.min} value(s), but found ${count}`,\n { path: element.path },\n ),\n );\n }\n\n // Check maximum cardinality\n if (element.max !== 'unbounded') {\n if (count > element.max) {\n issues.push(\n createValidationIssue(\n 'error',\n 'CARDINALITY_MAX_VIOLATION',\n `Element '${element.path}' allows at most ${element.max} value(s), but found ${count}`,\n { path: element.path },\n ),\n );\n }\n }\n}\n\n// =============================================================================\n// Section 2: validateRequired\n// =============================================================================\n\n/**\n * Validate that a required element (min \u2265 1) is present.\n *\n * This is a convenience wrapper that checks element presence without\n * needing to extract values first. It only checks the `exists` flag.\n *\n * @param element - The canonical element definition.\n * @param exists - Whether the element exists in the resource.\n * @param issues - Mutable array to push validation issues into.\n */\nexport function validateRequired(\n element: CanonicalElement,\n exists: boolean,\n issues: ValidationIssue[],\n): void {\n if (element.min > 0 && !exists) {\n issues.push(\n createValidationIssue(\n 'error',\n 'REQUIRED_ELEMENT_MISSING',\n `Required element '${element.path}' is missing (min=${element.min})`,\n { path: element.path },\n ),\n );\n }\n}\n\n// =============================================================================\n// Section 3: inferFhirType\n// =============================================================================\n\n/**\n * Known FHIR primitive type names (lowercase) that map to JS `string`.\n *\n * @internal\n */\nconst STRING_FHIR_TYPES = new Set([\n 'string',\n 'uri',\n 'url',\n 'canonical',\n 'code',\n 'oid',\n 'id',\n 'markdown',\n 'base64Binary',\n 'instant',\n 'date',\n 'dateTime',\n 'time',\n 'uuid',\n 'xhtml',\n]);\n\n/**\n * Infer the FHIR type from a JavaScript value.\n *\n * Uses heuristics to determine the most likely FHIR type based on\n * the JavaScript runtime type and object shape. This is inherently\n * imperfect \u2014 for example, a JS `string` could be any of the FHIR\n * string-like primitives. The inference returns the broadest matching\n * category.\n *\n * **Type mapping:**\n *\n * | JS type | Inferred FHIR type |\n * |---------|-------------------|\n * | `string` | `'string'` |\n * | `boolean` | `'boolean'` |\n * | `number` (integer) | `'integer'` |\n * | `number` (decimal) | `'decimal'` |\n * | `object` with `system`+`code` | `'Coding'` |\n * | `object` with `coding` array | `'CodeableConcept'` |\n * | `object` with `value`+`unit` or `value`+`system` | `'Quantity'` |\n * | `object` with `reference` | `'Reference'` |\n * | `object` with `start` or `end` | `'Period'` |\n * | `object` with `numerator`+`denominator` | `'Ratio'` |\n * | `object` with `line`+`city` or `city`+`state` | `'Address'` |\n * | `object` with `family` or `given` | `'HumanName'` |\n * | `object` with `system`+`value` (no `code`) | `'Identifier'` |\n * | `object` with `contentType` or `data` | `'Attachment'` |\n * | `object` with `url`+`value[x]` shape | `'Extension'` |\n * | other `object` | `'BackboneElement'` |\n * | `null`/`undefined` | `'null'` |\n *\n * @param value - The JavaScript value to infer type from.\n * @returns The inferred FHIR type name.\n */\nexport function inferFhirType(value: unknown): string {\n if (value === null || value === undefined) {\n return 'null';\n }\n\n if (typeof value === 'string') {\n return 'string';\n }\n\n if (typeof value === 'boolean') {\n return 'boolean';\n }\n\n if (typeof value === 'number') {\n return Number.isInteger(value) ? 'integer' : 'decimal';\n }\n\n if (Array.isArray(value)) {\n return 'array';\n }\n\n if (typeof value === 'object') {\n const obj = value as Record<string, unknown>;\n return inferComplexType(obj);\n }\n\n return 'unknown';\n}\n\n/**\n * Infer FHIR complex type from an object's shape.\n *\n * @internal\n */\nfunction inferComplexType(obj: Record<string, unknown>): string {\n // Coding: { system, code }\n if ('system' in obj && 'code' in obj && !('value' in obj)) {\n return 'Coding';\n }\n\n // CodeableConcept: { coding: [...] }\n if ('coding' in obj && Array.isArray(obj.coding)) {\n return 'CodeableConcept';\n }\n\n // Quantity (and sub-types Age, Count, Distance, Duration, Money):\n // { value, unit } or { value, system, code }\n if ('value' in obj && typeof obj.value === 'number') {\n if ('unit' in obj || ('system' in obj && 'code' in obj)) {\n return 'Quantity';\n }\n }\n\n // Reference: { reference } or { reference, display }\n if ('reference' in obj && typeof obj.reference === 'string') {\n return 'Reference';\n }\n\n // Period: { start } or { end } or { start, end }\n if (('start' in obj || 'end' in obj) && !('value' in obj)) {\n return 'Period';\n }\n\n // Ratio: { numerator, denominator }\n if ('numerator' in obj && 'denominator' in obj) {\n return 'Ratio';\n }\n\n // HumanName: { family } or { given }\n if ('family' in obj || ('given' in obj && Array.isArray(obj.given))) {\n return 'HumanName';\n }\n\n // Address: { line, city } or { city, state }\n if (('line' in obj && 'city' in obj) || ('city' in obj && 'state' in obj)) {\n return 'Address';\n }\n\n // Identifier: { system, value } (no code)\n if ('system' in obj && 'value' in obj && !('code' in obj)) {\n return 'Identifier';\n }\n\n // ContactPoint: { system, value } with system being phone/fax/email/pager/url/sms/other\n if ('system' in obj && 'value' in obj && 'code' in obj) {\n // Already matched as Coding above, but just in case\n return 'Coding';\n }\n\n // Attachment: { contentType } or { data }\n if ('contentType' in obj || ('data' in obj && typeof obj.data === 'string')) {\n return 'Attachment';\n }\n\n // Extension: { url, value[x] }\n if ('url' in obj && typeof obj.url === 'string') {\n // Check for any value[x] property\n for (const key of Object.keys(obj)) {\n if (\n key.startsWith('value') &&\n key.length > 5 &&\n key[5] >= 'A' &&\n key[5] <= 'Z'\n ) {\n return 'Extension';\n }\n }\n }\n\n // Meta: { versionId } or { lastUpdated } or { profile }\n if ('versionId' in obj || 'lastUpdated' in obj || ('profile' in obj && Array.isArray(obj.profile))) {\n return 'Meta';\n }\n\n // Narrative: { status, div }\n if ('status' in obj && 'div' in obj) {\n return 'Narrative';\n }\n\n // Generic backbone/complex element\n return 'BackboneElement';\n}\n\n// =============================================================================\n// Section 4: validateType\n// =============================================================================\n\n/**\n * Check if an inferred type is compatible with a set of allowed type constraints.\n *\n * Handles FHIR's type hierarchy where:\n * - All string-like primitives (uri, code, id, etc.) are compatible with `string`\n * - `integer`, `positiveInt`, `unsignedInt` are compatible with each other\n * - `Quantity` sub-types (Age, Count, Distance, Duration, Money) match `Quantity`\n * - `BackboneElement` is compatible with any complex type (structural match)\n *\n * @internal\n */\nfunction isTypeCompatible(inferredType: string, allowedType: string): boolean {\n // Exact match\n if (inferredType === allowedType) {\n return true;\n }\n\n // String-like primitives are all compatible with 'string'\n if (inferredType === 'string' && STRING_FHIR_TYPES.has(allowedType)) {\n return true;\n }\n\n // Integer variants\n if (\n inferredType === 'integer' &&\n (allowedType === 'positiveInt' || allowedType === 'unsignedInt' || allowedType === 'integer')\n ) {\n return true;\n }\n\n // Decimal is compatible with integer (integer is a subset of decimal)\n if (inferredType === 'integer' && allowedType === 'decimal') {\n return true;\n }\n\n // Quantity sub-types\n if (\n inferredType === 'Quantity' &&\n (allowedType === 'Age' ||\n allowedType === 'Count' ||\n allowedType === 'Distance' ||\n allowedType === 'Duration' ||\n allowedType === 'Money' ||\n allowedType === 'SimpleQuantity')\n ) {\n return true;\n }\n\n // BackboneElement is a generic complex type \u2014 compatible with any complex type\n // This handles cases where we can't precisely infer the type from shape alone\n if (inferredType === 'BackboneElement') {\n // BackboneElement is compatible with any non-primitive type\n const primitives = new Set(['string', 'boolean', 'integer', 'decimal', 'null', 'array', 'unknown']);\n return !primitives.has(allowedType);\n }\n\n // Element type (base of all) \u2014 very permissive\n if (allowedType === 'Element' || allowedType === 'BackboneElement') {\n return true;\n }\n\n // Resource type \u2014 any object with resourceType\n if (allowedType === 'Resource') {\n return inferredType !== 'string' && inferredType !== 'boolean' &&\n inferredType !== 'integer' && inferredType !== 'decimal' &&\n inferredType !== 'null' && inferredType !== 'unknown';\n }\n\n return false;\n}\n\n/**\n * Validate type constraints for an element value.\n *\n * Checks that the inferred FHIR type of a value matches at least one\n * of the allowed types defined in the element's type constraints.\n *\n * If the element has no type constraints (backbone element), validation\n * is skipped. If the element allows multiple types (choice type), the\n * value must match at least one.\n *\n * @param element - The canonical element definition with type constraints.\n * @param value - The actual value to validate.\n * @param issues - Mutable array to push validation issues into.\n *\n * @example\n * ```typescript\n * // element.types = [{ code: 'string' }]\n * validateType(element, 42, issues);\n * // \u2192 issues: [{ code: 'TYPE_MISMATCH', ... }]\n * ```\n */\nexport function validateType(\n element: CanonicalElement,\n value: unknown,\n issues: ValidationIssue[],\n): void {\n // No type constraints \u2192 backbone element, skip\n if (element.types.length === 0) {\n return;\n }\n\n // Null/undefined values are handled by cardinality, not type\n if (value === null || value === undefined) {\n return;\n }\n\n const inferredType = inferFhirType(value);\n\n // Check if inferred type matches any allowed type\n const isMatch = element.types.some((tc) => isTypeCompatible(inferredType, tc.code));\n\n if (!isMatch) {\n const allowedCodes = element.types.map((t) => t.code).join(', ');\n issues.push(\n createValidationIssue(\n 'error',\n 'TYPE_MISMATCH',\n `Element '${element.path}' expects type(s) [${allowedCodes}], but found '${inferredType}'`,\n {\n path: element.path,\n diagnostics: `Inferred type: ${inferredType}, allowed: [${allowedCodes}]`,\n },\n ),\n );\n }\n}\n\n// =============================================================================\n// Section 5: validateChoiceType\n// =============================================================================\n\n/**\n * Validate that a choice type element uses an allowed type suffix.\n *\n * For elements like `Observation.value[x]`, checks that the concrete\n * property name (e.g., `valueQuantity`) uses a type suffix that matches\n * one of the allowed types in the element definition.\n *\n * @param element - The canonical element definition (must be a choice type).\n * @param concreteFieldSuffix - The type suffix from the concrete property\n * (e.g., `'Quantity'` from `valueQuantity`).\n * @param issues - Mutable array to push validation issues into.\n */\nexport function validateChoiceType(\n element: CanonicalElement,\n concreteFieldSuffix: string,\n issues: ValidationIssue[],\n): void {\n if (element.types.length === 0) {\n return;\n }\n\n const allowedCodes = element.types.map((t) => t.code);\n const isAllowed = allowedCodes.some(\n (code) => code === concreteFieldSuffix || code.toLowerCase() === concreteFieldSuffix.toLowerCase(),\n );\n\n if (!isAllowed) {\n issues.push(\n createValidationIssue(\n 'error',\n 'INVALID_CHOICE_TYPE',\n `Element '${element.path}' does not allow type '${concreteFieldSuffix}'; allowed: [${allowedCodes.join(', ')}]`,\n { path: element.path },\n ),\n );\n }\n}\n\n// =============================================================================\n// Section 6: deepEqual\n// =============================================================================\n\n/**\n * Perform a recursive deep equality comparison between two values.\n *\n * Handles primitives, `null`, `undefined`, arrays (order-sensitive),\n * and plain objects. Does NOT handle `Date`, `RegExp`, `Map`, `Set`,\n * or other special JS types \u2014 those are not relevant for FHIR JSON.\n *\n * @param a - First value.\n * @param b - Second value.\n * @returns `true` if the values are deeply equal.\n */\nexport function deepEqual(a: unknown, b: unknown): boolean {\n // Identical references or both primitives with same value\n if (a === b) {\n return true;\n }\n\n // If either is null/undefined (and they're not ===), they differ\n if (a === null || a === undefined || b === null || b === undefined) {\n return false;\n }\n\n // Different JS types\n if (typeof a !== typeof b) {\n return false;\n }\n\n // Arrays\n if (Array.isArray(a)) {\n if (!Array.isArray(b)) return false;\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!deepEqual(a[i], b[i])) return false;\n }\n return true;\n }\n\n // Objects\n if (typeof a === 'object' && typeof b === 'object') {\n const objA = a as Record<string, unknown>;\n const objB = b as Record<string, unknown>;\n const keysA = Object.keys(objA);\n const keysB = Object.keys(objB);\n\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n if (!(key in objB)) return false;\n if (!deepEqual(objA[key], objB[key])) return false;\n }\n return true;\n }\n\n // Primitives that aren't === (e.g., NaN !== NaN)\n return false;\n}\n\n// =============================================================================\n// Section 7: validateFixed\n// =============================================================================\n\n/**\n * Validate a fixed value constraint on an element.\n *\n * When `element.fixed` is defined, the actual value MUST be deeply equal\n * to the fixed value. This is an exact-match constraint \u2014 no additional\n * or missing fields are allowed.\n *\n * @param element - The canonical element definition (may have `fixed`).\n * @param value - The actual value to validate.\n * @param issues - Mutable array to push validation issues into.\n */\nexport function validateFixed(\n element: CanonicalElement,\n value: unknown,\n issues: ValidationIssue[],\n): void {\n if (element.fixed === undefined) {\n return;\n }\n\n // Null/undefined values are handled by cardinality\n if (value === null || value === undefined) {\n return;\n }\n\n if (!deepEqual(value, element.fixed)) {\n issues.push(\n createValidationIssue(\n 'error',\n 'FIXED_VALUE_MISMATCH',\n `Element '${element.path}' must have fixed value ${JSON.stringify(element.fixed)}, but found ${JSON.stringify(value)}`,\n {\n path: element.path,\n diagnostics: `Expected: ${JSON.stringify(element.fixed)}, Actual: ${JSON.stringify(value)}`,\n },\n ),\n );\n }\n}\n\n// =============================================================================\n// Section 8: matchesPattern & validatePattern\n// =============================================================================\n\n/**\n * Check if a value matches a pattern (partial/subset match).\n *\n * A pattern match means: every field present in the `pattern` must also\n * be present in `value` with the same value. However, `value` may contain\n * additional fields not in the pattern.\n *\n * For primitives and arrays, this falls back to deep equality.\n * For objects, it performs recursive subset matching.\n *\n * @param value - The actual value to check.\n * @param pattern - The pattern to match against.\n * @returns `true` if the value matches the pattern.\n */\nexport function matchesPattern(value: unknown, pattern: unknown): boolean {\n // Primitives and null: exact match\n if (pattern === null || pattern === undefined) {\n return value === pattern;\n }\n\n if (typeof pattern !== 'object') {\n return value === pattern;\n }\n\n // Pattern is an array \u2192 value must be an array with matching elements\n if (Array.isArray(pattern)) {\n if (!Array.isArray(value)) return false;\n // Each element in the pattern array must have a matching element in value\n for (const patternItem of pattern) {\n const found = value.some((v) => matchesPattern(v, patternItem));\n if (!found) return false;\n }\n return true;\n }\n\n // Pattern is an object \u2192 value must be an object with all pattern keys\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return false;\n }\n\n const objValue = value as Record<string, unknown>;\n const objPattern = pattern as Record<string, unknown>;\n\n for (const key of Object.keys(objPattern)) {\n if (!(key in objValue)) return false;\n if (!matchesPattern(objValue[key], objPattern[key])) return false;\n }\n\n return true;\n}\n\n/**\n * Validate a pattern value constraint on an element.\n *\n * When `element.pattern` is defined, the actual value must be a superset\n * of the pattern \u2014 all fields in the pattern must exist in the value with\n * matching values, but the value may contain additional fields.\n *\n * @param element - The canonical element definition (may have `pattern`).\n * @param value - The actual value to validate.\n * @param issues - Mutable array to push validation issues into.\n */\nexport function validatePattern(\n element: CanonicalElement,\n value: unknown,\n issues: ValidationIssue[],\n): void {\n if (element.pattern === undefined) {\n return;\n }\n\n // Null/undefined values are handled by cardinality\n if (value === null || value === undefined) {\n return;\n }\n\n if (!matchesPattern(value, element.pattern)) {\n issues.push(\n createValidationIssue(\n 'error',\n 'PATTERN_VALUE_MISMATCH',\n `Element '${element.path}' must match pattern ${JSON.stringify(element.pattern)}, but found ${JSON.stringify(value)}`,\n {\n path: element.path,\n diagnostics: `Pattern: ${JSON.stringify(element.pattern)}, Actual: ${JSON.stringify(value)}`,\n },\n ),\n );\n }\n}\n\n// =============================================================================\n// Section 9: extractReferenceType & validateReference\n// =============================================================================\n\n/**\n * Extract the resource type from a FHIR reference string.\n *\n * Handles the following reference formats:\n * - Relative: `\"Patient/123\"` \u2192 `\"Patient\"`\n * - Absolute: `\"http://example.org/fhir/Patient/123\"` \u2192 `\"Patient\"`\n * - URN: `\"urn:uuid:abc-123\"` \u2192 `undefined` (cannot determine type)\n * - Fragment: `\"#contained-1\"` \u2192 `undefined`\n *\n * @param reference - The reference string to parse.\n * @returns The resource type, or `undefined` if it cannot be determined.\n */\nexport function extractReferenceType(reference: string | undefined): string | undefined {\n if (!reference) {\n return undefined;\n }\n\n // Fragment references\n if (reference.startsWith('#')) {\n return undefined;\n }\n\n // URN references\n if (reference.startsWith('urn:')) {\n return undefined;\n }\n\n // Absolute or relative: extract the segment before the last \"/\"\n // e.g., \"Patient/123\" \u2192 \"Patient\"\n // e.g., \"http://example.org/fhir/Patient/123\" \u2192 \"Patient\"\n const parts = reference.split('/');\n\n // Need at least 2 parts: [ResourceType, id]\n if (parts.length < 2) {\n return undefined;\n }\n\n // Walk backwards to find the resource type (first segment that starts with uppercase)\n for (let i = parts.length - 2; i >= 0; i--) {\n const segment = parts[i];\n if (segment.length > 0 && segment[0] >= 'A' && segment[0] <= 'Z') {\n return segment;\n }\n }\n\n return undefined;\n}\n\n/**\n * Validate reference target profile constraints.\n *\n * Checks that a Reference value's target resource type matches at least\n * one of the allowed target profiles defined in the element's type\n * constraints.\n *\n * @param element - The canonical element definition with Reference type constraints.\n * @param value - The actual value (expected to be a Reference object).\n * @param issues - Mutable array to push validation issues into.\n */\nexport function validateReference(\n element: CanonicalElement,\n value: unknown,\n issues: ValidationIssue[],\n): void {\n // Only validate objects that look like References\n if (\n value === null ||\n value === undefined ||\n typeof value !== 'object' ||\n !('reference' in (value as Record<string, unknown>))\n ) {\n return;\n }\n\n const ref = value as { reference?: string; type?: string };\n\n // Collect all targetProfiles from Reference type constraints\n const targetProfiles = element.types\n .filter((t) => t.code === 'Reference')\n .flatMap((t) => t.targetProfiles ?? []);\n\n // No target profile constraints \u2192 any reference is valid\n if (targetProfiles.length === 0) {\n return;\n }\n\n // Extract resource type from the reference string\n const refType = extractReferenceType(ref.reference);\n\n if (!refType) {\n // Cannot determine type (URN, fragment, or invalid format)\n issues.push(\n createValidationIssue(\n 'warning',\n 'REFERENCE_TARGET_MISMATCH',\n `Element '${element.path}': reference format '${ref.reference ?? ''}' cannot be validated against target profiles`,\n { path: element.path },\n ),\n );\n return;\n }\n\n // Check if the reference type matches any target profile\n // Target profiles are canonical URLs like \"http://hl7.org/fhir/StructureDefinition/Patient\"\n const matchesProfile = targetProfiles.some((profile) => {\n // Extract the type name from the profile URL\n const profileType = profile.split('/').pop();\n return profileType === refType;\n });\n\n if (!matchesProfile) {\n const allowedTypes = targetProfiles\n .map((p) => p.split('/').pop() ?? p)\n .join(', ');\n issues.push(\n createValidationIssue(\n 'error',\n 'REFERENCE_TARGET_MISMATCH',\n `Element '${element.path}' reference must target [${allowedTypes}], but found '${refType}'`,\n {\n path: element.path,\n diagnostics: `Reference: ${ref.reference}, allowed target profiles: [${targetProfiles.join(', ')}]`,\n },\n ),\n );\n }\n}\n", "/**\n * fhir-validator \u2014 Slicing Validation\n *\n * Implements slicing validation logic for FHIR array elements:\n * - {@link validateSlicing} \u2014 orchestrates slice matching, cardinality, rules, and ordering\n * - {@link findMatchingSlice} \u2014 matches a value to a named slice via discriminators\n * - {@link matchesDiscriminator} \u2014 checks a single discriminator against a value\n * - {@link isSliceOrderValid} \u2014 validates ordered slicing constraints\n * - {@link extractValueAtPath} \u2014 extracts a nested value from an object using a dot path\n * - {@link getSliceDiscriminatorValue} \u2014 retrieves the expected discriminator value from a slice element\n *\n * @module fhir-validator\n */\n\nimport type { CanonicalElement, SlicingDiscriminatorDef } from '../model/canonical-profile.js';\nimport type { ValidationIssue } from './types.js';\nimport { createValidationIssue } from './types.js';\nimport { validateCardinality, deepEqual, matchesPattern, inferFhirType } from './validation-rules.js';\n\n// =============================================================================\n// Section 1: extractValueAtPath\n// =============================================================================\n\n/**\n * Extract a value from an object using a simple dot-separated path.\n *\n * This is a lightweight path extractor for discriminator evaluation.\n * Unlike the full `extractValues` in path-extractor.ts, this operates\n * on plain objects (not full FHIR resources) and returns a single value.\n *\n * Handles:\n * - Simple dot paths: `\"system\"`, `\"coding.system\"`\n * - `$this` (returns the value itself)\n * - `resolve()` is ignored (returns the value at the preceding path)\n *\n * @param value - The object to extract from.\n * @param path - Dot-separated path (e.g., `\"coding.system\"`).\n * @returns The extracted value, or `undefined` if not found.\n */\nexport function extractValueAtPath(value: unknown, path: string): unknown {\n if (value === null || value === undefined) {\n return undefined;\n }\n\n // $this refers to the value itself\n if (path === '$this') {\n return value;\n }\n\n // Strip resolve() \u2014 we can't actually resolve references here\n const cleanPath = path.replace(/\\.resolve\\(\\)/g, '');\n\n if (cleanPath === '' || cleanPath === '$this') {\n return value;\n }\n\n const segments = cleanPath.split('.');\n let current: unknown = value;\n\n for (const segment of segments) {\n if (current === null || current === undefined) {\n return undefined;\n }\n\n // If current is an array, try to extract from the first element\n // (discriminators typically work on the first matching element)\n if (Array.isArray(current)) {\n if (current.length === 0) return undefined;\n current = current[0];\n }\n\n if (typeof current !== 'object' || current === null) {\n return undefined;\n }\n\n current = (current as Record<string, unknown>)[segment];\n }\n\n return current;\n}\n\n// =============================================================================\n// Section 2: getSliceDiscriminatorValue\n// =============================================================================\n\n/**\n * Get the expected discriminator value from a slice element definition.\n *\n * For a \"value\" discriminator, the expected value comes from the slice's\n * `fixed` or `pattern` constraint. The discriminator path is used to\n * navigate into the fixed/pattern value if it's a complex object.\n *\n * @param slice - The slice element definition.\n * @param discriminatorPath - The discriminator path (e.g., `\"system\"`).\n * @returns The expected value for this discriminator, or `undefined`.\n */\nexport function getSliceDiscriminatorValue(\n slice: CanonicalElement,\n discriminatorPath: string,\n): unknown {\n // Try fixed value first\n if (slice.fixed !== undefined) {\n if (discriminatorPath === '$this') {\n return slice.fixed;\n }\n return extractValueAtPath(slice.fixed, discriminatorPath);\n }\n\n // Try pattern value\n if (slice.pattern !== undefined) {\n if (discriminatorPath === '$this') {\n return slice.pattern;\n }\n return extractValueAtPath(slice.pattern, discriminatorPath);\n }\n\n return undefined;\n}\n\n// =============================================================================\n// Section 3: getSliceTypes\n// =============================================================================\n\n/**\n * Get the expected type codes from a slice element definition.\n *\n * For a \"type\" discriminator, the expected types come from the slice's\n * `types` array.\n *\n * @param slice - The slice element definition.\n * @param _discriminatorPath - The discriminator path (currently unused).\n * @returns Array of expected type code strings.\n */\nexport function getSliceTypes(\n slice: CanonicalElement,\n _discriminatorPath: string,\n): string[] {\n return slice.types.map((t) => t.code);\n}\n\n// =============================================================================\n// Section 4: matchesDiscriminator\n// =============================================================================\n\n/**\n * Check if a value matches a single discriminator for a slice.\n *\n * Supports 4 discriminator types:\n * - `value`: The value at the discriminator path must deeply equal the\n * slice's fixed/pattern value at the same path.\n * - `pattern`: The value at the discriminator path must match the\n * slice's pattern (partial/subset match).\n * - `type`: The inferred FHIR type of the value at the discriminator\n * path must match one of the slice's allowed types.\n * - `exists`: The discriminator path must exist (have a non-undefined value)\n * in the value.\n * - `profile`: Always returns `true` (placeholder \u2014 full profile conformance\n * checking requires context resolution not available here).\n *\n * @param value - The actual value to check.\n * @param slice - The slice element definition.\n * @param discriminator - The discriminator definition.\n * @returns `true` if the value matches this discriminator.\n */\nexport function matchesDiscriminator(\n value: unknown,\n slice: CanonicalElement,\n discriminator: SlicingDiscriminatorDef,\n): boolean {\n const { type, path } = discriminator;\n\n switch (type) {\n case 'value': {\n const actualValue = extractValueAtPath(value, path);\n const expectedValue = getSliceDiscriminatorValue(slice, path);\n if (expectedValue === undefined) {\n // No fixed/pattern constraint on this slice for this path\n return true;\n }\n return deepEqual(actualValue, expectedValue);\n }\n\n case 'pattern': {\n const actualValue = extractValueAtPath(value, path);\n const expectedPattern = getSliceDiscriminatorValue(slice, path);\n if (expectedPattern === undefined) {\n return true;\n }\n return matchesPattern(actualValue, expectedPattern);\n }\n\n case 'type': {\n const actualValue = extractValueAtPath(value, path);\n const actualType = inferFhirType(actualValue);\n const expectedTypes = getSliceTypes(slice, path);\n if (expectedTypes.length === 0) {\n return true;\n }\n return expectedTypes.includes(actualType);\n }\n\n case 'exists': {\n const actualValue = extractValueAtPath(value, path);\n // \"exists\" discriminator: the path must exist (not undefined)\n return actualValue !== undefined;\n }\n\n case 'profile': {\n // Profile conformance checking requires context resolution\n // which is not available at this level. Return true as placeholder.\n return true;\n }\n\n default:\n return false;\n }\n}\n\n// =============================================================================\n// Section 5: findMatchingSlice\n// =============================================================================\n\n/**\n * Find which named slice a value matches based on discriminators.\n *\n * Iterates through the slice elements and checks each discriminator.\n * A value matches a slice if ALL discriminators match.\n *\n * @param value - The actual value to match.\n * @param slices - Array of slice element definitions (must have `sliceName`).\n * @param discriminators - The discriminator definitions from the slicing root.\n * @returns The matching slice element, or `undefined` if no match.\n */\nexport function findMatchingSlice(\n value: unknown,\n slices: CanonicalElement[],\n discriminators: SlicingDiscriminatorDef[],\n): CanonicalElement | undefined {\n for (const slice of slices) {\n if (!slice.sliceName) continue;\n\n let allMatch = true;\n for (const disc of discriminators) {\n if (!matchesDiscriminator(value, slice, disc)) {\n allMatch = false;\n break;\n }\n }\n\n if (allMatch) return slice;\n }\n\n return undefined;\n}\n\n// =============================================================================\n// Section 6: isSliceOrderValid\n// =============================================================================\n\n/**\n * Check if values appear in the correct order according to slice definitions.\n *\n * For ordered slicing, values must appear in the same order as the slice\n * definitions. Values matching slice A must all appear before values\n * matching slice B if slice A is defined before slice B.\n *\n * @param values - The actual values in the array.\n * @param slices - The slice element definitions (in definition order).\n * @param discriminators - The discriminator definitions.\n * @returns `true` if the values are in valid order.\n */\nexport function isSliceOrderValid(\n values: unknown[],\n slices: CanonicalElement[],\n discriminators: SlicingDiscriminatorDef[],\n): boolean {\n // Build a slice index map: sliceName \u2192 position in definition order\n const sliceOrder = new Map<string, number>();\n let orderIndex = 0;\n for (const slice of slices) {\n if (slice.sliceName) {\n sliceOrder.set(slice.sliceName, orderIndex++);\n }\n }\n\n // Track the highest slice index seen so far\n let lastSliceIndex = -1;\n\n for (const value of values) {\n const matched = findMatchingSlice(value, slices, discriminators);\n if (!matched || !matched.sliceName) {\n // Unmatched values don't affect ordering\n continue;\n }\n\n const currentIndex = sliceOrder.get(matched.sliceName) ?? -1;\n if (currentIndex < lastSliceIndex) {\n return false; // Out of order\n }\n lastSliceIndex = currentIndex;\n }\n\n return true;\n}\n\n// =============================================================================\n// Section 7: validateSlicing\n// =============================================================================\n\n/**\n * Validate slicing constraints for an array element.\n *\n * Performs the following checks:\n * 1. **Slice matching** \u2014 each value is matched to a named slice via discriminators.\n * 2. **Slice cardinality** \u2014 each slice's min/max is checked against matched values.\n * 3. **Slicing rules** \u2014 for `closed` slicing, unmatched values produce errors.\n * For `openAtEnd`, unmatched values must appear after all matched values.\n * 4. **Ordering** \u2014 for `ordered` slicing, matched values must appear in\n * slice definition order.\n *\n * @param slicingRoot - The element with the slicing definition.\n * @param sliceElements - The named slice element definitions.\n * @param values - The actual values in the array.\n * @param issues - Mutable array to push validation issues into.\n */\nexport function validateSlicing(\n slicingRoot: CanonicalElement,\n sliceElements: CanonicalElement[],\n values: unknown[],\n issues: ValidationIssue[],\n): void {\n if (!slicingRoot.slicing) {\n return;\n }\n\n const { discriminators, rules, ordered } = slicingRoot.slicing;\n\n // Step 1: Match each value to a slice\n const sliceMatches = new Map<string, unknown[]>();\n const unmatchedValues: unknown[] = [];\n const unmatchedIndices: number[] = [];\n let lastMatchedIndex = -1;\n\n for (let i = 0; i < values.length; i++) {\n const value = values[i];\n const matchedSlice = findMatchingSlice(value, sliceElements, discriminators);\n\n if (matchedSlice && matchedSlice.sliceName) {\n const sliceName = matchedSlice.sliceName;\n if (!sliceMatches.has(sliceName)) {\n sliceMatches.set(sliceName, []);\n }\n sliceMatches.get(sliceName)!.push(value);\n lastMatchedIndex = i;\n } else {\n unmatchedValues.push(value);\n unmatchedIndices.push(i);\n }\n }\n\n // Step 2: Validate slice cardinality\n for (const slice of sliceElements) {\n if (!slice.sliceName) continue;\n const sliceValues = sliceMatches.get(slice.sliceName) ?? [];\n validateCardinality(slice, sliceValues, issues);\n }\n\n // Step 3: Check slicing rules\n if (rules === 'closed' && unmatchedValues.length > 0) {\n issues.push(\n createValidationIssue(\n 'error',\n 'SLICING_NO_MATCH',\n `Slicing at '${slicingRoot.path}' is closed, but ${unmatchedValues.length} value(s) do not match any defined slice`,\n {\n path: slicingRoot.path,\n diagnostics: `Unmatched value count: ${unmatchedValues.length}`,\n },\n ),\n );\n }\n\n if (rules === 'openAtEnd' && unmatchedValues.length > 0) {\n // For openAtEnd, unmatched values must appear AFTER all matched values\n const hasUnmatchedBeforeMatched = unmatchedIndices.some(\n (idx) => idx < lastMatchedIndex,\n );\n if (hasUnmatchedBeforeMatched) {\n issues.push(\n createValidationIssue(\n 'error',\n 'SLICING_NO_MATCH',\n `Slicing at '${slicingRoot.path}' is openAtEnd, but unmatched values appear before matched slice values`,\n {\n path: slicingRoot.path,\n diagnostics: `Unmatched values must appear after all slice-matched values`,\n },\n ),\n );\n }\n }\n\n // Step 4: Check ordering\n if (ordered && !isSliceOrderValid(values, sliceElements, discriminators)) {\n issues.push(\n createValidationIssue(\n 'error',\n 'SLICING_ORDER_VIOLATION',\n `Slicing at '${slicingRoot.path}' requires ordered slices, but values are out of order`,\n {\n path: slicingRoot.path,\n diagnostics: `Values must appear in the same order as slice definitions`,\n },\n ),\n );\n }\n}\n", "/**\n * fhir-validator \u2014 Error Types\n *\n * Structured error hierarchy for the FHIR validator module.\n * All errors extend {@link ValidatorError} so consumers can catch\n * validator-related failures with a single `catch` clause.\n *\n * Error hierarchy:\n * ```\n * ValidatorError (base)\n * \u251C\u2500\u2500 ProfileNotFoundError\n * \u2514\u2500\u2500 ValidationFailedError\n * ```\n *\n * @module fhir-validator\n */\n\nimport type { ValidationIssue } from './types.js';\n\n// =============================================================================\n// Section 1: Base Error\n// =============================================================================\n\n/**\n * Base error class for all fhir-validator failures.\n *\n * Provides a stable `name` property and preserves the original `cause`\n * when wrapping lower-level errors.\n *\n * @example\n * ```typescript\n * try {\n * await validator.validate(resource);\n * } catch (err) {\n * if (err instanceof ValidatorError) {\n * // Handle any validator-related error\n * }\n * }\n * ```\n */\nexport class ValidatorError extends Error {\n override readonly name: string = 'ValidatorError';\n\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n // Restore prototype chain (required for `instanceof` after transpilation)\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n// =============================================================================\n// Section 2: ProfileNotFoundError\n// =============================================================================\n\n/**\n * Thrown when the profile required for validation cannot be found or loaded.\n *\n * This occurs when:\n * - The specified `profileUrl` does not exist in the FhirContext\n * - The profile exists but has no snapshot\n * - No profile URL is specified and none can be inferred from the resource\n *\n * @example\n * ```typescript\n * throw new ProfileNotFoundError(\n * 'http://example.org/StructureDefinition/UnknownProfile',\n * );\n * ```\n */\nexport class ProfileNotFoundError extends ValidatorError {\n override readonly name = 'ProfileNotFoundError';\n\n /** The canonical URL of the profile that could not be found. */\n readonly profileUrl: string;\n\n constructor(profileUrl: string, cause?: Error) {\n super(\n `Profile not found: ${profileUrl}`,\n cause ? { cause } : undefined,\n );\n this.profileUrl = profileUrl;\n }\n}\n\n// =============================================================================\n// Section 3: ValidationFailedError\n// =============================================================================\n\n/**\n * Thrown when validation fails and {@link ValidationOptions.failFast} is enabled.\n *\n * Contains the issues accumulated up to the point of failure. This allows\n * callers to inspect the first error(s) that triggered the failure.\n *\n * @example\n * ```typescript\n * try {\n * await validator.validate(resource, { failFast: true });\n * } catch (err) {\n * if (err instanceof ValidationFailedError) {\n * console.error('First error:', err.issues[0].message);\n * }\n * }\n * ```\n */\nexport class ValidationFailedError extends ValidatorError {\n override readonly name = 'ValidationFailedError';\n\n /** The validation issues accumulated before failure. */\n readonly issues: readonly ValidationIssue[];\n\n constructor(message: string, issues: readonly ValidationIssue[], cause?: Error) {\n super(\n message,\n cause ? { cause } : undefined,\n );\n this.issues = issues;\n }\n}\n", "/**\n * FHIRPath Core Types\n *\n * Defines the fundamental types used throughout the FHIRPath engine:\n * - {@link TypedValue} \u2014 A value paired with its FHIR type\n * - {@link PropertyType} \u2014 Enum of all FHIR property types\n * - {@link Atom} \u2014 AST node interface for parsed expressions\n * - {@link AtomContext} \u2014 Evaluation context with variable scoping\n *\n * @module fhirpath\n */\n\n// =============================================================================\n// PropertyType \u2014 FHIR type identifiers\n// =============================================================================\n\n/**\n * Enum of FHIR property type identifiers used in {@link TypedValue}.\n * Covers all FHIR R4 primitive types and commonly used complex types.\n */\nexport const PropertyType = {\n // Primitives\n boolean: 'boolean',\n integer: 'integer',\n decimal: 'decimal',\n string: 'string',\n uri: 'uri',\n url: 'url',\n canonical: 'canonical',\n base64Binary: 'base64Binary',\n instant: 'instant',\n date: 'date',\n dateTime: 'dateTime',\n time: 'time',\n code: 'code',\n oid: 'oid',\n id: 'id',\n markdown: 'markdown',\n unsignedInt: 'unsignedInt',\n positiveInt: 'positiveInt',\n uuid: 'uuid',\n xhtml: 'xhtml',\n\n // Complex types\n BackboneElement: 'BackboneElement',\n CodeableConcept: 'CodeableConcept',\n Coding: 'Coding',\n Quantity: 'Quantity',\n Reference: 'Reference',\n Period: 'Period',\n Identifier: 'Identifier',\n HumanName: 'HumanName',\n Address: 'Address',\n ContactPoint: 'ContactPoint',\n Attachment: 'Attachment',\n Extension: 'Extension',\n} as const;\n\nexport type PropertyType = (typeof PropertyType)[keyof typeof PropertyType];\n\n// =============================================================================\n// TypedValue \u2014 A value with its FHIR type\n// =============================================================================\n\n/**\n * A value paired with its FHIR type identifier.\n * This is the fundamental unit of data flowing through the FHIRPath engine.\n *\n * @example\n * ```ts\n * const tv: TypedValue = { type: PropertyType.string, value: 'hello' };\n * ```\n */\nexport interface TypedValue {\n readonly type: string;\n readonly value: unknown;\n}\n\n// =============================================================================\n// AtomContext \u2014 Evaluation context with variable scoping\n// =============================================================================\n\n/**\n * Evaluation context for FHIRPath expressions.\n * Supports nested scoping via the `parent` chain, used by functions\n * like `where()` and `select()` that introduce `$this`.\n */\nexport interface AtomContext {\n readonly parent?: AtomContext;\n readonly variables: Record<string, TypedValue>;\n}\n\n// =============================================================================\n// Atom \u2014 AST node interface\n// =============================================================================\n\n/**\n * Interface for all AST nodes in the FHIRPath expression tree.\n * Each node can evaluate itself given a context and input collection.\n */\nexport interface Atom {\n /**\n * Evaluate this atom against the given input collection.\n * @param context - The evaluation context (variables, parent scope).\n * @param input - The input collection of typed values.\n * @returns The result collection.\n */\n eval(context: AtomContext, input: TypedValue[]): TypedValue[];\n\n /** Returns a string representation of this atom (for debugging). */\n toString(): string;\n}\n\n// =============================================================================\n// Abstract base classes for operator atoms\n// =============================================================================\n\n/**\n * Base class for prefix (unary) operator atoms.\n * Examples: unary `-`, unary `+`\n */\nexport abstract class PrefixOperatorAtom implements Atom {\n readonly operator: string;\n readonly child: Atom;\n\n constructor(operator: string, child: Atom) {\n this.operator = operator;\n this.child = child;\n }\n\n abstract eval(context: AtomContext, input: TypedValue[]): TypedValue[];\n\n toString(): string {\n return `${this.operator}(${this.child.toString()})`;\n }\n}\n\n/**\n * Base class for infix (binary) operator atoms.\n * Examples: `+`, `-`, `=`, `and`, `or`\n */\nexport abstract class InfixOperatorAtom implements Atom {\n readonly operator: string;\n readonly left: Atom;\n readonly right: Atom;\n\n constructor(operator: string, left: Atom, right: Atom) {\n this.operator = operator;\n this.left = left;\n this.right = right;\n }\n\n abstract eval(context: AtomContext, input: TypedValue[]): TypedValue[];\n\n toString(): string {\n return `(${this.left.toString()} ${this.operator} ${this.right.toString()})`;\n }\n}\n", "/**\n * Generic Pratt Parser Framework\n *\n * A top-down operator precedence parser based on\n * {@link https://github.com/JacksonKearl/PrattParse | PrattParse}.\n *\n * The parser uses two kinds of \"parselets\":\n * - **PrefixParselet** \u2014 handles tokens that appear at the start of an expression\n * (literals, identifiers, unary operators, parenthesised groups)\n * - **InfixParselet** \u2014 handles tokens that appear between two expressions\n * (binary operators, function calls, indexers)\n *\n * @module fhirpath/lexer\n */\n\nimport type { Atom } from '../types.js';\nimport type { Token } from './tokenize.js';\n\n// =============================================================================\n// Parselet interfaces\n// =============================================================================\n\n/**\n * A parselet that handles a token appearing in prefix position.\n */\nexport interface PrefixParselet {\n parse(parser: Parser, token: Token): Atom;\n}\n\n/**\n * A parselet that handles a token appearing in infix position.\n * `precedence` controls how tightly this operator binds.\n */\nexport interface InfixParselet {\n precedence: number;\n parse?(parser: Parser, left: Atom, token: Token): Atom;\n}\n\n// =============================================================================\n// ParserBuilder \u2014 fluent API for registering parselets\n// =============================================================================\n\n/**\n * Fluent builder for constructing a {@link Parser} with registered parselets.\n *\n * @example\n * ```ts\n * const builder = new ParserBuilder()\n * .registerPrefix('Number', { parse: (_, token) => new LiteralAtom(...) })\n * .infixLeft('+', 5, (left, _, right) => new AddAtom(left, right));\n *\n * const parser = builder.construct(tokens);\n * const ast = parser.consumeAndParse();\n * ```\n */\nexport class ParserBuilder {\n private readonly prefixParselets: Record<string, PrefixParselet> = {};\n private readonly infixParselets: Record<string, InfixParselet> = {};\n\n public registerInfix(tokenType: string, parselet: InfixParselet): this {\n this.infixParselets[tokenType] = parselet;\n return this;\n }\n\n public registerPrefix(tokenType: string, parselet: PrefixParselet): this {\n this.prefixParselets[tokenType] = parselet;\n return this;\n }\n\n /**\n * Register a prefix operator with a given precedence.\n * The builder callback receives the consumed token and the right-hand operand.\n */\n public prefix(tokenType: string, precedence: number, builder: (token: Token, right: Atom) => Atom): this {\n return this.registerPrefix(tokenType, {\n parse(parser, token) {\n const right = parser.consumeAndParse(precedence);\n return builder(token, right);\n },\n });\n }\n\n /**\n * Register a left-associative infix operator with a given precedence.\n * The builder callback receives left operand, the consumed token, and right operand.\n */\n public infixLeft(\n tokenType: string,\n precedence: number,\n builder: (left: Atom, token: Token, right: Atom) => Atom,\n ): this {\n return this.registerInfix(tokenType, {\n parse(parser, left, token) {\n const right = parser.consumeAndParse(precedence);\n return builder(left, token, right);\n },\n precedence,\n });\n }\n\n /** Construct a {@link Parser} from the given token stream. */\n public construct(input: Token[]): Parser {\n return new Parser(input, this.prefixParselets, this.infixParselets);\n }\n}\n\n// =============================================================================\n// Parser \u2014 Pratt parser core\n// =============================================================================\n\n/**\n * Pratt parser that converts a token stream into an AST of {@link Atom} nodes.\n */\nexport class Parser {\n private tokens: Token[];\n private readonly prefixParselets: Record<string, PrefixParselet>;\n private readonly infixParselets: Record<string, InfixParselet>;\n\n constructor(\n tokens: Token[],\n prefixParselets: Record<string, PrefixParselet>,\n infixParselets: Record<string, InfixParselet>,\n ) {\n this.tokens = tokens;\n this.prefixParselets = prefixParselets;\n this.infixParselets = infixParselets;\n }\n\n /** Returns true if there are more tokens to consume. */\n hasMore(): boolean {\n return this.tokens.length > 0;\n }\n\n /**\n * If the next token has the expected `id`, consume it and return `true`.\n * Otherwise return `false` without consuming.\n */\n match(expected: string): boolean {\n const token = this.peek();\n if (token?.id !== expected) {\n return false;\n }\n this.consume();\n return true;\n }\n\n /**\n * Core Pratt parsing loop.\n * Consumes one prefix token, then continues consuming infix tokens\n * as long as their precedence is lower (tighter) than the given threshold.\n *\n * @param precedence - The precedence ceiling (default: `Infinity` = parse everything).\n * @returns The parsed AST node.\n */\n consumeAndParse(precedence = Infinity): Atom {\n const token = this.consume();\n const prefix = this.prefixParselets[token.id];\n if (!prefix) {\n throw new Error(\n `Parse error at \"${token.value}\" (line ${token.line}, column ${token.column}). No matching prefix parselet.`,\n );\n }\n\n let left = prefix.parse(this, token);\n\n while (precedence > this.getPrecedence()) {\n const next = this.consume();\n const infix = this.getInfixParselet(next) as InfixParselet;\n left = (infix.parse as (parser: Parser, left: Atom, token: Token) => Atom)(this, left, next);\n }\n\n return left;\n }\n\n /** Returns the precedence of the next infix parselet, or `Infinity` if none. */\n getPrecedence(): number {\n const nextToken = this.peek();\n if (!nextToken) {\n return Infinity;\n }\n const parser = this.getInfixParselet(nextToken);\n if (parser) {\n return parser.precedence;\n }\n return Infinity;\n }\n\n /**\n * Consume the next token, optionally asserting its `id` and/or `value`.\n * Throws if no tokens remain or if the assertion fails.\n */\n consume(expectedId?: string, expectedValue?: string): Token {\n if (!this.tokens.length) {\n throw new Error('Cant consume unknown more tokens.');\n }\n if (expectedId && this.peek()?.id !== expectedId) {\n const actual = this.peek() as Token;\n throw new Error(\n `Expected ${expectedId} but got \"${actual.id}\" (${actual.value}) at line ${actual.line} column ${actual.column}.`,\n );\n }\n if (expectedValue && this.peek()?.value !== expectedValue) {\n const actual = this.peek() as Token;\n throw new Error(\n `Expected \"${expectedValue}\" but got \"${actual.value}\" at line ${actual.line} column ${actual.column}.`,\n );\n }\n return this.tokens.shift() as Token;\n }\n\n /** Peek at the next token without consuming it. */\n peek(): Token | undefined {\n return this.tokens.length > 0 ? this.tokens[0] : undefined;\n }\n\n /** Remove all Comment tokens from the stream. */\n removeComments(): void {\n this.tokens = this.tokens.filter((t) => t.id !== 'Comment');\n }\n\n /** Look up the infix parselet for a token (by id, or by value for Symbols). */\n getInfixParselet(token: Token): InfixParselet | undefined {\n return this.infixParselets[token.id === 'Symbol' ? token.value : token.id];\n }\n}\n", "/**\n * FHIRPath utility functions.\n *\n * Provides type conversion, equality/equivalence comparison,\n * and helper functions used by atoms and the function library.\n *\n * @module fhirpath\n */\n\nimport type { Quantity } from '../model/primitives.js';\nimport type { TypedValue } from './types.js';\nimport { PropertyType } from './types.js';\n\n// =============================================================================\n// TypedValue constructors\n// =============================================================================\n\n/**\n * Returns a single-element array with a typed boolean value.\n */\nexport function booleanToTypedValue(value: boolean): [TypedValue] {\n return [{ type: PropertyType.boolean, value }];\n}\n\n/**\n * Returns a \"best guess\" TypedValue for a given unknown value.\n */\nexport function toTypedValue(value: unknown): TypedValue {\n if (value === null || value === undefined) {\n return { type: 'undefined', value: undefined };\n } else if (Number.isSafeInteger(value)) {\n return { type: PropertyType.integer, value };\n } else if (typeof value === 'number') {\n return { type: PropertyType.decimal, value };\n } else if (typeof value === 'boolean') {\n return { type: PropertyType.boolean, value };\n } else if (typeof value === 'string') {\n return { type: PropertyType.string, value };\n } else if (isQuantity(value)) {\n return { type: PropertyType.Quantity, value };\n } else if (isResource(value)) {\n return { type: (value as Record<string, unknown>).resourceType as string, value };\n } else {\n return { type: PropertyType.BackboneElement, value };\n }\n}\n\n// =============================================================================\n// Boolean conversion\n// =============================================================================\n\n/**\n * Converts a TypedValue collection to a JavaScript boolean.\n * Empty collection \u2192 false; otherwise truthy check on first element.\n */\nexport function toJsBoolean(obj: TypedValue[]): boolean {\n return obj.length === 0 ? false : !!obj[0].value;\n}\n\n// =============================================================================\n// Singleton\n// =============================================================================\n\n/**\n * Returns the single element from a collection, or undefined if empty.\n * Throws if the collection has more than one element.\n */\nexport function singleton(collection: TypedValue[], type?: string): TypedValue | undefined {\n if (collection.length === 0) {\n return undefined;\n } else if (collection.length === 1 && (!type || collection[0].type === type)) {\n return collection[0];\n } else {\n throw new Error(`Expected singleton of type ${type}, but found ${JSON.stringify(collection)}`);\n }\n}\n\n// =============================================================================\n// Property value extraction (schema-free)\n// =============================================================================\n\n/**\n * Extract a typed property value from a TypedValue without schema.\n * Handles simple paths and choice-type paths (value[x]).\n */\nexport function getTypedPropertyValue(input: TypedValue, path: string): TypedValue[] | TypedValue | undefined {\n const obj = input.value;\n if (!obj || typeof obj !== 'object') {\n return undefined;\n }\n\n const record = obj as Record<string, unknown>;\n\n // Direct property access\n if (path in record) {\n const propertyValue = record[path];\n if (Array.isArray(propertyValue)) {\n return propertyValue.map(toTypedValue);\n }\n return toTypedValue(propertyValue);\n }\n\n // Choice-type resolution: try path + capitalized type name\n const trimmedPath = path.endsWith('[x]') ? path.substring(0, path.length - 3) : path;\n for (const propertyType of Object.values(PropertyType)) {\n const propertyName = trimmedPath + capitalize(propertyType);\n if (propertyName in record) {\n const propertyValue = record[propertyName];\n if (Array.isArray(propertyValue)) {\n return propertyValue.map((v) => ({ type: propertyType, value: v }));\n }\n return { type: propertyType, value: propertyValue };\n }\n }\n\n return undefined;\n}\n\n// =============================================================================\n// FHIRPath equality\n// =============================================================================\n\n/**\n * FHIRPath equality comparison for two TypedValue elements.\n * Returns `[{type:'boolean', value:true/false}]` or `[]` for incomparable.\n */\nexport function fhirPathEquals(x: TypedValue, y: TypedValue): TypedValue[] {\n const xValue = x.value?.valueOf();\n const yValue = y.value?.valueOf();\n if (typeof xValue === 'number' && typeof yValue === 'number') {\n return booleanToTypedValue(Math.abs(xValue - yValue) < 1e-8);\n }\n if (isQuantity(xValue) && isQuantity(yValue)) {\n return booleanToTypedValue(isQuantityEquivalent(xValue as Quantity, yValue as Quantity));\n }\n if (typeof xValue === 'object' && typeof yValue === 'object') {\n return booleanToTypedValue(deepEquals(xValue as object, yValue as object));\n }\n return booleanToTypedValue(xValue === yValue);\n}\n\n/**\n * FHIRPath array equality: both arrays must have same length and pairwise equal elements.\n * Returns `[]` if either side is empty.\n */\nexport function fhirPathArrayEquals(x: TypedValue[], y: TypedValue[]): TypedValue[] {\n if (x.length === 0 || y.length === 0) {\n return [];\n }\n if (x.length !== y.length) {\n return booleanToTypedValue(false);\n }\n return booleanToTypedValue(x.every((val, index) => toJsBoolean(fhirPathEquals(val, y[index]))));\n}\n\n/**\n * FHIRPath array not-equals.\n */\nexport function fhirPathArrayNotEquals(x: TypedValue[], y: TypedValue[]): TypedValue[] {\n if (x.length === 0 || y.length === 0) {\n return [];\n }\n if (x.length !== y.length) {\n return booleanToTypedValue(true);\n }\n return booleanToTypedValue(x.some((val, index) => !toJsBoolean(fhirPathEquals(val, y[index]))));\n}\n\n// =============================================================================\n// FHIRPath equivalence\n// =============================================================================\n\n/**\n * FHIRPath equivalence comparison for two TypedValue elements.\n * More lenient than equality (case-insensitive strings, rounded decimals, etc.).\n */\nexport function fhirPathEquivalent(x: TypedValue, y: TypedValue): TypedValue[] {\n const xValue = x.value?.valueOf();\n const yValue = y.value?.valueOf();\n\n if (typeof xValue === 'number' && typeof yValue === 'number') {\n return booleanToTypedValue(Math.abs(xValue - yValue) < 0.01);\n }\n if (isQuantity(xValue) && isQuantity(yValue)) {\n return booleanToTypedValue(isQuantityEquivalent(xValue as Quantity, yValue as Quantity));\n }\n if (typeof xValue === 'object' && typeof yValue === 'object') {\n return booleanToTypedValue(deepEquals(xValue as object, yValue as object));\n }\n if (typeof xValue === 'string' && typeof yValue === 'string') {\n return booleanToTypedValue(xValue.toLowerCase() === yValue.toLowerCase());\n }\n return booleanToTypedValue(xValue === yValue);\n}\n\n/**\n * FHIRPath array equivalence: sorted pairwise equivalence.\n */\nexport function fhirPathArrayEquivalent(x: TypedValue[], y: TypedValue[]): TypedValue[] {\n if (x.length === 0 && y.length === 0) {\n return booleanToTypedValue(true);\n }\n if (x.length !== y.length) {\n return booleanToTypedValue(false);\n }\n const xs = [...x].sort(fhirPathEquivalentCompare);\n const ys = [...y].sort(fhirPathEquivalentCompare);\n return booleanToTypedValue(xs.every((val, index) => toJsBoolean(fhirPathEquivalent(val, ys[index]))));\n}\n\n// =============================================================================\n// FHIRPath negation & deduplication\n// =============================================================================\n\n/**\n * Negate a FHIRPath boolean result.\n */\nexport function fhirPathNot(input: TypedValue[]): TypedValue[] {\n return booleanToTypedValue(!toJsBoolean(input));\n}\n\n/**\n * Remove duplicates using FHIRPath equality rules.\n */\nexport function removeDuplicates(arr: TypedValue[]): TypedValue[] {\n const result: TypedValue[] = [];\n for (const i of arr) {\n let found = false;\n for (const j of result) {\n if (toJsBoolean(fhirPathEquals(i, j))) {\n found = true;\n break;\n }\n }\n if (!found) {\n result.push(i);\n }\n }\n return result;\n}\n\n// =============================================================================\n// FHIRPath `is` type checking\n// =============================================================================\n\n/**\n * Determines if a typed value matches the desired FHIRPath type name.\n */\nexport function fhirPathIs(typedValue: TypedValue, desiredType: string): boolean {\n const { value } = typedValue;\n if (value === undefined || value === null) {\n return false;\n }\n\n let cleanType = desiredType;\n if (cleanType.startsWith('System.')) {\n cleanType = cleanType.substring('System.'.length);\n }\n if (cleanType.startsWith('FHIR.')) {\n cleanType = cleanType.substring('FHIR.'.length);\n }\n\n switch (cleanType) {\n case 'Boolean':\n return typeof value === 'boolean';\n case 'Decimal':\n case 'Integer':\n return typeof value === 'number';\n case 'Date':\n return typeof value === 'string' && /^\\d{4}(-\\d{2}(-\\d{2})?)?$/.test(value);\n case 'DateTime':\n return typeof value === 'string' && /^\\d{4}/.test(value) && value.length > 10;\n case 'Time':\n return typeof value === 'string' && /^T\\d/.test(value);\n case 'Quantity':\n return isQuantity(value);\n case 'String':\n return typeof value === 'string';\n default:\n return typedValue.type === cleanType ||\n (typeof value === 'object' && value !== null && (value as Record<string, unknown>).resourceType === cleanType);\n }\n}\n\n// =============================================================================\n// Type guards\n// =============================================================================\n\n/**\n * Heuristic check for Quantity objects.\n */\nexport function isQuantity(input: unknown): input is Quantity {\n return !!(input && typeof input === 'object' && 'value' in input && typeof (input as Quantity).value === 'number');\n}\n\n/**\n * Heuristic check for FHIR Resource objects.\n */\nexport function isResource(input: unknown): boolean {\n return !!(input && typeof input === 'object' && 'resourceType' in input && typeof (input as Record<string, unknown>).resourceType === 'string');\n}\n\n/**\n * Check if a value is a FHIR Resource with a specific resourceType.\n */\nexport function isResourceType(input: unknown, resourceType: string): boolean {\n return isResource(input) && (input as Record<string, unknown>).resourceType === resourceType;\n}\n\n// =============================================================================\n// Internal helpers\n// =============================================================================\n\nfunction isQuantityEquivalent(x: Quantity, y: Quantity): boolean {\n return (\n Math.abs((x.value as number) - (y.value as number)) < 0.01 &&\n (x.unit === y.unit || x.code === y.code || x.unit === y.code || x.code === y.unit)\n );\n}\n\nfunction fhirPathEquivalentCompare(x: TypedValue, y: TypedValue): number {\n const xValue = x.value?.valueOf();\n const yValue = y.value?.valueOf();\n if (typeof xValue === 'number' && typeof yValue === 'number') {\n return xValue - yValue;\n }\n if (typeof xValue === 'string' && typeof yValue === 'string') {\n return xValue.localeCompare(yValue);\n }\n return 0;\n}\n\nfunction deepEquals(object1: object, object2: object): boolean {\n const keys1 = Object.keys(object1);\n const keys2 = Object.keys(object2);\n if (keys1.length !== keys2.length) {\n return false;\n }\n for (const key of keys1) {\n const val1 = (object1 as Record<string, unknown>)[key];\n const val2 = (object2 as Record<string, unknown>)[key];\n if (isObject(val1) && isObject(val2)) {\n if (!deepEquals(val1, val2)) {\n return false;\n }\n } else if (val1 !== val2) {\n return false;\n }\n }\n return true;\n}\n\nfunction isObject(obj: unknown): obj is object {\n return obj !== null && typeof obj === 'object';\n}\n\nfunction capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n", "/**\n * FHIRPath AST Node Classes (Atoms)\n *\n * Each class implements the {@link Atom} interface and represents a node\n * in the parsed FHIRPath expression tree.\n *\n * **Basic atoms** (Task 6.2):\n * - {@link FhirPathAtom} \u2014 Root wrapper\n * - {@link LiteralAtom} \u2014 String, number, boolean, DateTime, Quantity literals\n * - {@link SymbolAtom} \u2014 Identifiers and variables (`$this`, `%context`)\n * - {@link EmptySetAtom} \u2014 The empty set `{}`\n * - {@link UnaryOperatorAtom} \u2014 Unary `+` and `-`\n * - {@link DotAtom} \u2014 Property navigation (`.`)\n * - {@link FunctionAtom} \u2014 Function calls (`where()`, `exists()`, etc.)\n * - {@link IndexerAtom} \u2014 Indexer access (`[0]`)\n *\n * **Operator atoms** (Task 6.3):\n * - {@link ArithmeticOperatorAtom} \u2014 `+`, `-`, `*`, `/`, `div`, `mod`\n * - {@link ConcatAtom} \u2014 String concatenation `&`\n * - {@link UnionAtom} \u2014 Collection union `|`\n * - {@link EqualsAtom} / {@link NotEqualsAtom} \u2014 `=`, `!=`\n * - {@link EquivalentAtom} / {@link NotEquivalentAtom} \u2014 `~`, `!~`\n * - {@link IsAtom} / {@link AsAtom} \u2014 Type operators\n * - {@link ContainsAtom} / {@link InAtom} \u2014 Membership operators\n * - {@link AndAtom} / {@link OrAtom} / {@link XorAtom} / {@link ImpliesAtom} \u2014 Boolean operators\n *\n * @module fhirpath\n */\n\nimport type { Atom, AtomContext, TypedValue } from './types.js';\nimport { InfixOperatorAtom, PrefixOperatorAtom, PropertyType } from './types.js';\nimport {\n booleanToTypedValue,\n fhirPathArrayEquals,\n fhirPathArrayEquivalent,\n fhirPathArrayNotEquals,\n fhirPathEquals,\n fhirPathIs,\n fhirPathNot,\n getTypedPropertyValue,\n isQuantity,\n isResourceType,\n removeDuplicates,\n singleton,\n toJsBoolean,\n toTypedValue,\n} from './utils.js';\n\n// =============================================================================\n// Basic Atoms (Task 6.2)\n// =============================================================================\n\n/**\n * Root wrapper atom for a parsed FHIRPath expression.\n * Iterates over each input element, setting `$this` for each evaluation.\n */\nexport class FhirPathAtom implements Atom {\n readonly original: string;\n readonly child: Atom;\n\n constructor(original: string, child: Atom) {\n this.original = original;\n this.child = child;\n }\n\n eval(context: AtomContext, input: TypedValue[]): TypedValue[] {\n try {\n if (input.length > 0) {\n const result: TypedValue[][] = [];\n for (const e of input) {\n result.push(this.child.eval({ parent: context, variables: { $this: e } }, [e]));\n }\n return result.flat();\n } else {\n return this.child.eval(context, []);\n }\n } catch (error) {\n throw new Error(`FhirPathError on \"${this.original}\": ${error}`, { cause: error });\n }\n }\n\n toString(): string {\n return this.child.toString();\n }\n}\n\n/**\n * Literal value atom (string, number, boolean, DateTime, Quantity).\n */\nexport class LiteralAtom implements Atom {\n public readonly value: TypedValue;\n\n constructor(value: TypedValue) {\n this.value = value;\n }\n\n eval(): TypedValue[] {\n return [this.value];\n }\n\n toString(): string {\n const value = this.value.value;\n if (typeof value === 'string') {\n return `'${value}'`;\n }\n return String(value);\n }\n}\n\n/**\n * Symbol atom \u2014 identifiers, variables (`$this`, `%context`), and resource type names.\n */\nexport class SymbolAtom implements Atom {\n readonly name: string;\n\n constructor(name: string) {\n this.name = name;\n }\n\n eval(context: AtomContext, input: TypedValue[]): TypedValue[] {\n if (this.name === '$this') {\n return input;\n }\n const variableValue = this.getVariable(context);\n if (variableValue) {\n return [variableValue];\n }\n if (this.name.startsWith('%')) {\n throw new Error(`Undefined variable ${this.name}`);\n }\n return input.flatMap((e) => this.evalValue(e)).filter((e): e is TypedValue => e?.value !== undefined);\n }\n\n private getVariable(context: AtomContext): TypedValue | undefined {\n const value = context.variables[this.name];\n if (value !== undefined) {\n return value;\n }\n if (context.parent) {\n return this.getVariable(context.parent);\n }\n return undefined;\n }\n\n private evalValue(typedValue: TypedValue): TypedValue[] | TypedValue | undefined {\n const input = typedValue.value;\n if (!input || typeof input !== 'object') {\n return undefined;\n }\n\n // Check if input is a resource matching this symbol name\n if (isResourceType(input, this.name)) {\n return typedValue;\n }\n\n // Navigate into the property\n const result = getTypedPropertyValue(typedValue, this.name);\n if (result === undefined) {\n return undefined;\n }\n if (Array.isArray(result)) {\n return result;\n }\n return result;\n }\n\n toString(): string {\n return this.name;\n }\n}\n\n/**\n * Empty set atom \u2014 represents `{}`.\n */\nexport class EmptySetAtom implements Atom {\n eval(): TypedValue[] {\n return [];\n }\n\n toString(): string {\n return '{}';\n }\n}\n\n/**\n * Unary operator atom (prefix `+` and `-`).\n */\nexport class UnaryOperatorAtom extends PrefixOperatorAtom {\n readonly impl: (x: TypedValue[]) => TypedValue[];\n\n constructor(operator: string, child: Atom, impl: (x: TypedValue[]) => TypedValue[]) {\n super(operator, child);\n this.impl = impl;\n }\n\n eval(context: AtomContext, input: TypedValue[]): TypedValue[] {\n return this.impl(this.child.eval(context, input));\n }\n\n toString(): string {\n return this.operator + this.child.toString();\n }\n}\n\n/**\n * Dot (property navigation) atom.\n * Evaluates left, then feeds result as input to right.\n */\nexport class DotAtom extends InfixOperatorAtom {\n constructor(left: Atom, right: Atom) {\n super('.', left, right);\n }\n\n eval(context: AtomContext, input: TypedValue[]): TypedValue[] {\n return this.right.eval(context, this.left.eval(context, input));\n }\n\n toString(): string {\n return `${this.left.toString()}.${this.right.toString()}`;\n }\n}\n\n/**\n * Function call atom.\n * Delegates to the function registry at evaluation time.\n */\nexport class FunctionAtom implements Atom {\n readonly name: string;\n readonly args: Atom[];\n\n constructor(name: string, args: Atom[]) {\n this.name = name;\n this.args = args;\n }\n\n eval(context: AtomContext, input: TypedValue[]): TypedValue[] {\n // Functions are resolved at eval time via the global registry.\n // This will be wired in parse.ts via the functions import.\n const impl = getFunctionImpl(this.name);\n if (!impl) {\n throw new Error('Unrecognized function: ' + this.name);\n }\n return impl(context, input, ...this.args);\n }\n\n toString(): string {\n return `${this.name}(${this.args.map((arg) => arg.toString()).join(', ')})`;\n }\n}\n\n// Function registry \u2014 set by parse.ts to avoid circular imports\nlet _functionRegistry: Record<string, FhirPathFunction> | undefined;\n\nexport type FhirPathFunction = (context: AtomContext, input: TypedValue[], ...args: Atom[]) => TypedValue[];\n\nexport function setFunctionRegistry(registry: Record<string, FhirPathFunction>): void {\n _functionRegistry = registry;\n}\n\nfunction getFunctionImpl(name: string): FhirPathFunction | undefined {\n return _functionRegistry?.[name];\n}\n\n/**\n * Indexer atom \u2014 `collection[index]`.\n */\nexport class IndexerAtom implements Atom {\n readonly left: Atom;\n readonly expr: Atom;\n\n constructor(left: Atom, expr: Atom) {\n this.left = left;\n this.expr = expr;\n }\n\n eval(context: AtomContext, input: TypedValue[]): TypedValue[] {\n const evalResult = this.expr.eval(context, input);\n if (evalResult.length !== 1) {\n return [];\n }\n const index = evalResult[0].value;\n if (typeof index !== 'number') {\n throw new Error('Invalid indexer expression: should return integer');\n }\n const leftResult = this.left.eval(context, input);\n if (!(index in leftResult)) {\n return [];\n }\n return [leftResult[index]];\n }\n\n toString(): string {\n return `${this.left.toString()}[${this.expr.toString()}]`;\n }\n}\n\n// =============================================================================\n// Operator Atoms (Task 6.3)\n// =============================================================================\n\n/**\n * Base class for boolean-producing infix operators.\n */\nexport abstract class BooleanInfixOperatorAtom extends InfixOperatorAtom {\n abstract eval(context: AtomContext, input: TypedValue[]): TypedValue[];\n}\n\n/**\n * Arithmetic operator atom \u2014 handles `+`, `-`, `*`, `/`, `div`, `mod`,\n * and comparison operators `<`, `<=`, `>`, `>=`.\n * Works on numbers and Quantity values.\n */\nexport class ArithmeticOperatorAtom extends BooleanInfixOperatorAtom {\n readonly impl: (x: number, y: number) => number | boolean;\n\n constructor(operator: string, left: Atom, right: Atom, impl: (x: number, y: number) => number | boolean) {\n super(operator, left, right);\n this.impl = impl;\n }\n\n eval(context: AtomContext, input: TypedValue[]): TypedValue[] {\n const leftEvalResult = this.left.eval(context, input);\n if (leftEvalResult.length !== 1) {\n return [];\n }\n const rightEvalResult = this.right.eval(context, input);\n if (rightEvalResult.length !== 1) {\n return [];\n }\n const leftValue = leftEvalResult[0].value;\n const rightValue = rightEvalResult[0].value;\n\n // String concatenation with +\n if (this.operator === '+' && typeof leftValue === 'string' && typeof rightValue === 'string') {\n return [{ type: PropertyType.string, value: leftValue + rightValue }];\n }\n\n const leftNumber = isQuantity(leftValue) ? (leftValue as { value: number }).value : leftValue;\n const rightNumber = isQuantity(rightValue) ? (rightValue as { value: number }).value : rightValue;\n\n if (typeof leftNumber !== 'number' || typeof rightNumber !== 'number') {\n return [];\n }\n\n const result = this.impl(leftNumber, rightNumber);\n if (typeof result === 'boolean') {\n return booleanToTypedValue(result);\n } else if (isQuantity(leftValue)) {\n return [{ type: PropertyType.Quantity, value: { ...(leftValue as object), value: result } }];\n } else {\n return [toTypedValue(result)];\n }\n }\n}\n\n/**\n * String concatenation operator `&`.\n * Concatenates string values; for non-strings, collects into a union.\n */\nexport class ConcatAtom extends InfixOperatorAtom {\n constructor(left: Atom, right: Atom) {\n super('&', left, right);\n }\n\n eval(context: AtomContext, input: TypedValue[]): TypedValue[] {\n const leftValue = this.left.eval(context, input);\n const rightValue = this.right.eval(context, input);\n const result = [...leftValue, ...rightValue];\n if (result.length > 0 && result.every((e) => typeof e.value === 'string')) {\n return [{ type: PropertyType.string, value: result.map((e) => e.value as string).join('') }];\n }\n return result;\n }\n}\n\n/**\n * Union operator `|`.\n * Combines two collections, removing duplicates.\n */\nexport class UnionAtom extends InfixOperatorAtom {\n constructor(left: Atom, right: Atom) {\n super('|', left, right);\n }\n\n eval(context: AtomContext, input: TypedValue[]): TypedValue[] {\n const leftResult = this.left.eval(context, input);\n const rightResult = this.right.eval(context, input);\n return removeDuplicates([...leftResult, ...rightResult]);\n }\n}\n\n/**\n * Equality operator `=`.\n */\nexport class EqualsAtom extends BooleanInfixOperatorAtom {\n constructor(left: Atom, right: Atom) {\n super('=', left, right);\n }\n\n eval(context: AtomContext, input: TypedValue[]): TypedValue[] {\n const leftValue = this.left.eval(context, input);\n const rightValue = this.right.eval(context, input);\n return fhirPathArrayEquals(leftValue, rightValue);\n }\n}\n\n/**\n * Not-equals operator `!=`.\n */\nexport class NotEqualsAtom extends BooleanInfixOperatorAtom {\n constructor(left: Atom, right: Atom) {\n super('!=', left, right);\n }\n\n eval(context: AtomContext, input: TypedValue[]): TypedValue[] {\n const leftValue = this.left.eval(context, input);\n const rightValue = this.right.eval(context, input);\n return fhirPathArrayNotEquals(leftValue, rightValue);\n }\n}\n\n/**\n * Equivalence operator `~`.\n */\nexport class EquivalentAtom extends BooleanInfixOperatorAtom {\n constructor(left: Atom, right: Atom) {\n super('~', left, right);\n }\n\n eval(context: AtomContext, input: TypedValue[]): TypedValue[] {\n const leftValue = this.left.eval(context, input);\n const rightValue = this.right.eval(context, input);\n return fhirPathArrayEquivalent(leftValue, rightValue);\n }\n}\n\n/**\n * Not-equivalent operator `!~`.\n */\nexport class NotEquivalentAtom extends BooleanInfixOperatorAtom {\n constructor(left: Atom, right: Atom) {\n super('!~', left, right);\n }\n\n eval(context: AtomContext, input: TypedValue[]): TypedValue[] {\n const leftValue = this.left.eval(context, input);\n const rightValue = this.right.eval(context, input);\n return fhirPathNot(fhirPathArrayEquivalent(leftValue, rightValue));\n }\n}\n\n/**\n * Type-check operator `is`.\n */\nexport class IsAtom extends BooleanInfixOperatorAtom {\n constructor(left: Atom, right: Atom) {\n super('is', left, right);\n }\n\n eval(context: AtomContext, input: TypedValue[]): TypedValue[] {\n const leftValue = this.left.eval(context, input);\n if (leftValue.length !== 1) {\n return [];\n }\n const typeName = (this.right as SymbolAtom).name;\n return booleanToTypedValue(fhirPathIs(leftValue[0], typeName));\n }\n}\n\n/**\n * Type-cast operator `as`.\n */\nexport class AsAtom extends InfixOperatorAtom {\n constructor(left: Atom, right: Atom) {\n super('as', left, right);\n }\n\n eval(context: AtomContext, input: TypedValue[]): TypedValue[] {\n const leftValue = this.left.eval(context, input);\n const typeName = (this.right as SymbolAtom).name;\n return leftValue.filter((v) => fhirPathIs(v, typeName));\n }\n}\n\n/**\n * Collection membership operator `contains`.\n * `collection contains value` \u2192 true if value is in collection.\n */\nexport class ContainsAtom extends BooleanInfixOperatorAtom {\n constructor(left: Atom, right: Atom) {\n super('contains', left, right);\n }\n\n eval(context: AtomContext, input: TypedValue[]): TypedValue[] {\n const leftValue = this.left.eval(context, input);\n const rightValue = this.right.eval(context, input);\n return booleanToTypedValue(leftValue.some((e) => e.value === rightValue[0]?.value));\n }\n}\n\n/**\n * Collection membership operator `in`.\n * `value in collection` \u2192 true if value is in collection.\n */\nexport class InAtom extends BooleanInfixOperatorAtom {\n constructor(left: Atom, right: Atom) {\n super('in', left, right);\n }\n\n eval(context: AtomContext, input: TypedValue[]): TypedValue[] {\n const left = singleton(this.left.eval(context, input));\n const right = this.right.eval(context, input);\n if (!left) {\n return [];\n }\n return booleanToTypedValue(right.some((e) => toJsBoolean(fhirPathEquals(left, e))));\n }\n}\n\n// =============================================================================\n// Boolean Logic Operators\n// =============================================================================\n\n/**\n * Logical AND \u2014 three-valued logic per FHIRPath spec \u00A76.5.1.\n */\nexport class AndAtom extends BooleanInfixOperatorAtom {\n constructor(left: Atom, right: Atom) {\n super('and', left, right);\n }\n\n eval(context: AtomContext, input: TypedValue[]): TypedValue[] {\n const left = singleton(this.left.eval(context, input), 'boolean');\n const right = singleton(this.right.eval(context, input), 'boolean');\n if (left?.value === true && right?.value === true) {\n return booleanToTypedValue(true);\n }\n if (left?.value === false || right?.value === false) {\n return booleanToTypedValue(false);\n }\n return [];\n }\n}\n\n/**\n * Logical OR \u2014 three-valued logic per FHIRPath spec \u00A76.5.2.\n */\nexport class OrAtom extends BooleanInfixOperatorAtom {\n constructor(left: Atom, right: Atom) {\n super('or', left, right);\n }\n\n eval(context: AtomContext, input: TypedValue[]): TypedValue[] {\n const left = singleton(this.left.eval(context, input), 'boolean');\n const right = singleton(this.right.eval(context, input), 'boolean');\n if (left?.value === false && right?.value === false) {\n return booleanToTypedValue(false);\n } else if (left?.value || right?.value) {\n return booleanToTypedValue(true);\n } else {\n return [];\n }\n }\n}\n\n/**\n * Logical XOR \u2014 three-valued logic per FHIRPath spec \u00A76.5.4.\n */\nexport class XorAtom extends BooleanInfixOperatorAtom {\n constructor(left: Atom, right: Atom) {\n super('xor', left, right);\n }\n\n eval(context: AtomContext, input: TypedValue[]): TypedValue[] {\n const left = singleton(this.left.eval(context, input), 'boolean');\n const right = singleton(this.right.eval(context, input), 'boolean');\n if (!left || !right) {\n return [];\n }\n return booleanToTypedValue(left.value !== right.value);\n }\n}\n\n/**\n * Logical IMPLIES \u2014 three-valued logic per FHIRPath spec \u00A76.5.5.\n */\nexport class ImpliesAtom extends BooleanInfixOperatorAtom {\n constructor(left: Atom, right: Atom) {\n super('implies', left, right);\n }\n\n eval(context: AtomContext, input: TypedValue[]): TypedValue[] {\n const left = singleton(this.left.eval(context, input), 'boolean');\n const right = singleton(this.right.eval(context, input), 'boolean');\n if (right?.value === true || left?.value === false) {\n return booleanToTypedValue(true);\n } else if (!left || !right) {\n return [];\n }\n return booleanToTypedValue(false);\n }\n}\n", "/**\n * FHIRPath date/time parsing utilities.\n *\n * @module fhirpath\n */\n\n/**\n * Parse a FHIRPath date/time string into a normalized string.\n *\n * - Time-only strings (`T10:30:00`) are padded to full length.\n * - Local dates (`2021-01-01`) are returned as-is.\n * - DateTime strings are normalized to UTC via `Date.toISOString()`.\n *\n * @param str - The date/time string from a DateTime token.\n * @returns The normalized date/time string.\n */\nexport function parseDateString(str: string): string {\n if (str.startsWith('T')) {\n // Time string \u2014 normalize to full length\n return str + 'T00:00:00.000Z'.substring(str.length);\n }\n\n if (str.length <= 10) {\n // Local date (e.g. \"2021-01-01\") \u2014 return as-is\n return str;\n }\n\n try {\n // Normalize to UTC\n return new Date(str).toISOString();\n } catch (_err) {\n // Fallback for unsupported formats (e.g. \"2021-01-01T12\")\n return str;\n }\n}\n", "/**\n * Generic Tokenizer for FHIR languages (FHIRPath, FML).\n *\n * Based on Medplum's fhirlexer, which is itself inspired by\n * {@link https://github.com/JacksonKearl/PrattParse | PrattParse}.\n *\n * Supports:\n * - String literals (single/double quotes, escape sequences)\n * - Number literals (integer, decimal)\n * - DateTime literals (`@2024-01-15T10:30:00Z`)\n * - Quantity literals (`5 'mg'`, `10 days`)\n * - Operators (`.`, `+`, `-`, `*`, `/`, `=`, `!=`, `<`, `>`, etc.)\n * - Keywords (`and`, `or`, `xor`, `implies`, `is`, `as`, etc.)\n * - Symbols (identifiers: `name`, `birthDate`, `$this`, `%context`, etc.)\n * - Comments (`//` line comments, `/* ... *\u200B/` block comments)\n *\n * @module fhirpath/lexer\n */\n\n// =============================================================================\n// Token types\n// =============================================================================\n\n/** Position marker in source text. */\nexport interface Marker {\n index: number;\n line: number;\n column: number;\n}\n\n/**\n * A single token produced by the tokenizer.\n * `id` is the token type (e.g. `'Number'`, `'String'`, `'Symbol'`, `'+'`).\n * `value` is the raw text content.\n */\nexport interface Token extends Marker {\n id: string;\n value: string;\n}\n\n// =============================================================================\n// Constants\n// =============================================================================\n\nconst STANDARD_UNITS = [\n 'year',\n 'years',\n 'month',\n 'months',\n 'week',\n 'weeks',\n 'day',\n 'days',\n 'hour',\n 'hours',\n 'minute',\n 'minutes',\n 'second',\n 'seconds',\n 'millisecond',\n 'milliseconds',\n];\n\nconst ESCAPE_MAP: Record<string, string> = {\n \"'\": \"'\",\n '\"': '\"',\n '`': '`',\n r: '\\r',\n n: '\\n',\n t: '\\t',\n f: '\\f',\n '\\\\': '\\\\',\n};\n\n// =============================================================================\n// Tokenizer options\n// =============================================================================\n\nexport interface TokenizerOptions {\n /** Enable `@`-prefixed DateTime literal parsing. */\n dateTimeLiterals?: boolean;\n /** Regex for valid symbol characters (default: `/[$\\w%]/`). */\n symbolRegex?: RegExp;\n}\n\n// =============================================================================\n// Tokenizer\n// =============================================================================\n\n/**\n * Generic tokenizer for FHIR languages.\n *\n * Usage:\n * ```ts\n * const tokens = new Tokenizer(input, keywords, operators).tokenize();\n * ```\n */\nexport class Tokenizer {\n private readonly str: string;\n private readonly keywords: string[];\n private readonly operators: string[];\n private readonly dateTimeLiterals: boolean;\n private readonly symbolRegex: RegExp;\n private readonly result: Token[] = [];\n private readonly pos: Marker = { index: 0, line: 1, column: 0 };\n private readonly markStack: Marker[] = [];\n\n constructor(str: string, keywords: string[], operators: string[], options?: TokenizerOptions) {\n this.str = str;\n this.keywords = keywords;\n this.operators = operators;\n this.dateTimeLiterals = !!options?.dateTimeLiterals;\n this.symbolRegex = options?.symbolRegex ?? /[$\\w%]/;\n }\n\n tokenize(): Token[] {\n while (this.pos.index < this.str.length) {\n const token = this.consumeToken();\n if (token) {\n this.result.push(token);\n }\n }\n return this.result;\n }\n\n private prevToken(): Token | undefined {\n return this.result[this.result.length - 1];\n }\n\n private peekToken(): Token | undefined {\n this.mark();\n const token = this.consumeToken();\n this.reset();\n return token;\n }\n\n private consumeToken(): Token | undefined {\n this.consumeWhitespace();\n\n const c = this.curr();\n if (!c) {\n return undefined;\n }\n\n this.mark();\n\n const next = this.peek();\n\n if (c === '/' && next === '*') {\n return this.consumeMultiLineComment();\n }\n\n if (c === '/' && next === '/') {\n return this.consumeSingleLineComment();\n }\n\n if (c === \"'\" || c === '\"' || c === '`') {\n return this.consumeString(c);\n }\n\n if (c === '@') {\n return this.consumeDateTime();\n }\n\n if (/\\d/.exec(c)) {\n return this.consumeNumber();\n }\n\n if (/\\w/.exec(c)) {\n return this.consumeSymbol();\n }\n\n if ((c === '$' || c === '%') && /\\w/.exec(next)) {\n return this.consumeSymbol();\n }\n\n if ((c === '$' || c === '%') && (next === \"'\" || next === '\"' || next === '`')) {\n return this.consumeQuotedSymbol(next);\n }\n\n return this.consumeOperator();\n }\n\n private consumeWhitespace(): void {\n this.consumeWhile(() => /\\s/.exec(this.curr()));\n }\n\n private consumeMultiLineComment(): Token {\n const start = this.pos.index;\n this.consumeWhile(() => this.curr() !== '*' || this.peek() !== '/');\n this.advance();\n this.advance();\n return this.buildToken('Comment', this.str.substring(start, this.pos.index));\n }\n\n private consumeSingleLineComment(): Token {\n return this.buildToken(\n 'Comment',\n this.consumeWhile(() => this.curr() !== '\\n'),\n );\n }\n\n private consumeString(endChar: string): Token {\n this.advance();\n let str = '';\n let char: string;\n while ((char = this.consumeChar(endChar))) {\n str += char;\n }\n const result = this.buildToken(endChar === '`' ? 'Symbol' : 'String', str);\n this.advance();\n return result;\n }\n\n private consumeChar(endChar: string): string {\n const char1 = this.curr();\n\n if (char1 === '\\\\') {\n this.advance();\n const char2 = this.curr();\n const escaped = ESCAPE_MAP[char2];\n if (escaped !== undefined) {\n this.advance();\n return escaped;\n }\n if (char2 === 'u') {\n this.advance();\n const hex = /^[0-9a-fA-F]{4}$/.exec(this.str.substring(this.pos.index, this.pos.index + 4))?.[0];\n if (!hex) {\n return 'u';\n }\n this.advance();\n this.advance();\n this.advance();\n this.advance();\n return String.fromCodePoint(Number.parseInt(hex, 16));\n }\n return this.consumeChar(endChar);\n }\n\n if (char1 === endChar || !char1) {\n return '';\n }\n\n this.advance();\n return char1;\n }\n\n private consumeQuotedSymbol(endChar: string): Token {\n this.mark();\n const start = this.pos.index;\n this.advance(); // Consume \"$\" or \"%\"\n this.consumeString(endChar);\n const value = this.str.substring(start, this.pos.index);\n return this.buildToken('Symbol', value);\n }\n\n private consumeDateTime(): Token {\n this.advance(); // Consume \"@\"\n\n const start = this.pos.index;\n this.consumeWhile(() => /[\\d-]/.exec(this.curr()));\n\n let foundTime = false;\n let foundTimeZone = false;\n\n if (this.curr() === 'T') {\n foundTime = true;\n this.advance();\n this.consumeWhile(() => /[\\d:]/.exec(this.curr()));\n\n if (this.curr() === '.' && /\\d/.exec(this.peek())) {\n this.advance();\n this.consumeWhile(() => /\\d/.exec(this.curr()));\n }\n\n if (this.curr() === 'Z') {\n foundTimeZone = true;\n this.advance();\n } else if (this.curr() === '+' || this.curr() === '-') {\n foundTimeZone = true;\n this.advance();\n this.consumeWhile(() => /[\\d:]/.exec(this.curr()));\n }\n }\n\n if (this.pos.index === start) {\n throw new Error('Invalid DateTime literal');\n }\n\n let value = this.str.substring(start, this.pos.index);\n if (value.endsWith('T')) {\n value = value.substring(0, value.length - 1);\n } else if (!value.startsWith('T') && foundTime && !foundTimeZone) {\n value += 'Z';\n }\n return this.buildToken('DateTime', value);\n }\n\n private consumeNumber(): Token {\n const start = this.pos.index;\n let id = 'Number';\n this.consumeWhile(() => /\\d/.exec(this.curr()));\n\n if (this.curr() === '.' && /\\d/.exec(this.peek())) {\n this.advance();\n this.consumeWhile(() => /\\d/.exec(this.curr()));\n }\n\n if (this.curr() === '-' && this.dateTimeLiterals) {\n this.pos.index = start - 1;\n return this.consumeDateTime();\n }\n\n if (this.curr() === ' ') {\n if (isUnitToken(this.peekToken())) {\n id = 'Quantity';\n this.consumeToken();\n }\n }\n\n return this.buildToken(id, this.str.substring(start, this.pos.index));\n }\n\n private consumeSymbol(): Token {\n const value = this.consumeWhile(() => this.symbolRegex.exec(this.curr()));\n if (this.prevToken()?.value !== '.' && this.keywords.includes(value)) {\n return this.buildToken(value, value);\n }\n return this.buildToken('Symbol', value);\n }\n\n private consumeOperator(): Token {\n const c = this.curr();\n const next = this.peek();\n const twoCharOp = c + next;\n\n if (this.operators.includes(twoCharOp)) {\n this.advance();\n this.advance();\n return this.buildToken(twoCharOp, twoCharOp);\n }\n\n this.advance();\n return this.buildToken(c, c);\n }\n\n private consumeWhile(condition: () => unknown): string {\n const start = this.pos.index;\n while (this.pos.index < this.str.length && condition()) {\n this.advance();\n }\n return this.str.substring(start, this.pos.index);\n }\n\n private curr(): string {\n return this.str[this.pos.index];\n }\n\n private peek(): string {\n return this.str[this.pos.index + 1] ?? '';\n }\n\n private mark(): void {\n this.markStack.push({ ...this.pos });\n }\n\n private reset(): void {\n const mark = this.markStack.pop();\n if (!mark) {\n throw new Error('No mark to reset to');\n }\n this.pos.index = mark.index;\n this.pos.line = mark.line;\n this.pos.column = mark.column;\n }\n\n private advance(): void {\n this.pos.index++;\n if (this.curr() === '\\n') {\n this.pos.line++;\n this.pos.column = 0;\n } else {\n this.pos.column++;\n }\n }\n\n private buildToken(id: string, value: string): Token {\n const mark = this.markStack.pop();\n if (!mark) {\n throw new Error('No mark for token');\n }\n return { id, value, ...mark };\n }\n}\n\n// =============================================================================\n// Helpers\n// =============================================================================\n\nfunction isUnitToken(token: Token | undefined): boolean {\n if (token) {\n if (token.id === 'String') {\n return true;\n }\n if (token.id === 'Symbol' && STANDARD_UNITS.includes(token.value)) {\n return true;\n }\n }\n return false;\n}\n", "/**\n * FHIRPath-specific tokenizer.\n *\n * Thin wrapper around the generic {@link Tokenizer} that provides\n * FHIRPath keywords and operators.\n *\n * @module fhirpath\n */\n\nimport type { Token } from './lexer/tokenize.js';\nimport { Tokenizer } from './lexer/tokenize.js';\n\n/** FHIRPath keywords that are treated as their own token type. */\nexport const FHIRPATH_KEYWORDS = ['true', 'false'];\n\n/** FHIRPath multi-character operators. */\nexport const FHIRPATH_OPERATORS = ['!=', '!~', '<=', '>=', '{}', '->'];\n\n/**\n * Tokenize a FHIRPath expression string into a token array.\n * @param str - The FHIRPath expression.\n * @returns Array of tokens.\n */\nexport function tokenize(str: string): Token[] {\n return new Tokenizer(str, FHIRPATH_KEYWORDS, FHIRPATH_OPERATORS).tokenize();\n}\n", "/**\n * FHIRPath Standard Functions\n *\n * Implements FHIRPath \u00A75.1\u20135.9 and \u00A76.3\u20136.5 functions.\n * Organized by FHIRPath spec section:\n * - \u00A75.1 Existence (empty, exists, all, allTrue, anyTrue, allFalse, anyFalse, subsetOf, supersetOf, count, distinct, isDistinct)\n * - \u00A75.2 Filtering and projection (where, select, repeat, ofType)\n * - \u00A75.3 Subsetting (single, first, last, tail, skip, take, intersect, exclude)\n * - \u00A75.4 Combining (union, combine)\n * - \u00A75.5 Conversion (iif, toBoolean, convertsToBoolean, toInteger, convertsToInteger, toDecimal, convertsToDecimal, toQuantity, convertsToQuantity, toString, convertsToString, toDateTime, convertsToDateTime, toTime, convertsToTime)\n * - \u00A75.6 String manipulation (indexOf, substring, startsWith, endsWith, contains, upper, lower, replace, matches, replaceMatches, length, toChars, join)\n * - \u00A75.7 Math (abs, ceiling, exp, floor, ln, log, power, round, sqrt, truncate)\n * - \u00A75.8 Tree navigation (children, descendants)\n * - \u00A75.9 Utility (trace, now, timeOfDay, today)\n * - \u00A76.3 Types (is, as, type, conformsTo)\n * - \u00A76.5 Boolean logic (not)\n * - FHIR-specific (resolve, extension, hasValue, htmlChecks, getResourceKey, getReferenceKey)\n *\n * @module fhirpath\n */\n\nimport type { Atom, AtomContext, TypedValue } from './types.js';\nimport { PropertyType } from './types.js';\nimport { parseDateString } from './date.js';\nimport {\n booleanToTypedValue,\n fhirPathIs,\n isQuantity,\n removeDuplicates,\n toJsBoolean,\n toTypedValue,\n} from './utils.js';\n\nexport type FhirPathFunction = (context: AtomContext, input: TypedValue[], ...args: Atom[]) => TypedValue[];\n\n// =============================================================================\n// Internal helpers\n// =============================================================================\n\n/** Walk up the context chain to find the root `$this` input. */\nfunction getRootInput(context: AtomContext): TypedValue[] {\n const thisVal = context.variables['$this'];\n if (thisVal) {\n return [thisVal];\n }\n if (context.parent) {\n return getRootInput(context.parent);\n }\n return [];\n}\n\n/** Validate that input has at most `max` items; return the items. */\nfunction validateInput(input: TypedValue[], max: number): TypedValue[] {\n if (input.length > max) {\n throw new Error(`Expected at most ${max} items, got ${input.length}`);\n }\n return input;\n}\n\n/**\n * Generic helper for applying a string function to the first input element.\n * Evaluates optional argument atoms and passes their values to the callback.\n */\nfunction applyStringFunc(\n fn: (str: string, ...args: unknown[]) => unknown,\n context: AtomContext,\n input: TypedValue[],\n ...argAtoms: (Atom | undefined)[]\n): TypedValue[] {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (typeof value !== 'string') {\n return [];\n }\n const args = argAtoms\n .filter((a): a is Atom => a !== undefined)\n .map((a) => a.eval(context, getRootInput(context))[0]?.value);\n const result = fn(value, ...args);\n if (result === undefined || result === null) {\n return [];\n }\n if (typeof result === 'boolean') {\n return booleanToTypedValue(result);\n }\n if (typeof result === 'number') {\n return [{ type: PropertyType.integer, value: result }];\n }\n if (Array.isArray(result)) {\n return result.map((v) => ({ type: PropertyType.string, value: v }));\n }\n return [{ type: PropertyType.string, value: result }];\n}\n\n/**\n * Generic helper for applying a math function to the first input element.\n * Handles Quantity values by extracting the numeric value and re-wrapping.\n */\nfunction applyMathFunc(\n fn: (value: number, ...args: unknown[]) => number,\n context: AtomContext,\n input: TypedValue[],\n ...argAtoms: (Atom | undefined)[]\n): TypedValue[] {\n if (input.length === 0) {\n return [];\n }\n const [typedValue] = validateInput(input, 1);\n const { value } = typedValue;\n const numValue = isQuantity(value) ? (value as { value: number }).value : value;\n if (typeof numValue !== 'number') {\n return [];\n }\n const args = argAtoms\n .filter((a): a is Atom => a !== undefined)\n .map((a) => a.eval(context, getRootInput(context))[0]?.value);\n const result = fn(numValue, ...args);\n if (!Number.isFinite(result)) {\n return [];\n }\n if (isQuantity(value)) {\n return [{ type: PropertyType.Quantity, value: { ...(value as object), value: result } }];\n }\n return [toTypedValue(result)];\n}\n\n/**\n * Resolve a type name from an Atom without importing concrete atom classes.\n * Uses duck-typing to detect SymbolAtom (has `.name`) and DotAtom (has `.left`/`.right`).\n */\nfunction resolveTypeName(atom: Atom): string {\n const asSymbol = atom as Atom & { name?: string };\n if (typeof asSymbol.name === 'string') {\n return asSymbol.name;\n }\n const asDot = atom as Atom & { left?: Atom & { name?: string }; right?: Atom & { name?: string }; operator?: string };\n if (asDot.operator === '.' && asDot.left?.name && asDot.right?.name) {\n return asDot.left.name + '.' + asDot.right.name;\n }\n return atom.toString();\n}\n\n// =============================================================================\n// Function registry\n// =============================================================================\n\n/**\n * Global function registry.\n * Keys are function names as they appear in FHIRPath expressions.\n */\nexport const functions: Record<string, FhirPathFunction> = {\n\n /*\n * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n * 5.1 Existence\n * See: https://hl7.org/fhirpath/#existence\n * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n */\n\n empty: (_context: AtomContext, input: TypedValue[]): TypedValue[] => {\n return booleanToTypedValue(input.length === 0);\n },\n\n hasValue: (_context: AtomContext, input: TypedValue[]): TypedValue[] => {\n return booleanToTypedValue(input.length !== 0);\n },\n\n exists: (context: AtomContext, input: TypedValue[], criteria?: Atom): TypedValue[] => {\n if (criteria) {\n return booleanToTypedValue(input.some((e) => toJsBoolean(criteria.eval(context, [e]))));\n }\n return booleanToTypedValue(input.length > 0);\n },\n\n all: (context: AtomContext, input: TypedValue[], criteria: Atom): TypedValue[] => {\n return booleanToTypedValue(input.every((e) => toJsBoolean(criteria.eval(context, [e]))));\n },\n\n allTrue: (_context: AtomContext, input: TypedValue[]): TypedValue[] => {\n for (const value of input) {\n if (!value.value) {\n return booleanToTypedValue(false);\n }\n }\n return booleanToTypedValue(true);\n },\n\n anyTrue: (_context: AtomContext, input: TypedValue[]): TypedValue[] => {\n for (const value of input) {\n if (value.value) {\n return booleanToTypedValue(true);\n }\n }\n return booleanToTypedValue(false);\n },\n\n allFalse: (_context: AtomContext, input: TypedValue[]): TypedValue[] => {\n for (const value of input) {\n if (value.value) {\n return booleanToTypedValue(false);\n }\n }\n return booleanToTypedValue(true);\n },\n\n anyFalse: (_context: AtomContext, input: TypedValue[]): TypedValue[] => {\n for (const value of input) {\n if (!value.value) {\n return booleanToTypedValue(true);\n }\n }\n return booleanToTypedValue(false);\n },\n\n subsetOf: (context: AtomContext, input: TypedValue[], other: Atom): TypedValue[] => {\n if (input.length === 0) {\n return booleanToTypedValue(true);\n }\n const otherArray = other.eval(context, getRootInput(context));\n if (otherArray.length === 0) {\n return booleanToTypedValue(false);\n }\n return booleanToTypedValue(input.every((e) => otherArray.some((o) => o.value === e.value)));\n },\n\n supersetOf: (context: AtomContext, input: TypedValue[], other: Atom): TypedValue[] => {\n const otherArray = other.eval(context, getRootInput(context));\n if (otherArray.length === 0) {\n return booleanToTypedValue(true);\n }\n if (input.length === 0) {\n return booleanToTypedValue(false);\n }\n return booleanToTypedValue(otherArray.every((e) => input.some((o) => o.value === e.value)));\n },\n\n count: (_context: AtomContext, input: TypedValue[]): TypedValue[] => {\n return [{ type: PropertyType.integer, value: input.length }];\n },\n\n distinct: (_context: AtomContext, input: TypedValue[]): TypedValue[] => {\n const result: TypedValue[] = [];\n for (const value of input) {\n if (!result.some((e) => e.value === value.value)) {\n result.push(value);\n }\n }\n return result;\n },\n\n isDistinct: (context: AtomContext, input: TypedValue[]): TypedValue[] => {\n return booleanToTypedValue(input.length === functions.distinct(context, input).length);\n },\n\n /*\n * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n * 5.2 Filtering and projection\n * See: https://hl7.org/fhirpath/#filtering-and-projection\n * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n */\n\n where: (context: AtomContext, input: TypedValue[], criteria: Atom): TypedValue[] => {\n return input.filter((e) => toJsBoolean(criteria.eval(context, [e])));\n },\n\n select: (context: AtomContext, input: TypedValue[], criteria: Atom): TypedValue[] => {\n return input.flatMap((e) => criteria.eval({ parent: context, variables: { $this: e } }, [e]));\n },\n\n repeat: (context: AtomContext, input: TypedValue[], projection: Atom): TypedValue[] => {\n const result: TypedValue[] = [];\n let current = input;\n while (current.length > 0) {\n const next: TypedValue[] = [];\n for (const item of current) {\n const projected = projection.eval({ parent: context, variables: { $this: item } }, [item]);\n for (const p of projected) {\n if (!result.some((r) => r.value === p.value)) {\n result.push(p);\n next.push(p);\n }\n }\n }\n current = next;\n }\n return result;\n },\n\n ofType: (_context: AtomContext, input: TypedValue[], criteria: Atom): TypedValue[] => {\n const typeName = (criteria as Atom & { name?: string }).name ?? criteria.toString();\n return input.filter((e) => fhirPathIs(e, typeName));\n },\n\n /*\n * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n * 5.3 Subsetting\n * See: https://hl7.org/fhirpath/#subsetting\n * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n */\n\n single: (_context: AtomContext, input: TypedValue[]): TypedValue[] => {\n if (input.length > 1) {\n throw new Error('Expected input length one for single()');\n }\n return input.length === 0 ? [] : input.slice(0, 1);\n },\n\n first: (_context: AtomContext, input: TypedValue[]): TypedValue[] => {\n return input.length === 0 ? [] : input.slice(0, 1);\n },\n\n last: (_context: AtomContext, input: TypedValue[]): TypedValue[] => {\n return input.length === 0 ? [] : input.slice(-1);\n },\n\n tail: (_context: AtomContext, input: TypedValue[]): TypedValue[] => {\n return input.length === 0 ? [] : input.slice(1);\n },\n\n skip: (context: AtomContext, input: TypedValue[], num: Atom): TypedValue[] => {\n const numValue = num.eval(context, input)[0]?.value;\n if (typeof numValue !== 'number') {\n throw new TypeError('Expected a number for skip(num)');\n }\n if (numValue >= input.length) {\n return [];\n }\n if (numValue <= 0) {\n return input;\n }\n return input.slice(numValue);\n },\n\n take: (context: AtomContext, input: TypedValue[], num: Atom): TypedValue[] => {\n const numValue = num.eval(context, input)[0]?.value;\n if (typeof numValue !== 'number') {\n throw new TypeError('Expected a number for take(num)');\n }\n if (numValue >= input.length) {\n return input;\n }\n if (numValue <= 0) {\n return [];\n }\n return input.slice(0, numValue);\n },\n\n intersect: (context: AtomContext, input: TypedValue[], other: Atom): TypedValue[] => {\n if (!other) {\n return input;\n }\n const otherArray = other.eval(context, getRootInput(context));\n const result: TypedValue[] = [];\n for (const value of input) {\n if (!result.some((e) => e.value === value.value) && otherArray.some((e) => e.value === value.value)) {\n result.push(value);\n }\n }\n return result;\n },\n\n exclude: (context: AtomContext, input: TypedValue[], other: Atom): TypedValue[] => {\n if (!other) {\n return input;\n }\n const otherArray = other.eval(context, getRootInput(context));\n return input.filter((value) => !otherArray.some((e) => e.value === value.value));\n },\n\n /*\n * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n * 5.4 Combining\n * See: https://hl7.org/fhirpath/#combining\n * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n */\n\n union: (context: AtomContext, input: TypedValue[], other: Atom): TypedValue[] => {\n if (!other) {\n return input;\n }\n const otherArray = other.eval(context, getRootInput(context));\n return removeDuplicates([...input, ...otherArray]);\n },\n\n combine: (context: AtomContext, input: TypedValue[], other: Atom): TypedValue[] => {\n if (!other) {\n return input;\n }\n const otherArray = other.eval(context, getRootInput(context));\n return [...input, ...otherArray];\n },\n\n /*\n * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n * 5.5 Conversion\n * See: https://hl7.org/fhirpath/#conversion\n * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n */\n\n iif: (\n context: AtomContext,\n input: TypedValue[],\n criterion: Atom,\n trueResult: Atom,\n otherwiseResult?: Atom,\n ): TypedValue[] => {\n if (toJsBoolean(criterion.eval(context, input))) {\n return trueResult.eval(context, input);\n }\n if (otherwiseResult) {\n return otherwiseResult.eval(context, input);\n }\n return [];\n },\n\n toBoolean: (_context: AtomContext, input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (typeof value === 'boolean') {\n return booleanToTypedValue(value);\n }\n if (typeof value === 'number') {\n if (value === 0 || value === 1) {\n return booleanToTypedValue(!!value);\n }\n }\n if (typeof value === 'string') {\n const lower = (value as string).toLowerCase();\n if (['true', 't', 'yes', 'y', '1', '1.0'].includes(lower)) {\n return booleanToTypedValue(true);\n }\n if (['false', 'f', 'no', 'n', '0', '0.0'].includes(lower)) {\n return booleanToTypedValue(false);\n }\n }\n return [];\n },\n\n convertsToBoolean: (context: AtomContext, input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n return booleanToTypedValue(functions.toBoolean(context, input).length === 1);\n },\n\n toInteger: (_context: AtomContext, input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (typeof value === 'number') {\n return [{ type: PropertyType.integer, value }];\n }\n if (typeof value === 'string' && /^[+-]?\\d+$/.exec(value)) {\n return [{ type: PropertyType.integer, value: Number.parseInt(value, 10) }];\n }\n if (typeof value === 'boolean') {\n return [{ type: PropertyType.integer, value: value ? 1 : 0 }];\n }\n return [];\n },\n\n convertsToInteger: (context: AtomContext, input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n return booleanToTypedValue(functions.toInteger(context, input).length === 1);\n },\n\n toDecimal: (_context: AtomContext, input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (typeof value === 'number') {\n return [{ type: PropertyType.decimal, value }];\n }\n if (typeof value === 'string' && /^[+-]?\\d+(\\.\\d+)?$/.exec(value)) {\n return [{ type: PropertyType.decimal, value: Number.parseFloat(value) }];\n }\n if (typeof value === 'boolean') {\n return [{ type: PropertyType.decimal, value: value ? 1.0 : 0.0 }];\n }\n return [];\n },\n\n convertsToDecimal: (context: AtomContext, input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n return booleanToTypedValue(functions.toDecimal(context, input).length === 1);\n },\n\n toQuantity: (_context: AtomContext, input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (isQuantity(value)) {\n return [{ type: PropertyType.Quantity, value }];\n }\n if (typeof value === 'number') {\n return [{ type: PropertyType.Quantity, value: { value, unit: '1' } }];\n }\n if (typeof value === 'string' && /^-?\\d+(\\.\\d+)?/.exec(value)) {\n return [{ type: PropertyType.Quantity, value: { value: Number.parseFloat(value), unit: '1' } }];\n }\n if (typeof value === 'boolean') {\n return [{ type: PropertyType.Quantity, value: { value: value ? 1 : 0, unit: '1' } }];\n }\n return [];\n },\n\n convertsToQuantity: (context: AtomContext, input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n return booleanToTypedValue(functions.toQuantity(context, input).length === 1);\n },\n\n toString: (_context: AtomContext, input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (value === null || value === undefined) {\n return [];\n }\n if (isQuantity(value)) {\n return [{ type: PropertyType.string, value: `${(value as { value: number }).value} '${(value as { unit?: string }).unit}'` }];\n }\n return [{ type: PropertyType.string, value: String(value) }];\n },\n\n convertsToString: (context: AtomContext, input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n return booleanToTypedValue((functions.toString as unknown as FhirPathFunction)(context, input).length === 1);\n },\n\n toDateTime: (_context: AtomContext, input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (typeof value === 'string') {\n const match = /^\\d{4}(-\\d{2}(-\\d{2}(T\\d{2}(:\\d{2}(:\\d{2}(\\.\\d+)?)?)?(Z|[+-]\\d{2}(:\\d{2})?)?)?)?)?$/.exec(value);\n if (match) {\n return [{ type: PropertyType.dateTime, value: parseDateString(value) }];\n }\n }\n return [];\n },\n\n convertsToDateTime: (context: AtomContext, input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n return booleanToTypedValue(functions.toDateTime(context, input).length === 1);\n },\n\n toTime: (_context: AtomContext, input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n const [{ value }] = validateInput(input, 1);\n if (typeof value === 'string') {\n const match = /^T?(\\d{2}(:\\d{2}(:\\d{2})?)?)/.exec(value);\n if (match) {\n return [{ type: PropertyType.time, value: parseDateString('T' + match[1]) }];\n }\n }\n return [];\n },\n\n convertsToTime: (context: AtomContext, input: TypedValue[]): TypedValue[] => {\n if (input.length === 0) {\n return [];\n }\n return booleanToTypedValue(functions.toTime(context, input).length === 1);\n },\n\n /*\n * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n * 5.6 String Manipulation\n * See: https://hl7.org/fhirpath/#string-manipulation\n * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n */\n\n indexOf: (context: AtomContext, input: TypedValue[], substringAtom: Atom): TypedValue[] => {\n return applyStringFunc((str, substring) => str.indexOf(substring as string), context, input, substringAtom);\n },\n\n substring: (context: AtomContext, input: TypedValue[], startAtom: Atom, lengthAtom?: Atom): TypedValue[] => {\n return applyStringFunc(\n (str, start, length) => {\n const startIndex = start as number;\n const endIndex = length !== undefined ? startIndex + (length as number) : str.length;\n return startIndex < 0 || startIndex >= str.length ? undefined : str.substring(startIndex, endIndex);\n },\n context,\n input,\n startAtom,\n lengthAtom,\n );\n },\n\n startsWith: (context: AtomContext, input: TypedValue[], prefixAtom: Atom): TypedValue[] => {\n return applyStringFunc((str, prefix) => str.startsWith(prefix as string), context, input, prefixAtom);\n },\n\n endsWith: (context: AtomContext, input: TypedValue[], suffixAtom: Atom): TypedValue[] => {\n return applyStringFunc((str, suffix) => str.endsWith(suffix as string), context, input, suffixAtom);\n },\n\n contains: (context: AtomContext, input: TypedValue[], substringAtom: Atom): TypedValue[] => {\n return applyStringFunc((str, substring) => str.includes(substring as string), context, input, substringAtom);\n },\n\n upper: (context: AtomContext, input: TypedValue[]): TypedValue[] => {\n return applyStringFunc((str) => str.toUpperCase(), context, input);\n },\n\n lower: (context: AtomContext, input: TypedValue[]): TypedValue[] => {\n return applyStringFunc((str) => str.toLowerCase(), context, input);\n },\n\n replace: (context: AtomContext, input: TypedValue[], patternAtom: Atom, substitutionAtom: Atom): TypedValue[] => {\n return applyStringFunc(\n (str, pattern, substitution) => str.replaceAll(pattern as string, substitution as string),\n context,\n input,\n patternAtom,\n substitutionAtom,\n );\n },\n\n matches: (context: AtomContext, input: TypedValue[], regexAtom: Atom): TypedValue[] => {\n return applyStringFunc((str, regex) => !!new RegExp(regex as string).exec(str), context, input, regexAtom);\n },\n\n replaceMatches: (context: AtomContext, input: TypedValue[], regexAtom: Atom, substitutionAtom: Atom): TypedValue[] => {\n return applyStringFunc(\n (str, pattern, substitution) => str.replaceAll(new RegExp(pattern as string, 'g'), substitution as string),\n context,\n input,\n regexAtom,\n substitutionAtom,\n );\n },\n\n length: (context: AtomContext, input: TypedValue[]): TypedValue[] => {\n return applyStringFunc((str) => str.length, context, input);\n },\n\n toChars: (context: AtomContext, input: TypedValue[]): TypedValue[] => {\n return applyStringFunc((str) => (str ? str.split('') : undefined), context, input);\n },\n\n join: (context: AtomContext, input: TypedValue[], separatorAtom?: Atom): TypedValue[] => {\n const separator = separatorAtom?.eval(context, getRootInput(context))[0]?.value ?? '';\n if (typeof separator !== 'string') {\n throw new TypeError('Separator must be a string.');\n }\n return [{ type: PropertyType.string, value: input.map((i) => String(i.value ?? '')).join(separator) }];\n },\n\n /*\n * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n * 5.7 Math\n * See: https://hl7.org/fhirpath/#math\n * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n */\n\n abs: (context: AtomContext, input: TypedValue[]): TypedValue[] => {\n return applyMathFunc(Math.abs, context, input);\n },\n\n ceiling: (context: AtomContext, input: TypedValue[]): TypedValue[] => {\n return applyMathFunc(Math.ceil, context, input);\n },\n\n exp: (context: AtomContext, input: TypedValue[]): TypedValue[] => {\n return applyMathFunc(Math.exp, context, input);\n },\n\n floor: (context: AtomContext, input: TypedValue[]): TypedValue[] => {\n return applyMathFunc(Math.floor, context, input);\n },\n\n ln: (context: AtomContext, input: TypedValue[]): TypedValue[] => {\n return applyMathFunc(Math.log, context, input);\n },\n\n log: (context: AtomContext, input: TypedValue[], baseAtom: Atom): TypedValue[] => {\n return applyMathFunc((value, base) => Math.log(value) / Math.log(base as number), context, input, baseAtom);\n },\n\n power: (context: AtomContext, input: TypedValue[], expAtom: Atom): TypedValue[] => {\n return applyMathFunc(Math.pow as (x: number, ...args: unknown[]) => number, context, input, expAtom);\n },\n\n round: (context: AtomContext, input: TypedValue[], ...argsAtoms: Atom[]): TypedValue[] => {\n return applyMathFunc(\n (n, precision: unknown = 0) => {\n if (typeof precision !== 'number' || precision < 0) {\n throw new Error('Invalid precision provided to round()');\n }\n const exp = Math.pow(10, precision);\n return Math.round(n * exp) / exp;\n },\n context,\n input,\n ...argsAtoms,\n );\n },\n\n sqrt: (context: AtomContext, input: TypedValue[]): TypedValue[] => {\n return applyMathFunc(Math.sqrt, context, input);\n },\n\n truncate: (context: AtomContext, input: TypedValue[]): TypedValue[] => {\n return applyMathFunc((x) => Math.trunc(x), context, input);\n },\n\n /*\n * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n * 5.8 Tree navigation\n * See: https://hl7.org/fhirpath/#tree-navigation\n * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n */\n\n children: (_context: AtomContext, input: TypedValue[]): TypedValue[] => {\n const result: TypedValue[] = [];\n for (const item of input) {\n const value = item.value;\n if (value && typeof value === 'object') {\n for (const key of Object.keys(value as Record<string, unknown>)) {\n const child = (value as Record<string, unknown>)[key];\n if (Array.isArray(child)) {\n for (const c of child) {\n result.push(toTypedValue(c));\n }\n } else if (child !== undefined && child !== null) {\n result.push(toTypedValue(child));\n }\n }\n }\n }\n return result;\n },\n\n descendants: (context: AtomContext, input: TypedValue[]): TypedValue[] => {\n const result: TypedValue[] = [];\n let current = functions.children(context, input);\n while (current.length > 0) {\n result.push(...current);\n current = functions.children(context, current);\n }\n return result;\n },\n\n /*\n * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n * 5.9 Utility functions\n * See: https://hl7.org/fhirpath/#utility-functions\n * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n */\n\n trace: (_context: AtomContext, input: TypedValue[]): TypedValue[] => {\n return input;\n },\n\n now: (): TypedValue[] => {\n return [{ type: PropertyType.dateTime, value: new Date().toISOString() }];\n },\n\n timeOfDay: (): TypedValue[] => {\n return [{ type: PropertyType.time, value: new Date().toISOString().substring(11) }];\n },\n\n today: (): TypedValue[] => {\n return [{ type: PropertyType.date, value: new Date().toISOString().substring(0, 10) }];\n },\n\n /*\n * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n * 6.3 Types\n * See: https://hl7.org/fhirpath/#types-2\n * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n */\n\n is: (_context: AtomContext, input: TypedValue[], typeAtom: Atom): TypedValue[] => {\n const typeName = resolveTypeName(typeAtom);\n if (!typeName) {\n return [];\n }\n return input.map((value) => ({ type: PropertyType.boolean, value: fhirPathIs(value, typeName) }));\n },\n\n as: (_context: AtomContext, input: TypedValue[]): TypedValue[] => {\n return input;\n },\n\n type: (_context: AtomContext, input: TypedValue[]): TypedValue[] => {\n return input.map(({ value }) => {\n if (typeof value === 'boolean') {\n return { type: PropertyType.BackboneElement, value: { namespace: 'System', name: 'Boolean' } };\n }\n if (typeof value === 'number') {\n return { type: PropertyType.BackboneElement, value: { namespace: 'System', name: 'Integer' } };\n }\n if (typeof value === 'string') {\n return { type: PropertyType.BackboneElement, value: { namespace: 'System', name: 'String' } };\n }\n if (value && typeof value === 'object' && 'resourceType' in value) {\n return { type: PropertyType.BackboneElement, value: { namespace: 'FHIR', name: (value as Record<string, unknown>).resourceType } };\n }\n return { type: PropertyType.BackboneElement, value: null };\n });\n },\n\n conformsTo: (context: AtomContext, input: TypedValue[], systemAtom: Atom): TypedValue[] => {\n const system = systemAtom.eval(context, input)[0].value as string;\n if (!system.startsWith('http://hl7.org/fhir/StructureDefinition/')) {\n throw new Error('Expected a StructureDefinition URL');\n }\n const expectedResourceType = system.replace('http://hl7.org/fhir/StructureDefinition/', '');\n return input.map((value) => ({\n type: PropertyType.boolean,\n value: (value.value as Record<string, unknown>)?.resourceType === expectedResourceType,\n }));\n },\n\n /*\n * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n * 6.5 Boolean logic\n * See: https://hl7.org/fhirpath/#boolean-logic\n * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n */\n\n not: (context: AtomContext, input: TypedValue[]): TypedValue[] => {\n return functions.toBoolean(context, input).map((value) => ({ type: PropertyType.boolean, value: !value.value }));\n },\n\n /*\n * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n * FHIR-specific functions\n * See: https://hl7.org/fhir/fhirpath.html#functions\n * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n */\n\n resolve: (_context: AtomContext, input: TypedValue[]): TypedValue[] => {\n return input\n .map((e) => {\n const value = e.value;\n let refStr: string | undefined;\n if (typeof value === 'string') {\n refStr = value;\n } else if (typeof value === 'object' && value !== null) {\n const ref = value as Record<string, unknown>;\n if (ref.reference && typeof ref.reference === 'string') {\n refStr = ref.reference;\n }\n }\n if (refStr?.includes('/')) {\n const [resourceType, id] = refStr.split('/');\n return { type: resourceType, value: { resourceType, id } };\n }\n return { type: PropertyType.BackboneElement, value: undefined };\n })\n .filter((e) => !!e.value);\n },\n\n extension: (context: AtomContext, input: TypedValue[], urlAtom: Atom): TypedValue[] => {\n const url = urlAtom.eval(context, input)[0]?.value as string;\n const result: TypedValue[] = [];\n for (const item of input) {\n const value = item.value;\n if (value && typeof value === 'object') {\n const extensions = (value as Record<string, unknown>).extension;\n if (Array.isArray(extensions)) {\n for (const ext of extensions) {\n if (ext && typeof ext === 'object' && (ext as Record<string, unknown>).url === url) {\n result.push({ type: PropertyType.Extension, value: ext });\n }\n }\n }\n }\n }\n return result;\n },\n\n htmlChecks: (): TypedValue[] => {\n return booleanToTypedValue(true);\n },\n};\n", "/**\n * LRU (Least Recently Used) Cache for parsed FHIRPath expressions.\n *\n * Caches parsed AST nodes so that repeated evaluation of the same\n * expression string avoids re-parsing.\n *\n * @module fhirpath\n */\n\n// =============================================================================\n// LRU Cache\n// =============================================================================\n\n/**\n * A generic LRU cache with O(1) get/set via a Map (insertion-ordered).\n *\n * When the cache exceeds `maxSize`, the least-recently-used entry is evicted.\n *\n * @typeParam K - Key type.\n * @typeParam V - Value type.\n */\nexport class LRUCache<K, V> {\n private readonly map = new Map<K, V>();\n private readonly _maxSize: number;\n\n /** Total number of `get` calls. */\n private _gets = 0;\n /** Number of `get` calls that returned a cached value. */\n private _hits = 0;\n\n constructor(maxSize: number) {\n if (maxSize < 1) {\n throw new RangeError('LRUCache maxSize must be >= 1');\n }\n this._maxSize = maxSize;\n }\n\n /** Maximum number of entries before eviction. */\n get maxSize(): number {\n return this._maxSize;\n }\n\n /** Current number of cached entries. */\n get size(): number {\n return this.map.size;\n }\n\n /** Total `get` calls since creation or last `resetStats()`. */\n get gets(): number {\n return this._gets;\n }\n\n /** Cache hits since creation or last `resetStats()`. */\n get hits(): number {\n return this._hits;\n }\n\n /**\n * Cache hit rate as a number between 0 and 1.\n * Returns 0 if no `get` calls have been made.\n */\n get hitRate(): number {\n return this._gets === 0 ? 0 : this._hits / this._gets;\n }\n\n /**\n * Retrieve a value by key.\n *\n * If found, the entry is promoted to most-recently-used.\n */\n get(key: K): V | undefined {\n this._gets++;\n const value = this.map.get(key);\n if (value === undefined) {\n return undefined;\n }\n // Promote to most-recently-used by re-inserting\n this.map.delete(key);\n this.map.set(key, value);\n this._hits++;\n return value;\n }\n\n /**\n * Insert or update a key-value pair.\n *\n * If the key already exists it is updated and promoted.\n * If the cache is full the least-recently-used entry is evicted.\n */\n set(key: K, value: V): void {\n if (this.map.has(key)) {\n this.map.delete(key);\n } else if (this.map.size >= this._maxSize) {\n // Evict the least-recently-used (first key in Map iteration order)\n const firstKey = this.map.keys().next().value as K;\n this.map.delete(firstKey);\n }\n this.map.set(key, value);\n }\n\n /** Check whether a key exists without affecting LRU order or stats. */\n has(key: K): boolean {\n return this.map.has(key);\n }\n\n /** Remove a specific key. Returns `true` if the key existed. */\n delete(key: K): boolean {\n return this.map.delete(key);\n }\n\n /** Remove all entries. Does not reset stats. */\n clear(): void {\n this.map.clear();\n }\n\n /** Reset hit/get counters to zero. */\n resetStats(): void {\n this._gets = 0;\n this._hits = 0;\n }\n\n /** Iterate over entries in LRU order (least-recent first). */\n *entries(): IterableIterator<[K, V]> {\n yield* this.map.entries();\n }\n\n /** Iterate over keys in LRU order (least-recent first). */\n *keys(): IterableIterator<K> {\n yield* this.map.keys();\n }\n}\n\n// =============================================================================\n// Default expression cache singleton\n// =============================================================================\n\n/** Default cache size for parsed FHIRPath expressions. */\nexport const DEFAULT_CACHE_SIZE = 1000;\n\n/** Singleton expression cache used by the high-level API. */\nlet expressionCache = new LRUCache<string, unknown>(DEFAULT_CACHE_SIZE);\n\n/**\n * Get the global expression cache instance.\n * The cache stores parsed FHIRPath AST nodes keyed by expression string.\n */\nexport function getExpressionCache(): LRUCache<string, unknown> {\n return expressionCache;\n}\n\n/**\n * Replace the global expression cache (e.g. to change max size).\n */\nexport function setExpressionCache(cache: LRUCache<string, unknown>): void {\n expressionCache = cache;\n}\n\n/**\n * Clear the global expression cache.\n */\nexport function clearExpressionCache(): void {\n expressionCache.clear();\n expressionCache.resetStats();\n}\n", "/**\n * FHIRPath Parser\n *\n * Builds a Pratt parser configured with FHIRPath-specific parselets,\n * and provides the public API for parsing and evaluating FHIRPath expressions.\n *\n * @module fhirpath\n */\n\nimport type { Atom } from './types.js';\nimport { PropertyType } from './types.js';\nimport type { TypedValue } from './types.js';\nimport type { InfixParselet, PrefixParselet } from './lexer/parse.js';\nimport { ParserBuilder } from './lexer/parse.js';\nimport type { Parser } from './lexer/parse.js';\nimport {\n ArithmeticOperatorAtom,\n AndAtom,\n AsAtom,\n ConcatAtom,\n ContainsAtom,\n DotAtom,\n EmptySetAtom,\n EqualsAtom,\n EquivalentAtom,\n FhirPathAtom,\n FunctionAtom,\n ImpliesAtom,\n InAtom,\n IndexerAtom,\n IsAtom,\n LiteralAtom,\n NotEqualsAtom,\n NotEquivalentAtom,\n OrAtom,\n SymbolAtom,\n UnaryOperatorAtom,\n UnionAtom,\n XorAtom,\n setFunctionRegistry,\n} from './atoms.js';\nimport { parseDateString } from './date.js';\nimport { tokenize } from './tokenize.js';\nimport { toTypedValue, toJsBoolean } from './utils.js';\nimport { functions } from './functions.js';\nimport { getExpressionCache } from './cache.js';\n\n// Wire the function registry into atoms\nsetFunctionRegistry(functions);\n\n// =============================================================================\n// Operator Precedence\n// =============================================================================\n\n/**\n * FHIRPath operator precedence levels.\n * Lower number = tighter binding.\n * @see https://hl7.org/fhirpath/#operator-precedence\n */\nexport const OperatorPrecedence = {\n FunctionCall: 0,\n Dot: 1,\n Indexer: 2,\n UnaryAdd: 3,\n UnarySubtract: 3,\n Multiply: 4,\n Divide: 4,\n IntegerDivide: 4,\n Modulo: 4,\n Add: 5,\n Subtract: 5,\n Ampersand: 5,\n Is: 6,\n As: 6,\n Union: 7,\n GreaterThan: 8,\n GreaterThanOrEquals: 8,\n LessThan: 8,\n LessThanOrEquals: 8,\n Equals: 9,\n Equivalent: 9,\n NotEquals: 9,\n NotEquivalent: 9,\n In: 10,\n Contains: 10,\n And: 11,\n Xor: 12,\n Or: 12,\n Implies: 13,\n} as const;\n\n// =============================================================================\n// Parselets\n// =============================================================================\n\nconst PARENTHESES_PARSELET: PrefixParselet = {\n parse(parser: Parser) {\n const expr = parser.consumeAndParse();\n if (!parser.match(')')) {\n throw new Error('Parse error: expected `)` got `' + parser.peek()?.value + '`');\n }\n return expr;\n },\n};\n\nconst INDEXER_PARSELET: InfixParselet = {\n parse(parser: Parser, left: Atom) {\n const expr = parser.consumeAndParse();\n if (!parser.match(']')) {\n throw new Error('Parse error: expected `]`');\n }\n return new IndexerAtom(left, expr);\n },\n precedence: OperatorPrecedence.Indexer,\n};\n\nconst FUNCTION_CALL_PARSELET: InfixParselet = {\n parse(parser: Parser, left: Atom) {\n if (!(left instanceof SymbolAtom)) {\n throw new Error('Unexpected parentheses');\n }\n const args: Atom[] = [];\n while (!parser.match(')')) {\n args.push(parser.consumeAndParse());\n parser.match(',');\n }\n return new FunctionAtom(left.name, args);\n },\n precedence: OperatorPrecedence.FunctionCall,\n};\n\n// =============================================================================\n// Quantity parsing\n// =============================================================================\n\ninterface QuantityLiteral {\n value: number;\n unit?: string;\n}\n\nfunction parseQuantity(str: string): QuantityLiteral {\n const parts = str.split(' ');\n const value = Number.parseFloat(parts[0]);\n let unit = parts[1];\n if (unit?.startsWith(\"'\") && unit.endsWith(\"'\")) {\n unit = unit.substring(1, unit.length - 1);\n } else if (unit) {\n unit = '{' + unit + '}';\n }\n return { value, unit };\n}\n\n// =============================================================================\n// Parser Builder\n// =============================================================================\n\n/**\n * Initialize the FHIRPath parser builder with all prefix and infix parselets.\n */\nexport function initFhirPathParserBuilder(): ParserBuilder {\n return new ParserBuilder()\n // \u2500\u2500 Prefix parselets (literals, symbols, grouping) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n .registerPrefix('String', {\n parse: (_, token) => new LiteralAtom({ type: PropertyType.string, value: token.value }),\n })\n .registerPrefix('DateTime', {\n parse: (_, token) => new LiteralAtom({ type: PropertyType.dateTime, value: parseDateString(token.value) }),\n })\n .registerPrefix('Quantity', {\n parse: (_, token) => new LiteralAtom({ type: PropertyType.Quantity, value: parseQuantity(token.value) }),\n })\n .registerPrefix('Number', {\n parse: (_, token) =>\n new LiteralAtom({\n type: token.value.includes('.') ? PropertyType.decimal : PropertyType.integer,\n value: Number.parseFloat(token.value),\n }),\n })\n .registerPrefix('true', { parse: () => new LiteralAtom({ type: PropertyType.boolean, value: true }) })\n .registerPrefix('false', { parse: () => new LiteralAtom({ type: PropertyType.boolean, value: false }) })\n .registerPrefix('Symbol', { parse: (_, token) => new SymbolAtom(token.value) })\n .registerPrefix('{}', { parse: () => new EmptySetAtom() })\n .registerPrefix('(', PARENTHESES_PARSELET)\n\n // \u2500\u2500 Infix parselets (indexer, function call) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n .registerInfix('[', INDEXER_PARSELET)\n .registerInfix('(', FUNCTION_CALL_PARSELET)\n\n // \u2500\u2500 Prefix operators \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n .prefix('+', OperatorPrecedence.UnaryAdd, (_, right) => new UnaryOperatorAtom('+', right, (x) => x))\n .prefix(\n '-',\n OperatorPrecedence.UnarySubtract,\n (_, right) => new ArithmeticOperatorAtom('-', right, right, (_, y) => -y),\n )\n\n // \u2500\u2500 Dot (property navigation) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n .infixLeft('.', OperatorPrecedence.Dot, (left, _, right) => new DotAtom(left, right))\n\n // \u2500\u2500 Arithmetic operators \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n .infixLeft('/', OperatorPrecedence.Divide, (left, _, right) =>\n new ArithmeticOperatorAtom('/', left, right, (x, y) => x / y))\n .infixLeft('*', OperatorPrecedence.Multiply, (left, _, right) =>\n new ArithmeticOperatorAtom('*', left, right, (x, y) => x * y))\n .infixLeft('+', OperatorPrecedence.Add, (left, _, right) =>\n new ArithmeticOperatorAtom('+', left, right, (x, y) => x + y))\n .infixLeft('-', OperatorPrecedence.Subtract, (left, _, right) =>\n new ArithmeticOperatorAtom('-', left, right, (x, y) => x - y))\n .infixLeft('div', OperatorPrecedence.IntegerDivide, (left, _, right) =>\n new ArithmeticOperatorAtom('div', left, right, (x, y) => Math.trunc(x / y)))\n .infixLeft('mod', OperatorPrecedence.Modulo, (left, _, right) =>\n new ArithmeticOperatorAtom('mod', left, right, (x, y) => x % y))\n\n // \u2500\u2500 String concatenation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n .infixLeft('&', OperatorPrecedence.Ampersand, (left, _, right) => new ConcatAtom(left, right))\n\n // \u2500\u2500 Union \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n .infixLeft('|', OperatorPrecedence.Union, (left, _, right) => new UnionAtom(left, right))\n\n // \u2500\u2500 Comparison operators \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n .infixLeft('<', OperatorPrecedence.LessThan, (left, _, right) =>\n new ArithmeticOperatorAtom('<', left, right, (x, y) => x < y))\n .infixLeft('<=', OperatorPrecedence.LessThanOrEquals, (left, _, right) =>\n new ArithmeticOperatorAtom('<=', left, right, (x, y) => x <= y))\n .infixLeft('>', OperatorPrecedence.GreaterThan, (left, _, right) =>\n new ArithmeticOperatorAtom('>', left, right, (x, y) => x > y))\n .infixLeft('>=', OperatorPrecedence.GreaterThanOrEquals, (left, _, right) =>\n new ArithmeticOperatorAtom('>=', left, right, (x, y) => x >= y))\n\n // \u2500\u2500 Equality / equivalence \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n .infixLeft('=', OperatorPrecedence.Equals, (left, _, right) => new EqualsAtom(left, right))\n .infixLeft('!=', OperatorPrecedence.NotEquals, (left, _, right) => new NotEqualsAtom(left, right))\n .infixLeft('~', OperatorPrecedence.Equivalent, (left, _, right) => new EquivalentAtom(left, right))\n .infixLeft('!~', OperatorPrecedence.NotEquivalent, (left, _, right) => new NotEquivalentAtom(left, right))\n\n // \u2500\u2500 Type operators \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n .infixLeft('as', OperatorPrecedence.As, (left, _, right) => new AsAtom(left, right))\n .infixLeft('is', OperatorPrecedence.Is, (left, _, right) => new IsAtom(left, right))\n\n // \u2500\u2500 Membership operators \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n .infixLeft('contains', OperatorPrecedence.Contains, (left, _, right) => new ContainsAtom(left, right))\n .infixLeft('in', OperatorPrecedence.In, (left, _, right) => new InAtom(left, right))\n\n // \u2500\u2500 Boolean operators \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n .infixLeft('and', OperatorPrecedence.And, (left, _, right) => new AndAtom(left, right))\n .infixLeft('or', OperatorPrecedence.Or, (left, _, right) => new OrAtom(left, right))\n .infixLeft('xor', OperatorPrecedence.Xor, (left, _, right) => new XorAtom(left, right))\n .infixLeft('implies', OperatorPrecedence.Implies, (left, _, right) => new ImpliesAtom(left, right));\n}\n\n// Singleton builder instance\nconst fhirPathParserBuilder = initFhirPathParserBuilder();\n\n// =============================================================================\n// Public API\n// =============================================================================\n\n/**\n * Parse a FHIRPath expression string into an AST.\n * Results are cached in the global expression cache for reuse.\n *\n * @param input - The FHIRPath expression string.\n * @returns The parsed AST as a {@link FhirPathAtom}.\n */\nexport function parseFhirPath(input: string): FhirPathAtom {\n const cache = getExpressionCache();\n const cached = cache.get(input) as FhirPathAtom | undefined;\n if (cached) {\n return cached;\n }\n const tokens = tokenize(input);\n const parser = fhirPathParserBuilder.construct(tokens);\n parser.removeComments();\n const ast = new FhirPathAtom(input, parser.consumeAndParse());\n cache.set(input, ast);\n return ast;\n}\n\n/**\n * Evaluate a FHIRPath expression against a resource or other object.\n * Accepts raw values (auto-wrapped in TypedValue) or pre-wrapped TypedValue arrays.\n *\n * @param expression - The FHIRPath expression string or pre-parsed AST.\n * @param input - The resource or object to evaluate against.\n * @returns Array of result values (unwrapped from TypedValue).\n */\nexport function evalFhirPath(expression: string | FhirPathAtom, input: unknown): unknown[] {\n const array = Array.isArray(input) ? input : [input];\n for (let i = 0; i < array.length; i++) {\n const el = array[i];\n if (!(typeof el === 'object' && el !== null && 'type' in el && 'value' in el)) {\n array[i] = toTypedValue(array[i]);\n }\n }\n return evalFhirPathTyped(expression, array as TypedValue[]).map((e) => e.value);\n}\n\n/**\n * Evaluate a FHIRPath expression against typed input values.\n *\n * @param expression - The FHIRPath expression string or pre-parsed AST.\n * @param input - Array of TypedValue inputs.\n * @param variables - Optional variable bindings.\n * @returns Array of TypedValue results.\n */\nexport function evalFhirPathTyped(\n expression: string | FhirPathAtom,\n input: TypedValue[],\n variables: Record<string, TypedValue> = {},\n): TypedValue[] {\n const ast = typeof expression === 'string' ? parseFhirPath(expression) : expression;\n return ast.eval({ variables }, input).map((v) => ({\n type: v.type,\n value: v.value?.valueOf(),\n }));\n}\n\n// =============================================================================\n// High-level convenience API\n// =============================================================================\n\n/**\n * Evaluate a FHIRPath expression and return a boolean result.\n *\n * Useful for invariant validation where the expression must evaluate to `true`.\n * Uses FHIRPath boolean semantics: empty \u2192 false, single truthy \u2192 true.\n *\n * @param expression - FHIRPath expression string or pre-parsed AST.\n * @param input - The resource or typed values to evaluate against.\n * @param variables - Optional variable bindings.\n * @returns Boolean result of the expression.\n */\nexport function evalFhirPathBoolean(\n expression: string | FhirPathAtom,\n input: unknown,\n variables: Record<string, TypedValue> = {},\n): boolean {\n const array = Array.isArray(input) ? input : [input];\n for (let i = 0; i < array.length; i++) {\n const el = array[i];\n if (!(typeof el === 'object' && el !== null && 'type' in el && 'value' in el)) {\n array[i] = toTypedValue(array[i]);\n }\n }\n const result = evalFhirPathTyped(expression, array as TypedValue[], variables);\n return toJsBoolean(result);\n}\n\n/**\n * Evaluate a FHIRPath expression and return the first result as a string.\n *\n * Useful for extracting display values, identifiers, etc.\n *\n * @param expression - FHIRPath expression string or pre-parsed AST.\n * @param input - The resource or typed values to evaluate against.\n * @param variables - Optional variable bindings.\n * @returns The first result value as a string, or `undefined` if empty.\n */\nexport function evalFhirPathString(\n expression: string | FhirPathAtom,\n input: unknown,\n variables: Record<string, TypedValue> = {},\n): string | undefined {\n const results = evalFhirPath(expression, input);\n if (results.length === 0) {\n return undefined;\n }\n const first = results[0];\n return first === undefined || first === null ? undefined : String(first);\n}\n", "/**\n * FHIRPath Invariant Validator\n *\n * Evaluates FHIRPath constraint expressions from StructureDefinition\n * elements and reports violations as ValidationIssues.\n *\n * @module validator\n */\n\nimport type { Invariant, CanonicalElement } from '../model/canonical-profile.js';\nimport type { ValidationIssue } from './types.js';\nimport { createValidationIssue } from './types.js';\nimport { evalFhirPathBoolean } from '../fhirpath/parse.js';\nimport { toTypedValue } from '../fhirpath/utils.js';\nimport type { TypedValue } from '../fhirpath/types.js';\n\n// =============================================================================\n// Public API\n// =============================================================================\n\n/**\n * Options for invariant validation.\n */\nexport interface InvariantValidationOptions {\n /** Skip all invariant evaluation. */\n skipInvariants?: boolean;\n /** Skip invariants from inherited profiles (only evaluate local constraints). */\n skipInheritedInvariants?: boolean;\n /** Profile URL of the current profile (used to filter inherited constraints). */\n currentProfileUrl?: string;\n}\n\n/**\n * Validate FHIRPath invariants (constraint.expression) on a single element value.\n *\n * For each constraint on the element that has an expression, the expression\n * is evaluated against the value. If it evaluates to `false`, a validation\n * issue is recorded.\n *\n * @param element - The canonical element with constraints.\n * @param value - The value at the element path (raw JS value).\n * @param resource - The root resource being validated (for %resource context).\n * @param issues - Mutable array to push validation issues into.\n * @param options - Validation options.\n */\nexport function validateInvariants(\n element: CanonicalElement,\n value: unknown,\n resource: unknown,\n issues: ValidationIssue[],\n options: InvariantValidationOptions = {},\n): void {\n if (options.skipInvariants) {\n return;\n }\n\n if (!element.constraints || element.constraints.length === 0) {\n return;\n }\n\n for (const constraint of element.constraints) {\n validateSingleInvariant(constraint, element.path, value, resource, issues, options);\n }\n}\n\n/**\n * Validate a single FHIRPath invariant constraint.\n *\n * @param constraint - The invariant to validate.\n * @param path - The element path for error reporting.\n * @param value - The value to validate.\n * @param resource - The root resource.\n * @param issues - Mutable array to push issues into.\n * @param options - Validation options.\n */\nexport function validateSingleInvariant(\n constraint: Invariant,\n path: string,\n value: unknown,\n resource: unknown,\n issues: ValidationIssue[],\n options: InvariantValidationOptions = {},\n): void {\n // Skip constraints without expression (human-only)\n if (!constraint.expression) {\n return;\n }\n\n // Skip inherited invariants if requested\n if (\n options.skipInheritedInvariants &&\n options.currentProfileUrl &&\n constraint.source &&\n constraint.source !== options.currentProfileUrl\n ) {\n return;\n }\n\n try {\n const typedValue = toTypedValue(value);\n const typedResource = toTypedValue(resource);\n\n // Build variables for the FHIRPath context\n const variables: Record<string, TypedValue> = {\n '%resource': typedResource,\n };\n\n const result = evalFhirPathBoolean(constraint.expression, [typedValue], variables);\n\n if (!result) {\n issues.push(\n createValidationIssue(\n constraint.severity === 'error' ? 'error' : 'warning',\n 'INVARIANT_VIOLATION',\n constraint.human || `Constraint '${constraint.key}' failed`,\n {\n path,\n expression: constraint.expression,\n diagnostics: `Constraint key: ${constraint.key}`,\n },\n ),\n );\n }\n } catch (error: unknown) {\n // FHIRPath evaluation error \u2014 report as warning, don't block validation\n const message = error instanceof Error ? error.message : String(error);\n issues.push(\n createValidationIssue(\n 'warning',\n 'INVARIANT_EVALUATION_ERROR',\n `Failed to evaluate constraint '${constraint.key}': ${message}`,\n {\n path,\n expression: constraint.expression,\n diagnostics: message,\n },\n ),\n );\n }\n}\n\n/**\n * Validate all invariants for multiple element-value pairs.\n *\n * Convenience function for batch validation of all constraints\n * across a resource's elements.\n *\n * @param elements - Array of [element, values] pairs.\n * @param resource - The root resource.\n * @param options - Validation options.\n * @returns Array of validation issues.\n */\nexport function validateAllInvariants(\n elements: Array<{ element: CanonicalElement; values: unknown[] }>,\n resource: unknown,\n options: InvariantValidationOptions = {},\n): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n\n if (options.skipInvariants) {\n return issues;\n }\n\n for (const { element, values } of elements) {\n for (const value of values) {\n validateInvariants(element, value, resource, issues, options);\n }\n }\n\n return issues;\n}\n", "/**\n * fhir-validator \u2014 Structure Validator (Orchestrator)\n *\n * Main validator class that coordinates all validation rules to validate\n * a FHIR resource instance against a {@link CanonicalProfile}.\n *\n * Integrates:\n * - Path extraction ({@link extractValues})\n * - Cardinality validation ({@link validateCardinality})\n * - Type validation ({@link validateType})\n * - Fixed/pattern validation ({@link validateFixed}, {@link validatePattern})\n * - Reference validation ({@link validateReference})\n * - Slicing validation ({@link validateSlicing})\n *\n * Exported:\n * - {@link StructureValidator} \u2014 main validator class\n *\n * @module fhir-validator\n */\n\nimport type { CanonicalProfile, CanonicalElement, Resource } from '../model/index.js';\nimport type { ValidationOptions, ValidationResult, ValidationIssue } from './types.js';\nimport { createValidationIssue, resolveValidationOptions } from './types.js';\nimport { ProfileNotFoundError, ValidationFailedError } from './errors.js';\nimport { extractValues } from './path-extractor.js';\nimport {\n validateCardinality,\n validateType,\n validateFixed,\n validatePattern,\n validateReference,\n} from './validation-rules.js';\nimport { validateSlicing } from './slicing-validator.js';\nimport { validateInvariants } from './invariant-validator.js';\n\n// =============================================================================\n// Section 1: StructureValidator\n// =============================================================================\n\n/**\n * Main validator class for structural validation of FHIR resources.\n *\n * Validates a resource instance against a {@link CanonicalProfile} by\n * orchestrating all individual validation rules (cardinality, type,\n * fixed/pattern, reference, slicing).\n *\n * @example\n * ```typescript\n * const validator = new StructureValidator();\n *\n * // Validate with an explicit profile\n * const result = validator.validate(patient, patientProfile);\n *\n * if (!result.valid) {\n * for (const issue of result.issues) {\n * console.error(`${issue.severity}: ${issue.message}`);\n * }\n * }\n * ```\n */\nexport class StructureValidator {\n private readonly options: Required<ValidationOptions>;\n\n constructor(options?: ValidationOptions) {\n this.options = resolveValidationOptions(options);\n }\n\n // ===========================================================================\n // Public API\n // ===========================================================================\n\n /**\n * Validate a resource instance against a CanonicalProfile.\n *\n * @param resource - The FHIR resource to validate.\n * @param profile - The CanonicalProfile to validate against.\n * @param options - Optional per-call overrides for validation options.\n * @returns The validation result with all issues.\n * @throws {@link ProfileNotFoundError} if profile is undefined.\n * @throws {@link ValidationFailedError} if failFast is enabled and an error is found.\n */\n validate(\n resource: Resource,\n profile: CanonicalProfile,\n options?: ValidationOptions,\n ): ValidationResult {\n if (!profile) {\n throw new ProfileNotFoundError('No profile provided for validation');\n }\n\n const opts = options\n ? resolveValidationOptions({ ...this.options, ...options })\n : this.options;\n\n const issues: ValidationIssue[] = [];\n\n // Step 1: Check resource type matches profile type\n this.validateResourceType(resource, profile, issues, opts);\n\n // Step 2: Validate all elements\n this.validateElements(resource, profile, issues, opts, 0);\n\n return {\n valid: !issues.some((i) => i.severity === 'error'),\n resource,\n profileUrl: opts.profileUrl || profile.url,\n profile,\n issues,\n };\n }\n\n // ===========================================================================\n // Private: Resource Type Check\n // ===========================================================================\n\n /**\n * Check that the resource type matches the profile type.\n */\n private validateResourceType(\n resource: Resource,\n profile: CanonicalProfile,\n issues: ValidationIssue[],\n opts: Required<ValidationOptions>,\n ): void {\n if (!resource.resourceType) {\n issues.push(\n createValidationIssue(\n 'error',\n 'RESOURCE_TYPE_MISMATCH',\n `Resource is missing 'resourceType' property`,\n ),\n );\n this.checkFailFast(opts, issues);\n return;\n }\n\n if (resource.resourceType !== profile.type) {\n issues.push(\n createValidationIssue(\n 'error',\n 'RESOURCE_TYPE_MISMATCH',\n `Expected resourceType '${profile.type}', but found '${resource.resourceType}'`,\n {\n diagnostics: `Expected: ${profile.type}, Actual: ${resource.resourceType}`,\n },\n ),\n );\n this.checkFailFast(opts, issues);\n }\n }\n\n // ===========================================================================\n // Private: Element Traversal\n // ===========================================================================\n\n /**\n * Validate all elements in the profile against the resource.\n */\n private validateElements(\n resource: Resource,\n profile: CanonicalProfile,\n issues: ValidationIssue[],\n opts: Required<ValidationOptions>,\n depth: number,\n ): void {\n if (depth >= opts.maxDepth) {\n issues.push(\n createValidationIssue(\n 'warning',\n 'INTERNAL_ERROR',\n `Maximum validation depth (${opts.maxDepth}) exceeded`,\n { diagnostics: `Depth: ${depth}` },\n ),\n );\n return;\n }\n\n for (const element of profile.elements.values()) {\n // Skip root element (already validated via resourceType check)\n if (element.path === profile.type) continue;\n\n // Skip slice-specific elements (handled by slicing validation)\n if (element.sliceName) continue;\n\n // Extract values from resource at this element's path\n const values = extractValues(resource as unknown as Record<string, unknown>, element.path);\n\n // Validate cardinality\n validateCardinality(element, values, issues);\n this.checkFailFast(opts, issues);\n\n // Validate each value individually\n for (const value of values) {\n // Type validation\n validateType(element, value, issues);\n this.checkFailFast(opts, issues);\n\n // Fixed/pattern validation\n if (opts.validateFixed) {\n validateFixed(element, value, issues);\n validatePattern(element, value, issues);\n this.checkFailFast(opts, issues);\n }\n\n // Reference validation\n if (element.types.some((t) => t.code === 'Reference')) {\n validateReference(element, value, issues);\n this.checkFailFast(opts, issues);\n }\n }\n\n // FHIRPath invariant validation\n if (!opts.skipInvariants && element.constraints && element.constraints.length > 0) {\n for (const value of values) {\n validateInvariants(element, value, resource, issues, {\n skipInvariants: opts.skipInvariants,\n });\n this.checkFailFast(opts, issues);\n }\n }\n\n // Slicing validation\n if (opts.validateSlicing && element.slicing) {\n const sliceElements = this.getSliceElements(profile, element.path);\n validateSlicing(element, sliceElements, values, issues);\n this.checkFailFast(opts, issues);\n }\n }\n }\n\n // ===========================================================================\n // Private: Helpers\n // ===========================================================================\n\n /**\n * Get all named slice elements for a slicing root path.\n */\n private getSliceElements(\n profile: CanonicalProfile,\n slicingRootPath: string,\n ): CanonicalElement[] {\n const slices: CanonicalElement[] = [];\n\n for (const element of profile.elements.values()) {\n if (element.path === slicingRootPath && element.sliceName) {\n slices.push(element);\n }\n }\n\n return slices;\n }\n\n /**\n * Check if failFast is enabled and there are errors; if so, throw.\n */\n private checkFailFast(\n opts: Required<ValidationOptions>,\n issues: ValidationIssue[],\n ): void {\n if (opts.failFast && issues.some((i) => i.severity === 'error')) {\n throw new ValidationFailedError(\n 'Validation failed (failFast enabled)',\n issues,\n );\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["underscoreKey", "result", "parentPath", "readFile", "join", "join", "readFile", "readFileSync", "readFileSync", "parentPath", "parentPath", "diffElements", "hasErrors", "ensureElementIds", "cloneElement", "diffsConstrainTypes", "getInnerDiffScope", "parentPath", "isTypeCompatible", "capitalize", "_"]
|
|
7
|
+
}
|