@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,285 @@
1
+ /**
2
+ * TypeSchema Cache System
3
+ *
4
+ * Caching system for TypeSchema documents with both in-memory and persistent file-based storage.
5
+ */
6
+ import { existsSync, mkdirSync } from "node:fs";
7
+ import { readdir, readFile, stat, unlink, writeFile } from "node:fs/promises";
8
+ import { join } from "node:path";
9
+ /**
10
+ * TypeSchema Cache with optional persistent storage
11
+ */
12
+ export class TypeSchemaCache {
13
+ cache = new Map();
14
+ config;
15
+ cacheDir;
16
+ constructor(config) {
17
+ this.config = {
18
+ enablePersistence: true,
19
+ cacheDir: ".typeschema-cache",
20
+ maxAge: 24 * 60 * 60 * 1000, // 24 hours
21
+ validateCached: true,
22
+ ...config,
23
+ };
24
+ if (this.config.enablePersistence && this.config.cacheDir) {
25
+ this.cacheDir = this.config.cacheDir;
26
+ }
27
+ }
28
+ /**
29
+ * Store a schema in the cache
30
+ */
31
+ async set(schema) {
32
+ const key = this.generateKey(schema.identifier);
33
+ this.cache.set(key, schema);
34
+ // Persist to disk if enabled
35
+ if (this.config.enablePersistence && this.cacheDir) {
36
+ await this.persistSchema(schema);
37
+ }
38
+ }
39
+ /**
40
+ * Retrieve a schema by identifier
41
+ */
42
+ get(identifier) {
43
+ const key = this.generateKey(identifier);
44
+ return this.cache.get(key) || null;
45
+ }
46
+ /**
47
+ * Retrieve a schema by URL
48
+ */
49
+ getByUrl(url) {
50
+ for (const schema of this.cache.values()) {
51
+ if (schema.identifier.url === url) {
52
+ return schema;
53
+ }
54
+ }
55
+ return null;
56
+ }
57
+ /**
58
+ * Check if a schema exists in cache
59
+ */
60
+ has(identifier) {
61
+ const key = this.generateKey(identifier);
62
+ return this.cache.has(key);
63
+ }
64
+ /**
65
+ * Check if a schema exists by URL
66
+ */
67
+ hasByUrl(url) {
68
+ for (const schema of this.cache.values()) {
69
+ if (schema.identifier.url === url) {
70
+ return true;
71
+ }
72
+ }
73
+ return false;
74
+ }
75
+ /**
76
+ * Delete a schema from cache
77
+ */
78
+ delete(identifier) {
79
+ const key = this.generateKey(identifier);
80
+ return this.cache.delete(key);
81
+ }
82
+ /**
83
+ * Delete a schema by URL
84
+ */
85
+ deleteByUrl(url) {
86
+ for (const [key, schema] of this.cache.entries()) {
87
+ if (schema.identifier.url === url) {
88
+ return this.cache.delete(key);
89
+ }
90
+ }
91
+ return false;
92
+ }
93
+ /**
94
+ * Get schemas by package
95
+ */
96
+ getByPackage(packageName) {
97
+ const results = [];
98
+ for (const schema of this.cache.values()) {
99
+ if (schema.identifier.package === packageName) {
100
+ results.push(schema);
101
+ }
102
+ }
103
+ return results;
104
+ }
105
+ /**
106
+ * Get schemas by kind
107
+ */
108
+ getByKind(kind) {
109
+ const results = [];
110
+ for (const schema of this.cache.values()) {
111
+ if (schema.identifier.kind === kind) {
112
+ results.push(schema);
113
+ }
114
+ }
115
+ return results;
116
+ }
117
+ /**
118
+ * Store multiple schemas
119
+ */
120
+ setMany(schemas) {
121
+ for (const schema of schemas) {
122
+ this.set(schema);
123
+ }
124
+ }
125
+ /**
126
+ * Clear all cached schemas
127
+ */
128
+ clear() {
129
+ this.cache.clear();
130
+ }
131
+ /**
132
+ * Generate cache key for identifier
133
+ */
134
+ generateKey(identifier) {
135
+ return `${identifier.package}:${identifier.version}:${identifier.kind}:${identifier.name}`;
136
+ }
137
+ /**
138
+ * Initialize cache directory if persistence is enabled
139
+ */
140
+ async initialize() {
141
+ if (this.config.enablePersistence && this.cacheDir) {
142
+ // Ensure cache directory exists
143
+ if (!existsSync(this.cacheDir)) {
144
+ mkdirSync(this.cacheDir, { recursive: true });
145
+ }
146
+ // Load all cached schemas from disk
147
+ await this.loadFromDisk();
148
+ }
149
+ }
150
+ /**
151
+ * Load all cached schemas from disk
152
+ */
153
+ async loadFromDisk() {
154
+ if (!this.cacheDir || !existsSync(this.cacheDir)) {
155
+ return;
156
+ }
157
+ try {
158
+ const files = await readdir(this.cacheDir);
159
+ const schemaFiles = files.filter((f) => f.endsWith(".typeschema.json"));
160
+ for (const file of schemaFiles) {
161
+ const filePath = join(this.cacheDir, file);
162
+ const stats = await stat(filePath);
163
+ // Check if cache is expired
164
+ if (this.config.maxAge) {
165
+ const age = Date.now() - stats.mtimeMs;
166
+ if (age > this.config.maxAge) {
167
+ // Remove expired cache file
168
+ await unlink(filePath);
169
+ continue;
170
+ }
171
+ }
172
+ try {
173
+ const content = await readFile(filePath, "utf-8");
174
+ const metadata = JSON.parse(content);
175
+ // Validate cached schema if configured
176
+ if (this.config.validateCached) {
177
+ // Basic validation - check required fields
178
+ if (!metadata.schema?.identifier) {
179
+ continue;
180
+ }
181
+ }
182
+ // Add to in-memory cache
183
+ const key = this.generateKey(metadata.schema.identifier);
184
+ this.cache.set(key, metadata.schema);
185
+ }
186
+ catch (error) {
187
+ console.warn(`Failed to load cached schema from ${file}:`, error);
188
+ }
189
+ }
190
+ }
191
+ catch (error) {
192
+ console.warn("Failed to load cached schemas from disk:", error);
193
+ }
194
+ }
195
+ /**
196
+ * Persist a schema to disk
197
+ */
198
+ async persistSchema(schema) {
199
+ if (!this.cacheDir) {
200
+ return;
201
+ }
202
+ // Ensure cache directory exists
203
+ if (!existsSync(this.cacheDir)) {
204
+ mkdirSync(this.cacheDir, { recursive: true });
205
+ }
206
+ const metadata = {
207
+ schema,
208
+ timestamp: Date.now(),
209
+ version: schema.identifier.version,
210
+ };
211
+ // Generate filename from identifier
212
+ const fileName = `${schema.identifier.package}-${schema.identifier.version}-${schema.identifier.kind}-${schema.identifier.name}.typeschema.json`.replace(/[^a-zA-Z0-9.-]/g, "_");
213
+ const filePath = join(this.cacheDir, fileName);
214
+ try {
215
+ await writeFile(filePath, JSON.stringify(metadata, null, 2), "utf-8");
216
+ }
217
+ catch (error) {
218
+ console.warn(`Failed to persist schema to ${filePath}:`, error);
219
+ }
220
+ }
221
+ /**
222
+ * Clear cache directory
223
+ */
224
+ async clearDisk() {
225
+ if (!this.cacheDir || !existsSync(this.cacheDir)) {
226
+ return;
227
+ }
228
+ try {
229
+ const files = await readdir(this.cacheDir);
230
+ const schemaFiles = files.filter((f) => f.endsWith(".typeschema.json"));
231
+ for (const file of schemaFiles) {
232
+ await unlink(join(this.cacheDir, file));
233
+ }
234
+ }
235
+ catch (error) {
236
+ console.warn("Failed to clear cache directory:", error);
237
+ }
238
+ }
239
+ }
240
+ // Global cache instance
241
+ let globalCache = null;
242
+ /**
243
+ * Get the global cache instance
244
+ */
245
+ export function getGlobalCache(config) {
246
+ if (!globalCache) {
247
+ globalCache = new TypeSchemaCache(config);
248
+ }
249
+ return globalCache;
250
+ }
251
+ /**
252
+ * Initialize global cache with configuration
253
+ */
254
+ export async function initializeGlobalCache(config) {
255
+ globalCache = new TypeSchemaCache(config);
256
+ await globalCache.initialize();
257
+ return globalCache;
258
+ }
259
+ /**
260
+ * Clear the global cache
261
+ */
262
+ export function clearGlobalCache() {
263
+ if (globalCache) {
264
+ globalCache.clear();
265
+ }
266
+ globalCache = null;
267
+ }
268
+ /**
269
+ * Cache a schema using global cache
270
+ */
271
+ export function cacheSchema(schema) {
272
+ getGlobalCache().set(schema);
273
+ }
274
+ /**
275
+ * Get cached schema using global cache
276
+ */
277
+ export function getCachedSchema(identifier) {
278
+ return getGlobalCache().get(identifier);
279
+ }
280
+ /**
281
+ * Check if schema is cached using global cache
282
+ */
283
+ export function isCached(identifier) {
284
+ return getGlobalCache().has(identifier);
285
+ }
@@ -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, TypeSchemaForBinding } from "../types";
8
+ import type { PackageInfo, TypeSchemaForBinding } from "../types.js";
9
9
  /**
10
10
  * Extract concepts from a ValueSet
11
11
  */
