@atomic-ehr/codegen 0.0.1-canary.20250821160126.c552195 → 0.0.1-canary.20250822150706.c3b8669

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/dist/api/builder.d.ts +3 -3
  2. package/dist/api/builder.d.ts.map +1 -1
  3. package/dist/api/builder.js +374 -0
  4. package/dist/api/generators/base/BaseGenerator.d.ts +4 -4
  5. package/dist/api/generators/base/BaseGenerator.d.ts.map +1 -1
  6. package/dist/api/generators/base/BaseGenerator.js +572 -0
  7. package/dist/api/generators/base/FileManager.d.ts +2 -2
  8. package/dist/api/generators/base/FileManager.d.ts.map +1 -1
  9. package/dist/api/generators/base/FileManager.js +204 -0
  10. package/dist/api/generators/base/PythonTypeMapper.d.ts +2 -2
  11. package/dist/api/generators/base/PythonTypeMapper.d.ts.map +1 -1
  12. package/dist/api/generators/base/PythonTypeMapper.js +71 -0
  13. package/dist/api/generators/base/TemplateEngine.d.ts +1 -1
  14. package/dist/api/generators/base/TemplateEngine.d.ts.map +1 -1
  15. package/dist/api/generators/base/TemplateEngine.js +133 -0
  16. package/dist/api/generators/base/TypeMapper.js +153 -0
  17. package/dist/api/generators/base/TypeScriptTypeMapper.d.ts +1 -1
  18. package/dist/api/generators/base/TypeScriptTypeMapper.d.ts.map +1 -1
  19. package/dist/api/generators/base/TypeScriptTypeMapper.js +232 -0
  20. package/dist/api/generators/base/builders/DirectoryBuilder.d.ts +4 -4
  21. package/dist/api/generators/base/builders/DirectoryBuilder.d.ts.map +1 -1
  22. package/dist/api/generators/base/builders/DirectoryBuilder.js +215 -0
  23. package/dist/api/generators/base/builders/FileBuilder.d.ts +2 -2
  24. package/dist/api/generators/base/builders/FileBuilder.d.ts.map +1 -1
  25. package/dist/api/generators/base/builders/FileBuilder.js +408 -0
  26. package/dist/api/generators/base/builders/IndexBuilder.d.ts +2 -2
  27. package/dist/api/generators/base/builders/IndexBuilder.d.ts.map +1 -1
  28. package/dist/api/generators/base/builders/IndexBuilder.js +290 -0
  29. package/dist/api/generators/base/enhanced-errors.d.ts +2 -2
  30. package/dist/api/generators/base/enhanced-errors.d.ts.map +1 -1
  31. package/dist/api/generators/base/enhanced-errors.js +259 -0
  32. package/dist/api/generators/base/error-handler.d.ts +1 -1
  33. package/dist/api/generators/base/error-handler.d.ts.map +1 -1
  34. package/dist/api/generators/base/error-handler.js +243 -0
  35. package/dist/api/generators/base/errors.d.ts +2 -2
  36. package/dist/api/generators/base/errors.d.ts.map +1 -1
  37. package/dist/api/generators/base/errors.js +694 -0
  38. package/dist/api/generators/base/index.d.ts +22 -22
  39. package/dist/api/generators/base/index.d.ts.map +1 -1
  40. package/dist/api/generators/base/index.js +161 -0
  41. package/dist/api/generators/base/types.d.ts +2 -2
  42. package/dist/api/generators/base/types.d.ts.map +1 -1
  43. package/dist/api/generators/base/types.js +12 -0
  44. package/dist/api/generators/rest-client.d.ts +2 -2
  45. package/dist/api/generators/rest-client.d.ts.map +1 -1
  46. package/dist/api/generators/rest-client.js +847 -0
  47. package/dist/api/generators/search-parameter-enhancer.d.ts +1 -1
  48. package/dist/api/generators/search-parameter-enhancer.d.ts.map +1 -1
  49. package/dist/api/generators/search-parameter-enhancer.js +801 -0
  50. package/dist/api/generators/types.js +4 -0
  51. package/dist/api/generators/typescript.d.ts +3 -3
  52. package/dist/api/generators/typescript.d.ts.map +1 -1
  53. package/dist/api/generators/typescript.js +537 -0
  54. package/dist/api/generators/validation-generator.js +632 -0
  55. package/dist/api/index.d.ts +10 -10
  56. package/dist/api/index.d.ts.map +1 -1
  57. package/dist/api/index.js +51 -0
  58. package/dist/cli/commands/generate/typescript.d.ts +1 -1
  59. package/dist/cli/commands/generate/typescript.d.ts.map +1 -1
  60. package/dist/cli/commands/generate/typescript.js +52 -0
  61. package/dist/cli/commands/generate.d.ts +5 -12
  62. package/dist/cli/commands/generate.d.ts.map +1 -1
  63. package/dist/cli/commands/generate.js +158 -0
  64. package/dist/cli/commands/index.d.ts +2 -1
  65. package/dist/cli/commands/index.d.ts.map +1 -1
  66. package/dist/cli/commands/index.js +100 -0
  67. package/dist/cli/commands/typeschema/generate.js +130 -0
  68. package/dist/cli/commands/typeschema.js +48 -0
  69. package/dist/cli/index.js +12 -8664
  70. package/dist/cli/utils/log.d.ts +2 -2
  71. package/dist/cli/utils/log.d.ts.map +1 -1
  72. package/dist/cli/utils/log.js +23 -0
  73. package/dist/cli/utils/prompts.js +224 -0
  74. package/dist/cli/utils/spinner.js +270 -0
  75. package/dist/config.d.ts +22 -2
  76. package/dist/config.d.ts.map +1 -1
  77. package/dist/config.js +703 -0
  78. package/dist/index.d.ts +2 -2
  79. package/dist/index.d.ts.map +1 -1
  80. package/dist/index.js +84 -38
  81. package/dist/logger.js +290 -0
  82. package/dist/typeschema/cache.d.ts +2 -2
  83. package/dist/typeschema/cache.d.ts.map +1 -1
  84. package/dist/typeschema/cache.js +285 -0
  85. package/dist/typeschema/core/binding.d.ts +1 -1
  86. package/dist/typeschema/core/binding.d.ts.map +1 -1
  87. package/dist/typeschema/core/binding.js +187 -0
  88. package/dist/typeschema/core/field-builder.d.ts +1 -1
  89. package/dist/typeschema/core/field-builder.d.ts.map +1 -1
  90. package/dist/typeschema/core/field-builder.js +259 -0
  91. package/dist/typeschema/core/identifier.js +117 -0
  92. package/dist/typeschema/core/nested-types.d.ts +1 -1
  93. package/dist/typeschema/core/nested-types.d.ts.map +1 -1
  94. package/dist/typeschema/core/nested-types.js +111 -0
  95. package/dist/typeschema/core/transformer.d.ts +2 -2
  96. package/dist/typeschema/core/transformer.d.ts.map +1 -1
  97. package/dist/typeschema/core/transformer.js +345 -0
  98. package/dist/typeschema/generator.d.ts +3 -3
  99. package/dist/typeschema/generator.d.ts.map +1 -1
  100. package/dist/typeschema/generator.js +352 -0
  101. package/dist/typeschema/index.d.ts +14 -14
  102. package/dist/typeschema/index.d.ts.map +1 -1
  103. package/dist/typeschema/index.js +92 -0
  104. package/dist/typeschema/parser.d.ts +2 -2
  105. package/dist/typeschema/parser.d.ts.map +1 -1
  106. package/dist/typeschema/parser.js +310 -0
  107. package/dist/typeschema/profile/processor.d.ts +1 -1
  108. package/dist/typeschema/profile/processor.d.ts.map +1 -1
  109. package/dist/typeschema/profile/processor.js +268 -0
  110. package/dist/typeschema/schema.js +456 -0
  111. package/dist/typeschema/type-schema.types.js +39 -0
  112. package/dist/typeschema/types.js +4 -0
  113. package/dist/typeschema/utils.d.ts +1 -1
  114. package/dist/typeschema/utils.d.ts.map +1 -1
  115. package/dist/typeschema/utils.js +13 -0
  116. package/dist/typeschema/value-set/processor.d.ts +1 -1
  117. package/dist/typeschema/value-set/processor.d.ts.map +1 -1
  118. package/dist/typeschema/value-set/processor.js +168 -0
  119. package/dist/utils/codegen-logger.js +204 -0
  120. package/dist/utils.js +42 -0
  121. package/package.json +15 -4
  122. package/dist/index-e7pfye24.js +0 -8532
