@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
package/dist/config.js ADDED
@@ -0,0 +1,703 @@
1
+ /**
2
+ * New Config Schema for High-Level API
3
+ *
4
+ * Simple configuration system compatible ONLY with the new high-level APIBuilder.
5
+ * All legacy config functionality has been removed.
6
+ */
7
+ import { existsSync } from "node:fs";
8
+ import { readFile } from "node:fs/promises";
9
+ import { resolve } from "node:path";
10
+ /**
11
+ * Default configuration values
12
+ */
13
+ export const DEFAULT_CONFIG = {
14
+ outputDir: "./generated",
15
+ verbose: false,
16
+ overwrite: true,
17
+ validate: true,
18
+ cache: true,
19
+ restClient: {
20
+ clientName: "FHIRClient",
21
+ includeValidation: false,
22
+ includeErrorHandling: true,
23
+ includeRequestInterceptors: false,
24
+ baseUrlOverride: "",
25
+ enhancedSearch: false,
26
+ chainedSearchBuilder: false,
27
+ searchAutocomplete: true,
28
+ generateValueSetEnums: true,
29
+ includeUtilities: true,
30
+ generateValidators: false,
31
+ useCanonicalManager: true,
32
+ defaultTimeout: 30000,
33
+ defaultRetries: 0,
34
+ includeDocumentation: true,
35
+ generateExamples: false,
36
+ },
37
+ typescript: {
38
+ moduleFormat: "esm",
39
+ generateIndex: true,
40
+ includeDocuments: false,
41
+ namingConvention: "PascalCase",
42
+ strictMode: true,
43
+ includeProfiles: true,
44
+ includeExtensions: false,
45
+ includeValueSets: true,
46
+ includeCodeSystems: false,
47
+ includeOperations: false,
48
+ fhirVersion: "R4",
49
+ resourceTypes: [],
50
+ maxDepth: 10,
51
+ // Profile generation defaults
52
+ profileOptions: {
53
+ generateKind: "interface",
54
+ includeConstraints: true,
55
+ includeDocumentation: true,
56
+ strictMode: false,
57
+ subfolder: "profiles",
58
+ },
59
+ // Builder generation defaults
60
+ generateBuilders: false,
61
+ builderOptions: {
62
+ includeValidation: true,
63
+ includeFactoryMethods: true,
64
+ includeInterfaces: true,
65
+ generateNestedBuilders: true,
66
+ includeHelperMethods: true,
67
+ supportPartialBuild: true,
68
+ includeJSDoc: true,
69
+ generateFactories: true,
70
+ includeTypeGuards: true,
71
+ handleChoiceTypes: true,
72
+ generateArrayHelpers: true,
73
+ },
74
+ // Validator generation defaults
75
+ validatorOptions: {
76
+ includeCardinality: true,
77
+ includeTypes: true,
78
+ includeConstraints: true,
79
+ includeInvariants: false,
80
+ validateRequired: true,
81
+ allowAdditional: false,
82
+ strictValidation: false,
83
+ collectMetrics: false,
84
+ generateAssertions: true,
85
+ generatePartialValidators: true,
86
+ optimizePerformance: true,
87
+ includeJSDoc: true,
88
+ generateCompositeValidators: true,
89
+ },
90
+ // Type guard generation defaults
91
+ guardOptions: {
92
+ includeRuntimeValidation: true,
93
+ includeErrorMessages: true,
94
+ treeShakeable: true,
95
+ targetTSVersion: "5.0",
96
+ strictGuards: false,
97
+ includeNullChecks: true,
98
+ verbose: false,
99
+ },
100
+ },
101
+ typeSchema: {
102
+ enablePersistence: true,
103
+ cacheDir: ".typeschema-cache",
104
+ maxAge: 24 * 60 * 60 * 1000, // 24 hours in milliseconds
105
+ validateCached: true,
106
+ forceRegenerate: false,
107
+ shareCache: true,
108
+ cacheKeyPrefix: "",
109
+ treeshake: [],
110
+ singleFile: false,
111
+ profiles: {
112
+ autoDetect: true,
113
+ },
114
+ },
115
+ packages: [],
116
+ files: [],
117
+ $schema: "",
118
+ };
119
+ /**
120
+ * Configuration file names to search for
121
+ */
122
+ export const CONFIG_FILE_NAMES = [
123
+ "atomic-codegen.config.ts",
124
+ "atomic-codegen.config.js",
125
+ "atomic-codegen.config.json",
126
+ ".atomic-codegenrc",
127
+ "atomic-codegen.json",
128
+ ".atomic-codegen.json",
129
+ "codegen.config.json",
130
+ "codegen.json",
131
+ ];
132
+ /**
133
+ * Simple configuration validator
134
+ */
135
+ export class ConfigValidator {
136
+ /**
137
+ * Validate a configuration object
138
+ */
139
+ validate(config) {
140
+ const result = {
141
+ valid: true,
142
+ errors: [],
143
+ warnings: [],
144
+ };
145
+ if (!config || typeof config !== "object") {
146
+ result.valid = false;
147
+ result.errors.push({
148
+ path: "root",
149
+ message: "Configuration must be an object",
150
+ value: config,
151
+ });
152
+ return result;
153
+ }
154
+ const cfg = config;
155
+ // Validate outputDir
156
+ if (cfg.outputDir !== undefined && typeof cfg.outputDir !== "string") {
157
+ result.errors.push({
158
+ path: "outputDir",
159
+ message: "outputDir must be a string",
160
+ value: cfg.outputDir,
161
+ });
162
+ }
163
+ // Validate boolean fields
164
+ const booleanFields = ["verbose", "overwrite", "validate", "cache"];
165
+ for (const field of booleanFields) {
166
+ if (cfg[field] !== undefined && typeof cfg[field] !== "boolean") {
167
+ result.errors.push({
168
+ path: field,
169
+ message: `${field} must be a boolean`,
170
+ value: cfg[field],
171
+ });
172
+ }
173
+ }
174
+ // Validate typescript config
175
+ if (cfg.typescript !== undefined) {
176
+ const tsErrors = this.validateTypeScriptConfig(cfg.typescript);
177
+ result.errors.push(...tsErrors);
178
+ }
179
+ // Validate typeSchema config
180
+ if (cfg.typeSchema !== undefined) {
181
+ const tsErrors = this.validateTypeSchemaConfig(cfg.typeSchema);
182
+ result.errors.push(...tsErrors);
183
+ }
184
+ // Validate restClient config
185
+ if (cfg.restClient !== undefined) {
186
+ const rcErrors = this.validateRestClientConfig(cfg.restClient);
187
+ result.errors.push(...rcErrors);
188
+ }
189
+ // Validate packages array
190
+ if (cfg.packages !== undefined) {
191
+ if (!Array.isArray(cfg.packages)) {
192
+ result.errors.push({
193
+ path: "packages",
194
+ message: "packages must be an array",
195
+ value: cfg.packages,
196
+ });
197
+ }
198
+ else {
199
+ cfg.packages.forEach((pkg, index) => {
200
+ if (typeof pkg !== "string") {
201
+ result.errors.push({
202
+ path: `packages[${index}]`,
203
+ message: "package name must be a string",
204
+ value: pkg,
205
+ });
206
+ }
207
+ });
208
+ }
209
+ }
210
+ // Validate files array
211
+ if (cfg.files !== undefined) {
212
+ if (!Array.isArray(cfg.files)) {
213
+ result.errors.push({
214
+ path: "files",
215
+ message: "files must be an array",
216
+ value: cfg.files,
217
+ });
218
+ }
219
+ else {
220
+ cfg.files.forEach((file, index) => {
221
+ if (typeof file !== "string") {
222
+ result.errors.push({
223
+ path: `files[${index}]`,
224
+ message: "file path must be a string",
225
+ value: file,
226
+ });
227
+ }
228
+ });
229
+ }
230
+ }
231
+ result.valid = result.errors.length === 0;
232
+ if (result.valid) {
233
+ result.config = cfg;
234
+ }
235
+ return result;
236
+ }
237
+ validateTypeScriptConfig(config) {
238
+ const errors = [];
239
+ if (typeof config !== "object" || config === null) {
240
+ errors.push({
241
+ path: "typescript",
242
+ message: "typescript config must be an object",
243
+ value: config,
244
+ });
245
+ return errors;
246
+ }
247
+ const cfg = config;
248
+ // Validate moduleFormat
249
+ if (cfg.moduleFormat !== undefined) {
250
+ if (!["esm", "cjs"].includes(cfg.moduleFormat)) {
251
+ errors.push({
252
+ path: "typescript.moduleFormat",
253
+ message: 'moduleFormat must be "esm" or "cjs"',
254
+ value: cfg.moduleFormat,
255
+ });
256
+ }
257
+ }
258
+ // Validate namingConvention
259
+ if (cfg.namingConvention !== undefined) {
260
+ if (!["PascalCase", "camelCase"].includes(cfg.namingConvention)) {
261
+ errors.push({
262
+ path: "typescript.namingConvention",
263
+ message: 'namingConvention must be "PascalCase" or "camelCase"',
264
+ value: cfg.namingConvention,
265
+ });
266
+ }
267
+ }
268
+ // Validate boolean fields
269
+ const booleanFields = [
270
+ "generateIndex",
271
+ "includeDocuments",
272
+ "strictMode",
273
+ "includeProfiles",
274
+ "includeExtensions",
275
+ ];
276
+ for (const field of booleanFields) {
277
+ if (cfg[field] !== undefined && typeof cfg[field] !== "boolean") {
278
+ errors.push({
279
+ path: `typescript.${field}`,
280
+ message: `${field} must be a boolean`,
281
+ value: cfg[field],
282
+ });
283
+ }
284
+ }
285
+ // Validate validatorOptions
286
+ if (cfg.validatorOptions !== undefined) {
287
+ const validatorErrors = this.validateValidatorOptions(cfg.validatorOptions);
288
+ errors.push(...validatorErrors);
289
+ }
290
+ // Validate guardOptions
291
+ if (cfg.guardOptions !== undefined) {
292
+ const guardErrors = this.validateGuardOptions(cfg.guardOptions);
293
+ errors.push(...guardErrors);
294
+ }
295
+ // Validate profileOptions
296
+ if (cfg.profileOptions !== undefined) {
297
+ const profileErrors = this.validateProfileOptions(cfg.profileOptions);
298
+ errors.push(...profileErrors);
299
+ }
300
+ return errors;
301
+ }
302
+ validateValidatorOptions(config) {
303
+ const errors = [];
304
+ if (typeof config !== "object" || config === null) {
305
+ errors.push({
306
+ path: "typescript.validatorOptions",
307
+ message: "validatorOptions must be an object",
308
+ value: config,
309
+ });
310
+ return errors;
311
+ }
312
+ const cfg = config;
313
+ // Validate boolean fields
314
+ const booleanFields = [
315
+ "includeCardinality",
316
+ "includeTypes",
317
+ "includeConstraints",
318
+ "includeInvariants",
319
+ "validateRequired",
320
+ "allowAdditional",
321
+ "strictValidation",
322
+ "collectMetrics",
323
+ "generateAssertions",
324
+ "generatePartialValidators",
325
+ "optimizePerformance",
326
+ "includeJSDoc",
327
+ "generateCompositeValidators",
328
+ ];
329
+ for (const field of booleanFields) {
330
+ if (cfg[field] !== undefined && typeof cfg[field] !== "boolean") {
331
+ errors.push({
332
+ path: `typescript.validatorOptions.${field}`,
333
+ message: `${field} must be a boolean`,
334
+ value: cfg[field],
335
+ });
336
+ }
337
+ }
338
+ return errors;
339
+ }
340
+ validateRestClientConfig(config) {
341
+ const errors = [];
342
+ if (typeof config !== "object" || config === null) {
343
+ errors.push({
344
+ path: "restClient",
345
+ message: "restClient config must be an object",
346
+ value: config,
347
+ });
348
+ return errors;
349
+ }
350
+ const cfg = config;
351
+ // Validate clientName
352
+ if (cfg.clientName !== undefined && typeof cfg.clientName !== "string") {
353
+ errors.push({
354
+ path: "restClient.clientName",
355
+ message: "clientName must be a string",
356
+ value: cfg.clientName,
357
+ });
358
+ }
359
+ // Validate baseUrlOverride
360
+ if (cfg.baseUrlOverride !== undefined &&
361
+ typeof cfg.baseUrlOverride !== "string") {
362
+ errors.push({
363
+ path: "restClient.baseUrlOverride",
364
+ message: "baseUrlOverride must be a string",
365
+ value: cfg.baseUrlOverride,
366
+ });
367
+ }
368
+ // Validate timeout
369
+ if (cfg.defaultTimeout !== undefined) {
370
+ if (typeof cfg.defaultTimeout !== "number" || cfg.defaultTimeout <= 0) {
371
+ errors.push({
372
+ path: "restClient.defaultTimeout",
373
+ message: "defaultTimeout must be a positive number",
374
+ value: cfg.defaultTimeout,
375
+ });
376
+ }
377
+ }
378
+ // Validate retries
379
+ if (cfg.defaultRetries !== undefined) {
380
+ if (typeof cfg.defaultRetries !== "number" || cfg.defaultRetries < 0) {
381
+ errors.push({
382
+ path: "restClient.defaultRetries",
383
+ message: "defaultRetries must be a non-negative number",
384
+ value: cfg.defaultRetries,
385
+ });
386
+ }
387
+ }
388
+ // Validate boolean fields
389
+ const booleanFields = [
390
+ "includeValidation",
391
+ "includeErrorHandling",
392
+ "includeRequestInterceptors",
393
+ "enhancedSearch",
394
+ "chainedSearchBuilder",
395
+ "searchAutocomplete",
396
+ "generateValueSetEnums",
397
+ "includeUtilities",
398
+ "generateValidators",
399
+ "useCanonicalManager",
400
+ "includeDocumentation",
401
+ "generateExamples",
402
+ ];
403
+ for (const field of booleanFields) {
404
+ if (cfg[field] !== undefined && typeof cfg[field] !== "boolean") {
405
+ errors.push({
406
+ path: `restClient.${field}`,
407
+ message: `${field} must be a boolean`,
408
+ value: cfg[field],
409
+ });
410
+ }
411
+ }
412
+ return errors;
413
+ }
414
+ validateGuardOptions(config) {
415
+ const errors = [];
416
+ if (typeof config !== "object" || config === null) {
417
+ errors.push({
418
+ path: "typescript.guardOptions",
419
+ message: "guardOptions must be an object",
420
+ value: config,
421
+ });
422
+ return errors;
423
+ }
424
+ const cfg = config;
425
+ // Validate targetTSVersion
426
+ if (cfg.targetTSVersion !== undefined) {
427
+ if (!["3.8", "4.0", "4.5", "5.0"].includes(cfg.targetTSVersion)) {
428
+ errors.push({
429
+ path: "typescript.guardOptions.targetTSVersion",
430
+ message: 'targetTSVersion must be one of: "3.8", "4.0", "4.5", "5.0"',
431
+ value: cfg.targetTSVersion,
432
+ });
433
+ }
434
+ }
435
+ // Validate boolean fields
436
+ const booleanFields = [
437
+ "includeRuntimeValidation",
438
+ "includeErrorMessages",
439
+ "treeShakeable",
440
+ "strictGuards",
441
+ "includeNullChecks",
442
+ "verbose",
443
+ ];
444
+ for (const field of booleanFields) {
445
+ if (cfg[field] !== undefined && typeof cfg[field] !== "boolean") {
446
+ errors.push({
447
+ path: `typescript.guardOptions.${field}`,
448
+ message: `${field} must be a boolean`,
449
+ value: cfg[field],
450
+ });
451
+ }
452
+ }
453
+ return errors;
454
+ }
455
+ validateProfileOptions(config) {
456
+ const errors = [];
457
+ if (typeof config !== "object" || config === null) {
458
+ errors.push({
459
+ path: "typescript.profileOptions",
460
+ message: "profileOptions must be an object",
461
+ value: config,
462
+ });
463
+ return errors;
464
+ }
465
+ const cfg = config;
466
+ // Validate generateKind
467
+ if (cfg.generateKind !== undefined) {
468
+ if (!["interface", "type", "both"].includes(cfg.generateKind)) {
469
+ errors.push({
470
+ path: "typescript.profileOptions.generateKind",
471
+ message: 'generateKind must be "interface", "type", or "both"',
472
+ value: cfg.generateKind,
473
+ });
474
+ }
475
+ }
476
+ // Validate subfolder
477
+ if (cfg.subfolder !== undefined && typeof cfg.subfolder !== "string") {
478
+ errors.push({
479
+ path: "typescript.profileOptions.subfolder",
480
+ message: "subfolder must be a string",
481
+ value: cfg.subfolder,
482
+ });
483
+ }
484
+ // Validate boolean fields
485
+ const booleanFields = [
486
+ "includeConstraints",
487
+ "includeDocumentation",
488
+ "strictMode",
489
+ ];
490
+ for (const field of booleanFields) {
491
+ if (cfg[field] !== undefined && typeof cfg[field] !== "boolean") {
492
+ errors.push({
493
+ path: `typescript.profileOptions.${field}`,
494
+ message: `${field} must be a boolean`,
495
+ value: cfg[field],
496
+ });
497
+ }
498
+ }
499
+ return errors;
500
+ }
501
+ validateTypeSchemaConfig(config) {
502
+ const errors = [];
503
+ if (typeof config !== "object" || config === null) {
504
+ errors.push({
505
+ path: "typeSchema",
506
+ message: "typeSchema config must be an object",
507
+ value: config,
508
+ });
509
+ return errors;
510
+ }
511
+ const cfg = config;
512
+ // Validate boolean fields
513
+ const booleanFields = [
514
+ "enablePersistence",
515
+ "validateCached",
516
+ "forceRegenerate",
517
+ "shareCache",
518
+ ];
519
+ for (const field of booleanFields) {
520
+ if (cfg[field] !== undefined && typeof cfg[field] !== "boolean") {
521
+ errors.push({
522
+ path: `typeSchema.${field}`,
523
+ message: `${field} must be a boolean`,
524
+ value: cfg[field],
525
+ });
526
+ }
527
+ }
528
+ // Validate string fields
529
+ const stringFields = ["cacheDir", "cacheKeyPrefix"];
530
+ for (const field of stringFields) {
531
+ if (cfg[field] !== undefined && typeof cfg[field] !== "string") {
532
+ errors.push({
533
+ path: `typeSchema.${field}`,
534
+ message: `${field} must be a string`,
535
+ value: cfg[field],
536
+ });
537
+ }
538
+ }
539
+ // Validate maxAge
540
+ if (cfg.maxAge !== undefined) {
541
+ if (typeof cfg.maxAge !== "number" || cfg.maxAge <= 0) {
542
+ errors.push({
543
+ path: "typeSchema.maxAge",
544
+ message: "maxAge must be a positive number",
545
+ value: cfg.maxAge,
546
+ });
547
+ }
548
+ }
549
+ // Validate profiles
550
+ if (cfg.profiles !== undefined) {
551
+ if (typeof cfg.profiles !== "object" || cfg.profiles === null) {
552
+ errors.push({
553
+ path: "typeSchema.profiles",
554
+ message: "profiles must be an object",
555
+ value: cfg.profiles,
556
+ });
557
+ }
558
+ else {
559
+ const profiles = cfg.profiles;
560
+ // Validate autoDetect
561
+ if (profiles.autoDetect !== undefined &&
562
+ typeof profiles.autoDetect !== "boolean") {
563
+ errors.push({
564
+ path: "typeSchema.profiles.autoDetect",
565
+ message: "autoDetect must be a boolean",
566
+ value: profiles.autoDetect,
567
+ });
568
+ }
569
+ }
570
+ }
571
+ return errors;
572
+ }
573
+ }
574
+ /**
575
+ * Configuration loader with autoloading capabilities
576
+ */
577
+ export class ConfigLoader {
578
+ validator = new ConfigValidator();
579
+ /**
580
+ * Auto-load configuration from the current working directory
581
+ */
582
+ async autoload(workingDir = process.cwd()) {
583
+ const configPath = await this.findConfigFile(workingDir);
584
+ if (configPath) {
585
+ return this.loadFromFile(configPath);
586
+ }
587
+ // Return default config if no file found
588
+ return { ...DEFAULT_CONFIG };
589
+ }
590
+ /**
591
+ * Load configuration from a specific file
592
+ */
593
+ async loadFromFile(filePath) {
594
+ try {
595
+ let config;
596
+ if (filePath.endsWith(".ts") || filePath.endsWith(".js")) {
597
+ // Use dynamic import for TypeScript/JavaScript files
598
+ const absolutePath = resolve(filePath);
599
+ const importResult = await import(absolutePath);
600
+ config = importResult.default || importResult;
601
+ }
602
+ else {
603
+ // JSON files
604
+ const content = await readFile(filePath, "utf-8");
605
+ config = JSON.parse(content);
606
+ }
607
+ const validation = this.validator.validate(config);
608
+ if (!validation.valid) {
609
+ const errorMessages = validation.errors
610
+ .map((e) => `${e.path}: ${e.message}`)
611
+ .join("\n");
612
+ throw new Error(`Configuration validation failed:\n${errorMessages}`);
613
+ }
614
+ // Merge with defaults
615
+ return this.mergeWithDefaults(validation.config);
616
+ }
617
+ catch (error) {
618
+ if (error instanceof Error) {
619
+ throw new Error(`Failed to load config from ${filePath}: ${error.message}`);
620
+ }
621
+ throw error;
622
+ }
623
+ }
624
+ /**
625
+ * Find configuration file in the given directory
626
+ */
627
+ async findConfigFile(startDir) {
628
+ for (const fileName of CONFIG_FILE_NAMES) {
629
+ const configPath = resolve(startDir, fileName);
630
+ if (existsSync(configPath)) {
631
+ return configPath;
632
+ }
633
+ }
634
+ return null;
635
+ }
636
+ /**
637
+ * Merge user config with defaults
638
+ */
639
+ mergeWithDefaults(userConfig) {
640
+ const merged = {
641
+ ...DEFAULT_CONFIG,
642
+ ...userConfig,
643
+ typescript: {
644
+ ...DEFAULT_CONFIG.typescript,
645
+ ...userConfig.typescript,
646
+ },
647
+ };
648
+ // Only include restClient if it was explicitly defined in user config
649
+ if (userConfig.restClient !== undefined) {
650
+ merged.restClient = {
651
+ ...DEFAULT_CONFIG.restClient,
652
+ ...userConfig.restClient,
653
+ };
654
+ }
655
+ else {
656
+ // Remove restClient from merged config if not defined in user config
657
+ delete merged.restClient;
658
+ }
659
+ return merged;
660
+ }
661
+ }
662
+ /**
663
+ * Global config loader instance
664
+ */
665
+ export const configLoader = new ConfigLoader();
666
+ /**
667
+ * Convenience function to auto-load configuration
668
+ */
669
+ export async function loadConfig(workingDir) {
670
+ return configLoader.autoload(workingDir);
671
+ }
672
+ /**
673
+ * Type guard to check if an object is a valid Config
674
+ */
675
+ export function isConfig(obj) {
676
+ const validator = new ConfigValidator();
677
+ const result = validator.validate(obj);
678
+ return result.valid;
679
+ }
680
+ /**
681
+ * Define configuration with type safety and IntelliSense support.
682
+ * Similar to Vite's defineConfig function pattern.
683
+ *
684
+ * @example
685
+ * ```typescript
686
+ * import { defineConfig } from "@atomic-ehr/codegen";
687
+ *
688
+ * export default defineConfig({
689
+ * outputDir: "./generated",
690
+ * packages: [
691
+ * "hl7.fhir.r4.core@4.0.1",
692
+ * "hl7.fhir.us.core@6.1.0"
693
+ * ],
694
+ * typescript: {
695
+ * generateIndex: true,
696
+ * strictMode: true
697
+ * }
698
+ * });
699
+ * ```
700
+ */
701
+ export function defineConfig(config) {
702
+ return config;
703
+ }
package/dist/index.d.ts CHANGED
@@ -78,6 +78,6 @@
78
78
  * @author Atomic EHR Team
79
79
  * @since 0.0.1
80
80
  */
81
- export * from "./api";
82
- export * from "./config";
81
+ export * from "./api/index.js";
82
+ export * from "./config.js";
83
83
  //# sourceMappingURL=index.d.ts.map