@@ -1 +1 @@
1
- {"version":3,"file":"binding.d.ts","sourceRoot":"","sources":["../../../src/typeschema/core/binding.ts"],"names":[],"mappings":"AACA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC5E,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAQlE;;GAEG;AACH,wBAAsB,uBAAuB,CAC5C,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,GAC1C,OAAO,CACT,KAAK,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,SAAS,CACrE,CA8DA;AAED;;GAEG;AACH,wBAAsB,SAAS,CAC9B,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,GAC1C,OAAO,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,CA4C/B;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAC1C,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EAC5C,WAAW,CAAC,EAAE,WAAW,GACvB,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CA8C3C;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAC1C,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EAC5C,WAAW,CAAC,EAAE,WAAW,GACvB,OAAO,CAAC,oBAAoB,EAAE,CAAC,CA0DjC"}
1
+ {"version":3,"file":"binding.d.ts","sourceRoot":"","sources":["../../../src/typeschema/core/binding.ts"],"names":[],"mappings":"AACA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC5E,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAQrE;;GAEG;AACH,wBAAsB,uBAAuB,CAC5C,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,GAC1C,OAAO,CACT,KAAK,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,SAAS,CACrE,CA8DA;AAED;;GAEG;AACH,wBAAsB,SAAS,CAC9B,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,GAC1C,OAAO,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,CA4C/B;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAC1C,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EAC5C,WAAW,CAAC,EAAE,WAAW,GACvB,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CA8C3C;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAC1C,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EAC5C,WAAW,CAAC,EAAE,WAAW,GACvB,OAAO,CAAC,oBAAoB,EAAE,CAAC,CA0DjC"}
@@ -0,0 +1,187 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * Binding and Enum Handling
4
+ *
5
+ * Functions for processing value set bindings and generating enums
6
+ */
7
+ import { buildFieldType } from "./field-builder.js";
8
+ import { buildBindingIdentifier, buildValueSetIdentifier, dropVersionFromUrl, } from "./identifier.js";
9
+ /**
10
+ * Extract concepts from a ValueSet
11
+ */
12
+ export async function extractValueSetConcepts(valueSetUrl, manager) {
13
+ try {
14
+ const cleanUrl = dropVersionFromUrl(valueSetUrl) || valueSetUrl;
15
+ const valueSet = await manager.resolve(cleanUrl);
16
+ if (!valueSet)
17
+ return undefined;
18
+ // If expansion is available, use it
19
+ if (valueSet.expansion?.contains) {
20
+ return valueSet.expansion.contains.map((concept) => ({
21
+ system: concept.system,
22
+ code: concept.code,
23
+ display: concept.display,
24
+ }));
25
+ }
26
+ // Otherwise try to extract from compose
27
+ const concepts = [];
28
+ if (valueSet.compose?.include) {
29
+ for (const include of valueSet.compose.include) {
30
+ if (include.concept) {
31
+ // Direct concept list
32
+ for (const concept of include.concept) {
33
+ concepts.push({
34
+ system: include.system,
35
+ code: concept.code,
36
+ display: concept.display,
37
+ });
38
+ }
39
+ }
40
+ else if (include.system && !include.filter) {
41
+ // Include all from CodeSystem
42
+ try {
43
+ const codeSystem = await manager.resolve(include.system);
44
+ if (codeSystem?.concept) {
45
+ const extractConcepts = (conceptList, system) => {
46
+ for (const concept of conceptList) {
47
+ concepts.push({
48
+ system,
49
+ code: concept.code,
50
+ display: concept.display,
51
+ });
52
+ // Handle nested concepts
53
+ if (concept.concept) {
54
+ extractConcepts(concept.concept, system);
55
+ }
56
+ }
57
+ };
58
+ extractConcepts(codeSystem.concept, include.system);
59
+ }
60
+ }
61
+ catch {
62
+ // Ignore if we can't resolve the CodeSystem
63
+ }
64
+ }
65
+ }
66
+ }
67
+ return concepts.length > 0 ? concepts : undefined;
68
+ }
69
+ catch {
70
+ return undefined;
71
+ }
72
+ }
73
+ /**
74
+ * Build enum values from binding if applicable
75
+ */
76
+ export async function buildEnum(element, manager) {
77
+ if (!element.binding)
78
+ return undefined;
79
+ const { strength, valueSet } = element.binding;
80
+ if (!valueSet)
81
+ return undefined;
82
+ // Enhanced support for more binding strengths and types
83
+ // Generate enum for:
84
+ // 1. Required bindings (always)
85
+ // 2. Extensible bindings on code types (for better type safety)
86
+ // 3. Preferred bindings on code types (for common usage patterns)
87
+ const shouldGenerateEnum = strength === "required" ||
88
+ (strength === "extensible" && element.type === "code") ||
89
+ (strength === "preferred" && element.type === "code");
90
+ if (!shouldGenerateEnum) {
91
+ return undefined;
92
+ }
93
+ // Check if manager is available and functional
94
+ if (!manager.resolve) {
95
+ return undefined;
96
+ }
97
+ try {
98
+ const concepts = await extractValueSetConcepts(valueSet, manager);
99
+ if (!concepts || concepts.length === 0)
100
+ return undefined;
101
+ // Extract just the codes and filter out any empty/invalid ones
102
+ const codes = concepts
103
+ .map((c) => c.code)
104
+ .filter((code) => code && typeof code === "string" && code.trim().length > 0);
105
+ // Only return if we have valid codes and not too many (avoid huge enums)
106
+ return codes.length > 0 && codes.length <= 50 ? codes : undefined;
107
+ }
108
+ catch (error) {
109
+ // Log the error for debugging but don't fail the generation
110
+ console.debug(`Failed to extract enum values for ${valueSet}: ${error}`);
111
+ return undefined;
112
+ }
113
+ }
114
+ /**
115
+ * Generate a binding TypeSchema
116
+ */
117
+ export async function generateBindingSchema(fhirSchema, path, element, manager, packageInfo) {
118
+ if (!element.binding?.valueSet)
119
+ return undefined;
120
+ const identifier = buildBindingIdentifier(fhirSchema, path, element.binding.bindingName, packageInfo);
121
+ const fieldType = buildFieldType(fhirSchema, path, element, manager, packageInfo);
122
+ const valueSetIdentifier = buildValueSetIdentifier(element.binding.valueSet, undefined, packageInfo);
123
+ const binding = {
124
+ identifier,
125
+ type: fieldType,
126
+ valueset: valueSetIdentifier,
127
+ strength: element.binding.strength,
128
+ dependencies: [],
129
+ };
130
+ // Add dependencies in specific order: type first, then value set
131
+ if (fieldType) {
132
+ binding.dependencies.push(fieldType);
133
+ }
134
+ binding.dependencies.push(valueSetIdentifier);
135
+ // Add enum if applicable
136
+ const enumValues = await buildEnum(element, manager);
137
+ if (enumValues) {
138
+ binding.enum = enumValues;
139
+ }
140
+ // Don't sort dependencies - keep them in the order: type, then value set
141
+ return binding;
142
+ }
143
+ /**
144
+ * Collect all binding schemas from a FHIRSchema
145
+ */
146
+ export async function collectBindingSchemas(fhirSchema, manager, packageInfo) {
147
+ const bindings = [];
148
+ const processedPaths = new Set();
149
+ // Recursive function to process elements
150
+ async function processElement(elements, parentPath) {
151
+ for (const [key, element] of Object.entries(elements)) {
152
+ const path = [...parentPath, key];
153
+ const pathKey = path.join(".");
154
+ // Skip if already processed
155
+ if (processedPaths.has(pathKey))
156
+ continue;
157
+ processedPaths.add(pathKey);
158
+ // Generate binding if present
159
+ if (element.binding) {
160
+ const binding = await generateBindingSchema(fhirSchema, path, element, manager, packageInfo);
161
+ if (binding) {
162
+ bindings.push(binding);
163
+ }
164
+ }
165
+ // Process nested elements
166
+ if (element.elements) {
167
+ await processElement(element.elements, path);
168
+ }
169
+ }
170
+ }
171
+ // Start processing from root elements
172
+ if (fhirSchema.elements) {
173
+ await processElement(fhirSchema.elements, []);
174
+ }
175
+ // Sort bindings by identifier name for consistent output
176
+ bindings.sort((a, b) => a.identifier.name.localeCompare(b.identifier.name));
177
+ // Remove duplicates (same identifier URL)
178
+ const uniqueBindings = [];
179
+ const seenUrls = new Set();
180
+ for (const binding of bindings) {
181
+ if (!seenUrls.has(binding.identifier.url)) {
182
+ seenUrls.add(binding.identifier.url);
183
+ uniqueBindings.push(binding);
184
+ }
185
+ }
186
+ return uniqueBindings;
187
+ }
@@ -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
  * Get the full element hierarchy for a given path