@@ -0,0 +1,259 @@
1
+ // @ts-nocheck
2
+ import { buildEnum } from "./binding.js";
3
+ import { buildBindingIdentifier, buildNestedIdentifier, buildSchemaIdentifier, } from "./identifier.js";
4
+ /**
5
+ * Get the full element hierarchy for a given path
6
+ */
7
+ export function getElementHierarchy(fhirSchema, path, _manager) {
8
+ const hierarchy = [];
9
+ // Get element at path from current schema
10
+ let element = fhirSchema.elements;
11
+ for (const key of path) {
12
+ element = element?.[key];
13
+ if (!element)
14
+ break;
15
+ }
16
+ if (element) {
17
+ hierarchy.push(element);
18
+ }
19
+ // For now, we only use the current schema's element
20
+ // TODO: Implement base schema traversal when we have proper schema loading
21
+ return hierarchy;
22
+ }
23
+ /**
24
+ * Merge element hierarchy into a snapshot
25
+ */
26
+ export function mergeElementHierarchy(hierarchy) {
27
+ // Handle empty hierarchy
28
+ if (hierarchy.length === 0) {
29
+ return {};
30
+ }
31
+ // Start with the most specific (first) element
32
+ const snapshot = { ...hierarchy[0] };
33
+ // Merge properties from base elements (reverse order to apply from base to specific)
34
+ for (let i = hierarchy.length - 1; i >= 0; i--) {
35
+ const element = hierarchy[i];
36
+ // Properties that should be taken from the most specific element
37
+ const specificProps = [
38
+ "choices",
39
+ "short",
40
+ "index",
41
+ "elements",
42
+ "required",
43
+ "excluded",
44
+ "binding",
45
+ "refers",
46
+ "elementReference",
47
+ "mustSupport",
48
+ "slices",
49
+ "slicing",
50
+ "url",
51
+ "extensions",
52
+ ];
53
+ // Merge non-specific properties
54
+ for (const [key, value] of Object.entries(element)) {
55
+ if (!specificProps.includes(key) && value !== undefined) {
56
+ snapshot[key] = value;
57
+ }
58
+ }
59
+ }
60
+ // Override with specific properties from the first element
61
+ for (const prop of ["choices", "binding", "refers", "elementReference"]) {
62
+ // @ts-ignore
63
+ if (hierarchy[0] &&
64
+ hierarchy[0][prop] !== undefined) {
65
+ // @ts-ignore
66
+ snapshot[prop] = hierarchy[0][prop];
67
+ }
68
+ }
69
+ return snapshot;
70
+ }
71
+ /**
72
+ * Check if a field is required based on parent required arrays
73
+ */
74
+ export function isRequired(fhirSchema, path, _manager) {
75
+ if (path.length === 0)
76
+ return false;
77
+ const fieldName = path[path.length - 1];
78
+ const parentPath = path.slice(0, -1);
79
+ // Navigate to parent element
80
+ let parentElement = fhirSchema;
81
+ for (const key of parentPath) {
82
+ parentElement = parentElement.elements?.[key];
83
+ if (!parentElement)
84
+ break;
85
+ }
86
+ // Check if field is in required array
87
+ if (parentElement?.required?.includes(fieldName)) {
88
+ return true;
89
+ }
90
+ // Also check at root level
91
+ if (parentPath.length === 0 &&
92
+ fieldName &&
93
+ fhirSchema.required?.includes(fieldName)) {
94
+ return true;
95
+ }
96
+ return false;
97
+ }
98
+ /**
99
+ * Check if a field is excluded
100
+ */
101
+ export function isExcluded(fhirSchema, path, _manager) {
102
+ if (path.length === 0)
103
+ return false;
104
+ const fieldName = path[path.length - 1];
105
+ const parentPath = path.slice(0, -1);
106
+ // Navigate to parent element
107
+ let parentElement = fhirSchema;
108
+ for (const key of parentPath) {
109
+ parentElement = parentElement.elements?.[key];
110
+ if (!parentElement)
111
+ break;
112
+ }
113
+ // Check if field is in excluded array
114
+ if (parentElement?.excluded?.includes(fieldName)) {
115
+ return true;
116
+ }
117
+ // Also check at root level
118
+ if (parentPath.length === 0 &&
119
+ fieldName &&
120
+ fhirSchema.excluded?.includes(fieldName)) {
121
+ return true;
122
+ }
123
+ return false;
124
+ }
125
+ /**
126
+ * Build reference array from element refers
127
+ */
128
+ export async function buildReferences(element, manager, packageInfo) {
129
+ if (!element.refers || element.refers.length === 0) {
130
+ return undefined;
131
+ }
132
+ const references = [];
133
+ for (const ref of element.refers) {
134
+ try {
135
+ const resource = await manager.resolve(ref);
136
+ if (resource) {
137
+ references.push(buildSchemaIdentifier(resource, packageInfo));
138
+ }
139
+ }
140
+ catch { }
141
+ }
142
+ return references;
143
+ }
144
+ /**
145
+ * Build field type identifier
146
+ */
147
+ export function buildFieldType(fhirSchema, _path, element, _manager, packageInfo) {
148
+ // Handle element reference (for slicing)
149
+ if (element.elementReference) {
150
+ const refPath = element.elementReference
151
+ .filter((_, i) => i % 2 === 1) // Get odd indices (the actual path parts)
152
+ .map((p) => p)
153
+ .filter((p) => p !== "elements"); // Remove 'elements' which is just a container
154
+ // Only return nested identifier if we have a non-empty path
155
+ if (refPath.length > 0) {
156
+ return buildNestedIdentifier(fhirSchema, refPath, packageInfo);
157
+ }
158
+ }
159
+ // Handle normal type
160
+ if (element.type) {
161
+ const typeUrl = element.type.includes("/")
162
+ ? element.type
163
+ : `http://hl7.org/fhir/StructureDefinition/${element.type}`;
164
+ // Always create a type identifier, even if we can't resolve
165
+ const kind = element.type.match(/^[a-z]/)
166
+ ? "primitive-type"
167
+ : "complex-type";
168
+ const isStandardFhir = typeUrl.startsWith("http://hl7.org/fhir/");
169
+ return {
170
+ kind: kind,
171
+ package: isStandardFhir
172
+ ? "hl7.fhir.r4.core"
173
+ : packageInfo?.name || "undefined",
174
+ version: isStandardFhir ? "4.0.1" : packageInfo?.version || "undefined",
175
+ name: element.type,
176
+ url: typeUrl,
177
+ };
178
+ }
179
+ return undefined;
180
+ }
181
+ /**
182
+ * Build a TypeSchema field from a FHIRSchema element
183
+ */
184
+ export async function buildField(fhirSchema, path, element, manager, packageInfo) {
185
+ const field = {
186
+ array: element.array || false,
187
+ required: isRequired(fhirSchema, path, manager),
188
+ excluded: isExcluded(fhirSchema, path, manager),
189
+ };
190
+ // Add type if present
191
+ const type = buildFieldType(fhirSchema, path, element, manager, packageInfo);
192
+ if (type) {
193
+ field.type = type;
194
+ }
195
+ // Add cardinality
196
+ if (element.min !== undefined)
197
+ field.min = element.min;
198
+ if (element.max !== undefined)
199
+ field.max = element.max;
200
+ // Add choices
201
+ // @ts-ignore
202
+ if (element.choices)
203
+ field.choices = element.choices;
204
+ // @ts-ignore
205
+ if (element.choiceOf)
206
+ field.choiceOf = element.choiceOf;
207
+ // Add binding if present
208
+ if (element.binding) {
209
+ field.binding = buildBindingIdentifier(fhirSchema, path, element.binding.bindingName, packageInfo);
210
+ // Add enum for required bindings on code types
211
+ if (element.binding.strength === "required" && element.type === "code") {
212
+ const enumValues = await buildEnum(element, manager);
213
+ if (enumValues && enumValues.length > 0) {
214
+ field.enum = enumValues;
215
+ }
216
+ }
217
+ }
218
+ // Add references
219
+ const references = await buildReferences(element, manager, packageInfo);
220
+ if (references) {
221
+ field.reference = references;
222
+ }
223
+ // Remove empty/default values
224
+ return removeEmptyValues(field);
225
+ }
226
+ /**
227
+ * Remove empty values from an object
228
+ */
229
+ function removeEmptyValues(obj) {
230
+ const result = {};
231
+ for (const [key, value] of Object.entries(obj)) {
232
+ if (value !== undefined && value !== null) {
233
+ if (Array.isArray(value) && value.length === 0) {
234
+ continue;
235
+ }
236
+ result[key] = value;
237
+ }
238
+ }
239
+ return result;
240
+ }
241
+ /**
242
+ * Check if an element represents a nested type (BackboneElement)
243
+ */
244
+ export function isNestedElement(element) {
245
+ return (element.type === "BackboneElement" ||
246
+ (element.elements && Object.keys(element.elements).length > 0) ||
247
+ false);
248
+ }
249
+ /**
250
+ * Build a field reference to a nested type
251
+ */
252
+ export function buildNestedField(fhirSchema, path, element, manager, packageInfo) {
253
+ return {
254
+ type: buildNestedIdentifier(fhirSchema, path, packageInfo),
255
+ array: element.array || false,
256
+ required: isRequired(fhirSchema, path, manager),
257
+ excluded: isExcluded(fhirSchema, path, manager),
258
+ };
259
+ }
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Identifier Building Utilities
3
+ *
4
+ * Functions for creating TypeSchema identifiers from FHIRSchema entities
5
+ */
6
+ /**
7
+ * Drop version suffix from canonical URL (e.g., "http://example.com|1.0.0" -> "http://example.com")
8
+ */
9
+ export function dropVersionFromUrl(url) {
10
+ if (!url)
11
+ return undefined;
12
+ return url.split("|")[0];
13
+ }
14
+ /**
15
+ * Determine the kind of schema based on FHIRSchema properties
16
+ */
17
+ function determineKind(fhirSchema) {
18
+ // Check for constraint/profile
19
+ if (fhirSchema.derivation === "constraint") {
20
+ // Distinguish between profiles and other constraints
21
+ // Profiles typically constrain resources or complex types and have a base type
22
+ if (fhirSchema.base &&
23
+ (fhirSchema.type === "Resource" ||
24
+ fhirSchema.kind === "resource" ||
25
+ fhirSchema.kind === "complex-type")) {
26
+ return "profile";
27
+ }
28
+ return "profile";
29
+ }
30
+ // Use explicit kind if available
31
+ if (fhirSchema.kind) {
32
+ switch (fhirSchema.kind) {
33
+ case "primitive-type":
34
+ return "primitive-type";
35
+ case "complex-type":
36
+ return "complex-type";
37
+ case "resource":
38
+ return "resource";
39
+ }
40
+ }
41
+ // Default to resource
42
+ return "resource";
43
+ }
44
+ /**
45
+ * Build identifier for primitive-type, complex-type, resource, or constraint
46
+ */
47
+ export function buildSchemaIdentifier(fhirSchema, packageInfo) {
48
+ const kind = determineKind(fhirSchema);
49
+ return {
50
+ kind,
51
+ package: packageInfo?.name || fhirSchema.package_name || "undefined",
52
+ version: packageInfo?.version || fhirSchema.package_version || "undefined",
53
+ name: fhirSchema.name,
54
+ url: fhirSchema.url,
55
+ };
56
+ }
57
+ /**
58
+ * Build nested type identifier for BackboneElements
59
+ */
60
+ export function buildNestedIdentifier(fhirSchema, path, packageInfo) {
61
+ const nestedName = path.join(".");
62
+ return {
63
+ kind: "nested",
64
+ package: packageInfo?.name || fhirSchema.package_name || "undefined",
65
+ version: packageInfo?.version || fhirSchema.package_version || "undefined",
66
+ name: nestedName,
67
+ url: `${fhirSchema.url}#${nestedName}`,
68
+ };
69
+ }
70
+ /**
71
+ * Build value set identifier
72
+ */
73
+ export function buildValueSetIdentifier(valueSetUrl, valueSet, packageInfo) {
74
+ const cleanUrl = dropVersionFromUrl(valueSetUrl) || valueSetUrl;
75
+ // Generate a meaningful name from the URL instead of using potentially hash-like IDs
76
+ let name = "unknown";
77
+ // First try to get the last segment of the URL path
78
+ const urlParts = cleanUrl.split("/");
79
+ const lastSegment = urlParts[urlParts.length - 1];
80
+ if (lastSegment && lastSegment.length > 0) {
81
+ // Convert kebab-case or snake_case to PascalCase for better readability
82
+ name = lastSegment
83
+ .split(/[-_]/)
84
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
85
+ .join("");
86
+ }
87
+ // Only fall back to valueSet.id if we couldn't extract a meaningful name from URL
88
+ // and the ID doesn't look like a hash (no long alphanumeric strings)
89
+ if (name === "unknown" &&
90
+ valueSet?.id &&
91
+ !/^[a-zA-Z0-9_-]{20,}$/.test(valueSet.id)) {
92
+ name = valueSet.id;
93
+ }
94
+ return {
95
+ kind: "value-set",
96
+ package: packageInfo?.name || valueSet?.package_name || "undefined",
97
+ version: packageInfo?.version || valueSet?.package_version || "undefined",
98
+ name,
99
+ url: cleanUrl,
100
+ };
101
+ }
102
+ /**
103
+ * Build binding identifier for an element with value set binding
104
+ */
105
+ export function buildBindingIdentifier(fhirSchema, path, bindingName, packageInfo) {
106
+ const pathStr = path.join(".");
107
+ const name = bindingName || `${fhirSchema.name}.${pathStr}_binding`;
108
+ return {
109
+ kind: "binding",
110
+ package: packageInfo?.name || fhirSchema.package_name || "undefined",
111
+ version: packageInfo?.version || fhirSchema.package_version || "undefined",
112
+ name,
113
+ url: bindingName
114
+ ? `urn:fhir:binding:${name}`
115
+ : `${fhirSchema.url}#${pathStr}_binding`,
116
+ };
117
+ }
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import type { CanonicalManager } from "@atomic-ehr/fhir-canonical-manager";
7
7
  import type { FHIRSchema, FHIRSchemaElement } from "@atomic-ehr/fhirschema";
