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,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FHIR JSON Parse Error Types
|
|
3
|
+
*
|
|
4
|
+
* Structured error types for the fhir-parser module. Provides precise
|
|
5
|
+
* error localization via JSON path tracking and supports collecting
|
|
6
|
+
* multiple issues (errors + warnings) in a single parse pass.
|
|
7
|
+
*
|
|
8
|
+
* Design decisions:
|
|
9
|
+
* - Result type over exceptions: allows multi-error collection
|
|
10
|
+
* - Path tracking: every issue carries the JSON path for precise localization
|
|
11
|
+
* - Warning support: non-fatal issues (e.g., unknown properties) reported
|
|
12
|
+
* as warnings without blocking the parse
|
|
13
|
+
*
|
|
14
|
+
* @module fhir-parser
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Severity level of a parse issue.
|
|
18
|
+
*
|
|
19
|
+
* - `error` — the issue prevents correct interpretation of the data
|
|
20
|
+
* - `warning` — the data can still be used, but something unexpected was found
|
|
21
|
+
*/
|
|
22
|
+
export type ParseSeverity = 'error' | 'warning';
|
|
23
|
+
/**
|
|
24
|
+
* Machine-readable error codes for parse issues.
|
|
25
|
+
*
|
|
26
|
+
* Each code corresponds to a specific category of parsing problem.
|
|
27
|
+
* Consumers can switch on these codes for programmatic error handling.
|
|
28
|
+
*/
|
|
29
|
+
export type ParseErrorCode =
|
|
30
|
+
/** JSON syntax error (e.g., malformed JSON string) */
|
|
31
|
+
'INVALID_JSON'
|
|
32
|
+
/** Missing required `resourceType` property */
|
|
33
|
+
| 'MISSING_RESOURCE_TYPE'
|
|
34
|
+
/** `resourceType` value is not a recognized FHIR resource type */
|
|
35
|
+
| 'UNKNOWN_RESOURCE_TYPE'
|
|
36
|
+
/** Primitive value has wrong JavaScript type (e.g., string where number expected) */
|
|
37
|
+
| 'INVALID_PRIMITIVE'
|
|
38
|
+
/** Object structure does not match expected shape (e.g., array where object expected) */
|
|
39
|
+
| 'INVALID_STRUCTURE'
|
|
40
|
+
/** Choice type `[x]` property name has an unrecognized type suffix */
|
|
41
|
+
| 'INVALID_CHOICE_TYPE'
|
|
42
|
+
/** Multiple variants of the same choice type field are present */
|
|
43
|
+
| 'MULTIPLE_CHOICE_VALUES'
|
|
44
|
+
/** `_element` array length does not match the corresponding value array */
|
|
45
|
+
| 'ARRAY_MISMATCH'
|
|
46
|
+
/** Unexpected `null` value in a non-nullable position */
|
|
47
|
+
| 'UNEXPECTED_NULL'
|
|
48
|
+
/** Property name not recognized for this type (severity: warning) */
|
|
49
|
+
| 'UNEXPECTED_PROPERTY';
|
|
50
|
+
/**
|
|
51
|
+
* A single issue encountered during parsing.
|
|
52
|
+
*
|
|
53
|
+
* Issues are collected throughout the parse process and returned in the
|
|
54
|
+
* {@link ParseResult}. Both errors and warnings use this same structure.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```typescript
|
|
58
|
+
* const issue: ParseIssue = {
|
|
59
|
+
* severity: 'error',
|
|
60
|
+
* code: 'MISSING_RESOURCE_TYPE',
|
|
61
|
+
* message: 'Object is missing the required "resourceType" property',
|
|
62
|
+
* path: '$',
|
|
63
|
+
* };
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export interface ParseIssue {
|
|
67
|
+
/** Severity level — `error` blocks successful parsing, `warning` does not */
|
|
68
|
+
readonly severity: ParseSeverity;
|
|
69
|
+
/** Machine-readable error code for programmatic handling */
|
|
70
|
+
readonly code: ParseErrorCode;
|
|
71
|
+
/** Human-readable description of the issue */
|
|
72
|
+
readonly message: string;
|
|
73
|
+
/**
|
|
74
|
+
* JSON path where the issue was detected.
|
|
75
|
+
*
|
|
76
|
+
* Uses dot notation with array indices:
|
|
77
|
+
* - `"StructureDefinition"` — root level
|
|
78
|
+
* - `"StructureDefinition.snapshot.element[0].type[1].code"` — nested
|
|
79
|
+
* - `"$"` — before resourceType is known
|
|
80
|
+
*/
|
|
81
|
+
readonly path: string;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Result of a parse operation.
|
|
85
|
+
*
|
|
86
|
+
* Uses a discriminated union on `success`:
|
|
87
|
+
* - `success: true` — parsing succeeded; `data` contains the parsed value,
|
|
88
|
+
* `issues` may contain warnings
|
|
89
|
+
* - `success: false` — parsing failed; `data` is `undefined`,
|
|
90
|
+
* `issues` contains at least one error
|
|
91
|
+
*
|
|
92
|
+
* @typeParam T - The expected output type (e.g., `StructureDefinition`)
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```typescript
|
|
96
|
+
* const result = parseFhirJson(jsonString);
|
|
97
|
+
* if (result.success) {
|
|
98
|
+
* console.log(result.data.url); // T is available
|
|
99
|
+
* } else {
|
|
100
|
+
* for (const issue of result.issues) {
|
|
101
|
+
* console.error(`[${issue.path}] ${issue.message}`);
|
|
102
|
+
* }
|
|
103
|
+
* }
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
export type ParseResult<T> = {
|
|
107
|
+
readonly success: true;
|
|
108
|
+
readonly data: T;
|
|
109
|
+
readonly issues: readonly ParseIssue[];
|
|
110
|
+
} | {
|
|
111
|
+
readonly success: false;
|
|
112
|
+
readonly data: undefined;
|
|
113
|
+
readonly issues: readonly ParseIssue[];
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Create a successful parse result.
|
|
117
|
+
*
|
|
118
|
+
* @param data - The parsed value
|
|
119
|
+
* @param issues - Any warnings collected during parsing (default: none)
|
|
120
|
+
*/
|
|
121
|
+
export declare function parseSuccess<T>(data: T, issues?: ParseIssue[]): ParseResult<T>;
|
|
122
|
+
/**
|
|
123
|
+
* Create a failed parse result.
|
|
124
|
+
*
|
|
125
|
+
* @param issues - The error(s) that caused the failure (must contain at least one error)
|
|
126
|
+
*/
|
|
127
|
+
export declare function parseFailure<T>(issues: ParseIssue[]): ParseResult<T>;
|
|
128
|
+
/**
|
|
129
|
+
* Create a single parse issue.
|
|
130
|
+
*
|
|
131
|
+
* Convenience factory to reduce boilerplate when constructing issues.
|
|
132
|
+
*
|
|
133
|
+
* @param severity - Error or warning
|
|
134
|
+
* @param code - Machine-readable error code
|
|
135
|
+
* @param message - Human-readable description
|
|
136
|
+
* @param path - JSON path where the issue was detected
|
|
137
|
+
*/
|
|
138
|
+
export declare function createIssue(severity: ParseSeverity, code: ParseErrorCode, message: string, path: string): ParseIssue;
|
|
139
|
+
/**
|
|
140
|
+
* Check whether an issues array contains at least one error (not just warnings).
|
|
141
|
+
*
|
|
142
|
+
* Useful for determining whether to return success or failure after
|
|
143
|
+
* collecting issues from sub-parsers.
|
|
144
|
+
*/
|
|
145
|
+
export declare function hasErrors(issues: readonly ParseIssue[]): boolean;
|
|
146
|
+
//# sourceMappingURL=parse-error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-error.d.ts","sourceRoot":"","sources":["../../../src/parser/parse-error.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,SAAS,CAAC;AAEhD;;;;;GAKG;AACH,MAAM,MAAM,cAAc;AACxB,sDAAsD;AACpD,cAAc;AAChB,+CAA+C;GAC7C,uBAAuB;AACzB,kEAAkE;GAChE,uBAAuB;AACzB,qFAAqF;GACnF,mBAAmB;AACrB,yFAAyF;GACvF,mBAAmB;AACrB,sEAAsE;GACpE,qBAAqB;AACvB,kEAAkE;GAChE,wBAAwB;AAC1B,2EAA2E;GACzE,gBAAgB;AAClB,yDAAyD;GACvD,iBAAiB;AACnB,qEAAqE;GACnE,qBAAqB,CAAC;AAM1B;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,UAAU;IACzB,6EAA6E;IAC7E,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IAEjC,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAE9B,8CAA8C;IAC9C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB;;;;;;;OAOG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAMD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,IACrB;IAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,CAAA;CAAE,GACpF;IAAE,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,CAAA;CAAE,CAAC;AAMlG;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,GAAE,UAAU,EAAO,GAAG,WAAW,CAAC,CAAC,CAAC,CAElF;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAKpE;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,aAAa,EACvB,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,GACX,UAAU,CAEZ;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,GAAG,OAAO,CAEhE"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FHIR Primitive Type Parser
|
|
3
|
+
*
|
|
4
|
+
* Handles the FHIR JSON dual-property representation of primitive types:
|
|
5
|
+
* - `name`: the actual value (string | number | boolean)
|
|
6
|
+
* - `_name`: the Element metadata (id, extension)
|
|
7
|
+
*
|
|
8
|
+
* FHIR R4 JSON Representation Rules (§2.6.2):
|
|
9
|
+
* 1. Primitive values appear as JSON string, number, or boolean
|
|
10
|
+
* 2. Element metadata (id, extension) appears under `_name`
|
|
11
|
+
* 3. Either or both may be present
|
|
12
|
+
* 4. For arrays, `null` is used for positional alignment
|
|
13
|
+
*
|
|
14
|
+
* Stage-1 Strategy:
|
|
15
|
+
* - Values are passed through as branded types (no regex validation)
|
|
16
|
+
* - `_element` id and extension are merged onto the result
|
|
17
|
+
* - Regex validation is deferred to fhir-validator (Phase 5)
|
|
18
|
+
*
|
|
19
|
+
* @see https://hl7.org/fhir/R4/json.html#primitive
|
|
20
|
+
* @module fhir-parser
|
|
21
|
+
*/
|
|
22
|
+
import type { ParseIssue } from './parse-error.js';
|
|
23
|
+
/**
|
|
24
|
+
* Expected JavaScript type for a FHIR primitive type name.
|
|
25
|
+
*
|
|
26
|
+
* FHIR R4 JSON type mapping:
|
|
27
|
+
* - `boolean` → JSON boolean
|
|
28
|
+
* - `integer`, `positiveInt`, `unsignedInt` → JSON number (integer)
|
|
29
|
+
* - `decimal` → JSON number
|
|
30
|
+
* - All others → JSON string
|
|
31
|
+
*/
|
|
32
|
+
export type PrimitiveJsType = 'boolean' | 'number' | 'string';
|
|
33
|
+
/**
|
|
34
|
+
* Get the expected JavaScript type for a FHIR primitive type name.
|
|
35
|
+
*
|
|
36
|
+
* Returns `'string'` for unknown type names (safe default).
|
|
37
|
+
*/
|
|
38
|
+
export declare function getExpectedJsType(fhirType: string): PrimitiveJsType;
|
|
39
|
+
/**
|
|
40
|
+
* Validate that a primitive value has the correct JavaScript type.
|
|
41
|
+
*
|
|
42
|
+
* This performs structural validation only (correct JS type). It does NOT
|
|
43
|
+
* validate the value against FHIR regex patterns — that is the responsibility
|
|
44
|
+
* of fhir-validator (Phase 5).
|
|
45
|
+
*
|
|
46
|
+
* @param value - The JSON value to validate
|
|
47
|
+
* @param fhirType - The FHIR primitive type name (e.g., "string", "boolean", "integer")
|
|
48
|
+
* @param path - JSON path for error reporting
|
|
49
|
+
* @returns A `ParseIssue` if validation fails, or `null` if valid
|
|
50
|
+
*/
|
|
51
|
+
export declare function validatePrimitiveValue(value: unknown, fhirType: string, path: string): ParseIssue | null;
|
|
52
|
+
/**
|
|
53
|
+
* The result of parsing a `_element` companion object.
|
|
54
|
+
*
|
|
55
|
+
* Contains the `id` and `extension` fields from the Element base type.
|
|
56
|
+
*/
|
|
57
|
+
export interface ElementMetadata {
|
|
58
|
+
/** Element id (0..1) */
|
|
59
|
+
readonly id?: string;
|
|
60
|
+
/** Extensions (0..*) */
|
|
61
|
+
readonly extension?: unknown[];
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* A merged primitive value combining the JSON value with Element metadata.
|
|
65
|
+
*
|
|
66
|
+
* This is the internal representation produced by the parser for primitive
|
|
67
|
+
* fields that have a `_element` companion.
|
|
68
|
+
*
|
|
69
|
+
* When no `_element` is present, the value is stored directly (not wrapped).
|
|
70
|
+
*/
|
|
71
|
+
export interface PrimitiveWithMetadata {
|
|
72
|
+
/** The primitive value (string | number | boolean), absent when only _element is present */
|
|
73
|
+
readonly value?: unknown;
|
|
74
|
+
/** Element id from _element (0..1) */
|
|
75
|
+
readonly id?: string;
|
|
76
|
+
/** Extensions from _element (0..*) */
|
|
77
|
+
readonly extension?: unknown[];
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Merge a primitive value with its `_element` companion.
|
|
81
|
+
*
|
|
82
|
+
* Handles all combinations:
|
|
83
|
+
* - Value only → returns value directly (no wrapping)
|
|
84
|
+
* - Value + _element → returns `PrimitiveWithMetadata`
|
|
85
|
+
* - _element only (no value) → returns `PrimitiveWithMetadata` with undefined value
|
|
86
|
+
* - Neither → returns `undefined`
|
|
87
|
+
*
|
|
88
|
+
* @param value - The primitive JSON value (string | number | boolean | undefined)
|
|
89
|
+
* @param elementExtension - The `_element` companion object (or undefined)
|
|
90
|
+
* @param fhirType - The FHIR primitive type name (for JS type validation)
|
|
91
|
+
* @param path - JSON path for error reporting
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```typescript
|
|
95
|
+
* // Value only
|
|
96
|
+
* mergePrimitiveElement("1970-03-30", undefined, "date", "Patient.birthDate")
|
|
97
|
+
* // → { result: "1970-03-30", issues: [] }
|
|
98
|
+
*
|
|
99
|
+
* // Value + _element
|
|
100
|
+
* mergePrimitiveElement("1970-03-30", { id: "314159" }, "date", "Patient.birthDate")
|
|
101
|
+
* // → { result: { value: "1970-03-30", id: "314159" }, issues: [] }
|
|
102
|
+
*
|
|
103
|
+
* // _element only
|
|
104
|
+
* mergePrimitiveElement(undefined, { extension: [...] }, "date", "Patient.birthDate")
|
|
105
|
+
* // → { result: { value: undefined, extension: [...] }, issues: [] }
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
export declare function mergePrimitiveElement(value: unknown, elementExtension: unknown, fhirType: string, path: string): {
|
|
109
|
+
result: unknown;
|
|
110
|
+
issues: ParseIssue[];
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Merge a repeating primitive array with its `_element` companion array.
|
|
114
|
+
*
|
|
115
|
+
* FHIR JSON uses null-alignment for repeating primitives:
|
|
116
|
+
* ```json
|
|
117
|
+
* "code": ["au", "nz"],
|
|
118
|
+
* "_code": [null, { "extension": [...] }]
|
|
119
|
+
* ```
|
|
120
|
+
*
|
|
121
|
+
* Rules:
|
|
122
|
+
* - Both arrays must have the same length (or `_element` may be absent)
|
|
123
|
+
* - `null` in the value array means "no value at this position" (only _element)
|
|
124
|
+
* - `null` in the `_element` array means "no metadata at this position"
|
|
125
|
+
* - If lengths differ, report `ARRAY_MISMATCH` error
|
|
126
|
+
*
|
|
127
|
+
* @param values - The primitive value array
|
|
128
|
+
* @param elementExtensions - The `_element` companion array (or undefined)
|
|
129
|
+
* @param fhirType - The FHIR primitive type name (for JS type validation)
|
|
130
|
+
* @param path - JSON path for error reporting
|
|
131
|
+
*/
|
|
132
|
+
export declare function mergePrimitiveArray(values: unknown[], elementExtensions: unknown[] | undefined, fhirType: string, path: string): {
|
|
133
|
+
result: unknown[];
|
|
134
|
+
issues: ParseIssue[];
|
|
135
|
+
};
|
|
136
|
+
//# sourceMappingURL=primitive-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"primitive-parser.d.ts","sourceRoot":"","sources":["../../../src/parser/primitive-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAQnD;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAmC9D;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,CAEnE;AAeD;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,UAAU,GAAG,IAAI,CAyBnB;AAMD;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,wBAAwB;IACxB,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,wBAAwB;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC;CAChC;AA+ED;;;;;;;GAOG;AACH,MAAM,WAAW,qBAAqB;IACpC,4FAA4F;IAC5F,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC;CAChC;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,OAAO,EACd,gBAAgB,EAAE,OAAO,EACzB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,UAAU,EAAE,CAAA;CAAE,CAqC3C;AAMD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,OAAO,EAAE,EACjB,iBAAiB,EAAE,OAAO,EAAE,GAAG,SAAS,EACxC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX;IAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAAC,MAAM,EAAE,UAAU,EAAE,CAAA;CAAE,CA8E7C"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FHIR JSON Serializer
|
|
3
|
+
*
|
|
4
|
+
* Converts TypeScript model objects back into FHIR R4 JSON.
|
|
5
|
+
* This is the inverse of the parser: it takes a `Resource` (or more
|
|
6
|
+
* specifically a `StructureDefinition`) and produces a FHIR-conformant
|
|
7
|
+
* JSON string or plain object.
|
|
8
|
+
*
|
|
9
|
+
* ## Serialization Rules
|
|
10
|
+
*
|
|
11
|
+
* 1. **resourceType first** — always the first property in output
|
|
12
|
+
* 2. **Choice type restoration** — `ChoiceValue.propertyName` restores the
|
|
13
|
+
* original JSON property name (e.g., `fixedString`, `patternCoding`)
|
|
14
|
+
* 3. **Empty value omission** — `undefined`, empty arrays `[]`, and
|
|
15
|
+
* empty objects `{}` are omitted from output
|
|
16
|
+
* 4. **Property ordering** — `resourceType` first, then remaining
|
|
17
|
+
* properties in alphabetical order (FHIR canonical JSON convention)
|
|
18
|
+
* 5. **Null alignment** — preserved in arrays for primitive `_element` alignment
|
|
19
|
+
*
|
|
20
|
+
* ## Scope (Stage-1)
|
|
21
|
+
*
|
|
22
|
+
* Stage-1 focuses on StructureDefinition serialization. The serializer
|
|
23
|
+
* handles:
|
|
24
|
+
* - All StructureDefinition top-level fields
|
|
25
|
+
* - All ElementDefinition fields including sub-types
|
|
26
|
+
* - Choice type fields (defaultValue[x], fixed[x], pattern[x], minValue[x], maxValue[x])
|
|
27
|
+
* - Example value[x] choice types
|
|
28
|
+
* - snapshot/differential element containers
|
|
29
|
+
*
|
|
30
|
+
* @module fhir-parser
|
|
31
|
+
*/
|
|
32
|
+
import type { Resource } from '../model/primitives.js';
|
|
33
|
+
/**
|
|
34
|
+
* Serialize a Resource object to a FHIR JSON string.
|
|
35
|
+
*
|
|
36
|
+
* Output conforms to FHIR R4 JSON conventions:
|
|
37
|
+
* - `resourceType` is the first property
|
|
38
|
+
* - Remaining properties are in alphabetical order
|
|
39
|
+
* - Choice type fields use their original JSON property names
|
|
40
|
+
* - Empty values (`undefined`, `[]`, `{}`) are omitted
|
|
41
|
+
*
|
|
42
|
+
* @param resource - The Resource to serialize
|
|
43
|
+
* @returns A FHIR JSON string (pretty-printed with 2-space indent)
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* const sd: StructureDefinition = { resourceType: 'StructureDefinition', ... };
|
|
48
|
+
* const json = serializeToFhirJson(sd);
|
|
49
|
+
* // '{\n "resourceType": "StructureDefinition",\n ...\n}'
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export declare function serializeToFhirJson(resource: Resource): string;
|
|
53
|
+
/**
|
|
54
|
+
* Serialize a Resource object to a plain JavaScript object suitable
|
|
55
|
+
* for FHIR JSON (without calling `JSON.stringify`).
|
|
56
|
+
*
|
|
57
|
+
* Use this when you need the object form (e.g., for storage or
|
|
58
|
+
* further manipulation) rather than a string.
|
|
59
|
+
*
|
|
60
|
+
* @param resource - The Resource to serialize
|
|
61
|
+
* @returns A plain object conforming to FHIR JSON conventions
|
|
62
|
+
*/
|
|
63
|
+
export declare function serializeToFhirObject(resource: Resource): Record<string, unknown>;
|
|
64
|
+
//# sourceMappingURL=serializer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../../../src/parser/serializer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAuBvD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAG9D;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,QAAQ,GACjB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKzB"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StructureDefinition & ElementDefinition Parser
|
|
3
|
+
*
|
|
4
|
+
* Dedicated parser for the most important resource type in Stage-1.
|
|
5
|
+
* All downstream modules (fhir-context, fhir-profile, fhir-validator)
|
|
6
|
+
* depend on correctly parsed StructureDefinitions.
|
|
7
|
+
*
|
|
8
|
+
* Architecture:
|
|
9
|
+
* ```
|
|
10
|
+
* parseStructureDefinition(obj, path)
|
|
11
|
+
* ├── top-level fields (url, name, status, kind, type, abstract, ...)
|
|
12
|
+
* ├── sub-types:
|
|
13
|
+
* │ ├── mapping[] → parseSDMapping()
|
|
14
|
+
* │ ├── context[] → parseSDContext()
|
|
15
|
+
* │ ├── snapshot → parseSnapshot() → element[] → parseElementDefinition()
|
|
16
|
+
* │ └── differential → parseDifferential() → element[] → parseElementDefinition()
|
|
17
|
+
* └── unknown property detection
|
|
18
|
+
*
|
|
19
|
+
* parseElementDefinition(obj, path)
|
|
20
|
+
* ├── basic fields (path, sliceName, min, max, ...)
|
|
21
|
+
* ├── sub-types:
|
|
22
|
+
* │ ├── slicing → parseSlicing() → discriminator[] → parseDiscriminator()
|
|
23
|
+
* │ ├── base → parseBase()
|
|
24
|
+
* │ ├── type[] → parseEDType()
|
|
25
|
+
* │ ├── constraint[] → parseConstraint()
|
|
26
|
+
* │ ├── binding → parseBinding()
|
|
27
|
+
* │ ├── example[] → parseExample() ← contains choice type
|
|
28
|
+
* │ └── mapping[] → parseEDMapping()
|
|
29
|
+
* └── choice type fields:
|
|
30
|
+
* ├── defaultValue[x] → extractChoiceValue()
|
|
31
|
+
* ├── fixed[x] → extractChoiceValue()
|
|
32
|
+
* ├── pattern[x] → extractChoiceValue()
|
|
33
|
+
* ├── minValue[x] → extractChoiceValue()
|
|
34
|
+
* └── maxValue[x] → extractChoiceValue()
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @module fhir-parser
|
|
38
|
+
*/
|
|
39
|
+
import type { StructureDefinition } from '../model/structure-definition.js';
|
|
40
|
+
import type { ElementDefinition } from '../model/element-definition.js';
|
|
41
|
+
import type { ParseResult, ParseIssue } from './parse-error.js';
|
|
42
|
+
/**
|
|
43
|
+
* Parse an ElementDefinition JSON object.
|
|
44
|
+
*
|
|
45
|
+
* ElementDefinition is the most complex data type in FHIR,
|
|
46
|
+
* with ~37 fields and 8 sub-types.
|
|
47
|
+
*/
|
|
48
|
+
export declare function parseElementDefinition(obj: Record<string, unknown>, path: string): {
|
|
49
|
+
result: ElementDefinition;
|
|
50
|
+
issues: ParseIssue[];
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Parse a StructureDefinition JSON object.
|
|
54
|
+
*
|
|
55
|
+
* This is the most important parse function in Stage-1. All downstream
|
|
56
|
+
* modules (fhir-context, fhir-profile, fhir-validator) depend on
|
|
57
|
+
* correctly parsed StructureDefinitions.
|
|
58
|
+
*
|
|
59
|
+
* @param obj - A parsed JSON object (already validated as having resourceType = "StructureDefinition")
|
|
60
|
+
* @param path - Current JSON path (for error reporting)
|
|
61
|
+
*/
|
|
62
|
+
export declare function parseStructureDefinition(obj: Record<string, unknown>, path: string): ParseResult<StructureDefinition>;
|
|
63
|
+
//# sourceMappingURL=structure-definition-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structure-definition-parser.d.ts","sourceRoot":"","sources":["../../../src/parser/structure-definition-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAO5E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAYxE,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAoXhE;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,IAAI,EAAE,MAAM,GACX;IAAE,MAAM,EAAE,iBAAiB,CAAC;IAAC,MAAM,EAAE,UAAU,EAAE,CAAA;CAAE,CA+GrD;AA0GD;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,IAAI,EAAE,MAAM,GACX,WAAW,CAAC,mBAAmB,CAAC,CA6GlC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fhir-profile — Canonical Profile Builder
|
|
3
|
+
*
|
|
4
|
+
* Converts a StructureDefinition (with populated snapshot) into the
|
|
5
|
+
* internal {@link CanonicalProfile} semantic model defined in Phase 1.
|
|
6
|
+
*
|
|
7
|
+
* The CanonicalProfile is MedXAI's own abstraction optimized for
|
|
8
|
+
* downstream consumption (validation, runtime, application layer):
|
|
9
|
+
* - Pre-resolved inheritance (flattened snapshot)
|
|
10
|
+
* - Semantic types (`max: 'unbounded'` instead of `"*"`)
|
|
11
|
+
* - Non-optional flags (mustSupport/isModifier/isSummary always boolean)
|
|
12
|
+
* - O(1) element lookup via `Map<string, CanonicalElement>`
|
|
13
|
+
*
|
|
14
|
+
* Exported functions:
|
|
15
|
+
* - {@link buildCanonicalProfile} — convert full SD → CanonicalProfile
|
|
16
|
+
* - {@link buildCanonicalElement} — convert single ElementDefinition → CanonicalElement
|
|
17
|
+
* - {@link buildTypeConstraints} — convert ElementDefinitionType[] → TypeConstraint[]
|
|
18
|
+
* - {@link buildBindingConstraint} — convert ElementDefinitionBinding → BindingConstraint
|
|
19
|
+
* - {@link buildInvariants} — convert ElementDefinitionConstraint[] → Invariant[]
|
|
20
|
+
* - {@link buildSlicingDefinition} — convert ElementDefinitionSlicing → SlicingDefinition
|
|
21
|
+
*
|
|
22
|
+
* @module fhir-profile
|
|
23
|
+
*/
|
|
24
|
+
import type { CanonicalProfile, CanonicalElement, TypeConstraint, BindingConstraint, Invariant, SlicingDefinition } from '../model/index.js';
|
|
25
|
+
import type { ElementDefinition, ElementDefinitionType, ElementDefinitionBinding, ElementDefinitionConstraint, ElementDefinitionSlicing, StructureDefinition } from '../model/index.js';
|
|
26
|
+
/**
|
|
27
|
+
* Convert a StructureDefinition (with snapshot) to a CanonicalProfile.
|
|
28
|
+
*
|
|
29
|
+
* Precondition: `sd.snapshot` must exist (generated by SnapshotGenerator).
|
|
30
|
+
* If snapshot is missing, throws an error.
|
|
31
|
+
*
|
|
32
|
+
* @param sd - The StructureDefinition with populated snapshot.
|
|
33
|
+
* @returns The internal CanonicalProfile representation.
|
|
34
|
+
* @throws Error if sd.snapshot is missing.
|
|
35
|
+
*/
|
|
36
|
+
export declare function buildCanonicalProfile(sd: StructureDefinition): CanonicalProfile;
|
|
37
|
+
/**
|
|
38
|
+
* Convert a single ElementDefinition to a CanonicalElement.
|
|
39
|
+
*
|
|
40
|
+
* Applies the following normalizations:
|
|
41
|
+
* - `max: "*"` → `max: 'unbounded'`; numeric strings → numbers
|
|
42
|
+
* - `mustSupport/isModifier/isSummary: undefined` → `false`
|
|
43
|
+
* - `constraint: undefined` → `[]`
|
|
44
|
+
* - `type: undefined` → `[]`
|
|
45
|
+
*
|
|
46
|
+
* @param ed - The ElementDefinition from a snapshot.
|
|
47
|
+
* @returns The normalized CanonicalElement.
|
|
48
|
+
*/
|
|
49
|
+
export declare function buildCanonicalElement(ed: ElementDefinition): CanonicalElement;
|
|
50
|
+
/**
|
|
51
|
+
* Convert ElementDefinitionType[] to TypeConstraint[].
|
|
52
|
+
*
|
|
53
|
+
* Returns an empty array if types is undefined or empty.
|
|
54
|
+
*
|
|
55
|
+
* @param types - The FHIR type array from an ElementDefinition.
|
|
56
|
+
* @returns Normalized TypeConstraint array.
|
|
57
|
+
*/
|
|
58
|
+
export declare function buildTypeConstraints(types: readonly ElementDefinitionType[] | undefined): TypeConstraint[];
|
|
59
|
+
/**
|
|
60
|
+
* Convert ElementDefinitionBinding to BindingConstraint.
|
|
61
|
+
*
|
|
62
|
+
* Returns undefined if binding is undefined or has no strength.
|
|
63
|
+
*
|
|
64
|
+
* @param binding - The FHIR binding from an ElementDefinition.
|
|
65
|
+
* @returns Normalized BindingConstraint or undefined.
|
|
66
|
+
*/
|
|
67
|
+
export declare function buildBindingConstraint(binding: ElementDefinitionBinding | undefined): BindingConstraint | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* Convert ElementDefinitionConstraint[] to Invariant[].
|
|
70
|
+
*
|
|
71
|
+
* Returns an empty array if constraints is undefined or empty.
|
|
72
|
+
*
|
|
73
|
+
* @param constraints - The FHIR constraint array from an ElementDefinition.
|
|
74
|
+
* @returns Normalized Invariant array.
|
|
75
|
+
*/
|
|
76
|
+
export declare function buildInvariants(constraints: readonly ElementDefinitionConstraint[] | undefined): Invariant[];
|
|
77
|
+
/**
|
|
78
|
+
* Convert ElementDefinitionSlicing to SlicingDefinition.
|
|
79
|
+
*
|
|
80
|
+
* Returns undefined if slicing is undefined.
|
|
81
|
+
* Normalizes `ordered` to boolean (default false).
|
|
82
|
+
*
|
|
83
|
+
* @param slicing - The FHIR slicing from an ElementDefinition.
|
|
84
|
+
* @returns Normalized SlicingDefinition or undefined.
|
|
85
|
+
*/
|
|
86
|
+
export declare function buildSlicingDefinition(slicing: ElementDefinitionSlicing | undefined): SlicingDefinition | undefined;
|
|
87
|
+
//# sourceMappingURL=canonical-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonical-builder.d.ts","sourceRoot":"","sources":["../../../src/profile/canonical-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,SAAS,EACT,iBAAiB,EAElB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACV,iBAAiB,EACjB,qBAAqB,EACrB,wBAAwB,EACxB,2BAA2B,EAC3B,wBAAwB,EACxB,mBAAmB,EACpB,MAAM,mBAAmB,CAAC;AAM3B;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,mBAAmB,GAAG,gBAAgB,CAyB/E;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,iBAAiB,GAAG,gBAAgB,CAuB7E;AAMD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,SAAS,qBAAqB,EAAE,GAAG,SAAS,GAClD,cAAc,EAAE,CAoBlB;AAMD;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,wBAAwB,GAAG,SAAS,GAC5C,iBAAiB,GAAG,SAAS,CAkB/B;AAMD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,SAAS,2BAA2B,EAAE,GAAG,SAAS,GAC9D,SAAS,EAAE,CAsBb;AAMD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,wBAAwB,GAAG,SAAS,GAC5C,iBAAiB,GAAG,SAAS,CAqB/B"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fhir-profile — Constraint Merging Engine
|
|
3
|
+
*
|
|
4
|
+
* Implements field-level merging of differential ElementDefinition constraints
|
|
5
|
+
* onto snapshot elements. This is the most granular part of snapshot generation.
|
|
6
|
+
*
|
|
7
|
+
* Corresponds to HAPI FHIR R4:
|
|
8
|
+
* - `ProfileUtilities.updateFromDefinition()` → {@link mergeConstraints}
|
|
9
|
+
* - `ProfileUtilities.updateFromBase()` → {@link setBaseTraceability}
|
|
10
|
+
*
|
|
11
|
+
* Merge strategies per field (from HAPI research):
|
|
12
|
+
* - **Overwrite**: short, definition, comment, requirements, label, fixed, pattern,
|
|
13
|
+
* maxLength, minValue, maxValue, mustSupport, defaultValue, meaningWhenMissing
|
|
14
|
+
* - **Validate-then-overwrite**: min, max, type[], binding
|
|
15
|
+
* - **Append/union**: constraint[], alias[], example[], mapping[]
|
|
16
|
+
* - **Conditional**: isModifier (extensions only), isSummary (base guard)
|
|
17
|
+
*
|
|
18
|
+
* @module fhir-profile
|
|
19
|
+
*/
|
|
20
|
+
import type { ElementDefinition, ElementDefinitionBinding, ElementDefinitionConstraint, ElementDefinitionType } from '../model/index.js';
|
|
21
|
+
import type { SnapshotIssue } from './types.js';
|
|
22
|
+
/**
|
|
23
|
+
* Apply differential constraints onto a snapshot element.
|
|
24
|
+
*
|
|
25
|
+
* Corresponds to HAPI `updateFromDefinition(dest, source, ...)`.
|
|
26
|
+
* The `dest` element is mutated in place and also returned.
|
|
27
|
+
*
|
|
28
|
+
* @param dest - The working snapshot element (initially cloned from base).
|
|
29
|
+
* @param source - The differential element to apply.
|
|
30
|
+
* @param issues - Mutable array to collect issues.
|
|
31
|
+
* @returns The mutated `dest` element.
|
|
32
|
+
*/
|
|
33
|
+
export declare function mergeConstraints(dest: ElementDefinition, source: ElementDefinition, issues: SnapshotIssue[]): ElementDefinition;
|
|
34
|
+
/**
|
|
35
|
+
* Populate `dest.base` with traceability information from the base element.
|
|
36
|
+
*
|
|
37
|
+
* Corresponds to HAPI `updateFromBase(derived, base)`.
|
|
38
|
+
* If `base` already has a `.base`, we copy from `base.base` (preserving
|
|
39
|
+
* original ancestry). Otherwise we copy from `base` directly.
|
|
40
|
+
*
|
|
41
|
+
* @param dest - The element to set base traceability on.
|
|
42
|
+
* @param base - The base element to derive traceability from.
|
|
43
|
+
*/
|
|
44
|
+
export declare function setBaseTraceability(dest: ElementDefinition, base: ElementDefinition): void;
|
|
45
|
+
/**
|
|
46
|
+
* Merge cardinality constraints (min/max) with validation.
|
|
47
|
+
*
|
|
48
|
+
* Rules:
|
|
49
|
+
* - `derived.min` must be >= `base.min` (except for slices)
|
|
50
|
+
* - `derived.max` must be <= `base.max`
|
|
51
|
+
*
|
|
52
|
+
* @internal Exported for direct testing.
|
|
53
|
+
*/
|
|
54
|
+
export declare function mergeCardinality(dest: ElementDefinition, source: ElementDefinition, issues: SnapshotIssue[], path?: string): void;
|
|
55
|
+
/**
|
|
56
|
+
* Merge type constraints with compatibility validation.
|
|
57
|
+
*
|
|
58
|
+
* Each derived type must be compatible with at least one base type.
|
|
59
|
+
* Special allowances: Extension, Element, *, Resource/DomainResource.
|
|
60
|
+
*
|
|
61
|
+
* If valid, derived types replace base types entirely.
|
|
62
|
+
*
|
|
63
|
+
* @returns The merged type array (derived types if valid, base types if no diff).
|
|
64
|
+
*/
|
|
65
|
+
export declare function mergeTypes(baseTypes: readonly ElementDefinitionType[] | undefined, diffTypes: readonly ElementDefinitionType[] | undefined, issues: SnapshotIssue[], path: string): ElementDefinitionType[] | undefined;
|
|
66
|
+
/**
|
|
67
|
+
* Merge binding constraints with strength validation.
|
|
68
|
+
*
|
|
69
|
+
* Rules:
|
|
70
|
+
* - Cannot relax a REQUIRED binding (REQUIRED → anything else = error)
|
|
71
|
+
* - Derived binding replaces base binding
|
|
72
|
+
*
|
|
73
|
+
* @returns The merged binding.
|
|
74
|
+
*/
|
|
75
|
+
export declare function mergeBinding(baseBinding: ElementDefinitionBinding | undefined, diffBinding: ElementDefinitionBinding | undefined, issues: SnapshotIssue[], path: string): ElementDefinitionBinding | undefined;
|
|
76
|
+
/**
|
|
77
|
+
* Merge constraint (invariant) lists by appending derived constraints,
|
|
78
|
+
* de-duplicating by `key`.
|
|
79
|
+
*
|
|
80
|
+
* Base constraints are kept; derived constraints with the same key
|
|
81
|
+
* replace the base version.
|
|
82
|
+
*
|
|
83
|
+
* @returns The merged constraint array.
|
|
84
|
+
*/
|
|
85
|
+
export declare function mergeConstraintList(baseConstraints: readonly ElementDefinitionConstraint[] | undefined, diffConstraints: readonly ElementDefinitionConstraint[] | undefined): ElementDefinitionConstraint[] | undefined;
|
|
86
|
+
/**
|
|
87
|
+
* Determine whether max value `a` is larger than max value `b`.
|
|
88
|
+
*
|
|
89
|
+
* FHIR max is either a non-negative integer string or `"*"` (unbounded).
|
|
90
|
+
* `"*"` is treated as infinity.
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* isLargerMax('5', '3') // true
|
|
94
|
+
* isLargerMax('*', '3') // true
|
|
95
|
+
* isLargerMax('3', '*') // false
|
|
96
|
+
* isLargerMax('3', '3') // false
|
|
97
|
+
* isLargerMax('*', '*') // false
|
|
98
|
+
*/
|
|
99
|
+
export declare function isLargerMax(a: string, b: string): boolean;
|
|
100
|
+
//# sourceMappingURL=constraint-merger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constraint-merger.d.ts","sourceRoot":"","sources":["../../../src/profile/constraint-merger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EACV,iBAAiB,EAEjB,wBAAwB,EACxB,2BAA2B,EAG3B,qBAAqB,EAGtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAOhD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,iBAAiB,EACvB,MAAM,EAAE,iBAAiB,EACzB,MAAM,EAAE,aAAa,EAAE,GACtB,iBAAiB,CAgFnB;AAMD;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,iBAAiB,EACvB,IAAI,EAAE,iBAAiB,GACtB,IAAI,CAcN;AAMD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,iBAAiB,EACvB,MAAM,EAAE,iBAAiB,EACzB,MAAM,EAAE,aAAa,EAAE,EACvB,IAAI,CAAC,EAAE,MAAM,GACZ,IAAI,CAyCN;AAMD;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CACxB,SAAS,EAAE,SAAS,qBAAqB,EAAE,GAAG,SAAS,EACvD,SAAS,EAAE,SAAS,qBAAqB,EAAE,GAAG,SAAS,EACvD,MAAM,EAAE,aAAa,EAAE,EACvB,IAAI,EAAE,MAAM,GACX,qBAAqB,EAAE,GAAG,SAAS,CA0BrC;AA0CD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,WAAW,EAAE,wBAAwB,GAAG,SAAS,EACjD,WAAW,EAAE,wBAAwB,GAAG,SAAS,EACjD,MAAM,EAAE,aAAa,EAAE,EACvB,IAAI,EAAE,MAAM,GACX,wBAAwB,GAAG,SAAS,CAiBtC;AAMD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,eAAe,EAAE,SAAS,2BAA2B,EAAE,GAAG,SAAS,EACnE,eAAe,EAAE,SAAS,2BAA2B,EAAE,GAAG,SAAS,GAClE,2BAA2B,EAAE,GAAG,SAAS,CAwB3C;AA0ED;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAUzD"}
|