11
11
  */
@@ -1 +1 @@
1
- {"version":3,"file":"field-builder.d.ts","sourceRoot":"","sources":["../../../src/typeschema/core/field-builder.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;AAQlB;;GAEG;AACH,wBAAgB,mBAAmB,CAClC,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,EAAE,EACd,QAAQ,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,GAC3C,iBAAiB,EAAE,CAkBrB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACpC,SAAS,EAAE,iBAAiB,EAAE,GAC5B,iBAAiB,CAoDnB;AAED;;GAEG;AACH,wBAAgB,UAAU,CACzB,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,EAAE,EACd,QAAQ,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,GAC3C,OAAO,CA4BT;AAED;;GAEG;AACH,wBAAgB,UAAU,CACzB,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,EAAE,EACd,QAAQ,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,GAC3C,OAAO,CA4BT;AAED;;GAEG;AACH,wBAAsB,eAAe,CACpC,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EAC5C,WAAW,CAAC,EAAE,WAAW,GACvB,OAAO,CAAC,oBAAoB,EAAE,GAAG,SAAS,CAAC,CAmB7C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC7B,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EAC7C,WAAW,CAAC,EAAE,WAAW,GACvB,oBAAoB,GAAG,SAAS,CAqClC;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC/B,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EAC5C,WAAW,CAAC,EAAE,WAAW,GACvB,OAAO,CAAC,eAAe,CAAC,CAiD1B;AAoBD;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAMnE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC/B,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EAC5C,WAAW,CAAC,EAAE,WAAW,GACvB,eAAe,CAOjB"}
1
+ {"version":3,"file":"field-builder.d.ts","sourceRoot":"","sources":["../../../src/typeschema/core/field-builder.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,mBAAmB,CAClC,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,EAAE,EACd,QAAQ,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,GAC3C,iBAAiB,EAAE,CAkBrB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACpC,SAAS,EAAE,iBAAiB,EAAE,GAC5B,iBAAiB,CAoDnB;AAED;;GAEG;AACH,wBAAgB,UAAU,CACzB,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,EAAE,EACd,QAAQ,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,GAC3C,OAAO,CA4BT;AAED;;GAEG;AACH,wBAAgB,UAAU,CACzB,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,EAAE,EACd,QAAQ,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,GAC3C,OAAO,CA4BT;AAED;;GAEG;AACH,wBAAsB,eAAe,CACpC,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EAC5C,WAAW,CAAC,EAAE,WAAW,GACvB,OAAO,CAAC,oBAAoB,EAAE,GAAG,SAAS,CAAC,CAmB7C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC7B,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EAC7C,WAAW,CAAC,EAAE,WAAW,GACvB,oBAAoB,GAAG,SAAS,CAqClC;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC/B,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EAC5C,WAAW,CAAC,EAAE,WAAW,GACvB,OAAO,CAAC,eAAe,CAAC,CAiD1B;AAoBD;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAMnE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC/B,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,EAC5C,WAAW,CAAC,EAAE,WAAW,GACvB,eAAe,CAOjB"}