8
- import type { PackageInfo, TypeSchemaField, TypeSchemaIdentifier } from "../types";
8
+ import type { PackageInfo, TypeSchemaField, TypeSchemaIdentifier } from "../types.js";
9
9
  /**
10
10
  * Collect all nested elements from a FHIRSchema
11
11
  */
@@ -1 +1 @@
1
- {"version":3,"file":"nested-types.d.ts","sourceRoot":"","sources":["../../../src/typeschema/core/nested-types.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC5E,OAAO,KAAK,EACX,WAAW,EACX,eAAe,EACf,oBAAoB,EACpB,MAAM,UAAU,CAAC;AAIlB;;GAEG;AACH,wBAAgB,qBAAqB,CACpC,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,MAAM,EAAE,EACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,GACzC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAkBtC;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC5C,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,MAAM,EAAE,EACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAC3C,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EAC5C,WAAW,CAAC,EAAE,WAAW,GACvB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CA4B1C;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACrC,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EAC5C,WAAW,CAAC,EAAE,WAAW,GACvB,OAAO,CAAC,GAAG,EAAE,CAAC,CAgEhB;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACxC,WAAW,EAAE,oBAAoB,EAAE,GACjC,oBAAoB,EAAE,CAwBxB"}
1
+ {"version":3,"file":"nested-types.d.ts","sourceRoot":"","sources":["../../../src/typeschema/core/nested-types.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC5E,OAAO,KAAK,EACX,WAAW,EACX,eAAe,EACf,oBAAoB,EACpB,MAAM,aAAa,CAAC;AAQrB;;GAEG;AACH,wBAAgB,qBAAqB,CACpC,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,MAAM,EAAE,EACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,GACzC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAkBtC;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC5C,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,MAAM,EAAE,EACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAC3C,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EAC5C,WAAW,CAAC,EAAE,WAAW,GACvB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CA4B1C;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACrC,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EAC5C,WAAW,CAAC,EAAE,WAAW,GACvB,OAAO,CAAC,GAAG,EAAE,CAAC,CAgEhB;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACxC,WAAW,EAAE,oBAAoB,EAAE,GACjC,oBAAoB,EAAE,CAwBxB"}
@@ -0,0 +1,111 @@
1
+ // @ts-nocheck
2
+ import { buildField, buildNestedField, isNestedElement, } from "./field-builder.js";
3
+ import { buildNestedIdentifier } from "./identifier.js";
4
+ /**
5
+ * Collect all nested elements from a FHIRSchema
6
+ */
7
+ export function collectNestedElements(fhirSchema, parentPath, elements) {
8
+ const nested = [];
9
+ for (const [key, element] of Object.entries(elements)) {
10
+ const path = [...parentPath, key];
11
+ // Add this element if it's nested (BackboneElement or has elements)
12
+ if (isNestedElement(element)) {
13
+ nested.push([path, element]);
14
+ }
15
+ // Recursively collect from child elements
16
+ if (element.elements) {
17
+ nested.push(...collectNestedElements(fhirSchema, path, element.elements));
18
+ }
19
+ }
20
+ return nested;
21
+ }
22
+ /**
23
+ * Transform elements into fields for a nested type
24
+ */
25
+ export async function transformNestedElements(fhirSchema, parentPath, elements, manager, packageInfo) {
26
+ const fields = {};
27
+ for (const [key, element] of Object.entries(elements)) {
28
+ const path = [...parentPath, key];
29
+ if (isNestedElement(element)) {
30
+ // Reference to another nested type
31
+ fields[key] = buildNestedField(fhirSchema, path, element, manager, packageInfo);
32
+ }
33
+ else {
34
+ // Regular field
35
+ fields[key] = await buildField(fhirSchema, path, element, manager, packageInfo);
36
+ }
37
+ }
38
+ return fields;
39
+ }
40
+ /**
41
+ * Build TypeSchema for all nested types in a FHIRSchema
42
+ */
43
+ export async function buildNestedTypes(fhirSchema, manager, packageInfo) {
44
+ if (!fhirSchema.elements)
45
+ return [];
46
+ const nestedTypes = [];
47
+ const nestedElements = collectNestedElements(fhirSchema, [], fhirSchema.elements);
48
+ // Filter to only include elements that have sub-elements (actual nested types)
49
+ const actualNested = nestedElements.filter(([_, element]) => element.elements && Object.keys(element.elements).length > 0);
50
+ for (const [path, element] of actualNested) {
51
+ const identifier = buildNestedIdentifier(fhirSchema, path, packageInfo);
52
+ // Base is usually BackboneElement - ensure all nested types have a base
53
+ // biome-ignore lint/suspicious/noImplicitAnyLet: <explanation>
54
+ let base;
55
+ if (element.type === "BackboneElement" || !element.type) {
56
+ // For BackboneElement or undefined type, always use BackboneElement as base
57
+ base = {
58
+ kind: "complex-type",
59
+ package: packageInfo?.name || "hl7.fhir.r4.core",
60
+ version: packageInfo?.version || "4.0.1",
61
+ name: "BackboneElement",
62
+ url: "http://hl7.org/fhir/StructureDefinition/BackboneElement",
63
+ };
64
+ }
65
+ else {
66
+ // Use the specified type as base
67
+ base = {
68
+ kind: "complex-type",
69
+ package: packageInfo?.name || "hl7.fhir.r4.core",
70
+ version: packageInfo?.version || "4.0.1",
71
+ name: element.type,
72
+ url: `http://hl7.org/fhir/StructureDefinition/${element.type}`,
73
+ };
74
+ }
75
+ // Transform sub-elements into fields
76
+ const fields = await transformNestedElements(fhirSchema, path, element.elements, manager, packageInfo);
77
+ const nestedType = {
78
+ identifier,
79
+ base, // Always include base
80
+ fields,
81
+ };
82
+ nestedTypes.push(nestedType);
83
+ }
84
+ // Sort by URL for consistent output
85
+ nestedTypes.sort((a, b) => a.identifier.url.localeCompare(b.identifier.url));
86
+ return nestedTypes;
87
+ }
88
+ /**
89
+ * Extract dependencies from nested types
90
+ */
91
+ export function extractNestedDependencies(nestedTypes) {
92
+ const deps = [];
93
+ for (const nested of nestedTypes) {
94
+ // Add the nested type itself as a dependency
95
+ deps.push(nested.identifier);
96
+ // Add base dependency
97
+ if (nested.base) {
98
+ deps.push(nested.base);
99
+ }
100
+ // Add field type dependencies
101
+ for (const field of Object.values(nested.fields)) {
102
+ if ("type" in field && field.type) {
103
+ deps.push(field.type);
104
+ }
105
+ if ("binding" in field && field.binding) {
106
+ deps.push(field.binding);
107
+ }
108
+ }
109
+ }
110
+ return deps;
111
+ }
@@ -5,8 +5,8 @@
5
5
  */
6
6
  import type { CanonicalManager } from "@atomic-ehr/fhir-canonical-manager";
7
7
  import type { FHIRSchema, FHIRSchemaElement } from "@atomic-ehr/fhirschema";
8
- import type { TypeSchema, TypeSchemaField } from "../type-schema.types";
9
- import type { PackageInfo } from "../types";
8
+ import type { TypeSchema, TypeSchemaField } from "../type-schema.types.js";
9
+ import type { PackageInfo } from "../types.js";
10
10
  /**
11
11
  * Transform elements into fields
12
12
  */
@@ -1 +1 @@
1
- {"version":3,"file":"transformer.d.ts","sourceRoot":"","sources":["../../../src/typeschema/core/transformer.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE5E,OAAO,KAAK,EACX,UAAU,EACV,eAAe,EAGf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAY5C;;GAEG;AACH,wBAAsB,iBAAiB,CACtC,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,MAAM,EAAE,EACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAC3C,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EAC5C,WAAW,CAAC,EAAE,WAAW,GACvB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAiC1C;AAqOD;;;GAGG;AACH,wBAAsB,mBAAmB,CACxC,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EAC5C,WAAW,CAAC,EAAE,WAAW,GACvB,OAAO,CAAC,UAAU,EAAE,CAAC,CAmMvB;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACzC,WAAW,EAAE,UAAU,EAAE,EACzB,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EAC5C,WAAW,CAAC,EAAE,WAAW,GACvB,OAAO,CAAC,UAAU,EAAE,CAAC,CASvB"}
1
+ {"version":3,"file":"transformer.d.ts","sourceRoot":"","sources":["../../../src/typeschema/core/transformer.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE5E,OAAO,KAAK,EACX,UAAU,EACV,eAAe,EAGf,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAY/C;;GAEG;AACH,wBAAsB,iBAAiB,CACtC,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,MAAM,EAAE,EACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAC3C,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EAC5C,WAAW,CAAC,EAAE,WAAW,GACvB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAiC1C;AAqOD;;;GAGG;AACH,wBAAsB,mBAAmB,CACxC,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EAC5C,WAAW,CAAC,EAAE,WAAW,GACvB,OAAO,CAAC,UAAU,EAAE,CAAC,CAmMvB;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACzC,WAAW,EAAE,UAAU,EAAE,EACzB,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EAC5C,WAAW,CAAC,EAAE,WAAW,GACvB,OAAO,CAAC,UAAU,EAAE,CAAC,CASvB"}