@atomic-ehr/codegen 0.0.1-canary.20251003085147.a5c0084 → 0.0.1-canary.20251003142740.59082f8

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.
@@ -1,168 +0,0 @@
1
- /**
2
- * Value Set Processing
3
- *
4
- * Functions for transforming FHIR ValueSets into TypeSchema format
5
- */
6
- import { mkValueSetIdentifier } from "../core/identifier";
7
- /**
8
- * Extract concepts from a CodeSystem
9
- */
10
- async function extractCodeSystemConcepts(codeSystemUrl, manager) {
11
- try {
12
- const codeSystem = await manager.resolve(codeSystemUrl);
13
- if (!codeSystem || codeSystem.resourceType !== "CodeSystem") {
14
- return undefined;
15
- }
16
- const concepts = [];
17
- // Recursive function to extract concepts (including nested ones)
18
- const extractConcepts = (conceptList, system) => {
19
- for (const concept of conceptList) {
20
- concepts.push({
21
- system,
22
- code: concept.code,
23
- display: concept.display,
24
- });
25
- // Handle nested concepts
26
- if (concept.concept) {
27
- extractConcepts(concept.concept, system);
28
- }
29
- }
30
- };
31
- if (codeSystem.concept) {
32
- extractConcepts(codeSystem.concept, codeSystemUrl);
33
- }
34
- return concepts;
35
- }
36
- catch {
37
- return undefined;
38
- }
39
- }
40
- /**
41
- * Process ValueSet compose include/exclude
42
- */
43
- async function processComposeItem(item, manager) {
44
- const concepts = [];
45
- // Direct concept list
46
- if (item.concept) {
47
- for (const concept of item.concept) {
48
- concepts.push({
49
- system: item.system,
50
- code: concept.code,
51
- display: concept.display,
52
- });
53
- }
54
- return concepts;
55
- }
56
- // Include all from CodeSystem (no filter)
57
- if (item.system && !item.filter) {
58
- const csConcepts = await extractCodeSystemConcepts(item.system, manager);
59
- if (csConcepts) {
60
- concepts.push(...csConcepts);
61
- }
62
- }
63
- // Include from another ValueSet
64
- if (item.valueSet) {
65
- for (const vsUrl of item.valueSet) {
66
- try {
67
- const vs = await manager.resolve(vsUrl);
68
- if (vs) {
69
- const vsConcepts = await extractValueSetConcepts(vs, manager);
70
- if (vsConcepts) {
71
- concepts.push(...vsConcepts);
72
- }
73
- }
74
- }
75
- catch {
76
- // Ignore if we can't resolve
77
- }
78
- }
79
- }
80
- return concepts;
81
- }
82
- /**
83
- * Extract all concepts from a ValueSet
84
- */
85
- export async function extractValueSetConcepts(valueSet, manager) {
86
- try {
87
- const concepts = [];
88
- if (valueSet.compose) {
89
- // Process includes
90
- if (valueSet.compose.include) {
91
- for (const include of valueSet.compose.include) {
92
- const includeConcepts = await processComposeItem(include, manager);
93
- concepts.push(...includeConcepts);
94
- }
95
- }
96
- // Process excludes (remove them from the list)
97
- if (valueSet.compose.exclude) {
98
- const excludeConcepts = new Set();
99
- for (const exclude of valueSet.compose.exclude) {
100
- const excludeList = await processComposeItem(exclude, manager);
101
- for (const concept of excludeList) {
102
- excludeConcepts.add(`${concept.system}|${concept.code}`);
103
- }
104
- }
105
- // Filter out excluded concepts
106
- return concepts.filter((c) => !excludeConcepts.has(`${c.system}|${c.code}`));
107
- }
108
- }
109
- return concepts.length > 0 ? concepts : undefined;
110
- }
111
- catch (error) {
112
- console.error("Error extracting ValueSet concepts:", error);
113
- return undefined;
114
- }
115
- }
116
- /**
117
- * Transform a FHIR ValueSet to TypeSchema format
118
- */
119
- export async function transformValueSet(valueSet, register, packageInfo) {
120
- const identifier = mkValueSetIdentifier(valueSet.url, valueSet);
121
- const typeSchemaValueSet = {
122
- identifier,
123
- };
124
- // Add description if present
125
- if (valueSet.description) {
126
- typeSchemaValueSet.description = valueSet.description;
127
- }
128
- // Try to extract concepts
129
- const concepts = await extractValueSetConcepts(valueSet, register);
130
- if (concepts && concepts.length > 0) {
131
- // If we can expand, include the concepts
132
- typeSchemaValueSet.concept = concepts;
133
- }
134
- else if (valueSet.compose) {
135
- // If we can't expand, include the compose structure
136
- typeSchemaValueSet.compose = valueSet.compose;
137
- }
138
- // Extract dependencies from compose
139
- if (valueSet.compose) {
140
- const deps = [];
141
- // Helper to process include/exclude
142
- const processCompose = (items) => {
143
- for (const item of items) {
144
- if (item.system) {
145
- deps.push({
146
- kind: "value-set",
147
- package: packageInfo?.name || "undefined",
148
- version: packageInfo?.version || "undefined",
149
- name: item.system.split("/").pop() || "unknown",
150
- url: item.system,
151
- });
152
- }
153
- if (item.valueSet) {
154
- for (const vsUrl of item.valueSet) {
155
- deps.push(mkValueSetIdentifier(register, vsUrl));
156
- }
157
- }
158
- }
159
- };
160
- if (valueSet.compose.include) {
161
- processCompose(valueSet.compose.include);
162
- }
163
- if (valueSet.compose.exclude) {
164
- processCompose(valueSet.compose.exclude);
165
- }
166
- }
167
- return typeSchemaValueSet;
168
- }